]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementIdentification.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementIdentification.java
new file mode 100644 (file)
index 0000000..bdacbaf
--- /dev/null
@@ -0,0 +1,272 @@
+package org.simantics.diagram.synchronization.graph;\r
+\r
+import gnu.trove.set.hash.THashSet;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.Collections;\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Statement;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.util.RelativeReference;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+\r
+public class ElementIdentification {\r
+\r
+    /**\r
+     * Browses from given resource to neighbor resources by connectors.\r
+     * @param g\r
+     * @param r\r
+     * @return\r
+     */\r
+    private static ArrayList<Statement> browseConnectors(ReadGraph g, Resource r) throws DatabaseException {\r
+        ArrayList<Statement> result = new ArrayList<Statement>(2);\r
+        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+        for(Resource connector : g.getObjects(r, STR.IsConnectedTo))\r
+            for(Statement other : g.getStatements(connector, STR.Connects))\r
+                if(!other.getObject().equals(r))\r
+                    result.add(other);\r
+        return result;\r
+    }\r
+    \r
+    private static Resource getJoinedFlag(ReadGraph g, Resource r) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(g);\r
+        for(Resource join : g.getObjects(r, DIA.FlagIsJoinedBy))\r
+            for(Resource flag : g.getObjects(join, DIA.JoinsFlag))\r
+                if(!flag.equals(r))\r
+                    return flag;\r
+        return null;\r
+    }\r
+    \r
+    /**\r
+     * Returns an identifier of the flag or null if the procedure fails.\r
+     */\r
+    private static RelativeReference getSimpleFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(g);        \r
+        if(!g.isInstanceOf(flag, DIA.Flag))\r
+            return null;\r
+        ArrayList<Statement> connections = browseConnectors(g, flag);\r
+        if(connections.size() != 1)\r
+            return null;        \r
+        Resource connection = connections.get(0).getObject();\r
+        ArrayList<Statement> connections2 = browseConnectors(g, connection);\r
+        for(Statement stat : connections2) {\r
+            Resource element = stat.getObject();\r
+            if(!g.isInstanceOf(element, DIA.Flag)) {   \r
+                Resource relation = g.getInverse(stat.getPredicate());                \r
+                RelativeReference ref = getElementIdentifier(g, element);\r
+                if(ref != null) {\r
+                    Layer0 L0 = Layer0.getInstance(g);\r
+                    return new RelativeReference(ref.base, ref.path + "#" + \r
+                            g.getRelatedValue(relation, L0.HasName) \r
+                            );\r
+                }\r
+            }            \r
+        }\r
+        return null;\r
+    }\r
+    \r
+    private static RelativeReference getFlagIdentifier(ReadGraph g, Resource flag) throws DatabaseException {\r
+        RelativeReference ref1 = getSimpleFlagIdentifier(g, flag);\r
+        if(ref1 == null)\r
+            return null;\r
+        Resource otherFlag = getJoinedFlag(g, flag);\r
+        if(otherFlag == null)\r
+            return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);\r
+        else {\r
+            RelativeReference ref2 = getSimpleFlagIdentifier(g, otherFlag);\r
+            if(ref2 == null)\r
+                return new RelativeReference(ref1.base, "UNJOINED_FLAG|" + ref1.path);\r
+            return new RelativeReference(ref1.base, "FLAG|" + ref1.path + "|" + ref2.path);\r
+        }\r
+    }\r
+    \r
+    public static RelativeReference getElementIdentifier(ReadGraph g, Resource element) throws DatabaseException {\r
+        DiagramResource DIA = DiagramResource.getInstance(g);\r
+        ModelingResources MOD = ModelingResources.getInstance(g);\r
+        if(g.isInstanceOf(element, DIA.Flag)) {\r
+            return getFlagIdentifier(g, element);            \r
+        }\r
+        else if(g.isInstanceOf(element, MOD.ReferenceElement)) {\r
+            Resource parent = g.getPossibleObject(element, MOD.HasParentComponent);\r
+            if(parent == null)\r
+                return null;\r
+            RelativeReference parentRef = \r
+                    RelativeReference.createReference(g, MOD.StructuralModel, parent);\r
+            if(parentRef == null)\r
+                return null;\r
+            Resource referenceRelation = \r
+                    g.getPossibleObject(element, MOD.HasReferenceRelation);\r
+            if(referenceRelation == null)\r
+                return null;\r
+            Layer0 L0 = Layer0.getInstance(g);\r
+            return new RelativeReference(parentRef.base, \r
+                    "REFERENCE#"+parentRef.path+"#"+\r
+                    g.getRelatedValue(referenceRelation, L0.HasName));\r
+        }\r
+        else {        \r
+            Resource component = g.getPossibleObject(element, MOD.ElementToComponent);\r
+            if(component == null)\r
+                return null;\r
+            return RelativeReference.createReference(g, MOD.StructuralModel, component);\r
+        }        \r
+    }\r
+    \r
+    public static RelativeReference getConnectorIdentifier(ReadGraph g, Resource connector) throws DatabaseException {\r
+        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+        DiagramResource DIA = DiagramResource.getInstance(g);\r
+        Layer0 L0 = Layer0.getInstance(g);\r
+        \r
+        for(Statement stat : g.getStatements(connector, STR.Connects)) {\r
+            if(!g.isInstanceOf(stat.getObject(), DIA.Connection)) {\r
+                RelativeReference ref = getElementIdentifier(g, stat.getObject());\r
+                if(ref == null || ref.path == null)\r
+                    continue;\r
+                if(ref.path.contains("#"))\r
+                    return ref;\r
+                else\r
+                    return new RelativeReference(ref.base, ref.path + "#" + \r
+                            g.getRelatedValue(g.getInverse(stat.getPredicate()), L0.HasName));\r
+            }\r
+        }\r
+        return new RelativeReference(null, "UNK");\r
+    } \r
+    \r
+    private static Resource resolveElementFromComponent(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
+        Resource component = RelativeReference.resolve(graph, model, path);\r
+        if(component == null) {\r
+            System.err.println("Didn't find component " + path);\r
+            return null;\r
+        }\r
+        \r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        Resource element = graph.getPossibleObject(component, MOD.ComponentToElement);\r
+        if(element == null) {\r
+            System.err.println("Didn't find element for component " + path);\r
+            return null;\r
+        }            \r
+        return element;\r
+    }\r
+    \r
+    private static ArrayList<Resource> findRelatedFlags(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
+        ArrayList<Resource> result = new ArrayList<Resource>();\r
+        String[] parts = path.split("#");\r
+        Resource element;\r
+        String attributeName;\r
+        if(parts[0].equals("REFERENCE")) {\r
+            element = resolveReference(graph, model, path);\r
+            attributeName = parts[3];\r
+        }\r
+        else {\r
+            element = resolveElementFromComponent(graph, model, parts[0]);\r
+            attributeName = parts[1];\r
+        }\r
+        if(element == null)\r
+            return result;\r
+        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+        DiagramResource DIA = DiagramResource.getInstance(graph);\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        for(Statement stat : graph.getStatements(element, STR.IsConnectedTo)) {\r
+            if(attributeName.equals(graph.getRelatedValue(stat.getPredicate(), L0.HasName))) {\r
+                Resource connector1 = stat.getObject();\r
+                for(Resource connection : graph.getObjects(connector1, STR.Connects)) {\r
+                    for(Resource connector2 : graph.getObjects(connection, STR.IsConnectedTo))\r
+                        if(!connector2.equals(connector1)) {\r
+                            for(Resource flag : graph.getObjects(connector2, STR.Connects)) {\r
+                                if(graph.isInstanceOf(flag, DIA.Flag))\r
+                                    result.add(flag);\r
+                            }\r
+                        }\r
+                }\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+    \r
+    public static Resource resolveElement(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
+        String[] parts = path.split("\\|");\r
+        \r
+        if(parts[0].equals("UNJOINED_FLAG")) {\r
+            ArrayList<Resource> flags = findRelatedFlags(graph, model, parts[1]);\r
+            if(flags.isEmpty()) {\r
+                System.err.println("Didn't find any flag " + path);\r
+                return null;\r
+            }\r
+            // TODO filter multiple found flags\r
+            return flags.get(0);\r
+        }\r
+        else if(parts[0].equals("FLAG")) {\r
+            ArrayList<Resource> flags = findRelatedFlags(graph, model, parts[1]);\r
+            if(flags.isEmpty()) {\r
+                System.err.println("Didn't find any flag " + path);\r
+                return null;\r
+            }\r
+            if(flags.size() == 1)\r
+                return flags.get(0);\r
+            THashSet<Resource> flagSet = new THashSet<Resource>(findRelatedFlags(graph, model, parts[2]));\r
+            DiagramResource DIA = DiagramResource.getInstance(graph);\r
+            for(Resource f : flags)\r
+                for(Resource join : graph.getObjects(f, DIA.FlagIsJoinedBy))\r
+                    for(Resource otherFlag : graph.getObjects(join, DIA.JoinsFlag))\r
+                        if(flagSet.contains(otherFlag))\r
+                            return f;\r
+            System.err.println("Ambiguous flag reference " + path);\r
+            return null;\r
+        }\r
+        else if(path.startsWith("REFERENCE#")) {\r
+            return resolveReference(graph, model, path);\r
+        }\r
+        else {\r
+            return resolveElementFromComponent(graph, model, path);\r
+        }\r
+    }\r
+    \r
+    private static Resource resolveReference(ReadGraph graph, Resource model, String path) throws DatabaseException {\r
+        String[] parts = path.split("#");\r
+        Resource component = RelativeReference.resolve(graph, model, parts[1]);\r
+        if(component == null) {\r
+            System.err.println("Didn't find component " + path);\r
+            return null;\r
+        }\r
+        \r
+        ModelingResources MOD = ModelingResources.getInstance(graph);\r
+        Layer0 L0 = Layer0.getInstance(graph);\r
+        for(Resource element : graph.getObjects(component, MOD.HasParentComponent_Inverse)) {\r
+            Resource referenceRelation = graph.getSingleObject(element, MOD.HasReferenceRelation);\r
+            if(parts[2].equals(graph.getRelatedValue(referenceRelation, L0.HasName)))\r
+                return element;\r
+        }\r
+\r
+        System.err.println("Didn't find element for " + path);\r
+        return null;\r
+    }\r
+    \r
+    public static List<Resource> resolveConnector(ReadGraph g, Resource model,\r
+            String name) throws DatabaseException {\r
+        if(name.equals("UNK"))\r
+            return Collections.emptyList();\r
+        if(name.startsWith("FLAG|") || name.startsWith("UNKNOWN_FLAG|")) {\r
+            Resource element = resolveElement(g, model, name);\r
+            return Arrays.asList(g.getSingleObject(element, \r
+                    DiagramResource.getInstance(g).Flag_ConnectionPoint));\r
+        }\r
+        String[] parts = name.split("#");\r
+        Resource element = resolveElement(g, model, parts[0]);\r
+        if (element == null)\r
+            return Collections.emptyList();\r
+        StructuralResource2 STR = StructuralResource2.getInstance(g);\r
+        Layer0 L0 = Layer0.getInstance(g);\r
+        ArrayList<Resource> result = new ArrayList<Resource>(2);\r
+        for(Statement stat : g.getStatements(element, STR.IsConnectedTo))\r
+            if(g.getRelatedValue(stat.getPredicate(), L0.HasName).equals(parts[1]))\r
+                result.add(stat.getObject());\r
+        return result;\r
+    }\r
+    \r
+}\r