1 package org.simantics.graph.matching;
3 import gnu.trove.map.hash.TIntIntHashMap;
4 import gnu.trove.map.hash.TIntObjectHashMap;
5 import gnu.trove.map.hash.TObjectIntHashMap;
7 import java.util.ArrayList;
9 import org.simantics.graph.representation.External;
10 import org.simantics.graph.representation.Identity;
11 import org.simantics.graph.representation.Internal;
12 import org.simantics.graph.representation.Optional;
13 import org.simantics.graph.representation.Root;
16 * A strategy matching resources with equal URIs.
18 * @author Hannu Niemistö
20 public enum IdentityMatchingStrategy implements GraphMatchingStrategy {
24 static class NamedResource {
28 public NamedResource(String name, int resource) {
30 this.resource = resource;
34 static class IdentityTree {
35 TIntObjectHashMap<ArrayList<NamedResource>> childMap = new TIntObjectHashMap<ArrayList<NamedResource>>();
36 ArrayList<NamedResource> roots = new ArrayList<NamedResource>();
38 public IdentityTree(Identity[] indentities) {
39 for(Identity id : indentities) {
40 if(id.definition instanceof External) {
41 External def = (External)id.definition;
42 addChild(id.resource, def.parent, def.name);
44 else if(id.definition instanceof Internal) {
45 Internal def = (Internal)id.definition;
46 addChild(id.resource, def.parent, def.name);
48 else if(id.definition instanceof Optional) {
49 Optional def = (Optional)id.definition;
50 addChild(id.resource, def.parent, def.name);
52 else if(id.definition instanceof Root) {
53 addRoot(id.resource, ((Root)id.definition).name);
58 private void addRoot(int root, String name) {
59 roots.add(new NamedResource(name, root));
62 private void addChild(int child, int parent, String name) {
63 ArrayList<NamedResource> children = childMap.get(parent);
64 if(children == null) {
65 children = new ArrayList<NamedResource>();
66 childMap.put(parent, children);
68 children.add(new NamedResource(name, child));
72 static class MatchingProcess {
80 public MatchingProcess(int[] aToB, int[] bToA,
81 TIntIntHashMap aInv, TIntIntHashMap bInv,
82 IdentityTree aTree, IdentityTree bTree) {
91 public void execute() {
92 match(aTree.roots, bTree.roots);
95 private void match(ArrayList<NamedResource> as, ArrayList<NamedResource> bs) {
96 TObjectIntHashMap<String> map = new TObjectIntHashMap<String>();
97 for(NamedResource b : bs)
98 map.put(b.name, b.resource);
99 for(NamedResource a : as)
100 if(map.contains(a.name))
101 match(a.resource, map.get(a.name));
104 private void match(int a, int b) {
105 if(aToB[a] < 0 && bToA[b] < 0) {
109 if(aInv.contains(a) && bInv.contains(b))
110 match(aInv.get(a), bInv.get(b));
112 ArrayList<NamedResource> as = aTree.childMap.get(a);
115 ArrayList<NamedResource> bs = bTree.childMap.get(b);
123 public void mapUnmapped(int[] map, TIntIntHashMap inverses, Identity[] identities, int rangeCount) {
124 for(Identity id : identities) {
127 map[r] = rangeCount++;
128 if(inverses.containsKey(r))
129 map[inverses.get(r)] = rangeCount++;
135 public void applyTo(GraphMatching matching) {
137 matching.aToB, matching.bToA,
138 matching.aGraph.inverses, matching.bGraph.inverses,
139 new IdentityTree(matching.aGraph.identities), new IdentityTree(matching.bGraph.identities)
141 mapUnmapped(matching.aToB, matching.aGraph.inverses,
142 matching.aGraph.identities, matching.bGraph.resourceCount);
143 mapUnmapped(matching.bToA, matching.bGraph.inverses,
144 matching.bGraph.identities, matching.aGraph.resourceCount);
145 matching.recomputeSize();