1 package org.simantics.diagram.synchronization.graph;
\r
3 import gnu.trove.set.hash.THashSet;
\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
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
20 public class ElementIdentification {
\r
23 * Browses from given resource to neighbor resources by connectors.
\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
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
48 * Returns an identifier of the flag or null if the procedure fails.
\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
54 ArrayList<Statement> connections = browseConnectors(g, flag);
\r
55 if(connections.size() != 1)
\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
65 Layer0 L0 = Layer0.getInstance(g);
\r
66 return new RelativeReference(ref.base, ref.path + "#" +
\r
67 g.getRelatedValue(relation, L0.HasName)
\r
75 private static RelativeReference getFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {
\r
76 RelativeReference ref1 = getSimpleFlagIdentifier(g, flag);
\r
79 Resource otherFlag = getJoinedFlag(g, flag);
\r
80 if(otherFlag == null)
\r
81 return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);
\r
83 RelativeReference ref2 = getSimpleFlagIdentifier(g, otherFlag);
\r
85 return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);
\r
86 return new RelativeReference(ref1.base, "FLAG|" + ref1.path + "|" + ref2.path);
\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
96 else if(g.isInstanceOf(element, MOD.ReferenceElement)) {
\r
97 Resource parent = g.getPossibleObject(element, MOD.HasParentComponent);
\r
100 RelativeReference parentRef =
\r
101 RelativeReference.createReference(g, MOD.StructuralModel, parent);
\r
102 if(parentRef == null)
\r
104 Resource referenceRelation =
\r
105 g.getPossibleObject(element, MOD.HasReferenceRelation);
\r
106 if(referenceRelation == 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
114 Resource component = g.getPossibleObject(element, MOD.ElementToComponent);
\r
115 if(component == null)
\r
117 return RelativeReference.createReference(g, MOD.StructuralModel, component);
\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
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
131 if(ref.path.contains("#"))
\r
134 return new RelativeReference(ref.base, ref.path + "#" +
\r
135 g.getRelatedValue(g.getInverse(stat.getPredicate()), L0.HasName));
\r
138 return new RelativeReference(null, "UNK");
\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
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
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
161 String attributeName;
\r
162 if(parts[0].equals("REFERENCE")) {
\r
163 element = resolveReference(graph, model, path);
\r
164 attributeName = parts[3];
\r
167 element = resolveElementFromComponent(graph, model, parts[0]);
\r
168 attributeName = parts[1];
\r
170 if(element == null)
\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
192 public static Resource resolveElement(ReadGraph graph, Resource model, String path) throws DatabaseException {
\r
193 String[] parts = path.split("\\|");
\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
201 // TODO filter multiple found flags
\r
202 return flags.get(0);
\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
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
219 System.err.println("Ambiguous flag reference " + path);
\r
222 else if(path.startsWith("REFERENCE#")) {
\r
223 return resolveReference(graph, model, path);
\r
226 return resolveElementFromComponent(graph, model, path);
\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
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
246 System.err.println("Didn't find element for " + path);
\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
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