1 /*******************************************************************************
2 * Copyright (c) 2012 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.db.layer0.util;
14 import java.io.IOException;
15 import java.util.ArrayList;
16 import java.util.Collection;
17 import java.util.Collections;
18 import java.util.Comparator;
19 import java.util.HashSet;
20 import java.util.List;
23 import java.util.TreeSet;
25 import org.eclipse.core.runtime.IProgressMonitor;
26 import org.eclipse.core.runtime.NullProgressMonitor;
27 import org.eclipse.core.runtime.SubMonitor;
28 import org.simantics.databoard.Bindings;
29 import org.simantics.databoard.Datatypes;
30 import org.simantics.databoard.adapter.AdaptException;
31 import org.simantics.databoard.adapter.Adapter;
32 import org.simantics.databoard.adapter.AdapterConstructionException;
33 import org.simantics.databoard.binding.Binding;
34 import org.simantics.databoard.binding.NumberBinding;
35 import org.simantics.databoard.binding.StringBinding;
36 import org.simantics.databoard.binding.error.BindingException;
37 import org.simantics.databoard.binding.mutable.MutableStringBinding;
38 import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
39 import org.simantics.databoard.parser.repository.DataValueRepository;
40 import org.simantics.databoard.primitives.MutableString;
41 import org.simantics.databoard.type.ArrayType;
42 import org.simantics.databoard.type.BooleanType;
43 import org.simantics.databoard.type.ByteType;
44 import org.simantics.databoard.type.Datatype;
45 import org.simantics.databoard.type.DoubleType;
46 import org.simantics.databoard.type.FloatType;
47 import org.simantics.databoard.type.IntegerType;
48 import org.simantics.databoard.type.LongType;
49 import org.simantics.databoard.type.MapType;
50 import org.simantics.databoard.type.NumberType;
51 import org.simantics.databoard.type.OptionalType;
52 import org.simantics.databoard.type.RecordType;
53 import org.simantics.databoard.type.StringType;
54 import org.simantics.databoard.type.UnionType;
55 import org.simantics.databoard.type.VariantType;
56 import org.simantics.databoard.util.ObjectUtils;
57 import org.simantics.datatypes.literal.GUID;
58 import org.simantics.db.ChangeSetIdentifier;
59 import org.simantics.db.Operation;
60 import org.simantics.db.ReadGraph;
61 import org.simantics.db.RelationContext;
62 import org.simantics.db.Resource;
63 import org.simantics.db.Session;
64 import org.simantics.db.Statement;
65 import org.simantics.db.WriteGraph;
66 import org.simantics.db.WriteOnlyGraph;
67 import org.simantics.db.common.CommentMetadata;
68 import org.simantics.db.common.Indexing;
69 import org.simantics.db.common.StandardStatement;
70 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
71 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
72 import org.simantics.db.common.request.DelayedWriteRequest;
73 import org.simantics.db.common.request.ObjectsWithType;
74 import org.simantics.db.common.request.PossibleChild;
75 import org.simantics.db.common.request.PossibleIndexRoot;
76 import org.simantics.db.common.request.WriteRequest;
77 import org.simantics.db.common.utils.CommonDBUtils;
78 import org.simantics.db.common.utils.NameUtils;
79 import org.simantics.db.event.ChangeListener;
80 import org.simantics.db.exception.CancelTransactionException;
81 import org.simantics.db.exception.DatabaseException;
82 import org.simantics.db.exception.ServiceException;
83 import org.simantics.db.layer0.adapter.CopyHandler;
84 import org.simantics.db.layer0.adapter.CopyHandler2;
85 import org.simantics.db.layer0.adapter.GenericRelationIndex;
86 import org.simantics.db.layer0.adapter.PasteHandler;
87 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
88 import org.simantics.db.layer0.adapter.impl.EntityRemover;
89 import org.simantics.db.layer0.adapter.impl.TGRemover;
90 import org.simantics.db.layer0.genericrelation.IndexedRelations;
91 import org.simantics.db.layer0.internal.SimanticsInternal;
92 import org.simantics.db.layer0.migration.OntologiesFromLibrary;
93 import org.simantics.db.layer0.property.OrderedResource;
94 import org.simantics.db.layer0.request.GlobalOntologies;
95 import org.simantics.db.layer0.request.PossibleVariableIndexRoot;
96 import org.simantics.db.layer0.request.PropertyInfo;
97 import org.simantics.db.layer0.request.PropertyInfoRequest;
98 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
99 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
100 import org.simantics.db.layer0.variable.Variable;
101 import org.simantics.db.service.ClusterCollectorPolicy;
102 import org.simantics.db.service.ClusterControl;
103 import org.simantics.db.service.ClusteringSupport;
104 import org.simantics.db.service.CollectionSupport;
105 import org.simantics.db.service.DebugSupport;
106 import org.simantics.db.service.GraphChangeListenerSupport;
107 import org.simantics.db.service.ManagementSupport;
108 import org.simantics.db.service.UndoRedoSupport;
109 import org.simantics.db.service.XSupport;
110 import org.simantics.graph.db.TransferableGraphSource;
111 import org.simantics.graph.db.TransferableGraphs;
112 import org.simantics.graph.diff.Diff;
113 import org.simantics.graph.diff.TransferableGraphDelta1;
114 import org.simantics.graph.refactoring.GraphRefactoringUtils;
115 import org.simantics.graph.representation.PrettyPrintTG;
116 import org.simantics.graph.representation.TransferableGraph1;
117 import org.simantics.layer0.Layer0;
118 import org.simantics.operation.Layer0X;
119 import org.simantics.scl.compiler.environment.Environments;
120 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
121 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
122 import org.simantics.scl.compiler.types.Type;
123 import org.simantics.scl.osgi.SCLOsgi;
124 import org.simantics.scl.runtime.function.Function;
125 import org.simantics.scl.runtime.function.Function1;
126 import org.simantics.scl.runtime.function.FunctionImpl1;
128 public class Layer0Utils {
130 @SuppressWarnings("rawtypes")
131 public static final ThreadLocal SCL_GRAPH = new ThreadLocal();
133 public static Resource literal(WriteGraph g, String value) throws DatabaseException {
134 Layer0 L0 = Layer0.getInstance(g);
135 Resource r = g.newResource();
136 g.claimValue(r, value, Bindings.STRING);
137 g.claim(r, L0.InstanceOf, L0.String);
141 public static Resource literal(WriteGraph g, double value) throws DatabaseException {
142 Layer0 L0 = Layer0.getInstance(g);
143 Resource r = g.newResource();
144 g.claimValue(r, value, Bindings.DOUBLE);
145 g.claim(r, L0.InstanceOf, L0.Double);
149 public static Resource literal(WriteGraph g, int value) throws DatabaseException {
150 Layer0 L0 = Layer0.getInstance(g);
151 Resource r = g.newResource();
152 g.claimValue(r, value, Bindings.INTEGER);
153 g.claim(r, L0.InstanceOf, L0.Integer);
157 public static void assert_(WriteGraph g, Resource type, Resource predicate, Resource object) throws DatabaseException {
158 Layer0 L0 = Layer0.getInstance(g);
159 Resource assertion = g.newResource();
160 g.claim(type, L0.Asserts, assertion);
161 g.claim(assertion, L0.InstanceOf, L0.Assertion);
162 g.claim(assertion, L0.HasPredicate, predicate);
163 g.claim(assertion, L0.HasObject, object);
166 public static Resource relation(WriteGraph g, Resource parent, String name, Resource superrelation) throws DatabaseException {
167 Layer0 L0 = Layer0.getInstance(g);
168 Resource relation = g.newResource();
169 g.claim(relation, L0.SubrelationOf, superrelation);
170 g.claim(relation, L0.HasName, literal(g, name));
171 g.claim(parent, L0.ConsistsOf, relation);
173 Resource superrelationInverse = g.getInverse(superrelation);
174 if(superrelationInverse != null) {
175 Resource inverse = g.newResource();
176 g.claim(inverse, L0.SubrelationOf, superrelationInverse);
177 g.claim(relation, L0.ConsistsOf, inverse);
178 g.claim(inverse, L0.HasName, literal(g, "Inverse"));
183 private static Resource getLiteralType(ReadGraph graph, Datatype type) throws DatabaseException {
184 Layer0 L0 = Layer0.getInstance(graph);
185 if(type instanceof DoubleType) return L0.Double;
186 else if(type instanceof StringType) return L0.String;
187 else if(type instanceof IntegerType) return L0.Integer;
188 else if(type instanceof LongType) return L0.Long;
189 else if(type instanceof FloatType) return L0.Float;
190 else if(type instanceof ByteType) return L0.Byte;
191 else if(type instanceof BooleanType) return L0.Boolean;
192 else if(type instanceof ArrayType) {
193 ArrayType at = (ArrayType)type;
194 if(at.componentType instanceof DoubleType) return L0.DoubleArray;
195 else if(at.componentType instanceof StringType) return L0.StringArray;
196 else if(at.componentType instanceof IntegerType) return L0.IntegerArray;
197 else if(at.componentType instanceof LongType) return L0.LongArray;
198 else if(at.componentType instanceof FloatType) return L0.FloatArray;
199 else if(at.componentType instanceof ByteType) return L0.ByteArray;
200 else if(at.componentType instanceof BooleanType) return L0.BooleanArray;
201 else if(at.componentType instanceof VariantType) return L0.VariantArray;
203 throw new DatabaseException("Unidentified literal type for datatype " + type);
206 private static Resource getPossibleLiteralType(ReadGraph graph, String type) throws DatabaseException {
208 Layer0 L0 = Layer0.getInstance(graph);
209 if("Double".equals(type)) return L0.Double;
210 else if("String".equals(type)) return L0.String;
211 else if("Integer".equals(type)) return L0.Integer;
212 else if("Long".equals(type)) return L0.Long;
213 else if("Float".equals(type)) return L0.Float;
214 else if("Byte".equals(type)) return L0.Byte;
215 else if("Boolean".equals(type)) return L0.Boolean;
216 else if("[Double]".equals(type)) return L0.DoubleArray;
217 else if("[String]".equals(type)) return L0.StringArray;
218 else if("[Integer]".equals(type)) return L0.IntegerArray;
219 else if("[Long]".equals(type)) return L0.LongArray;
220 else if("[Float]".equals(type)) return L0.FloatArray;
221 else if("[Byte]".equals(type)) return L0.ByteArray;
222 else if("[Boolean]".equals(type)) return L0.BooleanArray;
223 else if("[Variant]".equals(type)) return L0.VariantArray;
224 else if("Array Double".equals(type)) return L0.DoubleArray;
225 else if("Array String".equals(type)) return L0.StringArray;
226 else if("Array Integer".equals(type)) return L0.IntegerArray;
227 else if("Array Long".equals(type)) return L0.LongArray;
228 else if("Array Float".equals(type)) return L0.FloatArray;
229 else if("Array Byte".equals(type)) return L0.ByteArray;
230 else if("Array Boolean".equals(type)) return L0.BooleanArray;
231 else if("Array Variant".equals(type)) return L0.VariantArray;
232 else if("Vector Double".equals(type)) return L0.DoubleArray;
233 else if("Vector String".equals(type)) return L0.StringArray;
234 else if("Vector Integer".equals(type)) return L0.IntegerArray;
235 else if("Vector Long".equals(type)) return L0.LongArray;
236 else if("Vector Float".equals(type)) return L0.FloatArray;
237 else if("Vector Byte".equals(type)) return L0.ByteArray;
238 else if("Vector Boolean".equals(type)) return L0.BooleanArray;
239 else if("Vector Variant".equals(type)) return L0.VariantArray;
240 else if("Datatype".equals(type)) return L0.DataType;
241 else if("Variant".equals(type)) return L0.Variant;
245 public static Resource getPossibleLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {
246 Resource predicate = variable.getPossiblePredicateResource(graph);
247 if(predicate == null) return null;
248 return getPossibleLiteralType(graph, predicate);
251 public static Resource getLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {
252 Resource result = getPossibleLiteralType(graph, variable);
253 if(result == null) throw new DatabaseException("Unidentified literal type for variable " + variable.getURI(graph));
257 public static Resource getLiteralType(ReadGraph graph, Resource property) throws DatabaseException {
258 Resource result = getPossibleLiteralType(graph, property);
259 if(result == null) throw new DatabaseException("Unidentified literal type for property " + graph.getURI(property));
263 public static Resource getPossibleLiteralType(ReadGraph graph, Resource property) throws DatabaseException {
265 Layer0 L0 = Layer0.getInstance(graph);
266 Layer0X L0X = Layer0X.getInstance(graph);
268 Resource defaultLiteralType = graph.getPossibleObject(property, L0.HasDefaultLiteralType);
269 if(defaultLiteralType != null) return defaultLiteralType;
271 Resource range = graph.getPossibleObject(property, L0.HasRange);
272 if(range != null && !L0.Value.equals(range)) return range;
274 Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, Bindings.DATATYPE);
275 if(requiredDataType != null) return getLiteralType(graph, requiredDataType);
277 String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);
278 if(requiredValueType == null) return null;
280 return getPossibleLiteralType(graph, requiredValueType);
285 * @param type any data type definition
286 * @return SCL type that matches the specified data type on a basic level.
287 * Data type metadata is/cannot be converted into SCL types.
288 * @throws IllegalArgumentException
289 * if the input datatype can't be converted into an SCL type
291 public static String getSCLType(Datatype type) throws IllegalArgumentException {
292 return buildSCLType(type, null).toString();
296 * Only used internally by {@link #buildSCLType(Datatype, StringBuilder)}
300 * @see #buildSCLType(Datatype, StringBuilder)
302 private static StringBuilder append(StringBuilder toBuilder, String s) {
303 return toBuilder != null ? toBuilder.append(s) : new StringBuilder(s);
306 private static CharSequence append(CharSequence to, String s) {
307 if (to instanceof StringBuilder)
308 return ((StringBuilder) to).append(s);
309 return new StringBuilder(to.length() + s.length()).append(to).append(s);
312 private static CharSequence stringOrBuilder(StringBuilder toBuilder, String s) {
313 return toBuilder != null ? toBuilder.append(s) : s;
317 * @param type any data type definition
318 * @return SCL type that matches the specified data type on a basic level.
319 * Data type metadata is/cannot be converted into SCL types.
320 * @throws IllegalArgumentException
321 * if the input datatype can't be converted into an SCL type
323 private static CharSequence buildSCLType(Datatype type, StringBuilder result) throws IllegalArgumentException {
324 if(type instanceof DoubleType) return stringOrBuilder(result, "Double");
325 else if(type instanceof StringType) return stringOrBuilder(result, "String");
326 else if(type instanceof IntegerType) return stringOrBuilder(result, "Integer");
327 else if(type instanceof FloatType) return stringOrBuilder(result, "Float");
328 else if(type instanceof BooleanType) return stringOrBuilder(result, "Boolean");
329 else if(type instanceof ByteType) return stringOrBuilder(result, "Byte");
330 else if(type instanceof LongType) return stringOrBuilder(result, "Long");
331 else if(type instanceof VariantType) return stringOrBuilder(result, "Variant");
332 else if(type instanceof ArrayType) {
333 ArrayType at = (ArrayType) type;
334 // Optimization to prevent allocations in the most basic array cases
335 if(at.componentType instanceof DoubleType) return stringOrBuilder(result, "Vector Double");
336 else if(at.componentType instanceof StringType) return stringOrBuilder(result, "Vector String");
337 else if(at.componentType instanceof IntegerType) return stringOrBuilder(result, "Vector Integer");
338 else if(at.componentType instanceof FloatType) return stringOrBuilder(result, "Vector Float");
339 else if(at.componentType instanceof BooleanType) return stringOrBuilder(result, "Vector Boolean");
340 else if(at.componentType instanceof ByteType) return stringOrBuilder(result, "Vector Byte");
341 else if(at.componentType instanceof LongType) return stringOrBuilder(result, "Vector Long");
342 else if(at.componentType instanceof VariantType) return stringOrBuilder(result, "Vector Variant");
343 else return buildSCLType(at.componentType, append(result, "Vector "));
344 } else if(type instanceof OptionalType) {
345 OptionalType ot = (OptionalType) type;
346 return append(buildSCLType(ot.componentType, append(result, "Maybe (")), ")");
347 } else if (type instanceof RecordType) {
348 throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
349 } else if (type instanceof MapType) {
350 throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
351 } else if (type instanceof UnionType) {
352 throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
354 throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
358 public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException {
359 return CommonDBUtils.getSCLType(graph, runtimeEnvironment, typeText);
362 public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException {
364 RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(property.getIndexRoot(graph)));
365 return getSCLType(graph, runtimeEnvironment, getSCLTypeString(graph, property));
370 public static String getSCLTypeString(ReadGraph graph, Variable context) throws DatabaseException {
371 return getSCLTypeString(graph, context.getPossiblePredicateResource(graph), context.getRepresents(graph));
375 public static String getSCLTypeString(ReadGraph graph, Resource predicate, Resource value) throws DatabaseException {
377 if(predicate != null) {
378 String requiredValueTypes = graph.getPossibleRelatedValue(predicate, Layer0.getInstance(graph).RequiresValueType, Bindings.STRING);
379 if(requiredValueTypes != null)
380 return requiredValueTypes;
383 Layer0 L0 = Layer0.getInstance(graph);
384 Layer0X L0X = Layer0X.getInstance(graph);
386 Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, Bindings.DATATYPE);
387 if(literalDatatype != null) return getSCLType(literalDatatype);
389 String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING);
390 if(literalValueType != null) return literalValueType;
392 if(predicate != null) {
394 Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, Bindings.DATATYPE);
395 if(requiredDataType != null) return getSCLType(requiredDataType);
397 throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate));
401 throw new DatabaseException("Unidentified literal data type");
405 public static Datatype getDatatype(ReadGraph graph, Variable variable) throws DatabaseException {
406 Datatype result = getPossibleDatatype(graph, variable);
407 if(result != null) return result;
408 throw new DatabaseException("Unidentified literal data type for property " + variable.getURI(graph));
411 public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException {
412 return getPossibleDatatype(graph, variable, null, true);
415 private static Datatype getPossibleDatatype(ReadGraph graph, Variable variable, PropertyInfo info, boolean checkPropertyDatatype) throws DatabaseException {
416 Layer0 L0 = Layer0.getInstance(graph);
417 Layer0X L0X = Layer0X.getInstance(graph);
419 Resource property = variable.getPossiblePredicateResource(graph);
420 if(checkPropertyDatatype && property != null) {
421 Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue<Datatype>(property, L0X.RequiresDataType, Bindings.DATATYPE));
422 if(requiredDataType != null) return requiredDataType;
425 Resource literal = variable.getPossibleRepresents(graph);
426 if(literal != null) {
427 Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), Bindings.DATATYPE);
428 if(literalDatatype != null) return literalDatatype;
431 if(property != null) {
433 String requiredValueType = info != null
434 ? info.requiredValueType
435 : graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);
436 if(requiredValueType != null) {
437 Datatype datatype = getPossibleDatatypeForValueType(requiredValueType);
438 if(datatype != null) return datatype;
441 Resource subject = variable.getParent(graph).getPossibleRepresents(graph);
442 if(subject != null) {
443 Set<Resource> asses = new HashSet<Resource>();
444 for(Resource type : graph.getTypes(subject)) {
445 asses.addAll(graph.getAssertedObjects(type, property));
447 if(asses.size() == 1) {
448 Resource ass = asses.iterator().next();
449 Datatype dt = graph.getPossibleRelatedValue(ass, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class));
450 if(dt != null) return dt;
459 private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException {
461 String[] split = requiredValueType.split(" ");
462 String arrayType = null;
463 if(split.length == 2 && "Array".equals(split[0])) {
464 arrayType = split[1];
465 } else if(requiredValueType.startsWith("[") && requiredValueType.endsWith("]")) {
466 arrayType = requiredValueType.substring(1, requiredValueType.length()-1);
469 Datatype arrayDataType = getDatatypeForType(arrayType != null ? arrayType : requiredValueType, arrayType != null);
470 if(arrayDataType != null)
471 return arrayDataType;
473 Datatype dt = Datatypes.getDatatype(requiredValueType);
474 if(dt != null) return dt;
477 return Datatypes.translate(requiredValueType);
478 } catch (DataTypeSyntaxError e) {
484 private static Datatype getDatatypeForType(String type, boolean isArray) {
486 case "Double": return isArray ? Datatypes.DOUBLE_ARRAY : Datatypes.DOUBLE;
487 case "String": return isArray ? Datatypes.STRING_ARRAY : Datatypes.STRING;
488 case "Integer": return isArray ? Datatypes.INTEGER_ARRAY : Datatypes.INTEGER;
489 case "Long": return isArray ? Datatypes.LONG_ARRAY : Datatypes.LONG;
490 case "Float": return isArray ? Datatypes.FLOAT_ARRAY : Datatypes.FLOAT;
491 case "Byte": return isArray ? Datatypes.BYTE_ARRAY : Datatypes.BYTE;
492 case "Boolean": return isArray ? Datatypes.BOOLEAN_ARRAY : Datatypes.BOOLEAN;
493 case "Variant": return isArray ? Datatypes.VARIANT_ARRAY : Datatypes.VARIANT;
498 public static Binding getDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {
500 Resource property = variable.getPossiblePredicateResource(graph);
501 if(property != null) {
502 PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());
503 if(info.defaultBinding != null) return info.defaultBinding;
506 Datatype type = getDatatype(graph, variable);
507 return Bindings.getBinding(type);
511 public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {
513 Resource property = variable.getPossiblePredicateResource(graph);
514 PropertyInfo info = null;
515 if(property != null) {
516 info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());
517 if(info.defaultBinding != null) return info.defaultBinding;
520 Datatype type = getPossibleDatatype(graph, variable, info, false);
521 if (type == null) return null;
523 return Bindings.getBinding(type);
527 public static String getPossibleUnit(Datatype dt) {
530 else if (dt instanceof NumberType) {
531 return ((NumberType) dt).getUnit();
532 } else if (dt instanceof ArrayType) {
533 ArrayType at = (ArrayType) dt;
534 Datatype cdt = at.componentType();
535 if (cdt instanceof NumberType) {
536 return ((NumberType) cdt).getUnit();
543 public static String getUnit(ReadGraph graph, Variable variable) throws DatabaseException {
545 Layer0 L0 = Layer0.getInstance(graph);
546 Layer0X L0X = Layer0X.getInstance(graph);
548 Resource literal = variable.getPossibleRepresents(graph);
552 Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), Bindings.DATATYPE);
553 if(literalDatatype != null) {
554 String unit = getPossibleUnit(literalDatatype);
555 if(unit != null) return unit;
558 Resource property = variable.getPossiblePredicateResource(graph);
559 if(property != null) {
561 Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, Bindings.DATATYPE);
562 if(requiredDataType != null) {
563 String unit = getPossibleUnit(requiredDataType);
564 if(unit != null) return unit;
573 public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype targetDatatype) throws DatabaseException {
577 Datatype sourceDatatype = binding.type();
578 if(sourceDatatype.equals(targetDatatype)) {
579 graph.claimValue(objectResource, value, binding);
581 Binding target = Bindings.getBinding(targetDatatype);
582 Adapter adapter = Bindings.getTypeAdapter(binding, target);
583 graph.claimValue(objectResource, adapter.adapt(value), target);
586 } catch (AdapterConstructionException e) {
587 throw new DatabaseException(e);
588 } catch (AdaptException e) {
589 throw new DatabaseException(e);
594 public static String toString(Object value, Binding binding) throws DatabaseException {
596 if(value instanceof String) return (String)value;
597 StringBuilder sb = new StringBuilder();
598 DataValueRepository rep = new DataValueRepository();
599 binding.printValue(value, sb, rep, false);
600 return sb.toString();
601 } catch (BindingException e) {
602 throw new DatabaseException(e);
603 } catch (IOException e) {
604 throw new DatabaseException(e);
608 public static Object parseValue(String text, Binding binding) throws DatabaseException {
610 if(binding.isInstance(text)) return text;
611 DataValueRepository rep = new DataValueRepository();
612 return binding.parseValue(text, rep);
613 } catch (BindingException e) {
614 throw new DatabaseException(e);
615 } catch (DataTypeSyntaxError e) {
616 throw new DatabaseException(e);
620 @SuppressWarnings("unchecked")
621 public static <T> T getValueAdaptedToBinding(ReadGraph graph, Resource literal, Binding targetBinding) throws DatabaseException {
622 Datatype sourceDatatype = graph.getDataType(literal);
623 Datatype targetDatatype = targetBinding.type();
624 if (sourceDatatype.equals(targetDatatype))
625 return graph.getValue(literal, targetBinding);
627 Binding sourceBinding = Bindings.getBinding(sourceDatatype);
629 Adapter adapter = Bindings.adapterFactory.getAdapter(Bindings.getBinding(sourceDatatype), targetBinding, true, false);
630 Object value = graph.getValue(literal, sourceBinding);
631 return (T) adapter.adaptUnchecked(value);
632 } catch (AdapterConstructionException e) {
633 throw new DatabaseException(e);
637 public static Statement getStatementInLocal(Resource subject, Statement statement) {
638 if(statement.isAsserted(subject)) return new StandardStatement(subject, statement.getPredicate(), statement.getObject());
639 else return statement;
642 public static Resource browsePossible(ReadGraph graph, Resource root, String suffix) throws DatabaseException {
643 return graph.getPossibleResource(graph.getURI(root) + suffix);
647 public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException {
648 return CommonDBUtils.getPossibleChild(graph, resource, name);
652 public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException {
653 return CommonDBUtils.getPossibleChild(graph, resource, type, name);
656 public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {
657 Statement stm = graph.getSingleStatement(subject, predicate);
658 return new RelationContextImpl(subject, stm);
661 public static RelationContext relationContext(Statement stm) throws DatabaseException {
662 return new RelationContextImpl(stm.getSubject(), stm);
665 public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm) throws DatabaseException {
666 return graph.getValue2(subject, Layer0Utils.relationContext(stm));
669 public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm, Binding binding) throws DatabaseException {
670 return graph.getValue2(subject, Layer0Utils.relationContext(stm), binding);
673 public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {
674 Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));
675 return valueInRelationContext(graph, stm.getObject(), stm);
678 public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation, Binding binding) throws DatabaseException {
679 Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));
680 return valueInRelationContext(graph, stm.getObject(), stm, binding);
683 public static Statement possibleObtainedStatementInternal(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {
685 Layer0X L0X = Layer0X.getInstance(graph);
687 for(Resource ob : graph.getObjects(subject, L0X.DefinesObtainedStatement)) {
688 Resource pred = graph.getSingleObject(ob, L0X.ObtainedStatement_predicate);
689 if(graph.isSubrelationOf(pred, relation)) {
690 Resource object = graph.getSingleObject(ob, L0X.ObtainedStatement_object);
691 return new StandardStatement(subject, pred, object);
695 ArrayList<OrderedResource> order = new ArrayList<OrderedResource>();
696 for(Statement stm : graph.getStatements(subject, L0X.ObtainsProperty)) {
697 Integer position = graph.getRelatedValue(stm.getPredicate(), L0X.NaturalNumberOrderRelation, Bindings.INTEGER);
698 order.add(new OrderedResource(position, stm.getObject()));
701 for(OrderedResource or : order) {
702 Statement stm = possibleObtainedStatementInternal(graph, or.r, relation);
703 if(stm != null) return stm;
710 public static <T> T possibleObtainedValue(ReadGraph graph, RelationContext ctx, Binding binding) throws DatabaseException {
712 Statement stm = ctx.getStatement();
713 Statement obj = Layer0Utils.possibleObtainedStatementInternal(graph, stm.getSubject(), stm.getPredicate());
716 return Layer0Utils.valueInRelationContext(graph, obj.getObject(), obj, binding);
723 public static void addObtainedStatement(WriteGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException {
724 Layer0 L0 = Layer0.getInstance(graph);
725 Layer0X L0X = Layer0X.getInstance(graph);
726 Resource ob = graph.newResource();
727 graph.claim(ob, L0.InstanceOf, null, L0X.ObtainedStatement);
728 graph.claim(ob, L0X.ObtainedStatement_predicate, null, predicate);
729 graph.claim(ob, L0X.ObtainedStatement_object, null, object);
730 graph.claim(subject, L0X.DefinesObtainedStatement, null, ob);
733 public static void addObtainedValue(WriteGraph graph, Resource subject, Resource predicate, Resource type, Object value, Binding binding) throws DatabaseException {
734 Layer0 L0 = Layer0.getInstance(graph);
735 Resource object = graph.newResource();
736 graph.claim(object, L0.InstanceOf, type);
737 graph.claimValue(object, value, binding);
738 Layer0Utils.addObtainedStatement(graph, subject, predicate, object);
741 //-------------------------------------------------------------------------
742 // Indexing state query utilities idle handling utilities
743 //-------------------------------------------------------------------------
746 * This method waits until the indexing engine becomes idle.
749 public static void waitIndexPending() {
750 Indexing.waitIndexPending();
754 * @param graph an active database write handle to prove one is in a write
755 * transaction and wants to disable dependencies indexing for this
757 * @return previous value
760 public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) {
761 return Indexing.setDependenciesIndexingDisabled(graph, disabled);
764 public static String undo() throws DatabaseException {
766 Session session = SimanticsInternal.getSession();
768 UndoRedoSupport support = session.getService(UndoRedoSupport.class);
770 List<Operation> ops = support.undoAndReturnOperations(session, 1);
772 return "Undo history is empty.";
774 Operation mainOperation = ops.get(0);
776 long csId = mainOperation.getCSId();
778 ManagementSupport management = session.getService(ManagementSupport.class);
779 Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);
781 return "Undo reverted " + ids.size() + " change sets.";
785 public static String undoOperations(int amountOfOperations) throws DatabaseException {
787 Session session = SimanticsInternal.getSession();
789 UndoRedoSupport support = session.getService(UndoRedoSupport.class);
791 List<Operation> ops = support.undoAndReturnOperations(session, amountOfOperations);
793 return "Undo history is empty.";
795 Operation mainOperation = ops.get(0);
797 long csId = mainOperation.getCSId();
799 ManagementSupport management = session.getService(ManagementSupport.class);
800 Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);
802 return "Undo reverted " + ids.size() + " change sets.";
806 public static String redo() throws DatabaseException {
808 Session session = SimanticsInternal.getSession();
810 UndoRedoSupport support = session.getService(UndoRedoSupport.class);
812 List<Operation> ops = support.redo(session, 1);
814 return "Redo history is empty.";
816 Operation mainOperation = ops.get(0);
818 long csId = mainOperation.getCSId();
820 ManagementSupport management = session.getService(ManagementSupport.class);
821 Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);
823 return "Redo redid " + ids.size() + " change sets.";
827 public static String getComment(Session session, ChangeSetIdentifier id) {
828 byte[] data = id.getMetadata().get(CommentMetadata.class.getName());
830 return "Undescribed operation.";
831 String comment = CommentMetadata.deserialise(session, data).toString().trim();
832 if(comment.isEmpty())
833 return "Undescribed operation.";
838 * This method adds CommentMetadata for write transaction. CommentMetadata is used e.g. in Undo view.
843 * @throws ServiceException
845 public static void addCommentMetadata(WriteOnlyGraph graph, String string) throws ServiceException {
846 // Add a comment to metadata.
847 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
848 graph.addMetadata(cm.add(ObjectUtils.toString(string)));
851 //-------------------------------------------------------------------------
854 * Copy the specified source resource into the specified container using the
855 * specified write transaction handle.
857 * @param graph write transaction handle
858 * @param targetContainer target container resource of the created copy. The
859 * exact logic of how the copy will be contained by the target
860 * container is up to the PasteHandler to decide
861 * @param source the source resource to copy
862 * @throws DatabaseException
865 public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source) throws DatabaseException {
866 return copyTo(graph, targetContainer, source, null, null, null);
869 public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler) throws DatabaseException {
870 return copyTo(graph, targetContainer, source, handler, null, null);
873 public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {
874 if(copyHandler == null) copyHandler = graph.adapt(source, CopyHandler.class);
875 return copyTo(graph, targetContainer, handler, copyHandler, pasteHandler);
878 public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {
879 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
880 copyHandler.copyToClipboard(graph, clipboard, new NullProgressMonitor());
881 if(targetContainer != null) {
882 if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class);
883 return pasteHandler.pasteFromClipboard(graph, clipboard, handler);
885 DefaultPasteHandler ph = new DefaultPasteHandler(null);
886 return ph.pasteFromClipboard(graph, clipboard, handler);
890 public static CopyHandler2 getPossibleCopyHandler(ReadGraph graph, Collection<Resource> rs) throws DatabaseException {
891 CopyHandler2 ch = null;
892 for(Resource r : rs) {
894 CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);
895 if(ch2_ instanceof CopyHandler2) {
896 ch = (CopyHandler2)ch2_;
899 CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);
900 if(ch2_ instanceof CopyHandler2) {
901 CopyHandler2 ch2 = (CopyHandler2)ch2_;
902 ch = ch.combine(ch2);
909 public static ClusterCollectorPolicy setClusterCollectorPolicy(ClusterCollectorPolicy policy) {
910 Session session = SimanticsInternal.getSession();
911 ClusterControl cc = session.getService(ClusterControl.class);
912 return cc.setPolicy(policy);
915 private static String decodeType(ReadGraph graph, Variable variable) throws DatabaseException {
916 Datatype dt = getDatatype(graph, variable);
917 return dt.toSingleLineString();
920 private static boolean isAsserted(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {
921 Statement stm = graph.getPossibleStatement(subject, predicate);
922 return stm != null && stm.isAsserted(subject);
926 * Works around problems in WriteGraph methods with similar signature.
927 * Especially handles better some cases with existing literals.
930 public static void claimLiteral(WriteGraph graph, Resource r, Resource p, Resource i, Resource t, Object value, Binding binding) throws DatabaseException {
931 Statement stm = graph.getPossibleStatement(r, p);
932 if(stm != null && !stm.isAsserted(r)) {
933 if(graph.isInstanceOf(stm.getObject(), t)) {
934 // Existing statement is compatible, reuse the literal
935 graph.claimValue(stm.getObject(), value, binding);
938 // Existing statement is incompatible - remove it
942 // Create new statement
943 graph.claimLiteral(r, p, i, t, value, binding);
946 public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException {
948 Resource value = context.getRepresents(graph);
949 Resource predicateResource = context.getPredicateResource(graph);
950 Variable parent = context.getParent(graph);
951 Resource parentResource = parent.getRepresents(graph);
952 setExpression(graph, parentResource, predicateResource, value, text, expressionValueType);
956 public static void setExpression(WriteGraph graph, Resource parentResource, Resource predicateResource, Resource value, String text, Resource expressionValueType) throws DatabaseException {
958 Layer0 L0 = Layer0.getInstance(graph);
959 boolean hasExpression = graph.isInstanceOf(value, expressionValueType);
960 String t = getSCLTypeString(graph, predicateResource, value);
961 String expression = text.substring(1).trim();
962 if(isAsserted(graph, parentResource, predicateResource)) {
963 Resource newValue = graph.newResource();
964 graph.claim(newValue, L0.InstanceOf, expressionValueType);
965 graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);
966 graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);
967 graph.claim(parentResource, predicateResource, newValue);
970 graph.claimLiteral(value, L0.SCLValue_expression, expression, Bindings.STRING);
972 Resource newValue = graph.newResource();
973 graph.claim(newValue, L0.InstanceOf, expressionValueType);
974 graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);
975 graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);
976 graph.deny(parentResource, predicateResource);
977 graph.claim(parentResource, predicateResource, newValue);
983 public static void clearExpression(WriteGraph graph, Variable property, Resource expressionValueType) throws DatabaseException {
985 Resource object = property.getPossibleRepresents(graph);
987 boolean hasExpression = graph.isInstanceOf(object, expressionValueType);
989 // There was an expression and now we go back to a value
990 Resource subject = property.getParent(graph).getPossibleRepresents(graph);
991 if(subject != null) {
992 Resource predicate = property.getPossiblePredicateResource(graph);
993 if(predicate != null) {
994 graph.deny(subject, predicate, object);
995 RemoverUtil.remove(graph, object);
1003 public static boolean setOrClearExpression(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {
1005 if(text.startsWith("=")) {
1006 setExpression(graph, property, text, expressionValueType);
1010 clearExpression(graph, property, expressionValueType);
1016 public static void setValueAsString(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {
1020 if (setOrClearExpression(graph, property, text, expressionValueType))
1023 Object value = text;
1024 Datatype type = property.getPossibleDatatype(graph);
1027 Binding binding = Bindings.getBinding(type);
1029 if (binding instanceof StringBinding) {
1031 if (binding instanceof MutableStringBinding)
1032 value = new MutableString(text);
1038 if (binding instanceof NumberBinding) {
1039 text = text.replace(",", ".");
1042 value = binding.parseValue(text, new DataValueRepository());
1046 property.setValue(graph, value, binding);
1050 property.setValue(graph, value);
1054 // Add a comment to metadata.
1055 CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
1056 graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value)));
1058 } catch (DataTypeSyntaxError e) {
1059 throw new DatabaseException(e);
1060 } catch (BindingException e) {
1061 throw new DatabaseException(e);
1067 public static String queryDebugSupport(String query) {
1068 Session session = SimanticsInternal.getSession();
1069 DebugSupport ds = session.getService(DebugSupport.class);
1070 return ds.query(session, "exec " + query);
1073 public static String queryListSupport (String query) {
1074 Session session = SimanticsInternal.getSession();
1075 DebugSupport ds = session.getService(DebugSupport.class);
1076 return ds.query(session, "list " + query);
1079 final public static Function1<Resource,Resource> resourceCluster = new FunctionImpl1<Resource, Resource>() {
1081 public Resource apply(Resource p0) {
1086 public static void sort(ReadGraph graph, List<Resource> collection) {
1087 CollectionSupport cos = graph.getService(CollectionSupport.class);
1088 cos.sort(collection);
1091 public static List<Resource> sortByCluster(ReadGraph graph, Collection<Resource> collection) {
1092 CollectionSupport cos = graph.getService(CollectionSupport.class);
1093 return cos.asSortedList(collection);
1096 public static List<Object> sortByCluster(final ReadGraph graph, List<Object> list, final Function1<Object,Resource> fn) {
1097 final ClusteringSupport cs = graph.getService(ClusteringSupport.class);
1098 ArrayList<Object> result = new ArrayList<Object>(list);
1099 Collections.sort(result, new Comparator<Object>() {
1102 public int compare(Object o1, Object o2) {
1103 Resource r1 = fn.apply(o1);
1104 Resource r2 = fn.apply(o2);
1105 long l1 = cs.getCluster(r1);
1106 long l2 = cs.getCluster(r2);
1107 if(l1 < l2) return -1;
1108 else if (l1 > l2) return 1;
1116 public static <T> List<T> sortByClusterT(final ReadGraph graph, Collection<T> list, final Function1<T,Resource> fn) {
1117 final ClusteringSupport cs = graph.getService(ClusteringSupport.class);
1118 ArrayList<T> result = new ArrayList<T>(list);
1119 Collections.sort(result, new Comparator<Object>() {
1122 public int compare(Object o1, Object o2) {
1123 Resource r1 = fn.apply((T)o1);
1124 Resource r2 = fn.apply((T)o2);
1125 long l1 = cs.getCluster(r1);
1126 long l2 = cs.getCluster(r2);
1127 if(l1 < l2) return -1;
1128 else if (l1 > l2) return 1;
1136 public static void makeSynchronous(ReadGraph graph, boolean value) throws DatabaseException {
1137 graph.setSynchronous(value);
1140 public static Set<Resource> listIndexRoots(ReadGraph graph) throws DatabaseException {
1142 Layer0 L0 = Layer0.getInstance(graph);
1144 Set<Resource> indexRoots = new TreeSet<Resource>();
1145 indexRoots.addAll(Layer0Utils.listOntologies(graph));
1146 indexRoots.addAll(graph.syncRequest(new ObjectsWithType(SimanticsInternal.getProject(), L0.ConsistsOf, L0.IndexRoot)));
1151 public static List<Resource> listOntologies(ReadGraph graph) throws DatabaseException {
1152 return graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary()));
1155 public static List<Resource> listGlobalOntologies(ReadGraph graph) throws DatabaseException {
1156 return graph.syncRequest(new GlobalOntologies(graph.getRootLibrary()));
1159 public static <T> T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException {
1162 SCL_GRAPH.set(graph);
1163 T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module + "/" + function)).applyArray(args);
1164 SCL_GRAPH.set(null);
1166 } catch (Throwable t) {
1167 throw new DatabaseException(t);
1172 public static boolean isContainerPublished(ReadGraph graph, Variable variable) throws DatabaseException {
1174 Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable));
1175 if(indexRoot == null) return false;
1176 Resource represents = variable.getPossibleRepresents(graph);
1177 if(represents != null && represents.equals(indexRoot)) return false;
1178 return isPublished(graph, indexRoot);
1182 public static boolean isContainerPublished(ReadGraph graph, Resource resource) throws DatabaseException {
1184 Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resource));
1185 if(indexRoot == null) return false;
1186 if(resource.equals(indexRoot)) return false;
1187 return isPublished(graph, indexRoot);
1191 public static boolean isPublished(ReadGraph graph, Resource resource) throws DatabaseException {
1193 Layer0 L0 = Layer0.getInstance(graph);
1194 Boolean value = graph.getPossibleRelatedValue(resource, L0.Entity_published, Bindings.BOOLEAN);
1195 if(value != null && value) return true;
1197 // This is safety - root should not be published it child is not
1198 Resource root = graph.syncRequest(new PossibleIndexRoot(resource));
1200 value = graph.getPossibleRelatedValue(root, L0.Entity_published, Bindings.BOOLEAN);
1201 if(value != null && value) return true;
1208 private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException {
1210 SimanticsClipboardImpl cp = new SimanticsClipboardImpl();
1211 CopyHandler c1 = graph.adapt(r, CopyHandler.class);
1212 c1.copyToClipboard(graph, cp, null);
1213 Collection<Set<Representation>> reps = cp.getContents();
1214 if(reps.size() != 1) return null;
1215 return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
1219 public static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException {
1221 SimanticsClipboardImpl cp = new SimanticsClipboardImpl();
1222 CopyHandler c1 = graph.adapt(r, CopyHandler.class);
1223 c1.copyToClipboard(graph, cp, null);
1224 Collection<Set<Representation>> reps = cp.getContents();
1225 if(reps.size() != 1) return null;
1226 return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE);
1231 * Modifies target to resemble source.
1233 public static boolean merge(WriteGraph graph, Resource source, Resource target) throws DatabaseException {
1235 TransferableGraphSource tgs1 = makeTGSource(graph, target);
1236 TransferableGraph1 tg1 = TransferableGraphs.create(graph, tgs1);
1237 TransferableGraph1 tg2 = makeTG(graph, source);
1239 GraphRefactoringUtils.fixIncorrectRoot(tg1.identities);
1240 GraphRefactoringUtils.fixIncorrectRoot(tg2.identities);
1242 ModelTransferableGraphSource mtgs = (ModelTransferableGraphSource)tgs1;
1244 Diff diff = new Diff(tg1, tg2);
1245 TransferableGraphDelta1 delta = diff.diff();
1247 long[] oldResources = mtgs.getResourceArray(graph);
1248 if(TransferableGraphs.hasChanges(graph, oldResources, delta)) {
1249 TransferableGraphs.applyDelta(graph, mtgs.getResourceArray(graph), delta);
1257 public static Resource inferLiteralTypeFromString(ReadGraph graph, String text) {
1258 return Layer0.getInstance(graph).String;
1261 public static void emptyTrashBin() throws ServiceException {
1262 emptyTrashBin(new NullProgressMonitor());
1265 public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException {
1266 emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject());
1269 public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project)
1270 throws ServiceException {
1271 final SubMonitor mon = SubMonitor.convert(monitor, "Emptying Trash Bin...", 10000);
1273 ArrayList<Resource> unhandled = new ArrayList<Resource>();
1274 session.syncRequest(new DelayedWriteRequest() {
1276 public void perform(WriteGraph graph) throws DatabaseException {
1277 Layer0Utils.setDependenciesIndexingDisabled(graph, true);
1278 Layer0 L0 = Layer0.getInstance(graph);
1279 Layer0X L0X = Layer0X.getInstance(graph);
1280 Resource parent = graph.getSingleObject(project, L0.PartOf);
1281 Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin");
1282 Collection<Resource> trashes = trashBin != null ? graph.getObjects(trashBin, L0.ConsistsOf)
1283 : Collections.<Resource> emptyList();
1284 if (trashes.isEmpty())
1285 throw new CancelTransactionException();
1286 mon.setWorkRemaining((2 + trashes.size()) * 1000);
1287 for (Resource trash : trashes) {
1288 if (mon.isCanceled())
1289 throw new CancelTransactionException();
1290 mon.subTask(NameUtils.getSafeName(graph, trash));
1291 boolean isIndexRoot = graph.isInstanceOf(trash, L0.IndexRoot);
1292 TGRemover remo = new TGRemover(mon.newChild(1000, SubMonitor.SUPPRESS_ALL_LABELS), trash);
1295 unhandled.addAll(remo.getRoots());
1296 } catch (DatabaseException e) {
1297 // Something went wrong - try to remove this later
1298 // with EntityRemover
1299 unhandled.add(trash);
1302 // TODO: this should be an utility
1303 GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation,
1304 GenericRelationIndex.class);
1305 IndexedRelations ir = graph.getService(IndexedRelations.class);
1306 // Deletes index files
1307 ir.reset(null, graph, L0X.DependenciesRelation, trash);
1308 // Notifies DB listeners
1309 index.reset(graph, trash);
1312 if (mon.isCanceled())
1313 throw new CancelTransactionException();
1314 mon.subTask("Committing Changes");
1319 session.syncRequest(new WriteRequest() {
1321 public void perform(WriteGraph graph) throws DatabaseException {
1322 for (Resource r : unhandled)
1323 EntityRemover.remove(graph, r);
1327 if (mon.isCanceled())
1329 mon.subTask("Purging Database");
1331 purgeDatabase(monitor, session);
1332 } catch (CancelTransactionException e) {
1334 } catch (DatabaseException e) {
1335 throw new ServiceException(e);
1339 public static void purgeDatabase() throws ServiceException {
1340 purgeDatabase(new NullProgressMonitor());
1343 public static void purgeDatabase(final IProgressMonitor monitor) throws ServiceException {
1344 purgeDatabase(monitor, SimanticsInternal.getSession());
1347 public static void purgeDatabase(final IProgressMonitor monitor, Session session) throws ServiceException {
1349 XSupport xs = session.getService(XSupport.class);
1351 } catch (DatabaseException e) {
1352 throw new ServiceException(e);
1356 public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException {
1357 Resource result = null;
1358 for(Resource candidate : getDomainOf(graph, type).values()) {
1359 if(graph.isInstanceOf(candidate, target)) {
1360 if(result != null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));
1361 else result = candidate;
1364 if(result == null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));
1368 public static Map<String, Resource> getDomainOf(ReadGraph graph, Resource type) throws DatabaseException {
1369 CollectionSupport cs = graph.getService(CollectionSupport.class);
1370 Map<String, Resource> result = cs.createObjectResourceMap(String.class);
1371 Layer0 L0 = Layer0.getInstance(graph);
1372 for(Resource r : graph.getObjects(type, L0.DomainOf)) {
1373 String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
1374 if(name != null) result.put(name, r);
1376 for(Resource t : graph.getSupertypes(type)) {
1377 for(Resource r : graph.getObjects(t, L0.DomainOf)) {
1378 String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
1379 if(name != null) result.put(name, r);
1385 public static Resource getPossiblePredicateByNameFromType(ReadGraph graph, Resource type, String name) throws DatabaseException {
1386 Map<String,Resource> domain = getDomainOf(graph, type);
1387 return domain.get(name);
1390 public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {
1391 for(Resource type : graph.getPrincipalTypes(instance)) {
1392 Map<String, Resource> domainOf = getDomainOf(graph, type);
1393 Resource predicate = domainOf.get(predicateName);
1394 if(predicate != null) return predicate;
1399 public static Resource getPossiblePredicateByLabel(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {
1400 Layer0 L0 = Layer0.getInstance(graph);
1401 for(Resource type : graph.getPrincipalTypes(instance)) {
1402 Map<String, Resource> domainOf = getDomainOf(graph, type);
1403 for(Resource r : domainOf.values()) {
1404 String label = graph.getPossibleRelatedValue(r, L0.HasLabel, Bindings.STRING);
1405 if(predicateName.equals(label))
1412 public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException {
1415 PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(property));
1416 if(pi.literalRange == null) throw new DatabaseException("No suitable literal type defined as range for property.");
1417 if(pi.defaultBinding == null) throw new DatabaseException("No suitable default binding for property.");
1418 Object value = pi.defaultBinding.parseValue(valueText, new DataValueRepository());
1419 graph.claimLiteral(container, property, pi.literalRange, value, pi.defaultBinding);
1420 } catch (DataTypeSyntaxError e) {
1421 throw new DatabaseException(e);
1422 } catch (BindingException e) {
1423 throw new DatabaseException(e);
1428 public static String prettyPrintResource(ReadGraph graph, Resource resource, boolean ignoreIdentifiers) throws Exception {
1429 TransferableGraphSource source = makeTGSource(graph, resource);
1430 TransferableGraph1 tg = TransferableGraphs.create(graph, source);
1431 GraphRefactoringUtils.fixOntologyExport(tg);
1432 System.out.println("Printing resoure " + graph.getURI(resource));
1433 return PrettyPrintTG.print(tg, ignoreIdentifiers);
1437 * Adds a random {@link GUID} as a value for <code>L0.identifier</code>
1441 * for which the identifier is added
1443 * <code>true</code> to invoke addLiteral, <code>false</code> to
1444 * invoke claimLiteral
1445 * @throws DatabaseException
1447 public static void claimNewIdentifier(WriteGraph graph, Resource component, boolean add) throws DatabaseException {
1448 Layer0 L0 = Layer0.getInstance(graph);
1449 GUID guid = GUID.random();
1451 graph.addLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, guid, GUID.BINDING);
1453 graph.claimLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, guid, GUID.BINDING);
1457 * Sets a new random unique identifier for the specified entity if it already
1458 * has an identifier. If the entity does not have a previous identifier, nothing
1463 * for which the identifier is added
1464 * @return <code>true</code> if the identifier was renewed, <code>false</code>
1466 * @throws DatabaseException
1467 * @see {@link #claimNewIdentifier(WriteGraph, Resource, boolean)}
1469 public static boolean renewIdentifier(WriteGraph graph, Resource entity) throws DatabaseException {
1470 Layer0 L0 = Layer0.getInstance(graph);
1471 Statement stm = graph.getPossibleStatement(entity, L0.identifier);
1473 graph.claimValue(stm.getObject(), GUID.random(), GUID.BINDING);
1479 public static void addMetadataListener(ChangeListener listener) {
1480 SimanticsInternal.getSession().getService(GraphChangeListenerSupport.class).addMetadataListener(listener);
1483 public static void removeMetadataListener(ChangeListener listener) {
1484 SimanticsInternal.getSession().getService(GraphChangeListenerSupport.class).removeMetadataListener(listener);