]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / Layer0Utils.java
1 /*******************************************************************************\r
2  * Copyright (c) 2012 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.db.layer0.util;\r
13 \r
14 import java.io.IOException;\r
15 import java.util.ArrayList;\r
16 import java.util.Collection;\r
17 import java.util.Collections;\r
18 import java.util.Comparator;\r
19 import java.util.HashSet;\r
20 import java.util.List;\r
21 import java.util.Map;\r
22 import java.util.Set;\r
23 import java.util.TreeSet;\r
24 \r
25 import org.eclipse.core.runtime.IProgressMonitor;\r
26 import org.eclipse.core.runtime.SubMonitor;\r
27 import org.simantics.databoard.Bindings;\r
28 import org.simantics.databoard.Datatypes;\r
29 import org.simantics.databoard.adapter.AdaptException;\r
30 import org.simantics.databoard.adapter.Adapter;\r
31 import org.simantics.databoard.adapter.AdapterConstructionException;\r
32 import org.simantics.databoard.binding.Binding;\r
33 import org.simantics.databoard.binding.NumberBinding;\r
34 import org.simantics.databoard.binding.StringBinding;\r
35 import org.simantics.databoard.binding.error.BindingException;\r
36 import org.simantics.databoard.binding.mutable.MutableStringBinding;\r
37 import org.simantics.databoard.parser.repository.DataTypeSyntaxError;\r
38 import org.simantics.databoard.parser.repository.DataValueRepository;\r
39 import org.simantics.databoard.primitives.MutableString;\r
40 import org.simantics.databoard.type.ArrayType;\r
41 import org.simantics.databoard.type.BooleanType;\r
42 import org.simantics.databoard.type.ByteType;\r
43 import org.simantics.databoard.type.Datatype;\r
44 import org.simantics.databoard.type.DoubleType;\r
45 import org.simantics.databoard.type.FloatType;\r
46 import org.simantics.databoard.type.IntegerType;\r
47 import org.simantics.databoard.type.LongType;\r
48 import org.simantics.databoard.type.MapType;\r
49 import org.simantics.databoard.type.NumberType;\r
50 import org.simantics.databoard.type.OptionalType;\r
51 import org.simantics.databoard.type.RecordType;\r
52 import org.simantics.databoard.type.StringType;\r
53 import org.simantics.databoard.type.UnionType;\r
54 import org.simantics.databoard.type.VariantType;\r
55 import org.simantics.databoard.util.ObjectUtils;\r
56 import org.simantics.db.ChangeSetIdentifier;\r
57 import org.simantics.db.Operation;\r
58 import org.simantics.db.ReadGraph;\r
59 import org.simantics.db.RelationContext;\r
60 import org.simantics.db.Resource;\r
61 import org.simantics.db.Session;\r
62 import org.simantics.db.Statement;\r
63 import org.simantics.db.WriteGraph;\r
64 import org.simantics.db.WriteOnlyGraph;\r
65 import org.simantics.db.common.CommentMetadata;\r
66 import org.simantics.db.common.Indexing;\r
67 import org.simantics.db.common.StandardStatement;\r
68 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
69 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
70 import org.simantics.db.common.request.DelayedWriteRequest;\r
71 import org.simantics.db.common.request.ObjectsWithType;\r
72 import org.simantics.db.common.request.PossibleChild;\r
73 import org.simantics.db.common.request.PossibleIndexRoot;\r
74 import org.simantics.db.common.utils.NameUtils;\r
75 import org.simantics.db.exception.CancelTransactionException;\r
76 import org.simantics.db.exception.DatabaseException;\r
77 import org.simantics.db.exception.ServiceException;\r
78 import org.simantics.db.layer0.adapter.CopyHandler;\r
79 import org.simantics.db.layer0.adapter.CopyHandler2;\r
80 import org.simantics.db.layer0.adapter.GenericRelationIndex;\r
81 import org.simantics.db.layer0.adapter.PasteHandler;\r
82 import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
83 import org.simantics.db.layer0.adapter.impl.TGRemover;\r
84 import org.simantics.db.layer0.genericrelation.IndexedRelations;\r
85 import org.simantics.db.layer0.internal.SimanticsInternal;\r
86 import org.simantics.db.layer0.migration.OntologiesFromLibrary;\r
87 import org.simantics.db.layer0.property.OrderedResource;\r
88 import org.simantics.db.layer0.request.GlobalOntologies;\r
89 import org.simantics.db.layer0.request.PossibleVariableIndexRoot;\r
90 import org.simantics.db.layer0.request.PropertyInfo;\r
91 import org.simantics.db.layer0.request.PropertyInfoRequest;\r
92 import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
93 import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;\r
94 import org.simantics.db.layer0.variable.Variable;\r
95 import org.simantics.db.service.ClusterCollectorPolicy;\r
96 import org.simantics.db.service.ClusterControl;\r
97 import org.simantics.db.service.ClusteringSupport;\r
98 import org.simantics.db.service.CollectionSupport;\r
99 import org.simantics.db.service.DebugSupport;\r
100 import org.simantics.db.service.ManagementSupport;\r
101 import org.simantics.db.service.UndoRedoSupport;\r
102 import org.simantics.db.service.XSupport;\r
103 import org.simantics.graph.db.TransferableGraphSource;\r
104 import org.simantics.graph.db.TransferableGraphs;\r
105 import org.simantics.graph.diff.Diff;\r
106 import org.simantics.graph.diff.TransferableGraphDelta1;\r
107 import org.simantics.graph.refactoring.GraphRefactoringUtils;\r
108 import org.simantics.graph.representation.TransferableGraph1;\r
109 import org.simantics.layer0.Layer0;\r
110 import org.simantics.operation.Layer0X;\r
111 import org.simantics.scl.compiler.environment.Environments;\r
112 import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
113 import org.simantics.scl.compiler.top.SCLExpressionCompilationException;\r
114 import org.simantics.scl.compiler.types.Type;\r
115 import org.simantics.scl.osgi.SCLOsgi;\r
116 import org.simantics.scl.runtime.function.Function;\r
117 import org.simantics.scl.runtime.function.Function1;\r
118 import org.simantics.scl.runtime.function.FunctionImpl1;\r
119 \r
120 public class Layer0Utils {\r
121 \r
122         @SuppressWarnings("rawtypes")\r
123         public static final ThreadLocal SCL_GRAPH = new ThreadLocal();\r
124 \r
125         final public static Binding datatype_binging = Bindings.getBindingUnchecked(Datatype.class);\r
126 \r
127         public static Resource literal(WriteGraph g, String value) throws DatabaseException {\r
128                 Layer0 L0 = Layer0.getInstance(g);\r
129                 Resource r = g.newResource();\r
130                 g.claimValue(r, value, Bindings.STRING);\r
131                 g.claim(r, L0.InstanceOf, L0.String);\r
132                 return r;\r
133         }\r
134 \r
135         public static Resource literal(WriteGraph g, double value) throws DatabaseException {\r
136                 Layer0 L0 = Layer0.getInstance(g);\r
137                 Resource r = g.newResource();\r
138                 g.claimValue(r, value, Bindings.DOUBLE);\r
139                 g.claim(r, L0.InstanceOf, L0.Double);\r
140                 return r;\r
141         }\r
142 \r
143         public static Resource literal(WriteGraph g, int value) throws DatabaseException {\r
144                 Layer0 L0 = Layer0.getInstance(g);\r
145                 Resource r = g.newResource();\r
146                 g.claimValue(r, value, Bindings.INTEGER);\r
147                 g.claim(r, L0.InstanceOf, L0.Integer);\r
148                 return r;\r
149         }\r
150 \r
151         public static void assert_(WriteGraph g, Resource type, Resource predicate, Resource object) throws DatabaseException {\r
152                 Layer0 L0 = Layer0.getInstance(g);\r
153                 Resource assertion = g.newResource();\r
154                 g.claim(type, L0.Asserts, assertion);\r
155                 g.claim(assertion, L0.InstanceOf, L0.Assertion);\r
156                 g.claim(assertion, L0.HasPredicate, predicate);\r
157                 g.claim(assertion, L0.HasObject, object);\r
158         }\r
159 \r
160         public static Resource relation(WriteGraph g, Resource parent, String name, Resource superrelation) throws DatabaseException {\r
161                 Layer0 L0 = Layer0.getInstance(g);\r
162                 Resource relation = g.newResource();\r
163                 g.claim(relation, L0.SubrelationOf, superrelation);\r
164                 g.claim(relation, L0.HasName, literal(g, name));\r
165                 g.claim(parent, L0.ConsistsOf, relation);\r
166 \r
167                 Resource superrelationInverse = g.getInverse(superrelation);\r
168                 if(superrelationInverse != null) {\r
169                         Resource inverse = g.newResource();\r
170                         g.claim(inverse, L0.SubrelationOf, superrelationInverse);\r
171                         g.claim(relation, L0.ConsistsOf, inverse);\r
172                         g.claim(inverse, L0.HasName, literal(g, "Inverse"));\r
173                 }\r
174                 return relation;\r
175         }\r
176 \r
177         private static Resource getLiteralType(ReadGraph graph, Datatype type) throws DatabaseException {\r
178                 Layer0 L0 = Layer0.getInstance(graph);\r
179                 if(type instanceof DoubleType) return L0.Double;\r
180                 else if(type instanceof StringType) return L0.String;\r
181                 else if(type instanceof IntegerType) return L0.Integer;\r
182                 else if(type instanceof LongType) return L0.Long;\r
183                 else if(type instanceof FloatType) return L0.Float;\r
184                 else if(type instanceof ByteType) return L0.Byte;\r
185                 else if(type instanceof BooleanType) return L0.Boolean;\r
186                 else if(type instanceof ArrayType) {\r
187                         ArrayType at = (ArrayType)type;\r
188                         if(at.componentType instanceof DoubleType) return L0.DoubleArray;\r
189                         else if(at.componentType instanceof StringType) return L0.StringArray;\r
190                         else if(at.componentType instanceof IntegerType) return L0.IntegerArray;\r
191                         else if(at.componentType instanceof LongType) return L0.LongArray;\r
192                         else if(at.componentType instanceof FloatType) return L0.FloatArray;\r
193                         else if(at.componentType instanceof ByteType) return L0.ByteArray;\r
194                         else if(at.componentType instanceof BooleanType) return L0.BooleanArray;\r
195                         else if(at.componentType instanceof VariantType) return L0.VariantArray;\r
196                 }\r
197                 throw new DatabaseException("Unidentified literal type for datatype " + type);\r
198         }\r
199 \r
200         private static Resource getPossibleLiteralType(ReadGraph graph, String type) throws DatabaseException {\r
201 \r
202                 Layer0 L0 = Layer0.getInstance(graph);\r
203                 if("Double".equals(type)) return L0.Double;\r
204                 else if("String".equals(type)) return L0.String;\r
205                 else if("Integer".equals(type)) return L0.Integer;\r
206                 else if("Long".equals(type)) return L0.Long;\r
207                 else if("Float".equals(type)) return L0.Float;\r
208                 else if("Byte".equals(type)) return L0.Byte;\r
209                 else if("Boolean".equals(type)) return L0.Boolean;\r
210                 else if("[Double]".equals(type)) return L0.DoubleArray;\r
211                 else if("[String]".equals(type)) return L0.StringArray;\r
212                 else if("[Integer]".equals(type)) return L0.IntegerArray;\r
213                 else if("[Long]".equals(type)) return L0.LongArray;\r
214                 else if("[Float]".equals(type)) return L0.FloatArray;\r
215                 else if("[Byte]".equals(type)) return L0.ByteArray;\r
216                 else if("[Boolean]".equals(type)) return L0.BooleanArray;\r
217                 else if("[Variant]".equals(type)) return L0.VariantArray;\r
218                 else if("Array Double".equals(type)) return L0.DoubleArray;\r
219                 else if("Array String".equals(type)) return L0.StringArray;\r
220                 else if("Array Integer".equals(type)) return L0.IntegerArray;\r
221                 else if("Array Long".equals(type)) return L0.LongArray;\r
222                 else if("Array Float".equals(type)) return L0.FloatArray;\r
223                 else if("Array Byte".equals(type)) return L0.ByteArray;\r
224                 else if("Array Boolean".equals(type)) return L0.BooleanArray;\r
225                 else if("Array Variant".equals(type)) return L0.VariantArray;\r
226                 else if("Vector Double".equals(type)) return L0.DoubleArray;\r
227                 else if("Vector String".equals(type)) return L0.StringArray;\r
228                 else if("Vector Integer".equals(type)) return L0.IntegerArray;\r
229                 else if("Vector Long".equals(type)) return L0.LongArray;\r
230                 else if("Vector Float".equals(type)) return L0.FloatArray;\r
231                 else if("Vector Byte".equals(type)) return L0.ByteArray;\r
232                 else if("Vector Boolean".equals(type)) return L0.BooleanArray;\r
233                 else if("Vector Variant".equals(type)) return L0.VariantArray;\r
234                 else if("Datatype".equals(type)) return L0.DataType;\r
235                 else if("Variant".equals(type)) return L0.Variant;\r
236                 else return null;\r
237         }\r
238 \r
239         public static Resource getPossibleLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {\r
240                 Resource predicate = variable.getPossiblePredicateResource(graph);\r
241                 if(predicate == null) return null;\r
242                 return getPossibleLiteralType(graph, predicate);\r
243         }\r
244 \r
245         public static Resource getLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {\r
246                 Resource result = getPossibleLiteralType(graph, variable);\r
247                 if(result == null) throw new DatabaseException("Unidentified literal type for variable " + variable.getURI(graph));\r
248                 return result;\r
249         }\r
250 \r
251         public static Resource getLiteralType(ReadGraph graph, Resource property) throws DatabaseException {\r
252                 Resource result = getPossibleLiteralType(graph, property);\r
253                 if(result == null) throw new DatabaseException("Unidentified literal type for property " + graph.getURI(property));\r
254                 return result;\r
255         }\r
256 \r
257         public static Resource getPossibleLiteralType(ReadGraph graph, Resource property) throws DatabaseException {\r
258 \r
259                 Layer0 L0 = Layer0.getInstance(graph);\r
260                 Layer0X L0X = Layer0X.getInstance(graph);\r
261 \r
262                 Resource defaultLiteralType = graph.getPossibleObject(property, L0.HasDefaultLiteralType);\r
263                 if(defaultLiteralType != null) return defaultLiteralType;\r
264 \r
265                 Resource range = graph.getPossibleObject(property, L0.HasRange);\r
266                 if(range != null && !L0.Value.equals(range)) return range;\r
267 \r
268                 Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);\r
269                 if(requiredDataType != null) return getLiteralType(graph, requiredDataType);\r
270 \r
271                 String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);\r
272                 if(requiredValueType == null) return null;\r
273 \r
274                 return getPossibleLiteralType(graph, requiredValueType);\r
275 \r
276         }\r
277 \r
278         /**\r
279          * @param type any data type definition\r
280          * @return SCL type that matches the specified data type on a basic level.\r
281          *         Data type metadata is/cannot be converted into SCL types.\r
282          * @throws IllegalArgumentException\r
283          *             if the input datatype can't be converted into an SCL type\r
284          */\r
285         public static String getSCLType(Datatype type) throws IllegalArgumentException {\r
286                 return buildSCLType(type, null).toString();\r
287         }\r
288 \r
289         /**\r
290          * Only used internally by {@link #buildSCLType(Datatype, StringBuilder)}\r
291          * @param s\r
292          * @param toBuilder\r
293          * @return\r
294          * @see #buildSCLType(Datatype, StringBuilder)\r
295          */\r
296         private static StringBuilder append(StringBuilder toBuilder, String s) {\r
297                 return toBuilder != null ? toBuilder.append(s) : new StringBuilder(s);\r
298         }\r
299 \r
300         private static CharSequence append(CharSequence to, String s) {\r
301                 if (to instanceof StringBuilder)\r
302                         return ((StringBuilder) to).append(s);\r
303                 return new StringBuilder(to.length() + s.length()).append(to).append(s);\r
304         }\r
305 \r
306         private static CharSequence stringOrBuilder(StringBuilder toBuilder, String s) {\r
307                 return toBuilder != null ? toBuilder.append(s) : s;\r
308         }\r
309 \r
310         /**\r
311          * @param type any data type definition\r
312          * @return SCL type that matches the specified data type on a basic level.\r
313          *         Data type metadata is/cannot be converted into SCL types.\r
314          * @throws IllegalArgumentException\r
315          *             if the input datatype can't be converted into an SCL type\r
316          */\r
317         private static CharSequence buildSCLType(Datatype type, StringBuilder result) throws IllegalArgumentException {\r
318                 if(type instanceof DoubleType) return stringOrBuilder(result, "Double");\r
319                 else if(type instanceof StringType) return stringOrBuilder(result, "String");\r
320                 else if(type instanceof IntegerType) return stringOrBuilder(result, "Integer");\r
321                 else if(type instanceof FloatType) return stringOrBuilder(result, "Float");\r
322                 else if(type instanceof BooleanType) return stringOrBuilder(result, "Boolean");\r
323                 else if(type instanceof ByteType) return stringOrBuilder(result, "Byte");\r
324                 else if(type instanceof LongType) return stringOrBuilder(result, "Long");\r
325                 else if(type instanceof VariantType) return stringOrBuilder(result, "Variant");\r
326                 else if(type instanceof ArrayType) {\r
327                         ArrayType at = (ArrayType) type;\r
328                         // Optimization to prevent allocations in the most basic array cases\r
329                         if(at.componentType instanceof DoubleType) return stringOrBuilder(result, "Vector Double");\r
330                         else if(at.componentType instanceof StringType) return stringOrBuilder(result, "Vector String");\r
331                         else if(at.componentType instanceof IntegerType) return stringOrBuilder(result, "Vector Integer");\r
332                         else if(at.componentType instanceof FloatType) return stringOrBuilder(result, "Vector Float");\r
333                         else if(at.componentType instanceof BooleanType) return stringOrBuilder(result, "Vector Boolean");\r
334                         else if(at.componentType instanceof ByteType) return stringOrBuilder(result, "Vector Byte");\r
335                         else if(at.componentType instanceof LongType) return stringOrBuilder(result, "Vector Long");\r
336                         else if(at.componentType instanceof VariantType) return stringOrBuilder(result, "Vector Variant");\r
337                         else return buildSCLType(at.componentType, append(result, "Vector "));\r
338                 } else if(type instanceof OptionalType) {\r
339                         OptionalType ot = (OptionalType) type;\r
340                         return append(buildSCLType(ot.componentType, append(result, "Maybe (")), ")");\r
341                 } else if (type instanceof RecordType) {\r
342                         throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
343                 } else if (type instanceof MapType) {\r
344                         throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
345                 } else if (type instanceof UnionType) {\r
346                         throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
347                 }\r
348                 throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
349         }\r
350 \r
351 \r
352         public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException {\r
353         try {\r
354                         return Environments.getType(runtimeEnvironment.getEnvironment(), typeText);\r
355                 } catch (SCLExpressionCompilationException e) {\r
356                         throw new DatabaseException(e);\r
357                 }\r
358         }\r
359 \r
360         public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException {\r
361 \r
362                 RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(property.getIndexRoot(graph)));\r
363                 return getSCLType(graph, runtimeEnvironment, getSCLTypeString(graph, property));\r
364 \r
365         }\r
366 \r
367                 \r
368         public static String getSCLTypeString(ReadGraph graph, Variable context) throws DatabaseException {\r
369                 return getSCLTypeString(graph, context.getPossiblePredicateResource(graph), context.getRepresents(graph));\r
370         }\r
371 \r
372 \r
373         public static String getSCLTypeString(ReadGraph graph, Resource predicate, Resource value) throws DatabaseException {\r
374 \r
375                 if(predicate != null) {\r
376                     String requiredValueTypes = graph.getPossibleRelatedValue(predicate, Layer0.getInstance(graph).RequiresValueType, Bindings.STRING);\r
377                     if(requiredValueTypes != null)\r
378                         return requiredValueTypes;\r
379                 }\r
380 \r
381                 Layer0 L0 = Layer0.getInstance(graph);\r
382                 Layer0X L0X = Layer0X.getInstance(graph);\r
383 \r
384                 Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, datatype_binging);\r
385                 if(literalDatatype != null) return getSCLType(literalDatatype);\r
386 \r
387                 String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING);\r
388                 if(literalValueType != null) return literalValueType;\r
389 \r
390                 if(predicate != null) {\r
391 \r
392                         Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, datatype_binging);\r
393                         if(requiredDataType != null) return getSCLType(requiredDataType);\r
394 \r
395                         throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate));\r
396 \r
397                 }\r
398 \r
399                 throw new DatabaseException("Unidentified literal data type");\r
400 \r
401         }\r
402 \r
403         public static Datatype getDatatype(ReadGraph graph, Variable variable) throws DatabaseException {\r
404                 Datatype result = getPossibleDatatype(graph, variable);\r
405                 if(result != null) return result;\r
406                 throw new DatabaseException("Unidentified literal data type for property " + variable.getURI(graph));\r
407         }\r
408 \r
409         public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException {\r
410 \r
411                 Layer0 L0 = Layer0.getInstance(graph);\r
412                 Layer0X L0X = Layer0X.getInstance(graph);\r
413 \r
414                 Resource property = variable.getPossiblePredicateResource(graph);\r
415                 if(property != null) {\r
416 //                      Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);\r
417                         Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue<Datatype>(property, L0X.RequiresDataType, datatype_binging));\r
418                         if(requiredDataType != null) return requiredDataType;\r
419                 }\r
420 \r
421                 Resource literal = variable.getPossibleRepresents(graph);\r
422                 if(literal != null) {\r
423                     Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging);\r
424                     if(literalDatatype != null) return literalDatatype;\r
425                 }\r
426 \r
427                 if(property != null) {\r
428 \r
429                         String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);\r
430                         if(requiredValueType != null) {\r
431                                 Datatype datatype = getPossibleDatatypeForValueType(requiredValueType);\r
432                                 if(datatype != null) return datatype;\r
433                         }\r
434 \r
435                         Resource subject = variable.getParent(graph).getPossibleRepresents(graph);\r
436                         if(subject != null) {\r
437                                 Set<Resource> asses = new HashSet<Resource>();\r
438                                 for(Resource type : graph.getTypes(subject)) {\r
439                                         asses.addAll(graph.getAssertedObjects(type, property));\r
440                                 }\r
441                                 if(asses.size() == 1) {\r
442                                         Resource ass = asses.iterator().next();\r
443                                         Datatype dt = graph.getPossibleRelatedValue(ass, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class));\r
444                                         if(dt != null) return dt;\r
445                                 }\r
446                         }\r
447 \r
448                 }\r
449 \r
450                 return null;\r
451 \r
452         }\r
453 \r
454         private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException {\r
455 \r
456                 String[] split = requiredValueType.split(" ");\r
457                 String arrayType = null;\r
458                 if(split.length == 2 && "Array".equals(split[0])) {\r
459                         arrayType = split[1];\r
460                 } else if(requiredValueType.startsWith("[") && requiredValueType.endsWith("]")) {\r
461                         arrayType = requiredValueType.substring(1, requiredValueType.length()-1);\r
462                 }\r
463 \r
464                 if(arrayType != null) {\r
465                         Datatype arrayDataType = getArrayDataTypeForType(arrayType);\r
466                         if(arrayDataType != null)\r
467                                 return arrayDataType;\r
468                 }\r
469 \r
470                 Datatype dt = Datatypes.getDatatype(requiredValueType);\r
471                 if(dt != null) return dt;\r
472 \r
473                 try {\r
474                         return Datatypes.translate(requiredValueType);\r
475                 } catch (DataTypeSyntaxError e) {\r
476                         return null;\r
477                 }\r
478 \r
479 \r
480         }\r
481 \r
482         private static Datatype getArrayDataTypeForType(String type) {\r
483                 if("Double".equals(type)) return Datatypes.DOUBLE_ARRAY;\r
484                 else if("String".equals(type)) return Datatypes.STRING_ARRAY;\r
485                 else if("Integer".equals(type)) return Datatypes.INTEGER_ARRAY;\r
486                 else if("Long".equals(type)) return Datatypes.LONG_ARRAY;\r
487                 else if("Float".equals(type)) return Datatypes.FLOAT_ARRAY;\r
488                 else if("Byte".equals(type)) return Datatypes.BYTE_ARRAY;\r
489                 else if("Boolean".equals(type)) return Datatypes.BOOLEAN_ARRAY;\r
490                 else if("Variant".equals(type)) return Datatypes.VARIANT_ARRAY;\r
491                 return null;\r
492         }\r
493 \r
494         public static Binding getDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {\r
495 \r
496                 Resource property = variable.getPossiblePredicateResource(graph);\r
497                 if(property != null) {\r
498                         PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());\r
499                         if(info.defaultBinding != null) return info.defaultBinding;\r
500                 }\r
501 \r
502                 Datatype type = getDatatype(graph, variable);\r
503                 if (type == null)\r
504                         throw new DatabaseException("No datatype available for variable " + variable.getURI(graph));\r
505                 return Bindings.getBinding(type);\r
506 \r
507         }\r
508 \r
509         public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {\r
510 \r
511                 Resource property = variable.getPossiblePredicateResource(graph);\r
512                 if(property != null) {\r
513                         PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());\r
514                         if(info.defaultBinding != null) return info.defaultBinding;\r
515                 }\r
516 \r
517                 Datatype type = getPossibleDatatype(graph, variable);\r
518                 if (type == null) return null;\r
519 \r
520                 return Bindings.getBinding(type);\r
521 \r
522         }\r
523 \r
524         public static String getPossibleUnit(Datatype dt) {\r
525                 if (dt == null)\r
526                         return null;\r
527                 else if (dt instanceof NumberType) {\r
528                         return ((NumberType) dt).getUnit();\r
529                 } else if (dt instanceof ArrayType) {\r
530                         ArrayType at = (ArrayType) dt;\r
531                         Datatype cdt = at.componentType();\r
532                         if (cdt instanceof NumberType) {\r
533                                 return ((NumberType) cdt).getUnit();\r
534                         }\r
535                 }\r
536                 return null;\r
537 \r
538         }\r
539 \r
540         public static String getUnit(ReadGraph graph, Variable variable) throws DatabaseException {\r
541 \r
542                 Layer0 L0 = Layer0.getInstance(graph);\r
543                 Layer0X L0X = Layer0X.getInstance(graph);\r
544 \r
545                 Resource literal = variable.getPossibleRepresents(graph);\r
546                 if(literal == null)\r
547                     return "";\r
548 \r
549                 Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging);\r
550                 if(literalDatatype != null) {\r
551                         String unit = getPossibleUnit(literalDatatype);\r
552                         if(unit != null) return unit;\r
553                 }\r
554 \r
555                 Resource property = variable.getPossiblePredicateResource(graph);\r
556                 if(property != null) {\r
557 \r
558                         Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);\r
559                         if(requiredDataType != null) {\r
560                                 String unit = getPossibleUnit(requiredDataType);\r
561                                 if(unit != null) return unit;\r
562                         }\r
563 \r
564                 }\r
565 \r
566                 return "";\r
567 \r
568         }\r
569 \r
570         public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype datatype) throws DatabaseException {\r
571 \r
572                 try {\r
573 \r
574                         Datatype source = binding.type();\r
575                         if(source.equals(datatype)) {\r
576                                 graph.claimValue(objectResource, value, binding);\r
577                         } else {\r
578                                 Binding target = Bindings.getBinding(datatype);\r
579                                 Adapter adapter = Bindings.getAdapter(binding, target);\r
580                                 graph.claimValue(objectResource, adapter.adapt(value), target);\r
581                         }\r
582 \r
583                 } catch (AdapterConstructionException e) {\r
584                         throw new DatabaseException(e);\r
585                 } catch (AdaptException e) {\r
586                         throw new DatabaseException(e);\r
587                 }\r
588 \r
589         }\r
590 \r
591         public static String toString(Object value, Binding binding) throws DatabaseException {\r
592                 try {\r
593                         if(value instanceof String) return (String)value;\r
594                         StringBuilder sb = new StringBuilder();\r
595                         DataValueRepository rep = new DataValueRepository();\r
596                         binding.printValue(value, sb, rep, false);\r
597                         return sb.toString();\r
598                 } catch (BindingException e) {\r
599                         throw new DatabaseException(e);\r
600                 } catch (IOException e) {\r
601                         throw new DatabaseException(e);\r
602                 }\r
603         }\r
604 \r
605         public static Object parseValue(String text, Binding binding) throws DatabaseException {\r
606                 try {\r
607                         if(binding.isInstance(text)) return text;\r
608                         DataValueRepository rep = new DataValueRepository();\r
609                         return binding.parseValue(text, rep);\r
610                 } catch (BindingException e) {\r
611                         throw new DatabaseException(e);\r
612                 } catch (DataTypeSyntaxError e) {\r
613                         throw new DatabaseException(e);\r
614                 }\r
615         }\r
616 \r
617         @SuppressWarnings("unchecked")\r
618         public static <T> T getValueAdaptedToBinding(ReadGraph graph, Resource literal, Binding targetBinding) throws DatabaseException {\r
619                 Datatype sourceDatatype = graph.getDataType(literal);\r
620                 Datatype targetDatatype = targetBinding.type();\r
621                 if (sourceDatatype.equals(targetDatatype))\r
622                         return graph.getValue(literal, targetBinding);\r
623 \r
624                 Binding sourceBinding = Bindings.getBinding(sourceDatatype);\r
625                 try {\r
626                         Adapter adapter = Bindings.adapterFactory.getAdapter(Bindings.getBinding(sourceDatatype), targetBinding, true, false);\r
627                         Object value = graph.getValue(literal, sourceBinding);\r
628                         return (T) adapter.adaptUnchecked(value);\r
629                 } catch (AdapterConstructionException e) {\r
630                         throw new DatabaseException(e);\r
631                 }\r
632         }\r
633 \r
634         public static Statement getStatementInLocal(Resource subject, Statement statement) {\r
635                 if(statement.isAsserted(subject)) return new StandardStatement(subject, statement.getPredicate(), statement.getObject());\r
636                 else return statement;\r
637         }\r
638 \r
639         public static Resource browsePossible(ReadGraph graph, Resource root, String suffix) throws DatabaseException {\r
640                 return graph.getPossibleResource(graph.getURI(root) + suffix);\r
641         }\r
642 \r
643         public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException {\r
644                 return graph.sync(new PossibleChild(resource, name));\r
645         }\r
646 \r
647         public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException {\r
648                 Resource child = graph.sync(new PossibleChild(resource, name));\r
649                 if(child == null) return null;\r
650                 if(!graph.isInstanceOf(child, type)) return null;\r
651                 return child;\r
652         }\r
653 \r
654         public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {\r
655                 Statement stm = graph.getSingleStatement(subject, predicate);\r
656                 return new RelationContextImpl(subject, stm);\r
657         }\r
658 \r
659         public static RelationContext relationContext(Statement stm) throws DatabaseException {\r
660                 return new RelationContextImpl(stm.getSubject(), stm);\r
661         }\r
662 \r
663         public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm) throws DatabaseException {\r
664                 return graph.getValue2(subject, Layer0Utils.relationContext(stm));\r
665         }\r
666 \r
667         public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm, Binding binding) throws DatabaseException {\r
668                 return graph.getValue2(subject, Layer0Utils.relationContext(stm), binding);\r
669         }\r
670 \r
671         public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {\r
672                 Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));\r
673                 return valueInRelationContext(graph, stm.getObject(), stm);\r
674         }\r
675 \r
676         public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation, Binding binding) throws DatabaseException {\r
677                 Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));\r
678                 return valueInRelationContext(graph, stm.getObject(), stm, binding);\r
679         }\r
680 \r
681         public static Statement possibleObtainedStatementInternal(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {\r
682 \r
683                 Layer0X L0X = Layer0X.getInstance(graph);\r
684 \r
685                 for(Resource ob : graph.getObjects(subject, L0X.DefinesObtainedStatement)) {\r
686                         Resource pred = graph.getSingleObject(ob, L0X.ObtainedStatement_predicate);\r
687                         if(graph.isSubrelationOf(pred, relation)) {\r
688                                 Resource object = graph.getSingleObject(ob, L0X.ObtainedStatement_object);\r
689                                 return new StandardStatement(subject, pred, object);\r
690                         }\r
691                 }\r
692 \r
693                 ArrayList<OrderedResource> order = new ArrayList<OrderedResource>();\r
694                 for(Statement stm : graph.getStatements(subject, L0X.ObtainsProperty)) {\r
695                         Integer position = graph.getRelatedValue(stm.getPredicate(), L0X.NaturalNumberOrderRelation, Bindings.INTEGER);\r
696                         order.add(new OrderedResource(position, stm.getObject()));\r
697                 }\r
698 \r
699                 for(OrderedResource or : order) {\r
700                         Statement stm = possibleObtainedStatementInternal(graph, or.r, relation);\r
701                         if(stm != null) return stm;\r
702                 }\r
703 \r
704                 return null;\r
705 \r
706         }\r
707 \r
708         public static <T> T possibleObtainedValue(ReadGraph graph, RelationContext ctx, Binding binding) throws DatabaseException {\r
709 \r
710                 Statement stm = ctx.getStatement();\r
711                 Statement obj = Layer0Utils.possibleObtainedStatementInternal(graph, stm.getSubject(), stm.getPredicate());\r
712 \r
713                 if(obj != null) {\r
714                         return Layer0Utils.valueInRelationContext(graph, obj.getObject(), obj, binding);\r
715                 } else {\r
716                         return null;\r
717                 }\r
718 \r
719         }\r
720 \r
721         public static void addObtainedStatement(WriteGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException {\r
722                 Layer0 L0 = Layer0.getInstance(graph);\r
723                 Layer0X L0X = Layer0X.getInstance(graph);\r
724                 Resource ob = graph.newResource();\r
725                 graph.claim(ob, L0.InstanceOf, null, L0X.ObtainedStatement);\r
726                 graph.claim(ob, L0X.ObtainedStatement_predicate, null, predicate);\r
727                 graph.claim(ob, L0X.ObtainedStatement_object, null, object);\r
728                 graph.claim(subject, L0X.DefinesObtainedStatement, null, ob);\r
729         }\r
730 \r
731         public static void addObtainedValue(WriteGraph graph, Resource subject, Resource predicate, Resource type, Object value, Binding binding) throws DatabaseException {\r
732                 Layer0 L0 = Layer0.getInstance(graph);\r
733                 Resource object = graph.newResource();\r
734                 graph.claim(object, L0.InstanceOf, type);\r
735                 graph.claimValue(object, value, binding);\r
736                 Layer0Utils.addObtainedStatement(graph, subject, predicate, object);\r
737         }\r
738 \r
739         //-------------------------------------------------------------------------\r
740         // Indexing state query utilities idle handling utilities\r
741         //-------------------------------------------------------------------------\r
742 \r
743         /**\r
744          * This method waits until the indexing engine becomes idle.\r
745          * @since 1.8\r
746          */\r
747         public static void waitIndexPending() {\r
748                 Indexing.waitIndexPending();\r
749         }\r
750 \r
751         /**\r
752          * @param graph an active database write handle to prove one is in a write\r
753          *        transaction and wants to disable dependencies indexing for this\r
754          *        transaction only.\r
755          * @return previous value\r
756          * @since 1.8\r
757          */\r
758         public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) {\r
759                 return Indexing.setDependenciesIndexingDisabled(graph, disabled);\r
760         }\r
761 \r
762         public static String undo() throws DatabaseException {\r
763 \r
764             Session session = SimanticsInternal.getSession();\r
765 \r
766         UndoRedoSupport support = session.getService(UndoRedoSupport.class);\r
767 \r
768         List<Operation> ops = support.undoAndReturnOperations(session, 1);\r
769         if(ops.isEmpty())\r
770             return "Undo history is empty.";\r
771 \r
772         Operation mainOperation = ops.get(0);\r
773 \r
774         long csId = mainOperation.getCSId();\r
775 \r
776         ManagementSupport management = session.getService(ManagementSupport.class);\r
777         Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);\r
778 \r
779         return "Undo reverted " + ids.size() + " change sets.";\r
780 \r
781         }\r
782 \r
783         public static String undoOperations(int amountOfOperations) throws DatabaseException {\r
784 \r
785             Session session = SimanticsInternal.getSession();\r
786 \r
787         UndoRedoSupport support = session.getService(UndoRedoSupport.class);\r
788 \r
789         List<Operation> ops = support.undoAndReturnOperations(session, amountOfOperations);\r
790         if(ops.isEmpty())\r
791             return "Undo history is empty.";\r
792 \r
793         Operation mainOperation = ops.get(0);\r
794 \r
795         long csId = mainOperation.getCSId();\r
796 \r
797         ManagementSupport management = session.getService(ManagementSupport.class);\r
798         Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);\r
799 \r
800         return "Undo reverted " + ids.size() + " change sets.";\r
801 \r
802         }\r
803 \r
804         public static String redo() throws DatabaseException {\r
805 \r
806             Session session = SimanticsInternal.getSession();\r
807 \r
808         UndoRedoSupport support = session.getService(UndoRedoSupport.class);\r
809 \r
810         List<Operation> ops = support.redo(session, 1);\r
811         if(ops.isEmpty())\r
812             return "Redo history is empty.";\r
813 \r
814         Operation mainOperation = ops.get(0);\r
815 \r
816         long csId = mainOperation.getCSId();\r
817 \r
818         ManagementSupport management = session.getService(ManagementSupport.class);\r
819         Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);\r
820 \r
821         return "Redo redid " + ids.size() + " change sets.";\r
822 \r
823         }\r
824 \r
825         public static String getComment(Session session, ChangeSetIdentifier id) {\r
826             byte[] data = id.getMetadata().get(CommentMetadata.class.getName());\r
827             if(data == null)\r
828                 return "Undescribed operation.";\r
829             String comment = CommentMetadata.deserialise(session, data).toString().trim();\r
830             if(comment.isEmpty())\r
831                 return "Undescribed operation.";\r
832             return comment;\r
833         }\r
834 \r
835     /**\r
836      * This method adds CommentMetadata for write transaction. CommentMetadata is used e.g. in Undo view.\r
837      * @param graph\r
838      *    graph handle\r
839      * @param string\r
840      *    comment\r
841      * @throws ServiceException\r
842      */\r
843     public static void addCommentMetadata(WriteOnlyGraph graph, String string) throws ServiceException {\r
844         // Add a comment to metadata.\r
845         CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
846         graph.addMetadata(cm.add(ObjectUtils.toString(string)));\r
847     }\r
848 \r
849         //-------------------------------------------------------------------------\r
850 \r
851         /**\r
852          * Copy the specified source resource into the specified container using the\r
853          * specified write transaction handle.\r
854          *\r
855          * @param graph write transaction handle\r
856          * @param targetContainer target container resource of the created copy. The\r
857          *        exact logic of how the copy will be contained by the target\r
858          *        container is up to the PasteHandler to decide\r
859          * @param source the source resource to copy\r
860          * @throws DatabaseException\r
861          * @since 1.8\r
862          */\r
863         public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source) throws DatabaseException {\r
864                 return copyTo(graph, targetContainer, source, null, null, null);\r
865         }\r
866 \r
867         public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler) throws DatabaseException {\r
868                 return copyTo(graph, targetContainer, source, handler, null, null);\r
869         }\r
870 \r
871         public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {\r
872                 if(copyHandler == null) copyHandler = graph.adapt(source, CopyHandler.class);\r
873                 return copyTo(graph, targetContainer, handler, copyHandler, pasteHandler);\r
874         }\r
875 \r
876         public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {\r
877                 SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
878                 copyHandler.copyToClipboard(graph, clipboard);\r
879                 if(targetContainer != null) {\r
880                         if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class);\r
881                         return pasteHandler.pasteFromClipboard(graph, clipboard, handler);\r
882                 } else {\r
883                         DefaultPasteHandler ph = new DefaultPasteHandler(null);\r
884                         return ph.pasteFromClipboard(graph, clipboard, handler);\r
885                 }\r
886         }\r
887 \r
888         public static CopyHandler2 getPossibleCopyHandler(ReadGraph graph, Collection<Resource> rs) throws DatabaseException {\r
889         CopyHandler2 ch = null;\r
890         for(Resource r : rs) {\r
891             if(ch == null) {\r
892                 CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);\r
893                 if(ch2_ instanceof CopyHandler2) {\r
894                     ch = (CopyHandler2)ch2_;\r
895                 }\r
896             } else {\r
897                 CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);\r
898                 if(ch2_ instanceof CopyHandler2) {\r
899                     CopyHandler2 ch2 = (CopyHandler2)ch2_;\r
900                     ch = ch.combine(ch2);\r
901                 }\r
902             }\r
903         }\r
904         return ch;\r
905         }\r
906 \r
907         public static ClusterCollectorPolicy setClusterCollectorPolicy(ClusterCollectorPolicy policy) {\r
908                 Session session = SimanticsInternal.getSession();\r
909                 ClusterControl cc = session.getService(ClusterControl.class);\r
910                 return cc.setPolicy(policy);\r
911         }\r
912 \r
913         private static String decodeType(ReadGraph graph, Variable variable) throws DatabaseException {\r
914                 Datatype dt = getDatatype(graph, variable);\r
915                 return dt.toSingleLineString();\r
916         }\r
917 \r
918         private static boolean isAsserted(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {\r
919                 Statement stm = graph.getPossibleStatement(subject, predicate);\r
920                 return stm != null && stm.isAsserted(subject);\r
921         }\r
922 \r
923         public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException {\r
924                 \r
925                 Resource value = context.getRepresents(graph);\r
926                 Resource predicateResource = context.getPredicateResource(graph);\r
927                 Variable parent = context.getParent(graph);\r
928                 Resource parentResource = parent.getRepresents(graph);\r
929                 setExpression(graph, parentResource, predicateResource, value, text, expressionValueType);\r
930 \r
931         }\r
932 \r
933         public static void setExpression(WriteGraph graph, Resource parentResource, Resource predicateResource, Resource value, String text, Resource expressionValueType) throws DatabaseException {\r
934 \r
935                 Layer0 L0 = Layer0.getInstance(graph);\r
936                 boolean hasExpression = graph.isInstanceOf(value, expressionValueType);\r
937                 String t = getSCLTypeString(graph, predicateResource, value);\r
938                 String expression = text.substring(1).trim();\r
939                 if(isAsserted(graph, parentResource, predicateResource)) {\r
940                         Resource newValue = graph.newResource();\r
941                         graph.claim(newValue, L0.InstanceOf, expressionValueType);\r
942                         graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);\r
943                         graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);\r
944                         graph.claim(parentResource, predicateResource, newValue);\r
945                 } else {\r
946                         if(hasExpression) {\r
947                                 graph.claimLiteral(value, L0.SCLValue_expression, expression, Bindings.STRING);\r
948                         } else {\r
949                                 Resource newValue = graph.newResource();\r
950                                 graph.claim(newValue, L0.InstanceOf, expressionValueType);\r
951                                 graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);\r
952                                 graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);\r
953                                 graph.deny(parentResource, predicateResource);\r
954                                 graph.claim(parentResource, predicateResource, newValue);\r
955                         }\r
956                 }\r
957 \r
958         }\r
959 \r
960         public static void clearExpression(WriteGraph graph, Variable property, Resource expressionValueType) throws DatabaseException {\r
961 \r
962                 Resource object = property.getPossibleRepresents(graph);\r
963                 if(object != null) {\r
964                         boolean hasExpression = graph.isInstanceOf(object, expressionValueType);\r
965                         if(hasExpression) {\r
966                                 // There was an expression and now we go back to a value\r
967                                 Resource subject = property.getParent(graph).getPossibleRepresents(graph);\r
968                                 if(subject != null) {\r
969                                         Resource predicate = property.getPossiblePredicateResource(graph);\r
970                                         if(predicate != null) {\r
971                                                 graph.deny(subject, predicate, object);\r
972                                                 RemoverUtil.remove(graph, object);\r
973                                         }\r
974                                 }\r
975                         }\r
976                 }\r
977 \r
978         }\r
979 \r
980         public static boolean setOrClearExpression(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {\r
981 \r
982                 if(text.startsWith("=")) {\r
983                         setExpression(graph, property, text, expressionValueType);\r
984                         return true;\r
985                 }\r
986 \r
987                 clearExpression(graph, property, expressionValueType);\r
988 \r
989                 return false;\r
990 \r
991         }\r
992 \r
993         public static void setValueAsString(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {\r
994 \r
995                 try {\r
996 \r
997                         if (setOrClearExpression(graph, property, text, expressionValueType))\r
998                                 return;\r
999 \r
1000                         Object value = text;\r
1001                         Datatype type = property.getPossibleDatatype(graph);\r
1002                         if (type != null) {\r
1003 \r
1004                                 Binding binding = Bindings.getBinding(type);\r
1005 \r
1006                                 if (binding instanceof StringBinding) {\r
1007 \r
1008                                         if (binding instanceof MutableStringBinding)\r
1009                                                 value = new MutableString(text);\r
1010                                         else\r
1011                                                 value = text;\r
1012 \r
1013                                 } else {\r
1014 \r
1015                                         if (binding instanceof NumberBinding) {\r
1016                                                 text = text.replace(",", ".");\r
1017                                         }\r
1018 \r
1019                                         value = binding.parseValue(text, new DataValueRepository());\r
1020 \r
1021                                 }\r
1022 \r
1023                                 property.setValue(graph, value, binding);\r
1024 \r
1025                         } else {\r
1026 \r
1027                                 property.setValue(graph, value);\r
1028 \r
1029                         }\r
1030 \r
1031                         // Add a comment to metadata.\r
1032                         CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
1033                         graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value)));\r
1034 \r
1035                 } catch (DataTypeSyntaxError e) {\r
1036                         throw new DatabaseException(e);\r
1037                 } catch (BindingException e) {\r
1038                         throw new DatabaseException(e);\r
1039                 }\r
1040 \r
1041         }\r
1042 \r
1043 \r
1044     public static String queryDebugSupport(String query) {\r
1045         Session session = SimanticsInternal.getSession();\r
1046         DebugSupport ds = session.getService(DebugSupport.class);\r
1047         return ds.query(session, "exec " + query);\r
1048     }\r
1049 \r
1050     public static String queryListSupport (String query) {\r
1051         Session session = SimanticsInternal.getSession();\r
1052         DebugSupport ds = session.getService(DebugSupport.class);\r
1053         return ds.query(session, "list " + query);\r
1054     }\r
1055 \r
1056     final public static Function1<Resource,Resource> resourceCluster = new FunctionImpl1<Resource, Resource>() {\r
1057                 @Override\r
1058                 public Resource apply(Resource p0) {\r
1059                         return p0;\r
1060                 }\r
1061         };\r
1062 \r
1063         public static void sort(ReadGraph graph, List<Resource> collection) {\r
1064         CollectionSupport cos = graph.getService(CollectionSupport.class);\r
1065         cos.sort(collection);\r
1066         }\r
1067 \r
1068         public static List<Resource> sortByCluster(ReadGraph graph, Collection<Resource> collection) {\r
1069         CollectionSupport cos = graph.getService(CollectionSupport.class);\r
1070         return cos.asSortedList(collection);\r
1071         }\r
1072 \r
1073         public static List<Object> sortByCluster(final ReadGraph graph, List<Object> list, final Function1<Object,Resource> fn) {\r
1074         final ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
1075         ArrayList<Object> result = new ArrayList<Object>(list);\r
1076         Collections.sort(result, new Comparator<Object>() {\r
1077 \r
1078                         @Override\r
1079                         public int compare(Object o1, Object o2) {\r
1080                                 Resource r1 = fn.apply(o1);\r
1081                                 Resource r2 = fn.apply(o2);\r
1082                                 long l1 = cs.getCluster(r1);\r
1083                                 long l2 = cs.getCluster(r2);\r
1084                                 if(l1 < l2) return -1;\r
1085                                 else if (l1 > l2) return 1;\r
1086                                 else return 0;\r
1087                         }\r
1088 \r
1089         });\r
1090         return result;\r
1091     }\r
1092 \r
1093     public static <T> List<T> sortByClusterT(final ReadGraph graph, Collection<T> list, final Function1<T,Resource> fn) {\r
1094         final ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
1095         ArrayList<T> result = new ArrayList<T>(list);\r
1096         Collections.sort(result, new Comparator<Object>() {\r
1097 \r
1098             @Override\r
1099             public int compare(Object o1, Object o2) {\r
1100                 Resource r1 = fn.apply((T)o1);\r
1101                 Resource r2 = fn.apply((T)o2);\r
1102                 long l1 = cs.getCluster(r1);\r
1103                 long l2 = cs.getCluster(r2);\r
1104                 if(l1 < l2) return -1;\r
1105                 else if (l1 > l2) return 1;\r
1106                 else return 0;\r
1107             }\r
1108 \r
1109         });\r
1110         return result;\r
1111     }\r
1112 \r
1113     public static void makeSynchronous(ReadGraph graph, boolean value) throws DatabaseException {\r
1114         graph.setSynchronous(value);\r
1115     }\r
1116 \r
1117     public static Set<Resource> listIndexRoots(ReadGraph graph) throws DatabaseException {\r
1118         \r
1119         Layer0 L0 = Layer0.getInstance(graph);\r
1120         \r
1121                 Set<Resource> indexRoots = new TreeSet<Resource>();\r
1122                 indexRoots.addAll(Layer0Utils.listOntologies(graph));\r
1123                 indexRoots.addAll(graph.syncRequest(new ObjectsWithType(SimanticsInternal.getProject(), L0.ConsistsOf, L0.IndexRoot)));\r
1124                 return indexRoots;\r
1125 \r
1126     }\r
1127     \r
1128     public static List<Resource> listOntologies(ReadGraph graph) throws DatabaseException {\r
1129         return graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary()));\r
1130     }\r
1131 \r
1132     public static List<Resource> listGlobalOntologies(ReadGraph graph) throws DatabaseException {\r
1133         return graph.syncRequest(new GlobalOntologies(graph.getRootLibrary()));\r
1134     }\r
1135 \r
1136     public static <T> T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException {\r
1137 \r
1138                 try {\r
1139                         SCL_GRAPH.set(graph);\r
1140                         T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module + "/" + function)).applyArray(args);\r
1141                         SCL_GRAPH.set(null);\r
1142                         return t;\r
1143                 } catch (Throwable t) {\r
1144                         throw new DatabaseException(t);\r
1145                 }\r
1146 \r
1147     }\r
1148 \r
1149     public static boolean isContainerPublished(ReadGraph graph, Variable variable) throws DatabaseException {\r
1150 \r
1151         Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable));\r
1152         if(indexRoot == null) return false;\r
1153         if(variable.equals(indexRoot)) return false;\r
1154         return isPublished(graph, indexRoot);\r
1155 \r
1156     }\r
1157 \r
1158     public static boolean isContainerPublished(ReadGraph graph, Resource resource) throws DatabaseException {\r
1159 \r
1160         Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resource));\r
1161         if(indexRoot == null) return false;\r
1162         if(resource.equals(indexRoot)) return false;\r
1163         return isPublished(graph, indexRoot);\r
1164 \r
1165     }\r
1166 \r
1167     public static boolean isPublished(ReadGraph graph, Resource resource) throws DatabaseException {\r
1168 \r
1169         Layer0 L0 = Layer0.getInstance(graph);\r
1170         Boolean value = graph.getPossibleRelatedValue(resource, L0.Entity_published, Bindings.BOOLEAN);\r
1171         if(value != null && value) return true;\r
1172 \r
1173         // This is safety - root should not be published it child is not\r
1174         Resource root = graph.syncRequest(new PossibleIndexRoot(resource));\r
1175         if(root != null) {\r
1176                 value = graph.getPossibleRelatedValue(root, L0.Entity_published, Bindings.BOOLEAN);\r
1177                 if(value != null && value) return true;\r
1178         }\r
1179 \r
1180         return false;\r
1181 \r
1182     }\r
1183 \r
1184     private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException {\r
1185 \r
1186         SimanticsClipboardImpl cp = new SimanticsClipboardImpl();\r
1187         CopyHandler c1 = graph.adapt(r, CopyHandler.class);\r
1188         c1.copyToClipboard(graph, cp);\r
1189         Collection<Set<Representation>> reps = cp.getContents();\r
1190         if(reps.size() != 1) return null;\r
1191         return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
1192 \r
1193     }\r
1194 \r
1195     private static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException {\r
1196 \r
1197         SimanticsClipboardImpl cp = new SimanticsClipboardImpl();\r
1198         CopyHandler c1 = graph.adapt(r, CopyHandler.class);\r
1199         c1.copyToClipboard(graph, cp);\r
1200         Collection<Set<Representation>> reps = cp.getContents();\r
1201         if(reps.size() != 1) return null;\r
1202         return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE);\r
1203 \r
1204     }\r
1205 \r
1206     /*\r
1207      * Modifies target to resemble source.\r
1208      */\r
1209     public static boolean merge(WriteGraph graph, Resource source, Resource target) throws DatabaseException {\r
1210 \r
1211         TransferableGraphSource tgs1 = makeTGSource(graph, target);\r
1212         TransferableGraph1 tg1 = TransferableGraphs.create(graph, tgs1);\r
1213         TransferableGraph1 tg2 = makeTG(graph, source);\r
1214 \r
1215         GraphRefactoringUtils.fixIncorrectRoot(tg1.identities);\r
1216         GraphRefactoringUtils.fixIncorrectRoot(tg2.identities);\r
1217 \r
1218         ModelTransferableGraphSource mtgs = (ModelTransferableGraphSource)tgs1;\r
1219 \r
1220                 Diff diff = new Diff(tg1, tg2);\r
1221                 TransferableGraphDelta1 delta = diff.diff();\r
1222 \r
1223                 long[] oldResources = mtgs.getResourceArray(graph);\r
1224                 if(TransferableGraphs.hasChanges(graph, oldResources, delta)) {\r
1225                         TransferableGraphs.applyDelta(graph, mtgs.getResourceArray(graph), delta);\r
1226                         return true;\r
1227                 } else {\r
1228                         return false;\r
1229                 }\r
1230 \r
1231     }\r
1232 \r
1233     public static Resource inferLiteralTypeFromString(ReadGraph graph, String text) {\r
1234         return Layer0.getInstance(graph).String;\r
1235     }\r
1236 \r
1237     public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException {\r
1238         emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject());\r
1239     }\r
1240 \r
1241     public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project) throws ServiceException {\r
1242         final SubMonitor mon = SubMonitor.convert(monitor, "Emptying Trash Bin...", 10000);\r
1243         try {\r
1244             session.syncRequest(new DelayedWriteRequest() {\r
1245                 @Override\r
1246                 public void perform(WriteGraph graph) throws DatabaseException {\r
1247                     Layer0Utils.setDependenciesIndexingDisabled(graph, true);\r
1248                     Layer0 L0 = Layer0.getInstance(graph);\r
1249                     Layer0X L0X = Layer0X.getInstance(graph);\r
1250                     Resource parent = graph.getSingleObject(project, L0.PartOf);\r
1251                     Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin");\r
1252                     Collection<Resource> trashes = trashBin != null\r
1253                             ? graph.getObjects(trashBin, L0.ConsistsOf)\r
1254                             : Collections.<Resource>emptyList();\r
1255                     if (trashes.isEmpty())\r
1256                         throw new CancelTransactionException();\r
1257                     mon.setWorkRemaining((2 + trashes.size()) * 1000);\r
1258                     for(Resource trash : trashes) {\r
1259                         if (mon.isCanceled())\r
1260                             throw new CancelTransactionException();\r
1261                         mon.subTask(NameUtils.getSafeName(graph, trash));\r
1262                         TGRemover remo = new TGRemover(mon.newChild(1000, SubMonitor.SUPPRESS_ALL_LABELS), trash);\r
1263                         remo.remove(graph);\r
1264                         if(graph.isInstanceOf(trash, L0.IndexRoot)) {\r
1265                                 // TODO: this should be an utility \r
1266                                         GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);\r
1267                                         IndexedRelations ir = graph.getService(IndexedRelations.class);\r
1268                                         // Deletes index files\r
1269                                         ir.reset(null, graph, L0X.DependenciesRelation, trash);\r
1270                                         // Notifies DB listeners\r
1271                                         index.reset(graph, trash);\r
1272                         }\r
1273                     }\r
1274                     if (mon.isCanceled())\r
1275                         throw new CancelTransactionException();\r
1276                     mon.subTask("Committing Changes");\r
1277                     mon.newChild(1000);\r
1278                 }\r
1279             });\r
1280             if (mon.isCanceled())\r
1281                 return;\r
1282             mon.subTask("Purging Database");\r
1283             mon.newChild(1000);\r
1284             XSupport xs = session.getService(XSupport.class);\r
1285             xs.purge();\r
1286         } catch (CancelTransactionException e) {\r
1287             // Ignore.\r
1288         } catch (DatabaseException e) {\r
1289             throw new ServiceException(e);\r
1290         }\r
1291     }\r
1292     \r
1293     public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException {\r
1294         Resource result = null;\r
1295         for(Resource candidate : getDomainOf(graph, type).values()) {\r
1296                 if(graph.isInstanceOf(candidate, target)) {\r
1297                         if(result != null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));\r
1298                         else result = candidate;\r
1299                 }\r
1300         }\r
1301         if(result == null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));\r
1302         return result;\r
1303     }\r
1304 \r
1305     public static Map<String, Resource> getDomainOf(ReadGraph graph, Resource type) throws DatabaseException {\r
1306         CollectionSupport cs = graph.getService(CollectionSupport.class);\r
1307         Map<String, Resource> result = cs.createObjectResourceMap(String.class);\r
1308         Layer0 L0 = Layer0.getInstance(graph);\r
1309         for(Resource r : graph.getObjects(type, L0.DomainOf)) {\r
1310                 String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);\r
1311                 if(name != null) result.put(name, r);\r
1312         }\r
1313         for(Resource t : graph.getSupertypes(type)) {\r
1314                 for(Resource r : graph.getObjects(t, L0.DomainOf)) {\r
1315                         String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);\r
1316                         if(name != null) result.put(name, r);\r
1317                 }\r
1318         }\r
1319         return result;\r
1320     }\r
1321     \r
1322     public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {\r
1323         for(Resource type : graph.getPrincipalTypes(instance)) {\r
1324                 Map<String, Resource> domainOf = getDomainOf(graph, type);\r
1325                 Resource predicate = domainOf.get(predicateName);\r
1326                 if(predicate != null) return predicate;\r
1327         }\r
1328         return null;\r
1329     }\r
1330     \r
1331     \r
1332     public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException {\r
1333 \r
1334         try {\r
1335                 PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(property));\r
1336                 if(pi.literalRange == null) throw new DatabaseException("No suitable literal type defined as range for property.");\r
1337                 if(pi.defaultBinding == null) throw new DatabaseException("No suitable default binding for property.");\r
1338                         Object value = pi.defaultBinding.parseValue(valueText, new DataValueRepository());\r
1339                         graph.claimLiteral(container, property, pi.literalRange, value, pi.defaultBinding);\r
1340                 } catch (DataTypeSyntaxError e) {\r
1341                         throw new DatabaseException(e);\r
1342                 } catch (BindingException e) {\r
1343                         throw new DatabaseException(e);\r
1344                 }\r
1345         \r
1346     }\r
1347 \r
1348 }\r