/*******************************************************************************
* Copyright (c) 2010-2015 Henshin developers. All rights reserved.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* TU Berlin, University of Luxembourg, SES S.A.
*******************************************************************************/
package de.tub.tfs.henshin.tggeditor.util.rule.concurrent;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.emf.henshin.model.Rule;
import de.tub.tfs.henshin.tgg.TGGRule;
/**
* The ConRuleNamesComparator class provides a comparison method that, based on
* the predefined order of the priorityOrder attribute, checks whether a given
* rule is prior to another given rule according to their rule names.
*
* @author G�rard Kirpach
*/
public class ConcurrentRuleComparator {
public List<String> priorityOrder;
/**
*
* @param order this list contains the reference rules in priority order.
*/
public ConcurrentRuleComparator(final List<TGGRule> order) {
if (order == null) {
throw new IllegalArgumentException();
}
this.priorityOrder = new LinkedList<String>();
for (Rule cRule : order) {
this.priorityOrder.add(cRule.getName());
}
}
/**
*
* @param aName1
* @param aName2
* @return
*/
private Boolean prior(String aName1, String aName2) {
if (aName1.equals(aName2)) {
return null;
};
for (String name : priorityOrder) {
if (name.equals(aName1)) {
return true;
}
if (name.equals(aName2)) {
return false;
}
}
return null;
}
/**
* This method checks whether rule1 is strictly greater than rule2 based on their names.
* If both rules have equal (or uncomparable) subrule names with same order, they are considered to be equal
* and the method return null.
* @param rule1 first rule that is prior if result is true
* @param rule2 second rule that is prior if result is false
* @return null if rule1 and rule2 are equal or incomparable
*/
public Boolean prior(Rule rule1, Rule rule2) {
List<String> aNames1 = ConcurrentRuleUtil.getAtomicRuleNames(rule1.getName());
List<String> aNames2 = ConcurrentRuleUtil.getAtomicRuleNames(rule2.getName());
Boolean prior = null;
for (int i = 0; (i < aNames1.size()) && (i < aNames2.size()); i++) {
prior = prior(aNames1.get(i), aNames2.get(i));
if (prior != null) {
return prior;
}
}
return (aNames1.size() == aNames2.size() ? null : aNames1.size() > aNames2.size() );
}
/**
* This class represents the tree structure of a concurrent rule name and
* can be used to compare rules based on their names when consideration of
* braces is needed.
* @author Jerry
*
*/
public class AtomicRuleNamesTree {
private AtomicRuleNamesTree subRuleLTree;
private AtomicRuleNamesTree subRuleRTree;
private String ruleName;
public AtomicRuleNamesTree(String ruleName) {
this.ruleName = ruleName;
if (!(ruleName.startsWith("(")
&& ruleName.endsWith(")")
&& ruleName.contains("|"))) {
return;
}
String ruleNameL;
String ruleNameR;
String purgedName = ruleName.substring(1, ruleName.length() - 1);
int openBraces = 0;
int tmpIdx = 0;
int idxL = 0;
int idxR = 0;
char tmp;
boolean found = false;
while(!found && (tmpIdx < purgedName.length())) {
tmp = purgedName.charAt(tmpIdx);
switch (tmp) {
case '(':
openBraces++;
break;
case ')':
openBraces--;
break;
case '|':
if (openBraces == 0) {
idxL = tmpIdx;
do {
tmpIdx++;
tmp = purgedName.charAt(tmpIdx);
} while(('0' <= tmp) && (tmp <= '9'));
if (tmp != '|') {
throw new IllegalArgumentException();
}
idxR = tmpIdx+1;
found = true;
};
break;
default : break;
}
tmpIdx++;
}
ruleNameL = purgedName.substring(0, idxL);
ruleNameR = purgedName.substring(idxR);
System.out.println(ruleNameL);
System.out.println(ruleNameR);
subRuleLTree = new AtomicRuleNamesTree(ruleNameL);
subRuleRTree = new AtomicRuleNamesTree(ruleNameR);
}
public boolean isConcurrent() {
return ((subRuleLTree != null) && (subRuleRTree != null));
}
}
}