1 package org.simantics.diagram.synchronization.graph;
3 import gnu.trove.set.hash.THashSet;
5 import java.util.ArrayList;
6 import java.util.Arrays;
7 import java.util.Collections;
10 import org.simantics.db.ReadGraph;
11 import org.simantics.db.Resource;
12 import org.simantics.db.Statement;
13 import org.simantics.db.exception.DatabaseException;
14 import org.simantics.db.layer0.util.RelativeReference;
15 import org.simantics.diagram.stubs.DiagramResource;
16 import org.simantics.layer0.Layer0;
17 import org.simantics.modeling.ModelingResources;
18 import org.simantics.structural.stubs.StructuralResource2;
20 public class ElementIdentification {
23 * Browses from given resource to neighbor resources by connectors.
28 private static ArrayList<Statement> browseConnectors(ReadGraph g, Resource r) throws DatabaseException {
29 ArrayList<Statement> result = new ArrayList<Statement>(2);
30 StructuralResource2 STR = StructuralResource2.getInstance(g);
31 for(Resource connector : g.getObjects(r, STR.IsConnectedTo))
32 for(Statement other : g.getStatements(connector, STR.Connects))
33 if(!other.getObject().equals(r))
38 private static Resource getJoinedFlag(ReadGraph g, Resource r) throws DatabaseException {
39 DiagramResource DIA = DiagramResource.getInstance(g);
40 for(Resource join : g.getObjects(r, DIA.FlagIsJoinedBy))
41 for(Resource flag : g.getObjects(join, DIA.JoinsFlag))
48 * Returns an identifier of the flag or null if the procedure fails.
50 private static RelativeReference getSimpleFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {
51 DiagramResource DIA = DiagramResource.getInstance(g);
52 if(!g.isInstanceOf(flag, DIA.Flag))
54 ArrayList<Statement> connections = browseConnectors(g, flag);
55 if(connections.size() != 1)
57 Resource connection = connections.get(0).getObject();
58 ArrayList<Statement> connections2 = browseConnectors(g, connection);
59 for(Statement stat : connections2) {
60 Resource element = stat.getObject();
61 if(!g.isInstanceOf(element, DIA.Flag)) {
62 Resource relation = g.getInverse(stat.getPredicate());
63 RelativeReference ref = getElementIdentifier(g, element);
65 Layer0 L0 = Layer0.getInstance(g);
66 return new RelativeReference(ref.base, ref.path + "#" +
67 g.getRelatedValue(relation, L0.HasName)
75 private static RelativeReference getFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {
76 RelativeReference ref1 = getSimpleFlagIdentifier(g, flag);
79 Resource otherFlag = getJoinedFlag(g, flag);
81 return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);
83 RelativeReference ref2 = getSimpleFlagIdentifier(g, otherFlag);
85 return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);
86 return new RelativeReference(ref1.base, "FLAG|" + ref1.path + "|" + ref2.path);
90 public static RelativeReference getElementIdentifier(ReadGraph g, Resource element) throws DatabaseException {
91 DiagramResource DIA = DiagramResource.getInstance(g);
92 ModelingResources MOD = ModelingResources.getInstance(g);
93 if(g.isInstanceOf(element, DIA.Flag)) {
94 return getFlagIdentifier(g, element);
96 else if(g.isInstanceOf(element, MOD.ReferenceElement)) {
97 Resource parent = g.getPossibleObject(element, MOD.HasParentComponent);
100 RelativeReference parentRef =
101 RelativeReference.createReference(g, MOD.StructuralModel, parent);
102 if(parentRef == null)
104 Resource referenceRelation =
105 g.getPossibleObject(element, MOD.HasReferenceRelation);
106 if(referenceRelation == null)
108 Layer0 L0 = Layer0.getInstance(g);
109 return new RelativeReference(parentRef.base,
110 "REFERENCE#"+parentRef.path+"#"+
111 g.getRelatedValue(referenceRelation, L0.HasName));
114 Resource component = g.getPossibleObject(element, MOD.ElementToComponent);
115 if(component == null)
117 return RelativeReference.createReference(g, MOD.StructuralModel, component);
121 public static RelativeReference getConnectorIdentifier(ReadGraph g, Resource connector) throws DatabaseException {
122 StructuralResource2 STR = StructuralResource2.getInstance(g);
123 DiagramResource DIA = DiagramResource.getInstance(g);
124 Layer0 L0 = Layer0.getInstance(g);
126 for(Statement stat : g.getStatements(connector, STR.Connects)) {
127 if(!g.isInstanceOf(stat.getObject(), DIA.Connection)) {
128 RelativeReference ref = getElementIdentifier(g, stat.getObject());
129 if(ref == null || ref.path == null)
131 if(ref.path.contains("#"))
134 return new RelativeReference(ref.base, ref.path + "#" +
135 g.getRelatedValue(g.getInverse(stat.getPredicate()), L0.HasName));
138 return new RelativeReference(null, "UNK");
141 private static Resource resolveElementFromComponent(ReadGraph graph, Resource model, String path) throws DatabaseException {
142 Resource component = RelativeReference.resolve(graph, model, path);
143 if(component == null) {
144 System.err.println("Didn't find component " + path);
148 ModelingResources MOD = ModelingResources.getInstance(graph);
149 Resource element = graph.getPossibleObject(component, MOD.ComponentToElement);
150 if(element == null) {
151 System.err.println("Didn't find element for component " + path);
157 private static ArrayList<Resource> findRelatedFlags(ReadGraph graph, Resource model, String path) throws DatabaseException {
158 ArrayList<Resource> result = new ArrayList<Resource>();
159 String[] parts = path.split("#");
161 String attributeName;
162 if(parts[0].equals("REFERENCE")) {
163 element = resolveReference(graph, model, path);
164 attributeName = parts[3];
167 element = resolveElementFromComponent(graph, model, parts[0]);
168 attributeName = parts[1];
172 StructuralResource2 STR = StructuralResource2.getInstance(graph);
173 DiagramResource DIA = DiagramResource.getInstance(graph);
174 Layer0 L0 = Layer0.getInstance(graph);
175 for(Statement stat : graph.getStatements(element, STR.IsConnectedTo)) {
176 if(attributeName.equals(graph.getRelatedValue(stat.getPredicate(), L0.HasName))) {
177 Resource connector1 = stat.getObject();
178 for(Resource connection : graph.getObjects(connector1, STR.Connects)) {
179 for(Resource connector2 : graph.getObjects(connection, STR.IsConnectedTo))
180 if(!connector2.equals(connector1)) {
181 for(Resource flag : graph.getObjects(connector2, STR.Connects)) {
182 if(graph.isInstanceOf(flag, DIA.Flag))
192 public static Resource resolveElement(ReadGraph graph, Resource model, String path) throws DatabaseException {
193 String[] parts = path.split("\\|");
195 if(parts[0].equals("UNJOINED_FLAG")) {
196 ArrayList<Resource> flags = findRelatedFlags(graph, model, parts[1]);
197 if(flags.isEmpty()) {
198 System.err.println("Didn't find any flag " + path);
201 // TODO filter multiple found flags
204 else if(parts[0].equals("FLAG")) {
205 ArrayList<Resource> flags = findRelatedFlags(graph, model, parts[1]);
206 if(flags.isEmpty()) {
207 System.err.println("Didn't find any flag " + path);
210 if(flags.size() == 1)
212 THashSet<Resource> flagSet = new THashSet<Resource>(findRelatedFlags(graph, model, parts[2]));
213 DiagramResource DIA = DiagramResource.getInstance(graph);
214 for(Resource f : flags)
215 for(Resource join : graph.getObjects(f, DIA.FlagIsJoinedBy))
216 for(Resource otherFlag : graph.getObjects(join, DIA.JoinsFlag))
217 if(flagSet.contains(otherFlag))
219 System.err.println("Ambiguous flag reference " + path);
222 else if(path.startsWith("REFERENCE#")) {
223 return resolveReference(graph, model, path);
226 return resolveElementFromComponent(graph, model, path);
230 private static Resource resolveReference(ReadGraph graph, Resource model, String path) throws DatabaseException {
231 String[] parts = path.split("#");
232 Resource component = RelativeReference.resolve(graph, model, parts[1]);
233 if(component == null) {
234 System.err.println("Didn't find component " + path);
238 ModelingResources MOD = ModelingResources.getInstance(graph);
239 Layer0 L0 = Layer0.getInstance(graph);
240 for(Resource element : graph.getObjects(component, MOD.HasParentComponent_Inverse)) {
241 Resource referenceRelation = graph.getSingleObject(element, MOD.HasReferenceRelation);
242 if(parts[2].equals(graph.getRelatedValue(referenceRelation, L0.HasName)))
246 System.err.println("Didn't find element for " + path);
250 public static List<Resource> resolveConnector(ReadGraph g, Resource model,
251 String name) throws DatabaseException {
252 if(name.equals("UNK"))
253 return Collections.emptyList();
254 if(name.startsWith("FLAG|") || name.startsWith("UNKNOWN_FLAG|")) {
255 Resource element = resolveElement(g, model, name);
256 return Arrays.asList(g.getSingleObject(element,
257 DiagramResource.getInstance(g).Flag_ConnectionPoint));
259 String[] parts = name.split("#");
260 Resource element = resolveElement(g, model, parts[0]);
262 return Collections.emptyList();
263 StructuralResource2 STR = StructuralResource2.getInstance(g);
264 Layer0 L0 = Layer0.getInstance(g);
265 ArrayList<Resource> result = new ArrayList<Resource>(2);
266 for(Statement stat : g.getStatements(element, STR.IsConnectedTo))
267 if(g.getRelatedValue(stat.getPredicate(), L0.HasName).equals(parts[1]))
268 result.add(stat.getObject());