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 getRoots(TransferableGraph1 tg) { ArrayList result = new ArrayList(); 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 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 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 getChildren2(TransferableGraph1 tg, Identity parent) { return getChildren2(tg, parent.resource); } public static Collection getChildren2(TransferableGraph1 tg, int parentResource) { TreeMap 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"); 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 getChildren(TransferableGraph1 tg, Identity parent) { TreeMap 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 getNames(TransferableGraph1 tg, Collection ids) { Map result = new HashMap(); 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 ":"; } public static TIntObjectMap mapIdentities(TransferableGraph1 tg) { return mapIdentities(tg.identities); } public static TIntObjectMap mapIdentities(Identity[] identities) { // Integer.MIN_VALUE cannot be the value of Identity.resource TIntObjectMap 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 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 ":"; } }