-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
+package org.simantics.graph.refactoring;
+
+import java.util.Arrays;
+
+import org.simantics.databoard.util.URIStringUtils;
+import org.simantics.graph.query.Path;
+import org.simantics.graph.query.PathChild;
+import org.simantics.graph.query.TransferableGraphConversion;
+import org.simantics.graph.query.UriUtils;
+import org.simantics.graph.refactoring.MappingSpecification.MappingRule;
+import org.simantics.graph.representation.External;
+import org.simantics.graph.representation.Identity;
+import org.simantics.graph.representation.Internal;
+import org.simantics.graph.representation.Root;
+import org.simantics.graph.representation.TransferableGraph1;
+import org.simantics.graph.representation.TransferableGraphUtils;
+import org.simantics.graph.store.GraphStore;
+import org.simantics.graph.store.IdentityStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import gnu.trove.set.hash.TIntHashSet;
+
+public class GraphRefactoringUtils {
+ private static final Logger LOGGER = LoggerFactory.getLogger(GraphRefactoringUtils.class);
+ /**
+ * Moves an external resource. Returns true if did something.
+ * @param parentsAffected
+ */
+ public static boolean moveExternal(TransferableGraph1 tg, IdentityStore ids, Path from, PathChild to, TIntHashSet parentsAffected) throws GraphRefactoringException {
+ // Find from id
+ int fromId = ids.pathToId(from);
+ if(fromId < 0)
+ return false;
+ if(ids.isNewResource(fromId))
+ throw new GraphRefactoringException("Cannot move internal resource " + from + ".");
+
+ // Remove old identity
+ int parentId = ids.removeIdentity(fromId);
+ if(parentId >= 0)
+ parentsAffected.add(parentId);
+
+ // Find parent id
+ int toParentId = ids.createPathToId(to.parent);
+ if(ids.hasChild(toParentId, to.name)) {
+ LOGGER.info("refactor statements from " + from + " to " + to);
+ //throw new GraphRefactoringException("External reference to " + to + " already exists.");
+ int toId = ids.pathToId(to);
+ int[] statements = tg.statements;
+ for(int i=0;i<tg.statements.length;++i) {
+ if(statements[i] == fromId) statements[i] = toId;
+ }
+ return true;
+ }
+
+ // Set new identity
+ ids.setIdentity(fromId, toParentId, to.name);
+ return true;
+ }
+
+ public static void refactor(TransferableGraph1 tg, IdentityStore ids, MappingSpecification spec, TIntHashSet parentsAffected) throws GraphRefactoringException {
+ for(MappingRule rule : spec.getRules()) {
+ if(!(rule.to instanceof PathChild))
+ throw new GraphRefactoringException("Invalid target URI " + rule.to);
+ if(!moveExternal(tg, ids, rule.from, (PathChild)rule.to, parentsAffected))
+ LOGGER.warn("Didn't find " + rule.from);
+ }
+ }
+
+ public static boolean fixIncorrectRoot(Identity[] ids) {
+ for(int i=0;i<ids.length;++i) {
+ Identity id = ids[i];
+ if(id.definition instanceof External) {
+ External ext = (External)id.definition;
+ if(ext.parent == -1 && (ext.name.equals("http:/") || ext.name.equals(""))) {
+ id.definition = new Root("", "");
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ public static void fixOntologyExport(TransferableGraph1 tg) {
+
+ fixIncorrectRoot(tg.identities);
+ fixOntologyRoot(tg, true);
+
+ }
+
+ private static Identity recursePath(TransferableGraph1 tg, String path) {
+
+ Identity extId = TransferableGraphUtils.findExternal(tg, path);
+ if(extId != null) return extId;
+ if("http://".equals(path)) return TransferableGraphUtils.findRootWithName(tg, "");
+ String[] parts = URIStringUtils.splitURI(path);
+ Identity parentId = recursePath(tg, parts[0]);
+ tg.identities = Arrays.copyOf(tg.identities, tg.identities.length+1);
+ Identity childIdentity = new Identity(tg.resourceCount++, new External(parentId.resource, URIStringUtils.unescape(parts[1])));
+ tg.identities[tg.identities.length-1] = childIdentity;
+ return childIdentity;
+
+ }
+
+ public static void fixOntologyRoot(TransferableGraph1 tg, boolean tryToFix) {
+
+ Identity[] ids = tg.identities;
+ for(int i=0;i<ids.length;++i) {
+ Identity id = ids[i];
+ if(id.definition instanceof Root) {
+ Root ext = (Root)id.definition;
+ if(ext.name.startsWith("http://")) {
+
+ String[] parts = URIStringUtils.splitURI(ext.name);
+ Identity path = recursePath(tg, parts[0]);
+ id.definition = new Internal(path.resource, URIStringUtils.unescape(parts[1]));
+
+ GraphStore store = TransferableGraphConversion.convert(tg);
+ int rootId = store.identities.createPathToId(UriUtils.uriToPathUnescaped(ext.name));
+ propagateNewMarks(store.identities, rootId);
+
+ TransferableGraph1 tgNew = TransferableGraphConversion.convert(store);
+
+ tg.resourceCount = tgNew.resourceCount;
+ tg.identities = tgNew.identities;
+ tg.values = tgNew.values;
+ tg.statements = tgNew.statements;
+
+ return;
+
+ } else if (ext.type.startsWith("http://")) {
+ String first = "http://Projects/Development%20Project";
+ Identity path = recursePath(tg, first);
+ id.definition = new Internal(path.resource, ext.name);
+
+ GraphStore store = TransferableGraphConversion.convert(tg);
+ int rootId = store.identities.createPathToId(UriUtils.uriToPathUnescaped(first + "/" + ext.name));
+ propagateNewMarks(store.identities, rootId);
+
+ TransferableGraph1 tgNew = TransferableGraphConversion.convert(store);
+
+ tg.resourceCount = tgNew.resourceCount;
+ tg.identities = tgNew.identities;
+ tg.values = tgNew.values;
+ tg.statements = tgNew.statements;
+
+ }
+ }
+ }
+
+ }
+
+ private static void propagateNewMarks(IdentityStore identities, int resource) {
+ if(identities.markNew(resource)) {
+ for(int child : identities.getChildren(resource))
+ propagateNewMarks(identities, child);
+ }
+ }
+
+ public static void unfixIncorrectRoot(Identity[] ids) {
+ for(int i=0;i<ids.length;++i) {
+ Identity id = ids[i];
+ if(id.definition instanceof Root) {
+ Root root = (Root)id.definition;
+ if(root.name.equals("") && root.type.equals("")) {
+ id.definition = new External(-1, "http:/");
+ return;
+ }
+ }
+ }
+ }
+
+}