]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java
8ee29cc953a3eacc745edb77ad1854ce6ac3b56c
[simantics/platform.git] / bundles / org.simantics.graph / src / org / simantics / graph / representation / TransferableGraphUtils.java
1 package org.simantics.graph.representation;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.HashMap;
6 import java.util.Map;
7 import java.util.TreeMap;
8
9 import org.simantics.databoard.Bindings;
10 import org.simantics.databoard.adapter.AdaptException;
11 import org.simantics.databoard.util.URIStringUtils;
12
13 import gnu.trove.list.array.TIntArrayList;
14 import gnu.trove.map.TIntObjectMap;
15 import gnu.trove.map.hash.TIntObjectHashMap;
16
17 public class TransferableGraphUtils {
18
19     public static Collection<Identity> getRoots(TransferableGraph1 tg) {
20         
21         ArrayList<Identity> result = new ArrayList<Identity>();
22         for(Identity id : tg.identities) {
23             if(id.definition instanceof Root) result.add(id);
24         }
25         return result;
26         
27     }
28     
29     public static Identity findRootWithName(TransferableGraph1 tg, String name) {
30         
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;
35             }
36         }
37         return null;
38         
39     }
40
41     public static Identity findExternalWithName(TransferableGraph1 tg, String name) {
42         
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;
47             }
48         }
49         return null;
50         
51     }
52
53     public static Identity findExternalWithNameAndParent(TransferableGraph1 tg, int parent, String name) {
54         
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;
59             }
60             else if(id.definition instanceof Optional) {
61                 Optional ext = (Optional)id.definition;
62                 if(ext.name.equals(name) && ext.parent == parent) return id;
63             }
64         }
65         return null;
66         
67     }
68     
69     public static Identity findExternal(TransferableGraph1 tg, String uri) {
70         
71         Identity identity = findExternalWithName(tg, "http:/");
72         if(identity == null) identity = findExternalWithName(tg, "");
73         if(identity == null) identity = findRootWithName(tg, "");
74         if("http:/".equals(uri)) return identity;
75         String[] tokens = uri.substring("http://".length()).split("/");
76         for(String token : tokens) {
77             identity = findExternalWithNameAndParent(tg, identity.resource, token);
78             if (identity == null) {
79                 return null;
80             }
81         }
82         return identity;
83         
84     }
85     
86     public static Identity getIdentity(TransferableGraph1 tg, int resource) {
87         for(Identity id : tg.identities) {
88             if(id.resource == resource) return id;
89         }
90         return null;
91     }
92     
93     public static TIntArrayList getStatements(TransferableGraph1 tg, int resource) {
94         TIntArrayList result = new TIntArrayList();
95         for(int i=0;i<tg.statements.length;i+=4) {
96             if(tg.statements[i] == resource) {
97                 result.add(tg.statements[i+1]);
98                 result.add(tg.statements[i+3]);
99             }
100         }
101         return result;
102     }
103
104     public static Collection<Identity> getChildren2(TransferableGraph1 tg, Identity parent) {
105         return getChildren2(tg, parent.resource);
106     }
107     
108     public static Collection<Identity> getChildren2(TransferableGraph1 tg, int parentResource) {
109         TreeMap<String, Identity> result = new TreeMap<>();
110         for (Identity id : tg.identities) {
111             if (id.definition instanceof Internal) {
112                 Internal internal = (Internal) id.definition;
113                 if (internal.parent == parentResource)
114                     result.put(internal.name, id);
115             }
116         }
117         Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
118         Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
119         for (int i = 0; i < tg.statements.length; i += 4) {
120             if (tg.statements[i] == parentResource) {
121                 if (tg.statements[i + 1] == consistsOf.resource) {
122                     Identity identity = getIdentity(tg, tg.statements[i + 3]);
123                     if (identity != null) {
124                         if (identity.definition instanceof Internal) {
125                             Internal internal = (Internal) identity.definition;
126                             result.put(internal.name, identity);
127                         }
128                     } else {
129                         int possibleNameResource = getPossibleObject2(tg, tg.statements[i + 3], hasName);
130                         if (possibleNameResource != NOT_FOUND) {
131                             Value value = findValue(tg, possibleNameResource);
132                             if (value != null) {
133                                 try {
134                                     String name = (String) value.value.getValue(Bindings.STRING);
135                                     result.put(name, new Identity(tg.statements[i + 3], new Internal(tg.statements[i], name)));
136                                 } catch (AdaptException e) {
137                                     e.printStackTrace();
138                                 }
139                             }
140                         }
141                     }
142                 }
143             }
144         }
145         return result.values();
146     }
147
148     /**
149      * This implementation is no longer advised to use because it returns 0 as
150      * NOT_FOUND which is in fact a valid ID for resource in graph
151      */
152     @Deprecated
153     public static Collection<Identity> getChildren(TransferableGraph1 tg, Identity parent) {
154         TreeMap<String,Identity> result = new TreeMap<>();
155         for(Identity id : tg.identities) {
156             if(id.definition instanceof Internal) {
157                 Internal internal = (Internal)id.definition;
158                 if(internal.parent == parent.resource) result.put(internal.name, id);
159             }
160         }
161         Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf");
162         Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName");
163         for(int i=0;i<tg.statements.length;i+=4) {
164             if(tg.statements[i] == parent.resource) {
165                 if(tg.statements[i+1] == consistsOf.resource) {
166                     Identity identity = getIdentity(tg, tg.statements[i+3]);
167                     if(identity != null) {
168                         if(identity.definition instanceof Internal) {
169                             Internal internal = (Internal)identity.definition;
170                             result.put(internal.name, identity);
171                         }
172                     } else {
173                         int possibleNameResource = getPossibleObject(tg, tg.statements[i+3], hasName);
174                         if(possibleNameResource != 0) {
175                             Value value = findValue(tg, possibleNameResource);
176                             if(value != null) {
177                                 try {
178                                     String name = (String)value.value.getValue(Bindings.STRING);
179                                     result.put(name, new Identity(tg.statements[i+3], new Internal(tg.statements[i], name)));
180                                 } catch (AdaptException e) {
181                                     e.printStackTrace();
182                                 }
183                             }
184                         }
185                     }
186                 }
187             }
188         }
189         return result.values();
190     }
191     
192     public static TIntArrayList getObjects(TransferableGraph1 tg, int subject, Identity predicate) {
193         TIntArrayList result = new TIntArrayList();
194         for(int i=0;i<tg.statements.length;i+=4) {
195             if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
196                 result.add(tg.statements[i+3]);
197             }
198         }
199         return result;
200     }
201     
202     /**
203      * This implementation is no longer advised to use because it returns 0 as
204      * NOT_FOUND which is in fact a valid ID for resource in graph
205      */
206     @Deprecated
207     public static int getPossibleObject(TransferableGraph1 tg, int subject, Identity predicate) {
208         int result = 0;
209         for(int i=0;i<tg.statements.length;i+=4) {
210             if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
211                 if(result != 0 && tg.statements[i+3] != result) return 0;
212                 result = tg.statements[i+3];
213             }
214         }
215         return result;
216     }
217
218     public static final int NOT_FOUND = -2;
219
220     public static int getPossibleObject2(TransferableGraph1 tg, int subject, Identity predicate) {
221         int result = NOT_FOUND;
222         for(int i=0;i<tg.statements.length;i+=4) {
223             if(tg.statements[i] == subject && tg.statements[i+1] == predicate.resource) {
224                 if(result != NOT_FOUND && tg.statements[i+3] != result)
225                     return NOT_FOUND;
226                 result = tg.statements[i+3];
227             }
228         }
229         return result;
230     }
231     
232     /**
233      * @return 0 for presenting not found which is BAD
234      * @see getPossibleObject2
235      */
236     @Deprecated
237     public static int getPossibleObject(TransferableGraph1 tg, Identity subject, String predicate) {
238         Identity p = findExternal(tg, predicate);
239         if(p == null) return 0;
240         return getPossibleObject(tg, subject.resource, p);
241     }
242     
243     public static int getPossibleObject2(TransferableGraph1 tg, Identity subject, String predicate) {
244         Identity p = findExternal(tg, predicate);
245         if (p == null)
246             return NOT_FOUND;
247         return getPossibleObject2(tg, subject.resource, p);
248     }
249
250     public static Map<Identity, String> getNames(TransferableGraph1 tg, Collection<Identity> ids) {
251         Map<Identity, String> result = new HashMap<Identity, String>();
252         for(Identity id : ids) {
253             if(id.definition instanceof Internal) {
254                 Internal internal = (Internal)id.definition;
255                 result.put(id, internal.name);
256             }
257         }
258         return result;
259     }
260
261     public static String getName(TransferableGraph1 tg, Identity id) {
262         return getName(id);
263     }
264
265     public static String getName(Identity id) {
266         if(id.definition instanceof Internal) {
267             Internal internal = (Internal)id.definition;
268             return internal.name;
269         } else if(id.definition instanceof External) {
270             External external = (External)id.definition;
271             return external.name;
272         } else if(id.definition instanceof Root) {
273             Root root = (Root)id.definition;
274             return root.name;
275         } else  {
276             Optional optional = (Optional)id.definition;
277             return optional.name;
278         }
279     }
280
281     public static String getRootType(Identity id) {
282         if(id.definition instanceof Root) {
283             Root root = (Root)id.definition;
284             return root.type;
285         } else  {
286             throw new IllegalArgumentException("Expected root, got " + id);
287         }
288     }
289
290     public static Value findValue(TransferableGraph1 tg, int subject) {
291         for(Value v : tg.values) {
292             if(v.resource == subject) return v;
293         }
294         return null;
295     }
296     
297     public static String getURI(TransferableGraph1 tg, int id) {
298         return getURI(tg.identities, id);
299     }
300     
301     public static String getURI(Identity[] identities, int id) {
302         for(Identity identity : identities) {
303             if(identity.resource == id) {
304                 IdentityDefinition definition = identity.definition;
305                 if(definition instanceof External) {
306                     External def = (External)definition;
307                     if(def.parent == -1) return "http:/";
308                     else return getURI(identities, def.parent) + "/" + def.name;
309                 } else if(definition instanceof Root) {
310                     Root def = (Root)definition;
311                     if(def.name.isEmpty()) return "http:/";
312                     return def.name;
313                 } else if (definition instanceof Internal) {
314                     Internal def = (Internal)definition;
315                     return getURI(identities, def.parent) + "/" + def.name;
316                 } else if (definition instanceof Optional) {
317                     Optional def = (Optional)definition;
318                     return getURI(identities, def.parent) + "/" + def.name;
319                 } else {
320                     return "";
321                 }
322             }
323         }       
324         return "<internal reference " + id + ">:";
325     }
326
327     public static TIntObjectMap<Identity> mapIdentities(TransferableGraph1 tg) {
328         return mapIdentities(tg.identities);
329     }
330
331     public static TIntObjectMap<Identity> mapIdentities(Identity[] identities) {
332         // Integer.MIN_VALUE cannot be the value of Identity.resource
333         TIntObjectMap<Identity> map = new TIntObjectHashMap<>(identities.length, 0.5f, Integer.MIN_VALUE);
334         for (Identity id : identities)
335             map.put(id.resource, id);
336         return map;
337     }
338
339     public static String getURI(int resourceCount, TIntObjectMap<Identity> identities, int id) {
340         Identity identity = identities.get(id);
341         if(identity != null) {
342             IdentityDefinition definition = identity.definition;
343             if(definition instanceof External) {
344                 External def = (External)definition;
345                 if(def.parent == -1) return "http:/";
346                 else return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
347             } else if(definition instanceof Root) {
348                 Root def = (Root)definition;
349                 if(def.name.isEmpty()) return "http:/";
350                 return def.name;
351             } else if (definition instanceof Internal) {
352                 Internal def = (Internal)definition;
353                 return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
354             } else if (definition instanceof Optional) {
355                 Optional def = (Optional)definition;
356                 return getURI(resourceCount, identities, def.parent) + "/" + URIStringUtils.escape(def.name);
357             } else {
358                 return "";
359             }
360         }
361         return "<internal reference " + id + ">:";
362     }
363
364 }