1 package org.simantics.graph.representation;
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
7 import java.util.TreeMap;
9 import org.simantics.databoard.Bindings;
10 import org.simantics.databoard.adapter.AdaptException;
11 import org.simantics.databoard.util.URIStringUtils;
13 import gnu.trove.list.array.TIntArrayList;
14 import gnu.trove.map.TIntObjectMap;
15 import gnu.trove.map.hash.TIntObjectHashMap;
17 public class TransferableGraphUtils {
19 public static Collection<Identity> getRoots(TransferableGraph1 tg) {
21 ArrayList<Identity> result = new ArrayList<Identity>();
22 for(Identity id : tg.identities) {
23 if(id.definition instanceof Root) result.add(id);
29 public static Identity findRootWithName(TransferableGraph1 tg, String name) {
31 for(Identity id : tg.identities) {
32 if(id.definition instanceof Root) {
33 Root ext = (Root)id.definition;
34 if(ext.name.equals(name)) return id;
41 public static Identity findExternalWithName(TransferableGraph1 tg, String name) {
43 for(Identity id : tg.identities) {
44 if(id.definition instanceof External) {
45 External ext = (External)id.definition;
46 if(ext.name.equals(name)) return id;
53 public static Identity findExternalWithNameAndParent(TransferableGraph1 tg, int parent, String name) {
55 for(Identity id : tg.identities) {
56 if(id.definition instanceof External) {
57 External ext = (External)id.definition;
58 if(ext.name.equals(name) && ext.parent == parent) return id;
65 public static Identity findExternal(TransferableGraph1 tg, String uri) {
67 Identity identity = findExternalWithName(tg, "http:/");
68 if(identity == null) identity = findExternalWithName(tg, "");
69 if(identity == null) identity = findRootWithName(tg, "");
70 if("http:/".equals(uri)) return identity;
71 String[] tokens = uri.substring("http://".length()).split("/");
72 for(String token : tokens) {
73 identity = findExternalWithNameAndParent(tg, identity.resource, URIStringUtils.unescape(token));
74 if (identity == null) {
83 * Provided a tg and a resource uri, returns the identity of the tg if the uri_ matches the tg exactly
88 public static Identity getIdentity2(TransferableGraph1 tg, String uri_) {
89 Collection<Identity> identities = TransferableGraphUtils.getRoots(tg);
90 for (Identity i : identities) {
91 Identity id = getIdentity2(tg, uri_, i);
106 public static Identity getIdentity2(TransferableGraph1 tg, String uri_, Identity id) {
107 String uri = TransferableGraphUtils.getURI(tg, id.resource);
109 if (uri_.equals(uri)) {
113 if (uri_.startsWith(uri)) {
114 Collection<Identity> childIdentitiesOfRoot = TransferableGraphUtils.getChildren2(tg, id);
115 for (Identity i2 : childIdentitiesOfRoot) {
116 Identity id2 = getIdentity2(tg, uri_, i2);
126 public static Identity getIdentity(TransferableGraph1 tg, int resource) {
127 for(Identity id : tg.identities) {
128 if(id.resource == resource) return id;
133 public static TIntArrayList getStatements(TransferableGraph1 tg, int resource) {
134 TIntArrayList result = new TIntArrayList();
135 for(int i=0;i<tg.statements.length;i+=4) {
136 if(tg.statements[i] == resource) {
137 result.add(tg.statements[i+1]);
138 result.add(tg.statements[i+3]);
144 public static Collection<Identity> getChildren2(TransferableGraph1 tg, Identity parent) {
145 return getChildren2(tg, parent.resource);
148 public static Collection<Identity> getChildren2(TransferableGraph1 tg, int parentResource) {
149 TreeMap<String, Identity> result = new TreeMap<>();
150 for (Identity id : tg.identities) {
151 if (id.definition instanceof Internal) {
152 Internal internal = (Internal) id.definition;
153 if (internal.parent == parentResource)
154 result.put(internal.name, id);
157 Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
158 Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
159 if(consistsOf != null && hasName != null) {
160 for (int i = 0; i < tg.statements.length; i += 4) {
161 if (tg.statements[i] == parentResource) {
162 if (tg.statements[i + 1] == consistsOf.resource) {
163 Identity identity = getIdentity(tg, tg.statements[i + 3]);
164 if (identity != null) {
165 if (identity.definition instanceof Internal) {
166 Internal internal = (Internal) identity.definition;
167 result.put(internal.name, identity);
170 int possibleNameResource = getPossibleObject2(tg, tg.statements[i + 3], hasName);
171 if (possibleNameResource != NOT_FOUND) {
172 Value value = findValue(tg, possibleNameResource);
175 String name = (String) value.value.getValue(Bindings.STRING);
176 result.put(name, new Identity(tg.statements[i + 3], new Internal(tg.statements[i], name)));
177 } catch (AdaptException e) {
187 return result.values();
191 * This implementation is no longer advised to use because it returns 0 as
192 * NOT_FOUND which is in fact a valid ID for resource in graph
195 public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {
196 TreeMap<String,Identity> result = new TreeMap<>();
197 for(Identity id : tg.identities) {
198 if(id.definition instanceof Internal) {
199 Internal internal = (Internal)id.definition;
200 if(internal.parent == parent.resource) result.put(internal.name, id);
203 Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
204 Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
205 for(int i=0;i<tg.statements.length;i+=4) {
206 if(tg.statements[i] == parent.resource) {
207 if(tg.statements[i+1] == consistsOf.resource) {
208 Identity identity = getIdentity(tg, tg.statements[i+3]);
209 if(identity != null) {
210 if(identity.definition instanceof Internal) {
211 Internal internal = (Internal)identity.definition;
212 result.put(internal.name, identity);
215 int possibleNameResource = getPossibleObject(tg, tg.statements[i+3], hasName);
216 if(possibleNameResource != 0) {
217 Value value = findValue(tg, possibleNameResource);
220 String name = (String)value.value.getValue(Bindings.STRING);
221 result.put(name, new Identity(tg.statements[i+3], new Internal(tg.statements[i], name)));
222 } catch (AdaptException e) {
231 return result.values();
234 public static TIntArrayList getObjects(TransferableGraph1 tg, int subject, Identity predicate) {
235 TIntArrayList result = new TIntArrayList();
236 for(int i=0;i<tg.statements.length;i+=4) {
237 if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
238 result.add(tg.statements[i+3]);
245 * This implementation is no longer advised to use because it returns 0 as
246 * NOT_FOUND which is in fact a valid ID for resource in graph
249 public static int getPossibleObject(TransferableGraph1 tg, int subject, Identity predicate) {
251 for(int i=0;i<tg.statements.length;i+=4) {
252 if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
253 if(result != 0 && tg.statements[i+3] != result) return 0;
254 result = tg.statements[i+3];
260 public static final int NOT_FOUND = -2;
262 public static int getPossibleObject2(TransferableGraph1 tg, int subject, Identity predicate) {
263 int result = NOT_FOUND;
264 for(int i=0;i<tg.statements.length;i+=4) {
265 if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
266 if(result != NOT_FOUND && tg.statements[i+3] != result)
268 result = tg.statements[i+3];
275 * @return 0 for presenting not found which is BAD
276 * @see getPossibleObject2
279 public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
280 Identity p = findExternal(tg, predicate);
281 if(p == null) return 0;
282 return getPossibleObject(tg, subject.resource, p);
285 public static int getPossibleObject2(TransferableGraph1 tg, Identity subject, String predicate) {
286 Identity p = findExternal(tg, predicate);
289 return getPossibleObject2(tg, subject.resource, p);
292 public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {
293 Map<Identity, String> result = new HashMap<Identity, String>();
294 for(Identity id : ids) {
295 if(id.definition instanceof Internal) {
296 Internal internal = (Internal)id.definition;
297 result.put(id, internal.name);
303 public static String getName(TransferableGraph1 tg, Identity id) {
307 public static String getName(Identity id) {
308 if(id.definition instanceof Internal) {
309 Internal internal = (Internal)id.definition;
310 return internal.name;
311 } else if(id.definition instanceof External) {
312 External external = (External)id.definition;
313 return external.name;
314 } else if(id.definition instanceof Root) {
315 Root root = (Root)id.definition;
318 Optional optional = (Optional)id.definition;
319 return optional.name;
323 public static String getRootType(Identity id) {
324 if(id.definition instanceof Root) {
325 Root root = (Root)id.definition;
328 throw new IllegalArgumentException("Expected root, got " + id);
332 public static Value findValue(TransferableGraph1 tg, int subject) {
333 for(Value v : tg.values) {
334 if(v.resource == subject) return v;
339 public static String getURI(TransferableGraph1 tg, int id) {
340 return getURI(tg.identities, id);
343 public static String getURI(Identity[] identities, int id) {
344 for(Identity identity : identities) {
345 if(identity.resource == id) {
346 IdentityDefinition definition = identity.definition;
347 if(definition instanceof External) {
348 External def = (External)definition;
349 if(def.parent == -1) return "http:/";
350 else return getURI(identities, def.parent) + "/" + URIStringUtils.escape(def.name);
351 } else if(definition instanceof Root) {
352 Root def = (Root)definition;
353 if(def.name.isEmpty()) return "http:/";
355 } else if (definition instanceof Internal) {
356 Internal def = (Internal)definition;
357 return getURI(identities, def.parent) + "/" + URIStringUtils.escape(def.name);
363 return "<internal reference " + id + ">:";
366 public static TIntObjectMap<Identity> mapIdentities(TransferableGraph1 tg) {
367 return mapIdentities(tg.identities);
370 public static TIntObjectMap<Identity> mapIdentities(Identity[] identities) {
371 // Integer.MIN_VALUE cannot be the value of Identity.resource
372 TIntObjectMap<Identity> map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE);
373 for (Identity id : identities)
374 map.put(id.resource, id);
378 public static String getURI(int resourceCount, TIntObjectMap<Identity> identities, int id) {
379 Identity identity = identities.get(id);
380 if(identity != null) {
381 IdentityDefinition definition = identity.definition;
382 if(definition instanceof External) {
383 External def = (External)definition;
384 if(def.parent == -1) return "http:/";
385 else return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
386 } else if(definition instanceof Root) {
387 Root def = (Root)definition;
388 if(def.name.isEmpty()) return "http:/";
390 } else if (definition instanceof Internal) {
391 Internal def = (Internal)definition;
392 return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
397 return "<internal reference " + id + ">:";