]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.graph/src/org/simantics/graph/refactoring/GraphRefactoringUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / refactoring / GraphRefactoringUtils.java
diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/refactoring/GraphRefactoringUtils.java b/bundles/org.simantics.graph/src/org/simantics/graph/refactoring/GraphRefactoringUtils.java
new file mode 100644 (file)
index 0000000..1b62512
--- /dev/null
@@ -0,0 +1,210 @@
+package org.simantics.graph.refactoring;\r
+\r
+import java.util.ArrayList;\r
+\r
+import org.simantics.graph.query.Path;\r
+import org.simantics.graph.query.PathChild;\r
+import org.simantics.graph.query.TransferableGraphConversion;\r
+import org.simantics.graph.query.UriUtils;\r
+import org.simantics.graph.refactoring.MappingSpecification.MappingRule;\r
+import org.simantics.graph.representation.External;\r
+import org.simantics.graph.representation.Identity;\r
+import org.simantics.graph.representation.IdentityDefinition;\r
+import org.simantics.graph.representation.Internal;\r
+import org.simantics.graph.representation.Optional;\r
+import org.simantics.graph.representation.Root;\r
+import org.simantics.graph.representation.TransferableGraph1;\r
+import org.simantics.graph.representation.TransferableGraphUtils;\r
+import org.simantics.graph.representation.old.OldTransferableGraph1;\r
+import org.simantics.graph.representation.old.OldValue1;\r
+import org.simantics.graph.store.IdentityStore;\r
+\r
+import gnu.trove.list.array.TIntArrayList;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+public class GraphRefactoringUtils {\r
+\r
+    /**\r
+     * Moves an external resource. Returns true if did something.\r
+     * @param parentsAffected \r
+     */\r
+    public static boolean moveExternal(TransferableGraph1 tg, IdentityStore ids, Path from, PathChild to, TIntHashSet parentsAffected) throws GraphRefactoringException {\r
+        // Find from id\r
+        int fromId = ids.pathToId(from);\r
+        if(fromId < 0)\r
+            return false;\r
+        if(ids.isNewResource(fromId))\r
+            throw new GraphRefactoringException("Cannot move internal resource " + from + ".");\r
+\r
+        // Remove old identity\r
+        int parentId = ids.removeIdentity(fromId);\r
+        if(parentId >= 0)\r
+            parentsAffected.add(parentId);\r
+\r
+        // Find parent id\r
+        int toParentId = ids.createPathToId(to.parent);\r
+        if(ids.hasChild(toParentId, to.name)) {\r
+               System.err.println("refactor statements from " + from + " to " + to);\r
+            //throw new GraphRefactoringException("External reference to " + to + " already exists.");\r
+               int toId = ids.pathToId(to);\r
+            int[] statements = tg.statements;\r
+            for(int i=0;i<tg.statements.length;++i) {\r
+               if(statements[i] == fromId) statements[i] = toId;\r
+            }\r
+            return true;\r
+        }\r
+        \r
+        // Set new identity\r
+        ids.setIdentity(fromId, toParentId, to.name);\r
+        return true;\r
+    }\r
+    \r
+    public static void refactor(TransferableGraph1 tg, IdentityStore ids, MappingSpecification spec, TIntHashSet parentsAffected) throws GraphRefactoringException {\r
+        for(MappingRule rule : spec.getRules()) {\r
+            if(!(rule.to instanceof PathChild))\r
+                throw new GraphRefactoringException("Invalid target URI " + rule.to);\r
+            if(!moveExternal(tg, ids, rule.from, (PathChild)rule.to, parentsAffected))\r
+                System.err.println("Didn't find " + rule.from);\r
+        }\r
+    }\r
+\r
+    public static boolean fixIncorrectRoot(Identity[] ids) {\r
+        for(int i=0;i<ids.length;++i) {\r
+            Identity id = ids[i];\r
+            if(id.definition instanceof External) {\r
+                External ext = (External)id.definition;\r
+                if(ext.parent == -1 && (ext.name.equals("http:/") || ext.name.equals(""))) {\r
+                    id.definition = new Root("", "");\r
+                    return true;\r
+                }\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    public static void fixOntologyExport(TransferableGraph1 tg) {\r
+       \r
+       fixIncorrectRoot(tg.identities);\r
+        fixOntologyRoot(tg, true);\r
+        \r
+    }\r
+    \r
+    public static void fixOntologyRoot(TransferableGraph1 tg, boolean tryToFix) {\r
+\r
+       Identity[] ids = tg.identities;\r
+        for(int i=0;i<ids.length;++i) {\r
+            Identity id = ids[i];\r
+            if(id.definition instanceof Root) {\r
+                Root ext = (Root)id.definition;\r
+                if(ext.name.startsWith("http://")) {\r
+                       String rootName = ext.name.substring(ext.name.lastIndexOf("/")+1);\r
+                       String path = ext.name.substring(0, ext.name.lastIndexOf("/"));\r
+                       Identity pathId = TransferableGraphUtils.findExternal(tg, path);\r
+                       System.err.println("GraphRefactoringUtils.rootName=" + rootName);\r
+                       System.err.println("GraphRefactoringUtils.path2=" + path);\r
+                       if(pathId == null) {\r
+                               if(!tryToFix) return;\r
+                               IdentityStore idStore = TransferableGraphConversion.extractIdentities(tg);\r
+                               idStore.createPathToId(UriUtils.uriToPath(path));\r
+                               tg.resourceCount = idStore.getResourceCount();\r
+                               tg.identities = idStore.toArray();\r
+                               fixOntologyRoot(tg, false);\r
+                               return;\r
+                       } else {\r
+                               id.definition = new Internal(pathId.resource, rootName);\r
+                               TIntArrayList stms = new TIntArrayList(tg.statements);\r
+                       Identity consistsOf = TransferableGraphUtils.findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");\r
+                       Identity partOf = TransferableGraphUtils.findExternal(tg, "http://www.simantics.org/Layer0-1.1/PartOf");\r
+                               stms.add(id.resource);\r
+                               stms.add(partOf.resource);\r
+                               stms.add(consistsOf.resource);\r
+                               stms.add(pathId.resource);\r
+                               tg.statements = stms.toArray();\r
+                               return;\r
+                       }\r
+                       \r
+                }\r
+            }\r
+        }\r
+       \r
+    }\r
+\r
+    public static void unfixIncorrectRoot(Identity[] ids) {\r
+        for(int i=0;i<ids.length;++i) {\r
+            Identity id = ids[i];\r
+            if(id.definition instanceof Root) {\r
+                Root root = (Root)id.definition;\r
+                if(root.name.equals("") && root.type.equals("")) {\r
+                    id.definition = new External(-1, "http:/");\r
+                    return;\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    public static void compactify(OldTransferableGraph1 tg,\r
+            TIntHashSet removed) {\r
+        // Filter removed set\r
+        for(Identity id : tg.identities) {\r
+            IdentityDefinition def = id.definition;\r
+            if(def instanceof Root)\r
+                removed.remove(id.resource);\r
+            else if(def instanceof External)\r
+                removed.remove(((External)def).parent);\r
+            else if(def instanceof Internal)\r
+                removed.remove(((Internal)def).parent);\r
+            else if(def instanceof Optional)\r
+                removed.remove(((Optional)def).parent);\r
+        }\r
+        for(int r : tg.statements)\r
+            removed.remove(r);\r
+        for(OldValue1 value : tg.values)\r
+            removed.remove(value.resource);\r
+        \r
+        // Compactify\r
+        if(!removed.isEmpty()) {\r
+            // create map\r
+            int resourceCount = tg.resourceCount;\r
+            int[] map = new int[resourceCount];\r
+            for(int i=0;i<resourceCount;++i)\r
+                map[i] = i;\r
+            for(int r : removed.toArray()) {\r
+                map[--resourceCount] = map[r];\r
+            }\r
+            \r
+            // map\r
+            ArrayList<Identity> newIdentities = new ArrayList<Identity>(tg.identities.length);\r
+            for(Identity id : tg.identities) {\r
+                if(removed.contains(id.resource))\r
+                    continue;\r
+                else\r
+                    newIdentities.add(id);                \r
+                id.resource = map[id.resource];\r
+                IdentityDefinition def = id.definition;\r
+                if(def instanceof External) {\r
+                    External d = (External)def;\r
+                    d.parent = map[d.parent];\r
+                }\r
+                else if(def instanceof Internal) {\r
+                    External d = (External)def;\r
+                    d.parent = map[d.parent];\r
+                }\r
+                else if(def instanceof Optional) {\r
+                    External d = (External)def;\r
+                    d.parent = map[d.parent];\r
+                }\r
+            }\r
+            tg.identities = newIdentities.toArray(new Identity[newIdentities.size()]);\r
+            int[] statements = tg.statements;\r
+            for(int i=0;i<statements.length;++i) {\r
+                int r = statements[i];                        \r
+                if(r >= 0)\r
+                    statements[i] = map[r];\r
+            }\r
+            for(OldValue1 value : tg.values)\r
+                value.resource = map[value.resource];\r
+            tg.resourceCount = resourceCount;\r
+        }\r
+    }\r
+\r
+}\r