package org.eclipse.emf.henshin.model.actions;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.henshin.model.Attribute;
import org.eclipse.emf.henshin.model.Edge;
import org.eclipse.emf.henshin.model.Graph;
import org.eclipse.emf.henshin.model.NestedCondition;
import org.eclipse.emf.henshin.model.Node;
public class ConditionElemMapEditor {
// Source and target conditions.
private final NestedCondition source, target;
private final boolean sameRule;
public ConditionElemMapEditor(NestedCondition source, NestedCondition target) {
this.source = source;
this.target = target;
this.sameRule = (source.getHost().getRule()==target.getHost().getRule());
}
private static void ensureCompleteness(NestedCondition cond) {
Graph graph = cond.getConclusion();
if (graph==null) return;
for (Node node : cond.getHost().getRule().getLhs().getNodes()) {
if (cond.getMappings().getImage(node, graph)==null) {
Node image = EcoreUtil.copy(node);
image.getAttributes().clear();
graph.getNodes().add(image);
cond.getMappings().add(node, image);
}
}
for (Edge edge : cond.getHost().getRule().getLhs().getEdges()) {
if (cond.getMappings().getImage(edge, graph)==null) {
Edge image = EcoreUtil.copy(edge);
image.setSource(cond.getMappings().getImage(edge.getSource(), graph));
image.setTarget(cond.getMappings().getImage(edge.getTarget(), graph));
graph.getEdges().add(image);
}
}
}
private Node getOppositeCondNode(Node node) {
if (node.getGraph().eContainer()==source) {
return target.getMappings().getImage(getOppositeLhsNode(source.getMappings().getOrigin(node)), target.getConclusion());
} else {
return source.getMappings().getImage(getOppositeLhsNode(target.getMappings().getOrigin(node)), source.getConclusion());
}
}
private Node getOppositeLhsNode(Node lhsNode) {
if (sameRule) return lhsNode;
if (lhsNode.getGraph()==source.getHost().getRule().getLhs()) {
return target.getHost().getRule().getMultiMappings().getImage(lhsNode, target.getHost().getRule().getLhs());
} else {
return target.getHost().getRule().getMultiMappings().getOrigin(lhsNode);
}
}
/**
* Move a condition node.
* @param node Node to be moved.
*/
public void moveConditionNode(Node node) {
// Check whether it is really a condition node:
if (((NestedCondition) node.getGraph().eContainer()).getMappings().getOrigin(node)!=null) {
return;
}
ensureCompleteness(source);
ensureCompleteness(target);
Graph oppGraph = node.getGraph()==source.getConclusion() ? target.getConclusion() : source.getConclusion();
for (Edge incoming : node.getIncoming()) {
incoming.setSource(getOppositeCondNode(incoming.getSource()));
incoming.setGraph(oppGraph);
}
for (Edge outgoing : node.getOutgoing()) {
outgoing.setTarget(getOppositeCondNode(outgoing.getTarget()));
outgoing.setGraph(oppGraph);
}
node.setGraph(oppGraph);
}
/**
* Move a condition edge.
* @param edge Edge to be moved.
*/
public void moveConditionEdge(Edge edge) {
// Check whether it is really a condition edge:
if (((NestedCondition) edge.getGraph().eContainer()).getMappings().getOrigin(edge)!=null) {
return;
}
ensureCompleteness(source);
ensureCompleteness(target);
Graph oppGraph = edge.getGraph()==source.getConclusion() ? target.getConclusion() : source.getConclusion();
edge.setSource(getOppositeCondNode(edge.getSource()));
edge.setTarget(getOppositeCondNode(edge.getTarget()));
edge.setGraph(oppGraph);
}
/**
* Move a condition attribute.
* @param attribute Attribute to be moved.
*/
public void moveConditionAttribute(Attribute attribute) {
// Check whether it is really a condition edge:
if (((NestedCondition) attribute.getGraph().eContainer()).getMappings().getOrigin(attribute)!=null) {
return;
}
ensureCompleteness(source);
ensureCompleteness(target);
attribute.setNode(getOppositeCondNode(attribute.getNode()));
}
/**
* Move a condition element. This can be either a node or
* an edge. If it is neither, nothing happens.
* @param element Element to be moved.
*/
public void moveConditionElement(Object element) {
if (element instanceof Node) {
moveConditionNode((Node) element);
} else if (element instanceof Edge) {
moveConditionEdge((Edge) element);
} else if (element instanceof Attribute) {
moveConditionAttribute((Attribute) element);
}
}
}