blob: edfbbdf529d52fc259005f5ad6d014a91bb2aac5 [file] [log] [blame]
/**
* <copyright>
* OCL2AC is developed by Nebras Nassar based on an initial version developed by Thorsten Arendt and Jan Steffen Becker.
* </copyright>
*/
package de.unimarburg.swt.ocl2ac.tool.optimizer;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.henshin.model.Action;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.Edge;
import org.eclipse.emf.henshin.model.Node;
import org.eclipse.emf.henshin.model.Rule;
import de.unimarburg.swt.ocl2ac.gc2ac.core.NestedConditionPreparer;
import de.unimarburg.swt.ocl2ac.gc2ac.util.RuleClassifier;
import laxcondition.Condition;
import nestedcondition.NestedCondition;
import nestedcondition.NestedConstraint;
public class IntegrationChecker {
EList<EClass> graphsNodesTypes = new BasicEList<EClass>();
EList<EReference> graphsEdgesTypes = new BasicEList<EReference>();
EList<EAttribute> graphsAttributesTypes = new BasicEList<EAttribute>();
/**
* The official ones
*
* @param rule
* @param nestedConstraint
* @return
*/
public boolean mustIntegrate(Rule rule, NestedConstraint nestedConstraint) {
if (isThereOverlap(rule, nestedConstraint)) {
System.out.println("There is an overlap.");
NestedConditionPreparer preparer = new NestedConditionPreparer(nestedConstraint);
preparer.eliminateForAllANotExistsC();
NestedCondition condition = preparer.getCondition();
RuleClassifier rc = new RuleClassifier(rule);
if (preparer.isOfFormExistsC(condition)) {
System.out.println("The constraint is of form Exists C.");
if (rc.doesRuleCreateOnly()) {
System.out.println("The rule creates only.");
System.out.println("There is an overlap but no need for the integration.");
return false;
}
}
if (preparer.isOfFormNotExistsC(condition)) {
System.out.println("The constraint is of form Not Exists C.");
if (rc.doesRuleDeleteOnly()) {
System.out.println("The rule deletes only.");
System.out.println("There is an overlap but no need for the integration.");
return false;
}
}
System.out.println("Go to the integration");
return true;
} else {
System.out.println("No overlap at all");
return false;
}
}
/**
*
* @param rule
* @param nestedConstraint
* @return
*/
private boolean isThereOverlap(Rule rule, NestedConstraint nestedConstraint) {
EList<Node> createActionNodes = rule.getActionNodes(new Action(Action.Type.CREATE));
EList<Node> deleteActionNodes = rule.getActionNodes(new Action(Action.Type.DELETE));
EList<Node> ruleNodes = new BasicEList<Node>();
ruleNodes.addAll(createActionNodes);
ruleNodes.addAll(deleteActionNodes);
EList<EClass> ruleNodesTypes = new BasicEList<EClass>();
for (Node node : ruleNodes) {
if (!ruleNodesTypes.contains(node.getType()))
ruleNodesTypes.add(node.getType());
}
EList<Edge> createActionEdges = rule.getActionEdges(new Action(Action.Type.CREATE));
EList<Edge> deleteActionEdges = rule.getActionEdges(new Action(Action.Type.DELETE));
EList<Edge> ruleEdges = new BasicEList<Edge>();
ruleEdges.addAll(createActionEdges);
ruleEdges.addAll(deleteActionEdges);
EList<EReference> ruleEdgesTypes = new BasicEList<EReference>();
for (Edge edge : ruleEdges) {
if (!ruleEdgesTypes.contains(edge.getType()))
ruleEdgesTypes.add(edge.getType());
}
EList<Attribute> createActionAttribute = new BasicEList<Attribute>();
for (Node node : rule.getRhs().getNodes()) {
for (Attribute attr : node.getAttributes()) {
if (attr.getAction() != null) {
if (attr.getAction().getType() == Action.Type.CREATE)
createActionAttribute.add(attr);
}
}
}
EList<Attribute> deleteActionAttribute = new BasicEList<Attribute>();
for (Node node : rule.getLhs().getNodes()) {
for (Attribute attr : node.getAttributes()) {
if (attr.getAction().getType() == Action.Type.DELETE)
deleteActionAttribute.add(attr);
}
}
EList<Attribute> ruleAttributes = new BasicEList<Attribute>();
ruleAttributes.addAll(createActionAttribute);
ruleAttributes.addAll(deleteActionAttribute);
EList<EAttribute> ruleAttributeTypes = new BasicEList<EAttribute>();
for (Attribute attr : ruleAttributes) {
if (!ruleAttributeTypes.contains(attr.getType()))
ruleAttributeTypes.add(attr.getType());
}
fillNodesTypesAndEdgesTypes(nestedConstraint);
if (areClanDisjoint(ruleNodesTypes, graphsNodesTypes) && areEdgeDisjoint(ruleEdgesTypes, graphsEdgesTypes)
&& areAttibuteDisjoint(ruleAttributeTypes, graphsAttributesTypes))
return false;
else
return true;
}
/**
*
*
* @param rule
* @param condition
* @return
*/
public boolean mustIntegrateWithoutAttribute(Rule rule, Condition condition) {
EList<Node> createActionNodes = rule.getActionNodes(new Action(Action.Type.CREATE));
EList<Node> deleteActionNodes = rule.getActionNodes(new Action(Action.Type.DELETE));
EList<Node> ruleNodes = new BasicEList<Node>();
ruleNodes.addAll(createActionNodes);
ruleNodes.addAll(deleteActionNodes);
EList<EClass> ruleNodesTypes = new BasicEList<EClass>();
for (Node node : ruleNodes) {
if (!ruleNodesTypes.contains(node.getType()))
ruleNodesTypes.add(node.getType());
}
EList<Edge> createActionEdges = rule.getActionEdges(new Action(Action.Type.CREATE));
EList<Edge> deleteActionEdges = rule.getActionEdges(new Action(Action.Type.DELETE));
EList<Edge> ruleEdges = new BasicEList<Edge>();
ruleEdges.addAll(createActionEdges);
ruleEdges.addAll(deleteActionEdges);
EList<EReference> ruleEdgesTypes = new BasicEList<EReference>();
for (Edge edge : ruleEdges) {
if (!ruleEdgesTypes.contains(edge.getType()))
ruleEdgesTypes.add(edge.getType());
}
fillNodesTypesAndEdgesTypes(condition);
if (areClanDisjoint(ruleNodesTypes, graphsNodesTypes) && areEdgeDisjoint(ruleEdgesTypes, graphsEdgesTypes))
return false;
else
return true;
}
/**
*
* @param nestedConstraint
*/
private void fillNodesTypesAndEdgesTypes(NestedConstraint nestedConstraint) {
graphsNodesTypes.clear();
graphsEdgesTypes.clear();
TreeIterator<EObject> iter = nestedConstraint.eAllContents();
while (iter.hasNext()) {
EObject eObject = iter.next();
if (eObject instanceof graph.Node) {
graph.Node node = (graph.Node) eObject;
if (!graphsNodesTypes.contains(node.getType()))
graphsNodesTypes.add(node.getType());
}
if (eObject instanceof graph.Edge) {
graph.Edge edge = (graph.Edge) eObject;
if (!graphsEdgesTypes.contains(edge.getType()))
graphsEdgesTypes.add(edge.getType());
}
if (eObject instanceof graph.Attribute) {
graph.Attribute attribute = (graph.Attribute) eObject;
if (!graphsAttributesTypes.contains(attribute.getType()))
graphsAttributesTypes.add(attribute.getType());
}
}
}
/**
*
* @param condition
*/
private void fillNodesTypesAndEdgesTypes(Condition condition) {
graphsNodesTypes.clear();
graphsEdgesTypes.clear();
TreeIterator<EObject> iter = condition.eAllContents();
while (iter.hasNext()) {
EObject eObject = iter.next();
if (eObject instanceof graph.Node) {
graph.Node node = (graph.Node) eObject;
if (!graphsNodesTypes.contains(node.getType()))
graphsNodesTypes.add(node.getType());
}
if (eObject instanceof graph.Edge) {
graph.Edge edge = (graph.Edge) eObject;
if (!graphsEdgesTypes.contains(edge.getType()))
graphsEdgesTypes.add(edge.getType());
}
if (eObject instanceof graph.Attribute) {
graph.Attribute attribute = (graph.Attribute) eObject;
if (!graphsAttributesTypes.contains(attribute.getType()))
graphsAttributesTypes.add(attribute.getType());
}
}
}
/**
*
*
* @param typesList1
* @param typesList2
* @return
*/
private boolean areClanDisjoint(EList<EClass> typesList1, EList<EClass> typesList2) {
for (EClass type1 : typesList1) {
EList<EClass> clan1 = getClan(type1);
for (EClass type2 : typesList2) {
if (clan1.contains(type2)) {
return false;
}
}
}
for (EClass type2 : typesList2) {
EList<EClass> clan2 = getClan(type2);
for (EClass type1 : typesList1) {
if (clan2.contains(type1)) {
return false;
}
}
}
return true;
}
/**
*
* @param typesList1
* @param typesList2
* @return
*/
private boolean areEdgeDisjoint(EList<EReference> typesList1, EList<EReference> typesList2) {
if (typesList1.size() <= typesList2.size()) {
for (EReference type1 : typesList1) {
if (typesList2.contains(type1))
return false;
}
} else {
for (EReference type2 : typesList2) {
if (typesList1.contains(type2))
return false;
}
}
return true;
}
/**
*
* @param typesList1
* @param typesList2
* @return
*/
private boolean areAttibuteDisjoint(EList<EAttribute> typesList1, EList<EAttribute> typesList2) {
if (typesList1.size() <= typesList2.size()) {
for (EAttribute type1 : typesList1) {
if (typesList2.contains(type1))
return false;
}
} else {
for (EAttribute type2 : typesList2) {
if (typesList1.contains(type2))
return false;
}
}
return true;
}
/**
*
* @param eClass
* @return
*/
private EList<EClass> getClan(EClass eClass) {
EList<EClass> eClasses = new BasicEList<EClass>();
eClasses.add(eClass);
eClasses.addAll(getAllSubclasses(eClass));
return eClasses;
}
/**
*
* @param eClass
* @return
*/
private EList<EClass> getAllSubclasses(EClass eClass) {
EList<EClass> eClasses = new BasicEList<EClass>();
EPackage ePackage = eClass.getEPackage();
TreeIterator<EObject> iter = ePackage.eAllContents();
while (iter.hasNext()) {
EObject eObject = iter.next();
if (eObject instanceof EClass) {
EClass clazz = (EClass) eObject;
if (clazz.getEAllSuperTypes().contains(eClass)) {
eClasses.add(clazz);
}
}
}
return eClasses;
}
}