package org.eclipse.emf.henshin.model.staticanalysis; import java.util.ArrayList; import java.util.List; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.henshin.model.Edge; import org.eclipse.emf.henshin.model.GraphElement; import org.eclipse.emf.henshin.model.NestedCondition; import org.eclipse.emf.henshin.model.Node; public class Path { final List<Node> nodes = new ArrayList<Node>(); final List<Edge> edges = new ArrayList<Edge>(); public boolean isCyclic() { int length = nodes.size(); for (int i=0; i<length; i++) { Node n = nodes.get(i); for (int j=i+1; j<length; j++) { if (nodes.get(j)==n) { return true; } } } return false; } public Node firstNode() { return nodes.get(0); } public Node lastNode() { return nodes.get(nodes.size()-1); } public void append(Path path) { for (int i=0; i<path.edges.size(); i++) { nodes.add(path.nodes.get(i+1)); edges.add(path.edges.get(i)); } } public Path copy() { Path copy = new Path(); copy.nodes.addAll(nodes); copy.edges.addAll(edges); return copy; } public boolean isViaPAC() { List<GraphElement> elems = new ArrayList<GraphElement>(); elems.addAll(nodes); elems.addAll(edges); for (GraphElement elem : elems) { if (elem.getGraph().isNestedCondition()) { NestedCondition nested = (NestedCondition) elem.getGraph().eContainer(); if (nested.isPAC()) { return true; } } } return false; } public void retract() { boolean changed = true; while (changed) { changed = false; for (int i=0; i<nodes.size(); i++) { Node node = nodes.get(i); if (node.getGraph()!=null && node.getGraph().isNestedCondition()) { NestedCondition nested = (NestedCondition) node.getGraph().eContainer(); Node origin = nested.getMappings().getOrigin(node); if (origin!=null) { nodes.set(i, origin); changed = true; } } } for (int i=0; i<edges.size(); i++) { Edge edge = edges.get(i); if (edge.getGraph()!=null && edge.getGraph().isNestedCondition()) { NestedCondition nested = (NestedCondition) edge.getGraph().eContainer(); Edge origin = nested.getMappings().getOrigin(edge); if (origin!=null) { edges.set(i, origin); changed = true; } } } } } public List<EReference> toReferenceList(boolean revertInverse) { List<EReference> refs = new ArrayList<EReference>(); for (int i=0; i<edges.size(); i++) { Node source = nodes.get(i); Edge edge = edges.get(i); Node realSource = edge.getSource(); while (realSource.getGraph()!=source.getGraph()) { NestedCondition nested = (NestedCondition) realSource.getGraph().eContainer(); realSource = nested.getMappings().getOrigin(realSource); } if (realSource==source || !revertInverse) { refs.add(edge.getType()); } else { EReference opp = edge.getType().getEOpposite(); if (opp!=null) { refs.add(opp); } else { return null; // error } } } return refs; } public boolean isViaNestedCondition() { for (Edge edge : edges) { if (edge.getGraph()!=null && edge.getGraph().isNestedCondition()) return true; } return false; } }