blob: 35c0a0608ceeaae7582bd35b91f04a0ba86fe65a [file] [log] [blame]
package org.eclipse.emf.henshin.sam.invcheck.algorithm;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.emf.henshin.sam.invcheck.InvariantCheckerUtil;
import org.eclipse.emf.henshin.sam.invcheck.nac.PatternEdge;
import org.eclipse.emf.henshin.sam.invcheck.nac.PatternNode;
import org.eclipse.emf.henshin.sam.model.samannotation.AnnotatedElem;
import org.eclipse.emf.henshin.sam.model.samgraph.Edge;
import org.eclipse.emf.henshin.sam.model.samgraph.Graph;
import org.eclipse.emf.henshin.sam.model.samgraph.Node;
import org.eclipse.emf.henshin.sam.model.samrules.RuleGraph;
import org.eclipse.emf.henshin.sam.model.samrules.SamrulesFactory;
import org.eclipse.emf.henshin.sam.model.samtrace.Match;
/**
* Merges two graphs and a graph matching to a merged graph. The typical inputs
* are a forbidden subgraph, a part of the right side of a graph rule and their
* matching.
*
* The following diagram shows the behaviour of the merge method.
*
* <p>
* <img src="../../../../../doc/diagrams/graphMerger.png" alt="Graph merger">
* </p>
*
*/
public class GraphMerger implements AlgorithmComponent {
private Map<Graph, Map<AnnotatedElem, AnnotatedElem>> refItems = new HashMap<Graph, Map<AnnotatedElem, AnnotatedElem>>();
// private Map<Graph, Map<AnnotatedElem, AnnotatedElem>>
// inverseSameInRuleProp = new HashMap<Graph, Map<AnnotatedElem,
// AnnotatedElem>>();
/**
* No comment provided by developer, please add a comment to improve
* documentation.
*
* @param forbiddenSubGraph
* No description provided
* @param rule
* No description provided
* @param matching
* No description provided
* @return No description provided
*/
public RuleGraph merge(Graph forbiddenSubGraph, Graph rule, Match matching) {
refItems.put(forbiddenSubGraph, new HashMap<AnnotatedElem, AnnotatedElem>());
refItems.put(rule, new HashMap<AnnotatedElem, AnnotatedElem>());
RuleGraph result = null;
if (forbiddenSubGraph != null && rule != null && matching != null) {
result = SamrulesFactory.eINSTANCE.createRuleGraph();// new Graph();
result.setTypedOver(rule.getTypedOver());
copyItems(forbiddenSubGraph, result, true);
createAssocs(forbiddenSubGraph, result);
/*
* this for loop ensures that items mentioned by the given matching,
* won't be copied twice.
*/
for (Iterator<Map.Entry<Node, Node>> iter = matching.getNodeMatching().iterator(); iter.hasNext();) {
Map.Entry<Node, Node> tmpEntry = iter.next();
Node ruleNode = tmpEntry.getKey();
Node resultNode = (Node) refItems.get(forbiddenSubGraph).get(tmpEntry.getValue());
assert resultNode != null;
refItems.get(rule).put(ruleNode, resultNode);
((PatternNode) resultNode).setSameInRule(ruleNode);
}
for (Iterator<Map.Entry<Edge, Edge>> iter = matching.getEdgeMatching().iterator(); iter.hasNext();) {
Map.Entry<Edge, Edge> tmpEntry = iter.next();
Edge ruleEdge = tmpEntry.getKey();
Edge resultEdge = (Edge) refItems.get(forbiddenSubGraph).get(tmpEntry.getValue());
assert resultEdge != null;
refItems.get(rule).put(ruleEdge, resultEdge);
((PatternEdge) resultEdge).setSameInRule(ruleEdge);
}
copyItems(rule, result, false);
createAssocs(rule, result);
}
return result;
}
/**
* copies all graph items from srcGraph to resultGraph. thereby the
* qualified assocs for copies of elements are set.
*
* @param srcGraph
* @param resultGraph
*/
private void copyItems(Graph srcGraph, Graph resultGraph, boolean isForbidden) {
for (Iterator<Node> iter = srcGraph.getNodes().iterator(); iter.hasNext();) {
final Node srcNode = iter.next();
if (!refItems.get(srcGraph).containsKey(srcNode)) {
PatternNode resultNode = InvariantCheckerUtil.copyAsPattern(srcNode);
resultGraph.getNodes().add(resultNode);
refItems.get(srcGraph).put(srcNode, resultNode);
if (isForbidden) {
resultNode.setSameInProp(srcNode);
} else {
resultNode.setSameInRule(srcNode);
}
}
}
for (Iterator<Edge> iter = srcGraph.getEdges().iterator(); iter.hasNext();) {
final Edge srcEdge = iter.next();
if (!refItems.get(srcGraph).containsKey(srcEdge)) {
PatternEdge resultEdge = InvariantCheckerUtil.copyAsPattern(srcEdge);
resultGraph.getEdges().add(resultEdge);
refItems.get(srcGraph).put(srcEdge, resultEdge);
if (isForbidden) {
resultEdge.setSameInProp(srcEdge);
} else {
resultEdge.setSameInRule(srcEdge);
}
}
}
}
/**
* creates the assocs between the nodes and edges of srcGraph between the
* elements of resultGraph. to make this work, all elements have be copied
* first before calling this method
*
* @param srcGraph
* the source Graph
* @param resultGraph
* the resulting graph containing then the assoc from srcGraph
*/
private void createAssocs(Graph srcGraph, Graph resultGraph) {
for (Iterator<Edge> iter = srcGraph.getEdges().iterator(); iter.hasNext();) {
final Edge srcEdge = iter.next();
Node srcTargetNode = srcEdge.getTarget();
Node srcSourceNode = srcEdge.getSource();
assert srcTargetNode != null : srcEdge + ": sourceNode equals null!";
assert srcSourceNode != null : srcEdge + ": targetNode quals null!";
Edge resultEdge = (Edge) refItems.get(srcGraph).get(srcEdge);
Node resultTargetNode = (Node) refItems.get(srcGraph).get(srcTargetNode);
Node resultSourceNode = (Node) refItems.get(srcGraph).get(srcSourceNode);
resultEdge.setSource(resultSourceNode);
resultEdge.setTarget(resultTargetNode);
}
}
public void reset() {
refItems = new HashMap<Graph, Map<AnnotatedElem, AnnotatedElem>>();
}
}
/*
* $Log$ Revision 1.4 2007/06/25 17:48:20 basilb fixed a lot of these bugs
* testing does not find but evaluating ;)
*
* Revision 1.3 2007/01/11 14:44:23 basilb even more usage of generics
*
* Revision 1.2 2007/01/03 09:27:48 basilb removed compile errors caused by
* wrong import declarations; introduced empty plugin class to ensure correct
* loading
*
*/