]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementIdentification.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / synchronization / graph / ElementIdentification.java
1 package org.simantics.diagram.synchronization.graph;\r
2 \r
3 import gnu.trove.set.hash.THashSet;\r
4 \r
5 import java.util.ArrayList;\r
6 import java.util.Arrays;\r
7 import java.util.Collections;\r
8 import java.util.List;\r
9 \r
10 import org.simantics.db.ReadGraph;\r
11 import org.simantics.db.Resource;\r
12 import org.simantics.db.Statement;\r
13 import org.simantics.db.exception.DatabaseException;\r
14 import org.simantics.db.layer0.util.RelativeReference;\r
15 import org.simantics.diagram.stubs.DiagramResource;\r
16 import org.simantics.layer0.Layer0;\r
17 import org.simantics.modeling.ModelingResources;\r
18 import org.simantics.structural.stubs.StructuralResource2;\r
19 \r
20 public class ElementIdentification {\r
21 \r
22     /**\r
23      * Browses from given resource to neighbor resources by connectors.\r
24      * @param g\r
25      * @param r\r
26      * @return\r
27      */\r
28     private static ArrayList<Statement> browseConnectors(ReadGraph g, Resource r) throws DatabaseException {\r
29         ArrayList<Statement> result = new ArrayList<Statement>(2);\r
30         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
31         for(Resource connector : g.getObjects(r, STR.IsConnectedTo))\r
32             for(Statement other : g.getStatements(connector, STR.Connects))\r
33                 if(!other.getObject().equals(r))\r
34                     result.add(other);\r
35         return result;\r
36     }\r
37     \r
38     private static Resource getJoinedFlag(ReadGraph g, Resource r) throws DatabaseException {\r
39         DiagramResource DIA = DiagramResource.getInstance(g);\r
40         for(Resource join : g.getObjects(r, DIA.FlagIsJoinedBy))\r
41             for(Resource flag : g.getObjects(join, DIA.JoinsFlag))\r
42                 if(!flag.equals(r))\r
43                     return flag;\r
44         return null;\r
45     }\r
46     \r
47     /**\r
48      * Returns an identifier of the flag or null if the procedure fails.\r
49      */\r
50     private static RelativeReference getSimpleFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {\r
51         DiagramResource DIA = DiagramResource.getInstance(g);        \r
52         if(!g.isInstanceOf(flag, DIA.Flag))\r
53             return null;\r
54         ArrayList<Statement> connections = browseConnectors(g, flag);\r
55         if(connections.size() != 1)\r
56             return null;        \r
57         Resource connection = connections.get(0).getObject();\r
58         ArrayList<Statement> connections2 = browseConnectors(g, connection);\r
59         for(Statement stat : connections2) {\r
60             Resource element = stat.getObject();\r
61             if(!g.isInstanceOf(element, DIA.Flag)) {   \r
62                 Resource relation = g.getInverse(stat.getPredicate());                \r
63                 RelativeReference ref = getElementIdentifier(g, element);\r
64                 if(ref != null) {\r
65                     Layer0 L0 = Layer0.getInstance(g);\r
66                     return new RelativeReference(ref.base, ref.path + "#" + \r
67                             g.getRelatedValue(relation, L0.HasName) \r
68                             );\r
69                 }\r
70             }            \r
71         }\r
72         return null;\r
73     }\r
74     \r
75     private static RelativeReference getFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {\r
76         RelativeReference ref1 = getSimpleFlagIdentifier(g, flag);\r
77         if(ref1 == null)\r
78             return null;\r
79         Resource otherFlag = getJoinedFlag(g, flag);\r
80         if(otherFlag == null)\r
81             return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);\r
82         else {\r
83             RelativeReference ref2 = getSimpleFlagIdentifier(g, otherFlag);\r
84             if(ref2 == null)\r
85                 return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);\r
86             return new RelativeReference(ref1.base, "FLAG|" + ref1.path + "|" + ref2.path);\r
87         }\r
88     }\r
89     \r
90     public static RelativeReference getElementIdentifier(ReadGraph g, Resource element) throws DatabaseException {\r
91         DiagramResource DIA = DiagramResource.getInstance(g);\r
92         ModelingResources MOD = ModelingResources.getInstance(g);\r
93         if(g.isInstanceOf(element, DIA.Flag)) {\r
94             return getFlagIdentifier(g, element);            \r
95         }\r
96         else if(g.isInstanceOf(element, MOD.ReferenceElement)) {\r
97             Resource parent = g.getPossibleObject(element, MOD.HasParentComponent);\r
98             if(parent == null)\r
99                 return null;\r
100             RelativeReference parentRef = \r
101                     RelativeReference.createReference(g, MOD.StructuralModel, parent);\r
102             if(parentRef == null)\r
103                 return null;\r
104             Resource referenceRelation = \r
105                     g.getPossibleObject(element, MOD.HasReferenceRelation);\r
106             if(referenceRelation == null)\r
107                 return null;\r
108             Layer0 L0 = Layer0.getInstance(g);\r
109             return new RelativeReference(parentRef.base, \r
110                     "REFERENCE#"+parentRef.path+"#"+\r
111                     g.getRelatedValue(referenceRelation, L0.HasName));\r
112         }\r
113         else {        \r
114             Resource component = g.getPossibleObject(element, MOD.ElementToComponent);\r
115             if(component == null)\r
116                 return null;\r
117             return RelativeReference.createReference(g, MOD.StructuralModel, component);\r
118         }        \r
119     }\r
120     \r
121     public static RelativeReference getConnectorIdentifier(ReadGraph g, Resource connector) throws DatabaseException {\r
122         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
123         DiagramResource DIA = DiagramResource.getInstance(g);\r
124         Layer0 L0 = Layer0.getInstance(g);\r
125         \r
126         for(Statement stat : g.getStatements(connector, STR.Connects)) {\r
127             if(!g.isInstanceOf(stat.getObject(), DIA.Connection)) {\r
128                 RelativeReference ref = getElementIdentifier(g, stat.getObject());\r
129                 if(ref == null || ref.path == null)\r
130                     continue;\r
131                 if(ref.path.contains("#"))\r
132                     return ref;\r
133                 else\r
134                     return new RelativeReference(ref.base, ref.path + "#" + \r
135                             g.getRelatedValue(g.getInverse(stat.getPredicate()), L0.HasName));\r
136             }\r
137         }\r
138         return new RelativeReference(null, "UNK");\r
139     } \r
140     \r
141     private static Resource resolveElementFromComponent(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
142         Resource component = RelativeReference.resolve(graph, model, path);\r
143         if(component == null) {\r
144             System.err.println("Didn't find component " + path);\r
145             return null;\r
146         }\r
147         \r
148         ModelingResources MOD = ModelingResources.getInstance(graph);\r
149         Resource element = graph.getPossibleObject(component, MOD.ComponentToElement);\r
150         if(element == null) {\r
151             System.err.println("Didn't find element for component " + path);\r
152             return null;\r
153         }            \r
154         return element;\r
155     }\r
156     \r
157     private static ArrayList<Resource> findRelatedFlags(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
158         ArrayList<Resource> result = new ArrayList<Resource>();\r
159         String[] parts = path.split("#");\r
160         Resource element;\r
161         String attributeName;\r
162         if(parts[0].equals("REFERENCE")) {\r
163             element = resolveReference(graph, model, path);\r
164             attributeName = parts[3];\r
165         }\r
166         else {\r
167             element = resolveElementFromComponent(graph, model, parts[0]);\r
168             attributeName = parts[1];\r
169         }\r
170         if(element == null)\r
171             return result;\r
172         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
173         DiagramResource DIA = DiagramResource.getInstance(graph);\r
174         Layer0 L0 = Layer0.getInstance(graph);\r
175         for(Statement stat : graph.getStatements(element, STR.IsConnectedTo)) {\r
176             if(attributeName.equals(graph.getRelatedValue(stat.getPredicate(), L0.HasName))) {\r
177                 Resource connector1 = stat.getObject();\r
178                 for(Resource connection : graph.getObjects(connector1, STR.Connects)) {\r
179                     for(Resource connector2 : graph.getObjects(connection, STR.IsConnectedTo))\r
180                         if(!connector2.equals(connector1)) {\r
181                             for(Resource flag : graph.getObjects(connector2, STR.Connects)) {\r
182                                 if(graph.isInstanceOf(flag, DIA.Flag))\r
183                                     result.add(flag);\r
184                             }\r
185                         }\r
186                 }\r
187             }\r
188         }\r
189         return result;\r
190     }\r
191     \r
192     public static Resource resolveElement(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
193         String[] parts = path.split("\\|");\r
194         \r
195         if(parts[0].equals("UNJOINED_FLAG")) {\r
196             ArrayList<Resource> flags = findRelatedFlags(graph, model, parts[1]);\r
197             if(flags.isEmpty()) {\r
198                 System.err.println("Didn't find any flag " + path);\r
199                 return null;\r
200             }\r
201             // TODO filter multiple found flags\r
202             return flags.get(0);\r
203         }\r
204         else if(parts[0].equals("FLAG")) {\r
205             ArrayList<Resource> flags = findRelatedFlags(graph, model, parts[1]);\r
206             if(flags.isEmpty()) {\r
207                 System.err.println("Didn't find any flag " + path);\r
208                 return null;\r
209             }\r
210             if(flags.size() == 1)\r
211                 return flags.get(0);\r
212             THashSet<Resource> flagSet = new THashSet<Resource>(findRelatedFlags(graph, model, parts[2]));\r
213             DiagramResource DIA = DiagramResource.getInstance(graph);\r
214             for(Resource f : flags)\r
215                 for(Resource join : graph.getObjects(f, DIA.FlagIsJoinedBy))\r
216                     for(Resource otherFlag : graph.getObjects(join, DIA.JoinsFlag))\r
217                         if(flagSet.contains(otherFlag))\r
218                             return f;\r
219             System.err.println("Ambiguous flag reference " + path);\r
220             return null;\r
221         }\r
222         else if(path.startsWith("REFERENCE#")) {\r
223             return resolveReference(graph, model, path);\r
224         }\r
225         else {\r
226             return resolveElementFromComponent(graph, model, path);\r
227         }\r
228     }\r
229     \r
230     private static Resource resolveReference(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
231         String[] parts = path.split("#");\r
232         Resource component = RelativeReference.resolve(graph, model, parts[1]);\r
233         if(component == null) {\r
234             System.err.println("Didn't find component " + path);\r
235             return null;\r
236         }\r
237         \r
238         ModelingResources MOD = ModelingResources.getInstance(graph);\r
239         Layer0 L0 = Layer0.getInstance(graph);\r
240         for(Resource element : graph.getObjects(component, MOD.HasParentComponent_Inverse)) {\r
241             Resource referenceRelation = graph.getSingleObject(element, MOD.HasReferenceRelation);\r
242             if(parts[2].equals(graph.getRelatedValue(referenceRelation, L0.HasName)))\r
243                 return element;\r
244         }\r
245 \r
246         System.err.println("Didn't find element for " + path);\r
247         return null;\r
248     }\r
249     \r
250     public static List<Resource> resolveConnector(ReadGraph g, Resource model,\r
251             String name) throws DatabaseException {\r
252         if(name.equals("UNK"))\r
253             return Collections.emptyList();\r
254         if(name.startsWith("FLAG|") || name.startsWith("UNKNOWN_FLAG|")) {\r
255             Resource element = resolveElement(g, model, name);\r
256             return Arrays.asList(g.getSingleObject(element, \r
257                     DiagramResource.getInstance(g).Flag_ConnectionPoint));\r
258         }\r
259         String[] parts = name.split("#");\r
260         Resource element = resolveElement(g, model, parts[0]);\r
261         if (element == null)\r
262             return Collections.emptyList();\r
263         StructuralResource2 STR = StructuralResource2.getInstance(g);\r
264         Layer0 L0 = Layer0.getInstance(g);\r
265         ArrayList<Resource> result = new ArrayList<Resource>(2);\r
266         for(Statement stat : g.getStatements(element, STR.IsConnectedTo))\r
267             if(g.getRelatedValue(stat.getPredicate(), L0.HasName).equals(parts[1]))\r
268                 result.add(stat.getObject());\r
269         return result;\r
270     }\r
271     \r
272 }\r