-package org.simantics.graph.representation;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.HashMap;\r
-import java.util.Map;\r
-\r
-public class TransferableGraphUtils {\r
-\r
- public static Collection<Identity> getRoots(TransferableGraph1 tg) {\r
- \r
- ArrayList<Identity> result = new ArrayList<Identity>();\r
- for(Identity id : tg.identities) {\r
- if(id.definition instanceof Root) result.add(id);\r
- }\r
- return result;\r
- \r
- }\r
- \r
- public static Identity findRootWithName(TransferableGraph1 tg, String name) {\r
- \r
- for(Identity id : tg.identities) {\r
- if(id.definition instanceof Root) {\r
- Root ext = (Root)id.definition;\r
- if(ext.name.equals(name)) return id;\r
- }\r
- }\r
- return null;\r
- \r
- }\r
-\r
- public static Identity findExternalWithName(TransferableGraph1 tg, String name) {\r
- \r
- for(Identity id : tg.identities) {\r
- if(id.definition instanceof External) {\r
- External ext = (External)id.definition;\r
- if(ext.name.equals(name)) return id;\r
- }\r
- }\r
- return null;\r
- \r
- }\r
-\r
- public static Identity findExternalWithNameAndParent(TransferableGraph1 tg, int parent, String name) {\r
- \r
- for(Identity id : tg.identities) {\r
- if(id.definition instanceof External) {\r
- External ext = (External)id.definition;\r
- if(ext.name.equals(name) && ext.parent == parent) return id;\r
- }\r
- }\r
- return null;\r
- \r
- }\r
- \r
- public static Identity findExternal(TransferableGraph1 tg, String uri) {\r
- \r
- Identity identity = findExternalWithName(tg, "http:/");\r
- if(identity == null) identity = findExternalWithName(tg, "");\r
- if(identity == null) identity = findRootWithName(tg, "");\r
- if("http:/".equals(uri)) return identity;\r
- String[] tokens = uri.substring("http://".length()).split("/");\r
- for(String token : tokens) {\r
- identity = findExternalWithNameAndParent(tg, identity.resource, token);\r
- }\r
- return identity;\r
- \r
- }\r
- \r
- public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {\r
- ArrayList<Identity> result = new ArrayList<Identity>();\r
- System.err.println("children for " + parent.resource);\r
- for(Identity id : tg.identities) {\r
- if(id.definition instanceof Internal) {\r
- Internal internal = (Internal)id.definition;\r
- System.err.println("internal with parent " + internal.parent);\r
- if(internal.parent == parent.resource) result.add(id);\r
- }\r
- }\r
- findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");\r
- for(int i=0;i<tg.statements.length;i+=4) {\r
- if(tg.statements[i] == parent.resource)\r
- System.err.println("related to parent " + tg.statements[i+3]);\r
- }\r
- return result;\r
- }\r
- \r
- public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {\r
- Identity p = findExternal(tg, predicate);\r
- if(p == null) return 0;\r
- int result = 0;\r
- for(int i=0;i<tg.statements.length;i+=4) {\r
- if(tg.statements[i] == subject.resource && tg.statements[i+1] == p.resource) {\r
- if(result != 0) return 0;\r
- result = tg.statements[i+3];\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {\r
- Map<Identity, String> result = new HashMap<Identity, String>();\r
- for(Identity id : ids) {\r
- if(id.definition instanceof Internal) {\r
- Internal internal = (Internal)id.definition;\r
- result.put(id, internal.name);\r
- }\r
- }\r
- return result;\r
- }\r
-\r
- public static String getName(TransferableGraph1 tg, Identity id) {\r
- return getName(id);\r
- }\r
-\r
- public static String getName(Identity id) {\r
- if(id.definition instanceof Internal) {\r
- Internal internal = (Internal)id.definition;\r
- return internal.name;\r
- } else if(id.definition instanceof External) {\r
- External external = (External)id.definition;\r
- return external.name;\r
- } else if(id.definition instanceof Root) {\r
- Root root = (Root)id.definition;\r
- return root.name;\r
- } else {\r
- Optional optional = (Optional)id.definition;\r
- return optional.name;\r
- }\r
- }\r
-\r
- public static String getRootType(Identity id) {\r
- if(id.definition instanceof Root) {\r
- Root root = (Root)id.definition;\r
- return root.type;\r
- } else {\r
- throw new IllegalArgumentException("Expected root, got " + id);\r
- }\r
- }\r
-\r
- public static Value findValue(TransferableGraph1 tg, int subject) {\r
- for(Value v : tg.values) {\r
- if(v.resource == subject) return v;\r
- }\r
- return null;\r
- }\r
- \r
- public static String getURI(TransferableGraph1 tg, int id) {\r
- return getURI(tg.resourceCount, tg.identities, id);\r
- }\r
- \r
- public static String getURI(int resourceCount, Identity[] identities, int id) {\r
- for(Identity identity : identities) {\r
- if(identity.resource == id) {\r
- IdentityDefinition definition = identity.definition;\r
- if(definition instanceof External) {\r
- External def = (External)definition;\r
- if(def.parent == -1) return "http:/";\r
- else return getURI(resourceCount, identities, def.parent) + "/" + def.name;\r
- } else if(definition instanceof Root) {\r
- Root def = (Root)definition;\r
- return def.name;\r
- } else if (definition instanceof Internal) {\r
- Internal def = (Internal)definition;\r
- System.err.println("External URI error: parent was internal '" + def.name + "'");\r
- return "";\r
- } else {\r
- return "";\r
- }\r
- }\r
- } \r
- return "<internal reference " + id + ">:";\r
- }\r
- \r
-}\r
+package org.simantics.graph.representation;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.util.URIStringUtils;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+
+public class TransferableGraphUtils {
+
+ public static Collection<Identity> getRoots(TransferableGraph1 tg) {
+
+ ArrayList<Identity> result = new ArrayList<Identity>();
+ for(Identity id : tg.identities) {
+ if(id.definition instanceof Root) result.add(id);
+ }
+ return result;
+
+ }
+
+ public static Identity findRootWithName(TransferableGraph1 tg, String name) {
+
+ for(Identity id : tg.identities) {
+ if(id.definition instanceof Root) {
+ Root ext = (Root)id.definition;
+ if(ext.name.equals(name)) return id;
+ }
+ }
+ return null;
+
+ }
+
+ public static Identity findExternalWithName(TransferableGraph1 tg, String name) {
+
+ for(Identity id : tg.identities) {
+ if(id.definition instanceof External) {
+ External ext = (External)id.definition;
+ if(ext.name.equals(name)) return id;
+ }
+ }
+ return null;
+
+ }
+
+ public static Identity findExternalWithNameAndParent(TransferableGraph1 tg, int parent, String name) {
+
+ for(Identity id : tg.identities) {
+ if(id.definition instanceof External) {
+ External ext = (External)id.definition;
+ if(ext.name.equals(name) && ext.parent == parent) return id;
+ }
+ }
+ return null;
+
+ }
+
+ public static Identity findExternal(TransferableGraph1 tg, String uri) {
+
+ Identity identity = findExternalWithName(tg, "http:/");
+ if(identity == null) identity = findExternalWithName(tg, "");
+ if(identity == null) identity = findRootWithName(tg, "");
+ if("http:/".equals(uri)) return identity;
+ String[] tokens = uri.substring("http://".length()).split("/");
+ for(String token : tokens) {
+ identity = findExternalWithNameAndParent(tg, identity.resource, URIStringUtils.unescape(token));
+ if (identity == null) {
+ return null;
+ }
+ }
+ return identity;
+
+ }
+
+ /**
+ * Provided a tg and a resource uri, returns the identity of the tg if the uri_ matches the tg exactly
+ * @param tg
+ * @param uri_
+ * @return
+ */
+ public static Identity getIdentity2(TransferableGraph1 tg, String uri_) {
+ Collection<Identity> identities = TransferableGraphUtils.getRoots(tg);
+ for (Identity i : identities) {
+ Identity id = getIdentity2(tg, uri_, i);
+ if (id != null) {
+ return id;
+ }
+ }
+ return null;
+ }
+
+ /**
+ *
+ * @param tg
+ * @param uri_
+ * @param id
+ * @return
+ */
+ public static Identity getIdentity2(TransferableGraph1 tg, String uri_, Identity id) {
+ String uri = TransferableGraphUtils.getURI(tg, id.resource);
+
+ if (uri_.equals(uri)) {
+ return id;
+ }
+
+ if (uri_.startsWith(uri)) {
+ Collection<Identity> childIdentitiesOfRoot = TransferableGraphUtils.getChildren2(tg, id);
+ for (Identity i2 : childIdentitiesOfRoot) {
+ Identity id2 = getIdentity2(tg, uri_, i2);
+ if (id2 != null) {
+ return id2;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ public static Identity getIdentity(TransferableGraph1 tg, int resource) {
+ for(Identity id : tg.identities) {
+ if(id.resource == resource) return id;
+ }
+ return null;
+ }
+
+ public static TIntArrayList getStatements(TransferableGraph1 tg, int resource) {
+ TIntArrayList result = new TIntArrayList();
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == resource) {
+ result.add(tg.statements[i+1]);
+ result.add(tg.statements[i+3]);
+ }
+ }
+ return result;
+ }
+
+ public static Collection<Identity> getChildren2(TransferableGraph1 tg, Identity parent) {
+ return getChildren2(tg, parent.resource);
+ }
+
+ public static Collection<Identity> getChildren2(TransferableGraph1 tg, int parentResource) {
+ TreeMap<String, Identity> result = new TreeMap<>();
+ for (Identity id : tg.identities) {
+ if (id.definition instanceof Internal) {
+ Internal internal = (Internal) id.definition;
+ if (internal.parent == parentResource)
+ result.put(internal.name, id);
+ }
+ }
+ Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+ Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
+ if(consistsOf != null && hasName != null) {
+ for (int i = 0; i < tg.statements.length; i += 4) {
+ if (tg.statements[i] == parentResource) {
+ if (tg.statements[i + 1] == consistsOf.resource) {
+ Identity identity = getIdentity(tg, tg.statements[i + 3]);
+ if (identity != null) {
+ if (identity.definition instanceof Internal) {
+ Internal internal = (Internal) identity.definition;
+ result.put(internal.name, identity);
+ }
+ } else {
+ int possibleNameResource = getPossibleObject2(tg, tg.statements[i + 3], hasName);
+ if (possibleNameResource != NOT_FOUND) {
+ Value value = findValue(tg, possibleNameResource);
+ if (value != null) {
+ try {
+ String name = (String) value.value.getValue(Bindings.STRING);
+ result.put(name, new Identity(tg.statements[i + 3], new Internal(tg.statements[i], name)));
+ } catch (AdaptException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return result.values();
+ }
+
+ /**
+ * This implementation is no longer advised to use because it returns 0 as
+ * NOT_FOUND which is in fact a valid ID for resource in graph
+ */
+ @Deprecated
+ public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {
+ TreeMap<String,Identity> result = new TreeMap<>();
+ for(Identity id : tg.identities) {
+ if(id.definition instanceof Internal) {
+ Internal internal = (Internal)id.definition;
+ if(internal.parent == parent.resource) result.put(internal.name, id);
+ }
+ }
+ Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
+ Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == parent.resource) {
+ if(tg.statements[i+1] == consistsOf.resource) {
+ Identity identity = getIdentity(tg, tg.statements[i+3]);
+ if(identity != null) {
+ if(identity.definition instanceof Internal) {
+ Internal internal = (Internal)identity.definition;
+ result.put(internal.name, identity);
+ }
+ } else {
+ int possibleNameResource = getPossibleObject(tg, tg.statements[i+3], hasName);
+ if(possibleNameResource != 0) {
+ Value value = findValue(tg, possibleNameResource);
+ if(value != null) {
+ try {
+ String name = (String)value.value.getValue(Bindings.STRING);
+ result.put(name, new Identity(tg.statements[i+3], new Internal(tg.statements[i], name)));
+ } catch (AdaptException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return result.values();
+ }
+
+ public static TIntArrayList getObjects(TransferableGraph1 tg, int subject, Identity predicate) {
+ TIntArrayList result = new TIntArrayList();
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
+ result.add(tg.statements[i+3]);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * This implementation is no longer advised to use because it returns 0 as
+ * NOT_FOUND which is in fact a valid ID for resource in graph
+ */
+ @Deprecated
+ public static int getPossibleObject(TransferableGraph1 tg, int subject, Identity predicate) {
+ int result = 0;
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
+ if(result != 0 && tg.statements[i+3] != result) return 0;
+ result = tg.statements[i+3];
+ }
+ }
+ return result;
+ }
+
+ public static final int NOT_FOUND = -2;
+
+ public static int getPossibleObject2(TransferableGraph1 tg, int subject, Identity predicate) {
+ int result = NOT_FOUND;
+ for(int i=0;i<tg.statements.length;i+=4) {
+ if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
+ if(result != NOT_FOUND && tg.statements[i+3] != result)
+ return NOT_FOUND;
+ result = tg.statements[i+3];
+ }
+ }
+ return result;
+ }
+
+ /**
+ * @return 0 for presenting not found which is BAD
+ * @see getPossibleObject2
+ */
+ @Deprecated
+ public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
+ Identity p = findExternal(tg, predicate);
+ if(p == null) return 0;
+ return getPossibleObject(tg, subject.resource, p);
+ }
+
+ public static int getPossibleObject2(TransferableGraph1 tg, Identity subject, String predicate) {
+ Identity p = findExternal(tg, predicate);
+ if (p == null)
+ return NOT_FOUND;
+ return getPossibleObject2(tg, subject.resource, p);
+ }
+
+ public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {
+ Map<Identity, String> result = new HashMap<Identity, String>();
+ for(Identity id : ids) {
+ if(id.definition instanceof Internal) {
+ Internal internal = (Internal)id.definition;
+ result.put(id, internal.name);
+ }
+ }
+ return result;
+ }
+
+ public static String getName(TransferableGraph1 tg, Identity id) {
+ return getName(id);
+ }
+
+ public static String getName(Identity id) {
+ if(id.definition instanceof Internal) {
+ Internal internal = (Internal)id.definition;
+ return internal.name;
+ } else if(id.definition instanceof External) {
+ External external = (External)id.definition;
+ return external.name;
+ } else if(id.definition instanceof Root) {
+ Root root = (Root)id.definition;
+ return root.name;
+ } else {
+ Optional optional = (Optional)id.definition;
+ return optional.name;
+ }
+ }
+
+ public static String getRootType(Identity id) {
+ if(id.definition instanceof Root) {
+ Root root = (Root)id.definition;
+ return root.type;
+ } else {
+ throw new IllegalArgumentException("Expected root, got " + id);
+ }
+ }
+
+ public static Value findValue(TransferableGraph1 tg, int subject) {
+ for(Value v : tg.values) {
+ if(v.resource == subject) return v;
+ }
+ return null;
+ }
+
+ public static String getURI(TransferableGraph1 tg, int id) {
+ return getURI(tg.identities, id);
+ }
+
+ public static String getURI(Identity[] identities, int id) {
+ for(Identity identity : identities) {
+ if(identity.resource == id) {
+ IdentityDefinition definition = identity.definition;
+ if(definition instanceof External) {
+ External def = (External)definition;
+ if(def.parent == -1) return "http:/";
+ else return getURI(identities, def.parent) + "/" + URIStringUtils.escape(def.name);
+ } else if(definition instanceof Root) {
+ Root def = (Root)definition;
+ if(def.name.isEmpty()) return "http:/";
+ return def.name;
+ } else if (definition instanceof Internal) {
+ Internal def = (Internal)definition;
+ return getURI(identities, def.parent) + "/" + URIStringUtils.escape(def.name);
+ } else {
+ return "";
+ }
+ }
+ }
+ return "<internal reference " + id + ">:";
+ }
+
+ public static TIntObjectMap<Identity> mapIdentities(TransferableGraph1 tg) {
+ return mapIdentities(tg.identities);
+ }
+
+ public static TIntObjectMap<Identity> mapIdentities(Identity[] identities) {
+ // Integer.MIN_VALUE cannot be the value of Identity.resource
+ TIntObjectMap<Identity> map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE);
+ for (Identity id : identities)
+ map.put(id.resource, id);
+ return map;
+ }
+
+ public static String getURI(int resourceCount, TIntObjectMap<Identity> identities, int id) {
+ Identity identity = identities.get(id);
+ if(identity != null) {
+ IdentityDefinition definition = identity.definition;
+ if(definition instanceof External) {
+ External def = (External)definition;
+ if(def.parent == -1) return "http:/";
+ else return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
+ } else if(definition instanceof Root) {
+ Root def = (Root)definition;
+ if(def.name.isEmpty()) return "http:/";
+ return def.name;
+ } else if (definition instanceof Internal) {
+ Internal def = (Internal)definition;
+ return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
+ } else {
+ return "";
+ }
+ }
+ return "<internal reference " + id + ">:";
+ }
+
+}