]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/utils/SourceLinkUtil.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.document.linking.ui / src / org / simantics / document / linking / utils / SourceLinkUtil.java
1 package org.simantics.document.linking.utils;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.Arrays;\r
5 import java.util.Collection;\r
6 import java.util.HashSet;\r
7 import java.util.List;\r
8 import java.util.Set;\r
9 import java.util.UUID;\r
10 \r
11 import org.simantics.databoard.Bindings;\r
12 import org.simantics.db.ReadGraph;\r
13 import org.simantics.db.Resource;\r
14 import org.simantics.db.WriteGraph;\r
15 import org.simantics.db.common.request.ObjectsWithType;\r
16 import org.simantics.db.exception.DatabaseException;\r
17 import org.simantics.db.layer0.adapter.Instances;\r
18 import org.simantics.db.layer0.variable.Variable;\r
19 import org.simantics.document.DocumentResource;\r
20 import org.simantics.document.linking.ontology.DocumentLink;\r
21 import org.simantics.document.linking.report.evaluator.PredefinedVariables;\r
22 import org.simantics.layer0.Layer0;\r
23 import org.simantics.modeling.ModelingResources;\r
24 import org.simantics.simulation.ontology.SimulationResource;\r
25 \r
26 /**\r
27  * \r
28  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
29  *\r
30  */\r
31 public class SourceLinkUtil {\r
32         \r
33         /**\r
34          * Creates a document link\r
35          * @param graph\r
36          * @param instance Object, where the link is attached\r
37          * @param relation Property relation (functional) or null.\r
38          * @param document\r
39          * @return\r
40          * @throws DatabaseException\r
41          */\r
42         public static Resource createDocumentLink(WriteGraph graph, Resource instance, Resource relation, Resource document) throws DatabaseException {\r
43                 Layer0 l0 = Layer0.getInstance(graph);\r
44                 \r
45                 Resource link = null;\r
46                 DependencyCheckResult result = checkDependecies(graph, document, instance);\r
47                 if (result == DependencyCheckResult.NoLocationModel)\r
48                         throw new DatabaseException("Location of document link is not part of a model.");\r
49                 if (result == DependencyCheckResult.DifferentModel) {\r
50                         throw new DatabaseException("Location of document link and document are in different models, document link cannot be created.");\r
51                 }\r
52                 if (result == DependencyCheckResult.NoReferenceModel) {\r
53                         //referred document and location are not in the same model, create an URI reference.\r
54                         String uri = graph.getPossibleURI(document);\r
55                         if (uri != null) {\r
56                                 if (relation != null && graph.isInstanceOf(relation, l0.FunctionalRelation)) {\r
57                                         link = SourceLinkUtil.createFunctionalSource(graph, uri, instance, relation);\r
58                                 } else {\r
59                                         link = SourceLinkUtil.createInstanceSource(graph, uri, instance);\r
60                                 }\r
61                         }\r
62                 }\r
63                 if (link == null) {\r
64                         if (relation != null && graph.isInstanceOf(relation, l0.FunctionalRelation)) {\r
65                                 link = SourceLinkUtil.createFunctionalSource(graph, document, instance, relation);\r
66                         } else {\r
67                                 link = SourceLinkUtil.createInstanceSource(graph, document, instance);\r
68                         }\r
69                 }\r
70                 \r
71                 return link;\r
72         }\r
73         \r
74         public static Resource createDocumentLink(WriteGraph graph, Resource instance, Resource document) throws DatabaseException {\r
75             return createDocumentLink(graph, instance, null, document);\r
76         }\r
77         \r
78         public static Resource createInstanceSource(WriteGraph graph, Resource reference, Resource location) throws DatabaseException {\r
79                 return createInstanceSource(graph, reference, location, "");\r
80         }\r
81 \r
82         public static Resource createInstanceSource(WriteGraph graph, Resource reference, Resource location, String comment) throws DatabaseException {\r
83                 Layer0 l0 = Layer0.getInstance(graph);\r
84                 DocumentLink sl = DocumentLink.getInstance(graph);\r
85                 \r
86                 \r
87                 \r
88                 // prevent duplicate references         \r
89                 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.InstanceSource));\r
90                 for (Resource source : sources) {\r
91                         if (reference.equals(graph.getPossibleObject(source, sl.hasSourceReference)))\r
92                                 return source;\r
93                 }\r
94                 \r
95                 if (!ensureDependencies(graph, reference, location))\r
96                         return null;\r
97                 \r
98                 Resource source = graph.newResource();\r
99                 graph.claim(source, l0.InstanceOf, sl.InstanceSource);\r
100                 graph.claim(source, sl.hasSourceReference, reference);\r
101                 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);\r
102                 graph.claim(location, sl.hasInstanceSource, source);\r
103                 // search / indexing requires this\r
104                 graph.claim(location, l0.ConsistsOf, source);\r
105                 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);\r
106                 return source;\r
107         }\r
108         \r
109         public static Resource createInstanceSource(WriteGraph graph, String reference, Resource location) throws DatabaseException {\r
110                 return createInstanceSource(graph, reference, location, "");\r
111         }\r
112 \r
113         public static Resource createInstanceSource(WriteGraph graph, String reference, Resource location, String comment) throws DatabaseException {\r
114                 Layer0 l0 = Layer0.getInstance(graph);\r
115                 DocumentLink sl = DocumentLink.getInstance(graph);\r
116                 \r
117                 \r
118                 \r
119                 // prevent duplicate references         \r
120                 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.InstanceSource));\r
121                 for (Resource source : sources) {\r
122                         if (reference.equals(graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING)))\r
123                                 return source;\r
124                 }\r
125                 \r
126                 if (!ensureDependencies(graph, null, location))\r
127                         return null;\r
128                 \r
129                 Resource source = graph.newResource();\r
130                 graph.claim(source, l0.InstanceOf, sl.InstanceSource);\r
131                 graph.claimLiteral(source, sl.hasSourceReferenceURI, reference, Bindings.STRING);\r
132                 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);\r
133                 graph.claim(location, sl.hasInstanceSource, source);\r
134                 // search / indexing requires this\r
135                 graph.claim(location, l0.ConsistsOf, source);\r
136                 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);\r
137                 return source;\r
138         }\r
139         \r
140         public static Resource createFunctionalSource(WriteGraph graph, Resource reference, Resource location, Resource relation) throws DatabaseException {\r
141                 return createFunctionalSource(graph, reference, location, relation, "");\r
142         }\r
143 \r
144         \r
145         public static Resource createFunctionalSource(WriteGraph graph, Resource reference, Resource location, Resource relation, String comment) throws DatabaseException {\r
146                 Layer0 l0 = Layer0.getInstance(graph);\r
147                 DocumentLink sl = DocumentLink.getInstance(graph);\r
148                 \r
149                 \r
150                 \r
151                 // prevent duplicate references\r
152                 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.FunctionalSource));\r
153                 for (Resource source : sources) {\r
154                         if (relation.equals(graph.getPossibleObject(source, sl.consernsRelation)) && \r
155                                 reference.equals(graph.getPossibleObject(source, sl.hasSourceReference)))\r
156                                 return null;\r
157                 }\r
158                 \r
159                 if (!ensureDependencies(graph, reference, location))\r
160                         return null;\r
161                 \r
162                 Resource source = graph.newResource();\r
163                 graph.claim(source, l0.InstanceOf, sl.FunctionalSource);\r
164                 graph.claim(source, sl.hasSourceReference, reference);\r
165                 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);\r
166                 graph.claim(source, sl.consernsRelation, relation);\r
167                 \r
168                 graph.claim(location, sl.hasFunctionalSource, source);\r
169                 // search / indexing requires this\r
170                 graph.claim(location, l0.ConsistsOf, source);\r
171                 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);\r
172                 return source;\r
173         }\r
174         \r
175         public static Resource createFunctionalSource(WriteGraph graph, String reference, Resource location, Resource relation) throws DatabaseException {\r
176                 return createFunctionalSource(graph, reference, location, relation, "");\r
177         }\r
178 \r
179         \r
180         public static Resource createFunctionalSource(WriteGraph graph, String reference, Resource location, Resource relation, String comment) throws DatabaseException {\r
181                 Layer0 l0 = Layer0.getInstance(graph);\r
182                 DocumentLink sl = DocumentLink.getInstance(graph);\r
183                 \r
184                 \r
185                 \r
186                 // prevent duplicate references\r
187                 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.FunctionalSource));\r
188                 for (Resource source : sources) {\r
189                         if (relation.equals(graph.getPossibleObject(source, sl.consernsRelation)) && \r
190                                 reference.equals(graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING)))\r
191                                 return null;\r
192                 }\r
193                 \r
194                 if (!ensureDependencies(graph, null, location))\r
195                         return null;\r
196                 \r
197                 Resource source = graph.newResource();\r
198                 graph.claim(source, l0.InstanceOf, sl.FunctionalSource);\r
199                 graph.claimLiteral(source, sl.hasSourceReferenceURI, reference, Bindings.STRING);\r
200                 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);\r
201                 graph.claim(source, sl.consernsRelation, relation);\r
202                 \r
203                 graph.claim(location, sl.hasFunctionalSource, source);\r
204                 // search / indexing requires this\r
205                 graph.claim(location, l0.ConsistsOf, source);\r
206                 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);\r
207                 return source;\r
208         }\r
209         \r
210         public static Resource getModel(ReadGraph graph, Resource location) throws DatabaseException {\r
211                 SimulationResource sim = SimulationResource.getInstance(graph);\r
212                 Layer0 l0 = Layer0.getInstance(graph);\r
213                 List<Resource> list = new ArrayList<Resource>();\r
214                 list.add(l0.PartOf);\r
215                 list.add(l0.IsDependencyOf);\r
216                 list.add(l0.PropertyOf);\r
217                 list.add(l0.IsOwnedBy);\r
218                 \r
219                 Resource r = location;\r
220                 Resource model = null;\r
221                 while (r != null) {\r
222                         if (graph.isInstanceOf(r, sim.Model)) {\r
223                                 model = r;\r
224                                 break;\r
225                         }\r
226                         Resource r2 = null;\r
227                         for (Resource rel : list) {\r
228                                 r2 = graph.getPossibleObject(r, rel);\r
229                                 if (r2 != null)\r
230                                         break;\r
231                         }\r
232                         r = r2;\r
233                 }\r
234                 \r
235                 return model;\r
236         }\r
237         \r
238         /**\r
239          * Ensures that the model's ontology dependencies are correct, and the reference will not create dependency between two models.\r
240          * \r
241          * @param graph\r
242          * @param reference\r
243          * @param location\r
244          * @return true, if everything is correct. \r
245          * @throws DatabaseException\r
246          */\r
247         private static boolean ensureDependencies(WriteGraph graph, Resource reference, Resource location) throws DatabaseException {\r
248 \r
249                 Layer0 l0 = Layer0.getInstance(graph);\r
250                 Resource model = getModel(graph, location);\r
251 \r
252                 if (model == null)\r
253                         return true;\r
254 \r
255                 DocumentLink sl = DocumentLink.getInstance(graph);\r
256                 Set<Resource> depencecies = new HashSet<Resource>();\r
257                 depencecies.add(getOntology(graph, sl.Source));\r
258                 if (reference != null) {\r
259                         Resource refModel = getModel(graph, reference);\r
260                         if (refModel != null && !refModel.equals(model))\r
261                                 return false;\r
262                         for (Resource t : graph.getTypes(reference)) {\r
263                                 Resource o = getOntology(graph, t);\r
264                                 if (o != null)\r
265                                         depencecies.add(o);\r
266                         }\r
267                 }\r
268                 \r
269                 Collection<Resource> linkedTo = graph.getObjects(model, l0.IsLinkedTo);\r
270                 for (Resource dep : depencecies) {\r
271                         if (!linkedTo.contains(dep)) {\r
272                                 graph.claim(model, l0.IsLinkedTo, dep);\r
273                         }\r
274                 }\r
275                 return true;\r
276         }\r
277         \r
278         private static enum DependencyCheckResult{NoLocationModel, NoReferenceModel, SameModel,DifferentModel};\r
279         \r
280         private static DependencyCheckResult checkDependecies(ReadGraph graph, Resource reference, Resource location) throws DatabaseException{\r
281                 Resource model = getModel(graph, location);\r
282 \r
283                 if (model == null)\r
284                         return DependencyCheckResult.NoLocationModel;\r
285                 Resource refModel = getModel(graph, reference);\r
286                 if (refModel != null) {\r
287                         if (refModel.equals(model))\r
288                                 return DependencyCheckResult.SameModel;\r
289                         return DependencyCheckResult.DifferentModel;\r
290                 }\r
291                 return DependencyCheckResult.NoReferenceModel;\r
292         }\r
293         \r
294         \r
295         private static Resource getOntology(ReadGraph graph, Resource type) throws DatabaseException{\r
296                 Layer0 l0 = Layer0.getInstance(graph);\r
297                 Resource r = type;\r
298                 while (r != null) {\r
299                         if (graph.isInstanceOf(r, l0.Ontology))\r
300                                 return r;\r
301                         r = graph.getPossibleObject(r, l0.PartOf);\r
302                 }\r
303                 \r
304                 r = type;\r
305                 while (r != null) {\r
306                         if (graph.isInstanceOf(r, l0.Library))\r
307                                 return r;\r
308                         r = graph.getPossibleObject(r, l0.PartOf);\r
309                 }       \r
310                 return null;\r
311         }\r
312         \r
313         public static boolean isSource(ReadGraph graph, Resource source) throws DatabaseException{\r
314                 DocumentLink sl = DocumentLink.getInstance(graph);\r
315                 return (graph.isInstanceOf(source, sl.Source));\r
316         }\r
317         \r
318         public static boolean isValidSource(ReadGraph graph, Resource source) throws DatabaseException{\r
319                 Resource reference = getReferredDocument(graph, source);\r
320                 return isValidReference(graph, reference);\r
321         }\r
322         \r
323         public static boolean isUpToDateSource(ReadGraph graph, Resource source) throws DatabaseException{\r
324                 Resource reference = getReferredDocument(graph, source);\r
325                 return isUpToDateReference(graph, reference);\r
326         }\r
327         \r
328         public static Resource getReferredDocument(ReadGraph graph, Resource source) throws DatabaseException {\r
329                 DocumentLink sl = DocumentLink.getInstance(graph);\r
330                 Resource document =  graph.getPossibleObject(source, sl.hasSourceReference);\r
331                 if (document != null) {\r
332                         return document;\r
333                 }\r
334                 String URI = graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING);\r
335                 if (URI != null)\r
336                         return graph.getPossibleResource(URI);\r
337                 return null;\r
338         }\r
339         \r
340         public static boolean isValidReference(ReadGraph graph, Resource reference) throws DatabaseException{\r
341                 if (reference == null)\r
342                         return false;\r
343                 return graph.hasStatement(reference);\r
344                 \r
345         }\r
346         \r
347         public static boolean isUpToDateReference(ReadGraph graph, Resource reference) throws DatabaseException{\r
348                 if (reference == null)\r
349                         return false;\r
350                 DocumentResource doc = DocumentResource.getInstance(graph);\r
351                 return !graph.hasStatement(reference,doc.HasNewerVersion);\r
352                 \r
353         }\r
354         \r
355         public static void updateToLatest(WriteGraph graph, Resource source) throws DatabaseException {\r
356                 DocumentLink sl = DocumentLink.getInstance(graph);\r
357                 DocumentResource doc = DocumentResource.getInstance(graph);\r
358                 \r
359                 if (!graph.isInstanceOf(source, sl.Source))\r
360                         return;\r
361                 Resource reference = getReferredDocument(graph, source);\r
362                 Resource newRef = reference;\r
363                 while (true) {\r
364                         Resource r = graph.getPossibleObject(newRef, doc.HasNewerVersion);\r
365                         if (r != null)\r
366                                 newRef = r;\r
367                         else\r
368                                 break;\r
369                 }\r
370                 if (newRef.equals(reference))\r
371                         return;\r
372                 if (graph.hasStatement(source, sl.hasSourceReference)) {\r
373                         graph.deny(source, sl.hasSourceReference,reference);\r
374                         graph.claim(source, sl.hasSourceReference, newRef);\r
375                 } else if (graph.hasStatement(source,sl.hasSourceReferenceURI)) {\r
376                         graph.deny(source, sl.hasSourceReferenceURI);\r
377                         graph.claimLiteral(source, sl.hasSourceReferenceURI, graph.getURI(newRef),Bindings.STRING);\r
378                 }\r
379         }\r
380         \r
381         public static Collection<Resource> findAllSources(ReadGraph graph, Resource model, Resource resource) throws DatabaseException {\r
382                 DocumentLink sl = DocumentLink.getInstance(graph);\r
383                 Instances instancesQuery = graph.adapt(sl.Source, Instances.class);\r
384         Collection<Resource> found = instancesQuery.find(graph, model);\r
385         Collection<Resource> result = new ArrayList<Resource>();\r
386         for (Resource source : found) {\r
387                 if (graph.hasStatement(source,sl.hasSourceReference,resource) || graph.hasStatement(source, sl.hasSourceReferenceURI))\r
388                         result.add(source);\r
389         }\r
390         return result;\r
391         }\r
392         \r
393         public static String getValueString(Object value) {\r
394                 if (value.getClass().isArray()) {\r
395                         if (value instanceof double[]) {\r
396                                 return Arrays.toString((double[])value);\r
397                         } else if (value instanceof float[]) {\r
398                                 return Arrays.toString((float[])value);\r
399                         } else if (value instanceof int[]) {\r
400                                 return Arrays.toString((int[])value);\r
401                         } else if (value instanceof boolean[]) {\r
402                                 return Arrays.toString((boolean[])value);\r
403                         } else if (value instanceof byte[]) {\r
404                                 return Arrays.toString((byte[])value);\r
405                         } else if (value instanceof String[]) {\r
406                                 return Arrays.toString((String[])value);\r
407                         } else if (value instanceof Object[]) {\r
408                                 return Arrays.toString((Object[])value);\r
409                         } else {\r
410                                 return "TODO: Array " + value.getClass().getSimpleName();\r
411                         }\r
412                 } else {\r
413                         return value.toString();\r
414                 }\r
415         }\r
416         \r
417         public static List<Resource> getPath(ReadGraph graph, Resource model, Resource obj) throws DatabaseException {\r
418                 Layer0 l0 = Layer0.getInstance(graph);\r
419                 List<Resource> path = new ArrayList<Resource>();\r
420                 Resource r = obj;\r
421                 while (r != null && !r.equals(model)) {\r
422                         path.add(0, r);\r
423                         r = graph.getPossibleObject(r, l0.PartOf);\r
424                 }\r
425                 return path;\r
426         }\r
427         \r
428         public static List<Resource> getDiagramPath(ReadGraph graph, Resource model, Resource obj) throws DatabaseException {\r
429                 ModelingResources mod = ModelingResources.getInstance(graph);\r
430                 List<Resource> path = getPath(graph, model, obj);\r
431                 for (int i = path.size()-1; i >= 0; i--) {\r
432                         if (graph.hasStatement(path.get(i),mod.CompositeToDiagram))\r
433                                 return path.subList(0, i+1);\r
434                 }\r
435                 return null;\r
436         }\r
437         \r
438         public static String getCustomizedString(ReadGraph graph, Resource document, List<String> annotationContent) throws DatabaseException{\r
439                 String label = "";\r
440                 Variable doc = graph.adapt(document, Variable.class);\r
441                 for (String path : annotationContent) {\r
442                         if (path.startsWith("\"") && path.endsWith("\"")) {\r
443                                 label += path.substring(1,path.length()-1)+ " ";\r
444                         } else {\r
445                                 Variable v = PredefinedVariables.getInstance().getVariable(graph, path, null, doc);\r
446                                 if (v != null) {\r
447                                         label += v.getValue(graph) + " ";\r
448                                 }\r
449                         }\r
450                 }\r
451                 return label;\r
452         }\r
453 }\r