1 package org.simantics.document.linking.utils;
\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
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
28 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
31 public class SourceLinkUtil {
\r
34 * Creates a document link
\r
36 * @param instance Object, where the link is attached
\r
37 * @param relation Property relation (functional) or null.
\r
40 * @throws DatabaseException
\r
42 public static Resource createDocumentLink(WriteGraph graph, Resource instance, Resource relation, Resource document) throws DatabaseException {
\r
43 Layer0 l0 = Layer0.getInstance(graph);
\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
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
56 if (relation != null && graph.isInstanceOf(relation, l0.FunctionalRelation)) {
\r
57 link = SourceLinkUtil.createFunctionalSource(graph, uri, instance, relation);
\r
59 link = SourceLinkUtil.createInstanceSource(graph, uri, instance);
\r
64 if (relation != null && graph.isInstanceOf(relation, l0.FunctionalRelation)) {
\r
65 link = SourceLinkUtil.createFunctionalSource(graph, document, instance, relation);
\r
67 link = SourceLinkUtil.createInstanceSource(graph, document, instance);
\r
74 public static Resource createDocumentLink(WriteGraph graph, Resource instance, Resource document) throws DatabaseException {
\r
75 return createDocumentLink(graph, instance, null, document);
\r
78 public static Resource createInstanceSource(WriteGraph graph, Resource reference, Resource location) throws DatabaseException {
\r
79 return createInstanceSource(graph, reference, location, "");
\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
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
95 if (!ensureDependencies(graph, reference, location))
\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
109 public static Resource createInstanceSource(WriteGraph graph, String reference, Resource location) throws DatabaseException {
\r
110 return createInstanceSource(graph, reference, location, "");
\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
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
126 if (!ensureDependencies(graph, null, location))
\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
140 public static Resource createFunctionalSource(WriteGraph graph, Resource reference, Resource location, Resource relation) throws DatabaseException {
\r
141 return createFunctionalSource(graph, reference, location, relation, "");
\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
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
159 if (!ensureDependencies(graph, reference, location))
\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
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
175 public static Resource createFunctionalSource(WriteGraph graph, String reference, Resource location, Resource relation) throws DatabaseException {
\r
176 return createFunctionalSource(graph, reference, location, relation, "");
\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
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
194 if (!ensureDependencies(graph, null, location))
\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
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
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
219 Resource r = location;
\r
220 Resource model = null;
\r
221 while (r != null) {
\r
222 if (graph.isInstanceOf(r, sim.Model)) {
\r
226 Resource r2 = null;
\r
227 for (Resource rel : list) {
\r
228 r2 = graph.getPossibleObject(r, rel);
\r
239 * Ensures that the model's ontology dependencies are correct, and the reference will not create dependency between two models.
\r
244 * @return true, if everything is correct.
\r
245 * @throws DatabaseException
\r
247 private static boolean ensureDependencies(WriteGraph graph, Resource reference, Resource location) throws DatabaseException {
\r
249 Layer0 l0 = Layer0.getInstance(graph);
\r
250 Resource model = getModel(graph, location);
\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
262 for (Resource t : graph.getTypes(reference)) {
\r
263 Resource o = getOntology(graph, t);
\r
265 depencecies.add(o);
\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
278 private static enum DependencyCheckResult{NoLocationModel, NoReferenceModel, SameModel,DifferentModel};
\r
280 private static DependencyCheckResult checkDependecies(ReadGraph graph, Resource reference, Resource location) throws DatabaseException{
\r
281 Resource model = getModel(graph, location);
\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
291 return DependencyCheckResult.NoReferenceModel;
\r
295 private static Resource getOntology(ReadGraph graph, Resource type) throws DatabaseException{
\r
296 Layer0 l0 = Layer0.getInstance(graph);
\r
298 while (r != null) {
\r
299 if (graph.isInstanceOf(r, l0.Ontology))
\r
301 r = graph.getPossibleObject(r, l0.PartOf);
\r
305 while (r != null) {
\r
306 if (graph.isInstanceOf(r, l0.Library))
\r
308 r = graph.getPossibleObject(r, l0.PartOf);
\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
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
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
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
334 String URI = graph.getPossibleRelatedValue(source, sl.hasSourceReferenceURI, Bindings.STRING);
\r
336 return graph.getPossibleResource(URI);
\r
340 public static boolean isValidReference(ReadGraph graph, Resource reference) throws DatabaseException{
\r
341 if (reference == null)
\r
343 return graph.hasStatement(reference);
\r
347 public static boolean isUpToDateReference(ReadGraph graph, Resource reference) throws DatabaseException{
\r
348 if (reference == null)
\r
350 DocumentResource doc = DocumentResource.getInstance(graph);
\r
351 return !graph.hasStatement(reference,doc.HasNewerVersion);
\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
359 if (!graph.isInstanceOf(source, sl.Source))
\r
361 Resource reference = getReferredDocument(graph, source);
\r
362 Resource newRef = reference;
\r
364 Resource r = graph.getPossibleObject(newRef, doc.HasNewerVersion);
\r
370 if (newRef.equals(reference))
\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
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
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
410 return "TODO: Array " + value.getClass().getSimpleName();
\r
413 return value.toString();
\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
421 while (r != null && !r.equals(model)) {
\r
423 r = graph.getPossibleObject(r, l0.PartOf);
\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
438 public static String getCustomizedString(ReadGraph graph, Resource document, List<String> annotationContent) throws DatabaseException{
\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
445 Variable v = PredefinedVariables.getInstance().getVariable(graph, path, null, doc);
\r
447 label += v.getValue(graph) + " ";
\r