1 package org.simantics.document.linking.utils;
3 import java.util.ArrayList;
4 import java.util.Arrays;
5 import java.util.Collection;
6 import java.util.HashSet;
11 import org.simantics.databoard.Bindings;
12 import org.simantics.db.ReadGraph;
13 import org.simantics.db.Resource;
14 import org.simantics.db.WriteGraph;
15 import org.simantics.db.common.request.ObjectsWithType;
16 import org.simantics.db.exception.DatabaseException;
17 import org.simantics.db.layer0.adapter.Instances;
18 import org.simantics.db.layer0.variable.Variable;
19 import org.simantics.document.DocumentResource;
20 import org.simantics.document.linking.ontology.DocumentLink;
21 import org.simantics.document.linking.report.evaluator.PredefinedVariables;
22 import org.simantics.layer0.Layer0;
23 import org.simantics.modeling.ModelingResources;
24 import org.simantics.simulation.ontology.SimulationResource;
28 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
31 public class SourceLinkUtil {
34 * Creates a document link
36 * @param instance Object, where the link is attached
37 * @param relation Property relation (functional) or null.
40 * @throws DatabaseException
42 public static Resource createDocumentLink(WriteGraph graph, Resource instance, Resource relation, Resource document) throws DatabaseException {
43 Layer0 l0 = Layer0.getInstance(graph);
46 DependencyCheckResult result = checkDependecies(graph, document, instance);
47 if (result == DependencyCheckResult.NoLocationModel)
48 throw new DatabaseException("Location of document link is not part of a model.");
49 if (result == DependencyCheckResult.DifferentModel) {
50 throw new DatabaseException("Location of document link and document are in different models, document link cannot be created.");
52 if (result == DependencyCheckResult.NoReferenceModel) {
53 //referred document and location are not in the same model, create an URI reference.
54 String uri = graph.getPossibleURI(document);
56 if (relation != null && graph.isInstanceOf(relation, l0.FunctionalRelation)) {
57 link = SourceLinkUtil.createFunctionalSource(graph, uri, instance, relation);
59 link = SourceLinkUtil.createInstanceSource(graph, uri, instance);
64 if (relation != null && graph.isInstanceOf(relation, l0.FunctionalRelation)) {
65 link = SourceLinkUtil.createFunctionalSource(graph, document, instance, relation);
67 link = SourceLinkUtil.createInstanceSource(graph, document, instance);
74 public static Resource createDocumentLink(WriteGraph graph, Resource instance, Resource document) throws DatabaseException {
75 return createDocumentLink(graph, instance, null, document);
78 public static Resource createInstanceSource(WriteGraph graph, Resource reference, Resource location) throws DatabaseException {
79 return createInstanceSource(graph, reference, location, "");
82 public static Resource createInstanceSource(WriteGraph graph, Resource reference, Resource location, String comment) throws DatabaseException {
83 Layer0 l0 = Layer0.getInstance(graph);
84 DocumentLink sl = DocumentLink.getInstance(graph);
88 // prevent duplicate references
89 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.InstanceSource));
90 for (Resource source : sources) {
91 if (reference.equals(graph.getPossibleObject(source, sl.hasSourceReference)))
95 if (!ensureDependencies(graph, reference, location))
98 Resource source = graph.newResource();
99 graph.claim(source, l0.InstanceOf, sl.InstanceSource);
100 graph.claim(source, sl.hasSourceReference, reference);
101 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);
102 graph.claim(location, sl.hasInstanceSource, source);
103 // search / indexing requires this
104 graph.claim(location, l0.ConsistsOf, source);
105 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);
109 public static Resource createInstanceSource(WriteGraph graph, String reference, Resource location) throws DatabaseException {
110 return createInstanceSource(graph, reference, location, "");
113 public static Resource createInstanceSource(WriteGraph graph, String reference, Resource location, String comment) throws DatabaseException {
114 Layer0 l0 = Layer0.getInstance(graph);
115 DocumentLink sl = DocumentLink.getInstance(graph);
119 // prevent duplicate references
120 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.InstanceSource));
121 for (Resource source : sources) {
122 if (reference.equals(graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING)))
126 if (!ensureDependencies(graph, null, location))
129 Resource source = graph.newResource();
130 graph.claim(source, l0.InstanceOf, sl.InstanceSource);
131 graph.claimLiteral(source, sl.hasSourceReferenceURI, reference, Bindings.STRING);
132 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);
133 graph.claim(location, sl.hasInstanceSource, source);
134 // search / indexing requires this
135 graph.claim(location, l0.ConsistsOf, source);
136 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);
140 public static Resource createFunctionalSource(WriteGraph graph, Resource reference, Resource location, Resource relation) throws DatabaseException {
141 return createFunctionalSource(graph, reference, location, relation, "");
145 public static Resource createFunctionalSource(WriteGraph graph, Resource reference, Resource location, Resource relation, String comment) throws DatabaseException {
146 Layer0 l0 = Layer0.getInstance(graph);
147 DocumentLink sl = DocumentLink.getInstance(graph);
151 // prevent duplicate references
152 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.FunctionalSource));
153 for (Resource source : sources) {
154 if (relation.equals(graph.getPossibleObject(source, sl.consernsRelation)) &&
155 reference.equals(graph.getPossibleObject(source, sl.hasSourceReference)))
159 if (!ensureDependencies(graph, reference, location))
162 Resource source = graph.newResource();
163 graph.claim(source, l0.InstanceOf, sl.FunctionalSource);
164 graph.claim(source, sl.hasSourceReference, reference);
165 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);
166 graph.claim(source, sl.consernsRelation, relation);
168 graph.claim(location, sl.hasFunctionalSource, source);
169 // search / indexing requires this
170 graph.claim(location, l0.ConsistsOf, source);
171 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);
175 public static Resource createFunctionalSource(WriteGraph graph, String reference, Resource location, Resource relation) throws DatabaseException {
176 return createFunctionalSource(graph, reference, location, relation, "");
180 public static Resource createFunctionalSource(WriteGraph graph, String reference, Resource location, Resource relation, String comment) throws DatabaseException {
181 Layer0 l0 = Layer0.getInstance(graph);
182 DocumentLink sl = DocumentLink.getInstance(graph);
186 // prevent duplicate references
187 Collection<Resource> sources = graph.syncRequest(new ObjectsWithType(location, sl.hasFunctionalSource, sl.FunctionalSource));
188 for (Resource source : sources) {
189 if (relation.equals(graph.getPossibleObject(source, sl.consernsRelation)) &&
190 reference.equals(graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING)))
194 if (!ensureDependencies(graph, null, location))
197 Resource source = graph.newResource();
198 graph.claim(source, l0.InstanceOf, sl.FunctionalSource);
199 graph.claimLiteral(source, sl.hasSourceReferenceURI, reference, Bindings.STRING);
200 graph.claimLiteral(source, sl.hasSourceComment, comment, Bindings.STRING);
201 graph.claim(source, sl.consernsRelation, relation);
203 graph.claim(location, sl.hasFunctionalSource, source);
204 // search / indexing requires this
205 graph.claim(location, l0.ConsistsOf, source);
206 graph.claimLiteral(source, l0.HasName,UUID.randomUUID().toString(), Bindings.STRING);
210 public static Resource getModel(ReadGraph graph, Resource location) throws DatabaseException {
211 SimulationResource sim = SimulationResource.getInstance(graph);
212 Layer0 l0 = Layer0.getInstance(graph);
213 List<Resource> list = new ArrayList<Resource>();
215 list.add(l0.IsDependencyOf);
216 list.add(l0.PropertyOf);
217 list.add(l0.IsOwnedBy);
219 Resource r = location;
220 Resource model = null;
222 if (graph.isInstanceOf(r, sim.Model)) {
227 for (Resource rel : list) {
228 r2 = graph.getPossibleObject(r, rel);
239 * Ensures that the model's ontology dependencies are correct, and the reference will not create dependency between two models.
244 * @return true, if everything is correct.
245 * @throws DatabaseException
247 private static boolean ensureDependencies(WriteGraph graph, Resource reference, Resource location) throws DatabaseException {
249 Layer0 l0 = Layer0.getInstance(graph);
250 Resource model = getModel(graph, location);
255 DocumentLink sl = DocumentLink.getInstance(graph);
256 Set<Resource> depencecies = new HashSet<Resource>();
257 depencecies.add(getOntology(graph, sl.Source));
258 if (reference != null) {
259 Resource refModel = getModel(graph, reference);
260 if (refModel != null && !refModel.equals(model))
262 for (Resource t : graph.getTypes(reference)) {
263 Resource o = getOntology(graph, t);
269 Collection<Resource> linkedTo = graph.getObjects(model, l0.IsLinkedTo);
270 for (Resource dep : depencecies) {
271 if (!linkedTo.contains(dep)) {
272 graph.claim(model, l0.IsLinkedTo, dep);
278 private static enum DependencyCheckResult{NoLocationModel, NoReferenceModel, SameModel,DifferentModel};
280 private static DependencyCheckResult checkDependecies(ReadGraph graph, Resource reference, Resource location) throws DatabaseException{
281 Resource model = getModel(graph, location);
284 return DependencyCheckResult.NoLocationModel;
285 Resource refModel = getModel(graph, reference);
286 if (refModel != null) {
287 if (refModel.equals(model))
288 return DependencyCheckResult.SameModel;
289 return DependencyCheckResult.DifferentModel;
291 return DependencyCheckResult.NoReferenceModel;
295 private static Resource getOntology(ReadGraph graph, Resource type) throws DatabaseException{
296 Layer0 l0 = Layer0.getInstance(graph);
299 if (graph.isInstanceOf(r, l0.Ontology))
301 r = graph.getPossibleObject(r, l0.PartOf);
306 if (graph.isInstanceOf(r, l0.Library))
308 r = graph.getPossibleObject(r, l0.PartOf);
313 public static boolean isSource(ReadGraph graph, Resource source) throws DatabaseException{
314 DocumentLink sl = DocumentLink.getInstance(graph);
315 return (graph.isInstanceOf(source, sl.Source));
318 public static boolean isValidSource(ReadGraph graph, Resource source) throws DatabaseException{
319 Resource reference = getReferredDocument(graph, source);
320 return isValidReference(graph, reference);
323 public static boolean isUpToDateSource(ReadGraph graph, Resource source) throws DatabaseException{
324 Resource reference = getReferredDocument(graph, source);
325 return isUpToDateReference(graph, reference);
328 public static Resource getReferredDocument(ReadGraph graph, Resource source) throws DatabaseException {
329 DocumentLink sl = DocumentLink.getInstance(graph);
330 Resource document = graph.getPossibleObject(source, sl.hasSourceReference);
331 if (document != null) {
334 String URI = graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING);
336 return graph.getPossibleResource(URI);
340 public static boolean isValidReference(ReadGraph graph, Resource reference) throws DatabaseException{
341 if (reference == null)
343 return graph.hasStatement(reference);
347 public static boolean isUpToDateReference(ReadGraph graph, Resource reference) throws DatabaseException{
348 if (reference == null)
350 DocumentResource doc = DocumentResource.getInstance(graph);
351 return !graph.hasStatement(reference,doc.HasNewerVersion);
355 public static void updateToLatest(WriteGraph graph, Resource source) throws DatabaseException {
356 DocumentLink sl = DocumentLink.getInstance(graph);
357 DocumentResource doc = DocumentResource.getInstance(graph);
359 if (!graph.isInstanceOf(source, sl.Source))
361 Resource reference = getReferredDocument(graph, source);
362 Resource newRef = reference;
364 Resource r = graph.getPossibleObject(newRef, doc.HasNewerVersion);
370 if (newRef.equals(reference))
372 if (graph.hasStatement(source, sl.hasSourceReference)) {
373 graph.deny(source, sl.hasSourceReference,reference);
374 graph.claim(source, sl.hasSourceReference, newRef);
375 } else if (graph.hasStatement(source,sl.hasSourceReferenceURI)) {
376 graph.deny(source, sl.hasSourceReferenceURI);
377 graph.claimLiteral(source, sl.hasSourceReferenceURI, graph.getURI(newRef),Bindings.STRING);
381 public static Collection<Resource> findAllSources(ReadGraph graph, Resource model, Resource resource) throws DatabaseException {
382 DocumentLink sl = DocumentLink.getInstance(graph);
383 Instances instancesQuery = graph.adapt(sl.Source, Instances.class);
384 Collection<Resource> found = instancesQuery.find(graph, model);
385 Collection<Resource> result = new ArrayList<Resource>();
386 for (Resource source : found) {
387 if (graph.hasStatement(source,sl.hasSourceReference,resource) || graph.hasStatement(source, sl.hasSourceReferenceURI))
393 public static String getValueString(Object value) {
394 if (value.getClass().isArray()) {
395 if (value instanceof double[]) {
396 return Arrays.toString((double[])value);
397 } else if (value instanceof float[]) {
398 return Arrays.toString((float[])value);
399 } else if (value instanceof int[]) {
400 return Arrays.toString((int[])value);
401 } else if (value instanceof boolean[]) {
402 return Arrays.toString((boolean[])value);
403 } else if (value instanceof byte[]) {
404 return Arrays.toString((byte[])value);
405 } else if (value instanceof String[]) {
406 return Arrays.toString((String[])value);
407 } else if (value instanceof Object[]) {
408 return Arrays.toString((Object[])value);
410 return "TODO: Array " + value.getClass().getSimpleName();
413 return value.toString();
417 public static List<Resource> getPath(ReadGraph graph, Resource model, Resource obj) throws DatabaseException {
418 Layer0 l0 = Layer0.getInstance(graph);
419 List<Resource> path = new ArrayList<Resource>();
421 while (r != null && !r.equals(model)) {
423 r = graph.getPossibleObject(r, l0.PartOf);
428 public static List<Resource> getDiagramPath(ReadGraph graph, Resource model, Resource obj) throws DatabaseException {
429 ModelingResources mod = ModelingResources.getInstance(graph);
430 List<Resource> path = getPath(graph, model, obj);
431 for (int i = path.size()-1; i >= 0; i--) {
432 if (graph.hasStatement(path.get(i),mod.CompositeToDiagram))
433 return path.subList(0, i+1);
438 public static String getCustomizedString(ReadGraph graph, Resource document, List<String> annotationContent) throws DatabaseException{
440 Variable doc = graph.adapt(document, Variable.class);
441 for (String path : annotationContent) {
442 if (path.startsWith("\"") && path.endsWith("\"")) {
443 label += path.substring(1,path.length()-1)+ " ";
445 Variable v = PredefinedVariables.getInstance().getVariable(graph, path, null, doc);
447 label += v.getValue(graph) + " ";