X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.db.layer0%2Fsrc%2Forg%2Fsimantics%2Fdb%2Flayer0%2Futil%2FLayer0Utils.java;h=5ccfcf325f49df3f919f6ee54f34b3d0f2033960;hp=c916b36b0ba31967e208a881be95268ad1c17271;hb=3f5adda763f6281e9988277d067c1f71615e3da2;hpb=969bd23cab98a79ca9101af33334000879fb60c5 diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java index c916b36b0..5ccfcf325 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java @@ -1,1348 +1,1404 @@ -/******************************************************************************* - * Copyright (c) 2012 Association for Decentralized Information Management in - * Industry THTH ry. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * VTT Technical Research Centre of Finland - initial API and implementation - *******************************************************************************/ -package org.simantics.db.layer0.util; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.TreeSet; - -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.SubMonitor; -import org.simantics.databoard.Bindings; -import org.simantics.databoard.Datatypes; -import org.simantics.databoard.adapter.AdaptException; -import org.simantics.databoard.adapter.Adapter; -import org.simantics.databoard.adapter.AdapterConstructionException; -import org.simantics.databoard.binding.Binding; -import org.simantics.databoard.binding.NumberBinding; -import org.simantics.databoard.binding.StringBinding; -import org.simantics.databoard.binding.error.BindingException; -import org.simantics.databoard.binding.mutable.MutableStringBinding; -import org.simantics.databoard.parser.repository.DataTypeSyntaxError; -import org.simantics.databoard.parser.repository.DataValueRepository; -import org.simantics.databoard.primitives.MutableString; -import org.simantics.databoard.type.ArrayType; -import org.simantics.databoard.type.BooleanType; -import org.simantics.databoard.type.ByteType; -import org.simantics.databoard.type.Datatype; -import org.simantics.databoard.type.DoubleType; -import org.simantics.databoard.type.FloatType; -import org.simantics.databoard.type.IntegerType; -import org.simantics.databoard.type.LongType; -import org.simantics.databoard.type.MapType; -import org.simantics.databoard.type.NumberType; -import org.simantics.databoard.type.OptionalType; -import org.simantics.databoard.type.RecordType; -import org.simantics.databoard.type.StringType; -import org.simantics.databoard.type.UnionType; -import org.simantics.databoard.type.VariantType; -import org.simantics.databoard.util.ObjectUtils; -import org.simantics.db.ChangeSetIdentifier; -import org.simantics.db.Operation; -import org.simantics.db.ReadGraph; -import org.simantics.db.RelationContext; -import org.simantics.db.Resource; -import org.simantics.db.Session; -import org.simantics.db.Statement; -import org.simantics.db.WriteGraph; -import org.simantics.db.WriteOnlyGraph; -import org.simantics.db.common.CommentMetadata; -import org.simantics.db.common.Indexing; -import org.simantics.db.common.StandardStatement; -import org.simantics.db.common.primitiverequest.PossibleRelatedValue; -import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; -import org.simantics.db.common.request.DelayedWriteRequest; -import org.simantics.db.common.request.ObjectsWithType; -import org.simantics.db.common.request.PossibleChild; -import org.simantics.db.common.request.PossibleIndexRoot; -import org.simantics.db.common.utils.NameUtils; -import org.simantics.db.exception.CancelTransactionException; -import org.simantics.db.exception.DatabaseException; -import org.simantics.db.exception.ServiceException; -import org.simantics.db.layer0.adapter.CopyHandler; -import org.simantics.db.layer0.adapter.CopyHandler2; -import org.simantics.db.layer0.adapter.GenericRelationIndex; -import org.simantics.db.layer0.adapter.PasteHandler; -import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler; -import org.simantics.db.layer0.adapter.impl.TGRemover; -import org.simantics.db.layer0.genericrelation.IndexedRelations; -import org.simantics.db.layer0.internal.SimanticsInternal; -import org.simantics.db.layer0.migration.OntologiesFromLibrary; -import org.simantics.db.layer0.property.OrderedResource; -import org.simantics.db.layer0.request.GlobalOntologies; -import org.simantics.db.layer0.request.PossibleVariableIndexRoot; -import org.simantics.db.layer0.request.PropertyInfo; -import org.simantics.db.layer0.request.PropertyInfoRequest; -import org.simantics.db.layer0.util.SimanticsClipboard.Representation; -import org.simantics.db.layer0.variable.StandardGraphPropertyVariable; -import org.simantics.db.layer0.variable.Variable; -import org.simantics.db.service.ClusterCollectorPolicy; -import org.simantics.db.service.ClusterControl; -import org.simantics.db.service.ClusteringSupport; -import org.simantics.db.service.CollectionSupport; -import org.simantics.db.service.DebugSupport; -import org.simantics.db.service.ManagementSupport; -import org.simantics.db.service.UndoRedoSupport; -import org.simantics.db.service.XSupport; -import org.simantics.graph.db.TransferableGraphSource; -import org.simantics.graph.db.TransferableGraphs; -import org.simantics.graph.diff.Diff; -import org.simantics.graph.diff.TransferableGraphDelta1; -import org.simantics.graph.refactoring.GraphRefactoringUtils; -import org.simantics.graph.representation.TransferableGraph1; -import org.simantics.layer0.Layer0; -import org.simantics.operation.Layer0X; -import org.simantics.scl.compiler.environment.Environments; -import org.simantics.scl.compiler.runtime.RuntimeEnvironment; -import org.simantics.scl.compiler.top.SCLExpressionCompilationException; -import org.simantics.scl.compiler.types.Type; -import org.simantics.scl.osgi.SCLOsgi; -import org.simantics.scl.runtime.function.Function; -import org.simantics.scl.runtime.function.Function1; -import org.simantics.scl.runtime.function.FunctionImpl1; - -public class Layer0Utils { - - @SuppressWarnings("rawtypes") - public static final ThreadLocal SCL_GRAPH = new ThreadLocal(); - - final public static Binding datatype_binging = Bindings.getBindingUnchecked(Datatype.class); - - public static Resource literal(WriteGraph g, String value) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(g); - Resource r = g.newResource(); - g.claimValue(r, value, Bindings.STRING); - g.claim(r, L0.InstanceOf, L0.String); - return r; - } - - public static Resource literal(WriteGraph g, double value) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(g); - Resource r = g.newResource(); - g.claimValue(r, value, Bindings.DOUBLE); - g.claim(r, L0.InstanceOf, L0.Double); - return r; - } - - public static Resource literal(WriteGraph g, int value) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(g); - Resource r = g.newResource(); - g.claimValue(r, value, Bindings.INTEGER); - g.claim(r, L0.InstanceOf, L0.Integer); - return r; - } - - public static void assert_(WriteGraph g, Resource type, Resource predicate, Resource object) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(g); - Resource assertion = g.newResource(); - g.claim(type, L0.Asserts, assertion); - g.claim(assertion, L0.InstanceOf, L0.Assertion); - g.claim(assertion, L0.HasPredicate, predicate); - g.claim(assertion, L0.HasObject, object); - } - - public static Resource relation(WriteGraph g, Resource parent, String name, Resource superrelation) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(g); - Resource relation = g.newResource(); - g.claim(relation, L0.SubrelationOf, superrelation); - g.claim(relation, L0.HasName, literal(g, name)); - g.claim(parent, L0.ConsistsOf, relation); - - Resource superrelationInverse = g.getInverse(superrelation); - if(superrelationInverse != null) { - Resource inverse = g.newResource(); - g.claim(inverse, L0.SubrelationOf, superrelationInverse); - g.claim(relation, L0.ConsistsOf, inverse); - g.claim(inverse, L0.HasName, literal(g, "Inverse")); - } - return relation; - } - - private static Resource getLiteralType(ReadGraph graph, Datatype type) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - if(type instanceof DoubleType) return L0.Double; - else if(type instanceof StringType) return L0.String; - else if(type instanceof IntegerType) return L0.Integer; - else if(type instanceof LongType) return L0.Long; - else if(type instanceof FloatType) return L0.Float; - else if(type instanceof ByteType) return L0.Byte; - else if(type instanceof BooleanType) return L0.Boolean; - else if(type instanceof ArrayType) { - ArrayType at = (ArrayType)type; - if(at.componentType instanceof DoubleType) return L0.DoubleArray; - else if(at.componentType instanceof StringType) return L0.StringArray; - else if(at.componentType instanceof IntegerType) return L0.IntegerArray; - else if(at.componentType instanceof LongType) return L0.LongArray; - else if(at.componentType instanceof FloatType) return L0.FloatArray; - else if(at.componentType instanceof ByteType) return L0.ByteArray; - else if(at.componentType instanceof BooleanType) return L0.BooleanArray; - else if(at.componentType instanceof VariantType) return L0.VariantArray; - } - throw new DatabaseException("Unidentified literal type for datatype " + type); - } - - private static Resource getPossibleLiteralType(ReadGraph graph, String type) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - if("Double".equals(type)) return L0.Double; - else if("String".equals(type)) return L0.String; - else if("Integer".equals(type)) return L0.Integer; - else if("Long".equals(type)) return L0.Long; - else if("Float".equals(type)) return L0.Float; - else if("Byte".equals(type)) return L0.Byte; - else if("Boolean".equals(type)) return L0.Boolean; - else if("[Double]".equals(type)) return L0.DoubleArray; - else if("[String]".equals(type)) return L0.StringArray; - else if("[Integer]".equals(type)) return L0.IntegerArray; - else if("[Long]".equals(type)) return L0.LongArray; - else if("[Float]".equals(type)) return L0.FloatArray; - else if("[Byte]".equals(type)) return L0.ByteArray; - else if("[Boolean]".equals(type)) return L0.BooleanArray; - else if("[Variant]".equals(type)) return L0.VariantArray; - else if("Array Double".equals(type)) return L0.DoubleArray; - else if("Array String".equals(type)) return L0.StringArray; - else if("Array Integer".equals(type)) return L0.IntegerArray; - else if("Array Long".equals(type)) return L0.LongArray; - else if("Array Float".equals(type)) return L0.FloatArray; - else if("Array Byte".equals(type)) return L0.ByteArray; - else if("Array Boolean".equals(type)) return L0.BooleanArray; - else if("Array Variant".equals(type)) return L0.VariantArray; - else if("Vector Double".equals(type)) return L0.DoubleArray; - else if("Vector String".equals(type)) return L0.StringArray; - else if("Vector Integer".equals(type)) return L0.IntegerArray; - else if("Vector Long".equals(type)) return L0.LongArray; - else if("Vector Float".equals(type)) return L0.FloatArray; - else if("Vector Byte".equals(type)) return L0.ByteArray; - else if("Vector Boolean".equals(type)) return L0.BooleanArray; - else if("Vector Variant".equals(type)) return L0.VariantArray; - else if("Datatype".equals(type)) return L0.DataType; - else if("Variant".equals(type)) return L0.Variant; - else return null; - } - - public static Resource getPossibleLiteralType(ReadGraph graph, Variable variable) throws DatabaseException { - Resource predicate = variable.getPossiblePredicateResource(graph); - if(predicate == null) return null; - return getPossibleLiteralType(graph, predicate); - } - - public static Resource getLiteralType(ReadGraph graph, Variable variable) throws DatabaseException { - Resource result = getPossibleLiteralType(graph, variable); - if(result == null) throw new DatabaseException("Unidentified literal type for variable " + variable.getURI(graph)); - return result; - } - - public static Resource getLiteralType(ReadGraph graph, Resource property) throws DatabaseException { - Resource result = getPossibleLiteralType(graph, property); - if(result == null) throw new DatabaseException("Unidentified literal type for property " + graph.getURI(property)); - return result; - } - - public static Resource getPossibleLiteralType(ReadGraph graph, Resource property) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - - Resource defaultLiteralType = graph.getPossibleObject(property, L0.HasDefaultLiteralType); - if(defaultLiteralType != null) return defaultLiteralType; - - Resource range = graph.getPossibleObject(property, L0.HasRange); - if(range != null && !L0.Value.equals(range)) return range; - - Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); - if(requiredDataType != null) return getLiteralType(graph, requiredDataType); - - String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); - if(requiredValueType == null) return null; - - return getPossibleLiteralType(graph, requiredValueType); - - } - - /** - * @param type any data type definition - * @return SCL type that matches the specified data type on a basic level. - * Data type metadata is/cannot be converted into SCL types. - * @throws IllegalArgumentException - * if the input datatype can't be converted into an SCL type - */ - public static String getSCLType(Datatype type) throws IllegalArgumentException { - return buildSCLType(type, null).toString(); - } - - /** - * Only used internally by {@link #buildSCLType(Datatype, StringBuilder)} - * @param s - * @param toBuilder - * @return - * @see #buildSCLType(Datatype, StringBuilder) - */ - private static StringBuilder append(StringBuilder toBuilder, String s) { - return toBuilder != null ? toBuilder.append(s) : new StringBuilder(s); - } - - private static CharSequence append(CharSequence to, String s) { - if (to instanceof StringBuilder) - return ((StringBuilder) to).append(s); - return new StringBuilder(to.length() + s.length()).append(to).append(s); - } - - private static CharSequence stringOrBuilder(StringBuilder toBuilder, String s) { - return toBuilder != null ? toBuilder.append(s) : s; - } - - /** - * @param type any data type definition - * @return SCL type that matches the specified data type on a basic level. - * Data type metadata is/cannot be converted into SCL types. - * @throws IllegalArgumentException - * if the input datatype can't be converted into an SCL type - */ - private static CharSequence buildSCLType(Datatype type, StringBuilder result) throws IllegalArgumentException { - if(type instanceof DoubleType) return stringOrBuilder(result, "Double"); - else if(type instanceof StringType) return stringOrBuilder(result, "String"); - else if(type instanceof IntegerType) return stringOrBuilder(result, "Integer"); - else if(type instanceof FloatType) return stringOrBuilder(result, "Float"); - else if(type instanceof BooleanType) return stringOrBuilder(result, "Boolean"); - else if(type instanceof ByteType) return stringOrBuilder(result, "Byte"); - else if(type instanceof LongType) return stringOrBuilder(result, "Long"); - else if(type instanceof VariantType) return stringOrBuilder(result, "Variant"); - else if(type instanceof ArrayType) { - ArrayType at = (ArrayType) type; - // Optimization to prevent allocations in the most basic array cases - if(at.componentType instanceof DoubleType) return stringOrBuilder(result, "Vector Double"); - else if(at.componentType instanceof StringType) return stringOrBuilder(result, "Vector String"); - else if(at.componentType instanceof IntegerType) return stringOrBuilder(result, "Vector Integer"); - else if(at.componentType instanceof FloatType) return stringOrBuilder(result, "Vector Float"); - else if(at.componentType instanceof BooleanType) return stringOrBuilder(result, "Vector Boolean"); - else if(at.componentType instanceof ByteType) return stringOrBuilder(result, "Vector Byte"); - else if(at.componentType instanceof LongType) return stringOrBuilder(result, "Vector Long"); - else if(at.componentType instanceof VariantType) return stringOrBuilder(result, "Vector Variant"); - else return buildSCLType(at.componentType, append(result, "Vector ")); - } else if(type instanceof OptionalType) { - OptionalType ot = (OptionalType) type; - return append(buildSCLType(ot.componentType, append(result, "Maybe (")), ")"); - } else if (type instanceof RecordType) { - throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); - } else if (type instanceof MapType) { - throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); - } else if (type instanceof UnionType) { - throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); - } - throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); - } - - - public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException { - try { - return Environments.getType(runtimeEnvironment.getEnvironment(), typeText); - } catch (SCLExpressionCompilationException e) { - throw new DatabaseException(e); - } - } - - public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException { - - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(property.getIndexRoot(graph))); - return getSCLType(graph, runtimeEnvironment, getSCLTypeString(graph, property)); - - } - - - public static String getSCLTypeString(ReadGraph graph, Variable context) throws DatabaseException { - return getSCLTypeString(graph, context.getPossiblePredicateResource(graph), context.getRepresents(graph)); - } - - - public static String getSCLTypeString(ReadGraph graph, Resource predicate, Resource value) throws DatabaseException { - - if(predicate != null) { - String requiredValueTypes = graph.getPossibleRelatedValue(predicate, Layer0.getInstance(graph).RequiresValueType, Bindings.STRING); - if(requiredValueTypes != null) - return requiredValueTypes; - } - - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - - Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, datatype_binging); - if(literalDatatype != null) return getSCLType(literalDatatype); - - String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING); - if(literalValueType != null) return literalValueType; - - if(predicate != null) { - - Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, datatype_binging); - if(requiredDataType != null) return getSCLType(requiredDataType); - - throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate)); - - } - - throw new DatabaseException("Unidentified literal data type"); - - } - - public static Datatype getDatatype(ReadGraph graph, Variable variable) throws DatabaseException { - Datatype result = getPossibleDatatype(graph, variable); - if(result != null) return result; - throw new DatabaseException("Unidentified literal data type for property " + variable.getURI(graph)); - } - - public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - - Resource property = variable.getPossiblePredicateResource(graph); - if(property != null) { -// Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); - Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging)); - if(requiredDataType != null) return requiredDataType; - } - - Resource literal = variable.getPossibleRepresents(graph); - if(literal != null) { - Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging); - if(literalDatatype != null) return literalDatatype; - } - - if(property != null) { - - String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); - if(requiredValueType != null) { - Datatype datatype = getPossibleDatatypeForValueType(requiredValueType); - if(datatype != null) return datatype; - } - - Resource subject = variable.getParent(graph).getPossibleRepresents(graph); - if(subject != null) { - Set asses = new HashSet(); - for(Resource type : graph.getTypes(subject)) { - asses.addAll(graph.getAssertedObjects(type, property)); - } - if(asses.size() == 1) { - Resource ass = asses.iterator().next(); - Datatype dt = graph.getPossibleRelatedValue(ass, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class)); - if(dt != null) return dt; - } - } - - } - - return null; - - } - - private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException { - - String[] split = requiredValueType.split(" "); - String arrayType = null; - if(split.length == 2 && "Array".equals(split[0])) { - arrayType = split[1]; - } else if(requiredValueType.startsWith("[") && requiredValueType.endsWith("]")) { - arrayType = requiredValueType.substring(1, requiredValueType.length()-1); - } - - if(arrayType != null) { - Datatype arrayDataType = getArrayDataTypeForType(arrayType); - if(arrayDataType != null) - return arrayDataType; - } - - Datatype dt = Datatypes.getDatatype(requiredValueType); - if(dt != null) return dt; - - try { - return Datatypes.translate(requiredValueType); - } catch (DataTypeSyntaxError e) { - return null; - } - - - } - - private static Datatype getArrayDataTypeForType(String type) { - if("Double".equals(type)) return Datatypes.DOUBLE_ARRAY; - else if("String".equals(type)) return Datatypes.STRING_ARRAY; - else if("Integer".equals(type)) return Datatypes.INTEGER_ARRAY; - else if("Long".equals(type)) return Datatypes.LONG_ARRAY; - else if("Float".equals(type)) return Datatypes.FLOAT_ARRAY; - else if("Byte".equals(type)) return Datatypes.BYTE_ARRAY; - else if("Boolean".equals(type)) return Datatypes.BOOLEAN_ARRAY; - else if("Variant".equals(type)) return Datatypes.VARIANT_ARRAY; - return null; - } - - public static Binding getDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException { - - Resource property = variable.getPossiblePredicateResource(graph); - if(property != null) { - PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.instance()); - if(info.defaultBinding != null) return info.defaultBinding; - } - - Datatype type = getDatatype(graph, variable); - if (type == null) - throw new DatabaseException("No datatype available for variable " + variable.getURI(graph)); - return Bindings.getBinding(type); - - } - - public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException { - - Resource property = variable.getPossiblePredicateResource(graph); - if(property != null) { - PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.instance()); - if(info.defaultBinding != null) return info.defaultBinding; - } - - Datatype type = getPossibleDatatype(graph, variable); - if (type == null) return null; - - return Bindings.getBinding(type); - - } - - public static String getPossibleUnit(Datatype dt) { - if (dt == null) - return null; - else if (dt instanceof NumberType) { - return ((NumberType) dt).getUnit(); - } else if (dt instanceof ArrayType) { - ArrayType at = (ArrayType) dt; - Datatype cdt = at.componentType(); - if (cdt instanceof NumberType) { - return ((NumberType) cdt).getUnit(); - } - } - return null; - - } - - public static String getUnit(ReadGraph graph, Variable variable) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - - Resource literal = variable.getPossibleRepresents(graph); - if(literal == null) - return ""; - - Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging); - if(literalDatatype != null) { - String unit = getPossibleUnit(literalDatatype); - if(unit != null) return unit; - } - - Resource property = variable.getPossiblePredicateResource(graph); - if(property != null) { - - Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); - if(requiredDataType != null) { - String unit = getPossibleUnit(requiredDataType); - if(unit != null) return unit; - } - - } - - return ""; - - } - - public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype datatype) throws DatabaseException { - - try { - - Datatype source = binding.type(); - if(source.equals(datatype)) { - graph.claimValue(objectResource, value, binding); - } else { - Binding target = Bindings.getBinding(datatype); - Adapter adapter = Bindings.getAdapter(binding, target); - graph.claimValue(objectResource, adapter.adapt(value), target); - } - - } catch (AdapterConstructionException e) { - throw new DatabaseException(e); - } catch (AdaptException e) { - throw new DatabaseException(e); - } - - } - - public static String toString(Object value, Binding binding) throws DatabaseException { - try { - if(value instanceof String) return (String)value; - StringBuilder sb = new StringBuilder(); - DataValueRepository rep = new DataValueRepository(); - binding.printValue(value, sb, rep, false); - return sb.toString(); - } catch (BindingException e) { - throw new DatabaseException(e); - } catch (IOException e) { - throw new DatabaseException(e); - } - } - - public static Object parseValue(String text, Binding binding) throws DatabaseException { - try { - if(binding.isInstance(text)) return text; - DataValueRepository rep = new DataValueRepository(); - return binding.parseValue(text, rep); - } catch (BindingException e) { - throw new DatabaseException(e); - } catch (DataTypeSyntaxError e) { - throw new DatabaseException(e); - } - } - - @SuppressWarnings("unchecked") - public static T getValueAdaptedToBinding(ReadGraph graph, Resource literal, Binding targetBinding) throws DatabaseException { - Datatype sourceDatatype = graph.getDataType(literal); - Datatype targetDatatype = targetBinding.type(); - if (sourceDatatype.equals(targetDatatype)) - return graph.getValue(literal, targetBinding); - - Binding sourceBinding = Bindings.getBinding(sourceDatatype); - try { - Adapter adapter = Bindings.adapterFactory.getAdapter(Bindings.getBinding(sourceDatatype), targetBinding, true, false); - Object value = graph.getValue(literal, sourceBinding); - return (T) adapter.adaptUnchecked(value); - } catch (AdapterConstructionException e) { - throw new DatabaseException(e); - } - } - - public static Statement getStatementInLocal(Resource subject, Statement statement) { - if(statement.isAsserted(subject)) return new StandardStatement(subject, statement.getPredicate(), statement.getObject()); - else return statement; - } - - public static Resource browsePossible(ReadGraph graph, Resource root, String suffix) throws DatabaseException { - return graph.getPossibleResource(graph.getURI(root) + suffix); - } - - public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException { - return graph.sync(new PossibleChild(resource, name)); - } - - public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException { - Resource child = graph.sync(new PossibleChild(resource, name)); - if(child == null) return null; - if(!graph.isInstanceOf(child, type)) return null; - return child; - } - - public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException { - Statement stm = graph.getSingleStatement(subject, predicate); - return new RelationContextImpl(subject, stm); - } - - public static RelationContext relationContext(Statement stm) throws DatabaseException { - return new RelationContextImpl(stm.getSubject(), stm); - } - - public static T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm) throws DatabaseException { - return graph.getValue2(subject, Layer0Utils.relationContext(stm)); - } - - public static T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm, Binding binding) throws DatabaseException { - return graph.getValue2(subject, Layer0Utils.relationContext(stm), binding); - } - - public static T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException { - Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation)); - return valueInRelationContext(graph, stm.getObject(), stm); - } - - public static T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation, Binding binding) throws DatabaseException { - Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation)); - return valueInRelationContext(graph, stm.getObject(), stm, binding); - } - - public static Statement possibleObtainedStatementInternal(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException { - - Layer0X L0X = Layer0X.getInstance(graph); - - for(Resource ob : graph.getObjects(subject, L0X.DefinesObtainedStatement)) { - Resource pred = graph.getSingleObject(ob, L0X.ObtainedStatement_predicate); - if(graph.isSubrelationOf(pred, relation)) { - Resource object = graph.getSingleObject(ob, L0X.ObtainedStatement_object); - return new StandardStatement(subject, pred, object); - } - } - - ArrayList order = new ArrayList(); - for(Statement stm : graph.getStatements(subject, L0X.ObtainsProperty)) { - Integer position = graph.getRelatedValue(stm.getPredicate(), L0X.NaturalNumberOrderRelation, Bindings.INTEGER); - order.add(new OrderedResource(position, stm.getObject())); - } - - for(OrderedResource or : order) { - Statement stm = possibleObtainedStatementInternal(graph, or.r, relation); - if(stm != null) return stm; - } - - return null; - - } - - public static T possibleObtainedValue(ReadGraph graph, RelationContext ctx, Binding binding) throws DatabaseException { - - Statement stm = ctx.getStatement(); - Statement obj = Layer0Utils.possibleObtainedStatementInternal(graph, stm.getSubject(), stm.getPredicate()); - - if(obj != null) { - return Layer0Utils.valueInRelationContext(graph, obj.getObject(), obj, binding); - } else { - return null; - } - - } - - public static void addObtainedStatement(WriteGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - Resource ob = graph.newResource(); - graph.claim(ob, L0.InstanceOf, null, L0X.ObtainedStatement); - graph.claim(ob, L0X.ObtainedStatement_predicate, null, predicate); - graph.claim(ob, L0X.ObtainedStatement_object, null, object); - graph.claim(subject, L0X.DefinesObtainedStatement, null, ob); - } - - public static void addObtainedValue(WriteGraph graph, Resource subject, Resource predicate, Resource type, Object value, Binding binding) throws DatabaseException { - Layer0 L0 = Layer0.getInstance(graph); - Resource object = graph.newResource(); - graph.claim(object, L0.InstanceOf, type); - graph.claimValue(object, value, binding); - Layer0Utils.addObtainedStatement(graph, subject, predicate, object); - } - - //------------------------------------------------------------------------- - // Indexing state query utilities idle handling utilities - //------------------------------------------------------------------------- - - /** - * This method waits until the indexing engine becomes idle. - * @since 1.8 - */ - public static void waitIndexPending() { - Indexing.waitIndexPending(); - } - - /** - * @param graph an active database write handle to prove one is in a write - * transaction and wants to disable dependencies indexing for this - * transaction only. - * @return previous value - * @since 1.8 - */ - public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) { - return Indexing.setDependenciesIndexingDisabled(graph, disabled); - } - - public static String undo() throws DatabaseException { - - Session session = SimanticsInternal.getSession(); - - UndoRedoSupport support = session.getService(UndoRedoSupport.class); - - List ops = support.undoAndReturnOperations(session, 1); - if(ops.isEmpty()) - return "Undo history is empty."; - - Operation mainOperation = ops.get(0); - - long csId = mainOperation.getCSId(); - - ManagementSupport management = session.getService(ManagementSupport.class); - Collection ids = management.getChangeSetIdentifiers(csId, csId); - - return "Undo reverted " + ids.size() + " change sets."; - - } - - public static String undoOperations(int amountOfOperations) throws DatabaseException { - - Session session = SimanticsInternal.getSession(); - - UndoRedoSupport support = session.getService(UndoRedoSupport.class); - - List ops = support.undoAndReturnOperations(session, amountOfOperations); - if(ops.isEmpty()) - return "Undo history is empty."; - - Operation mainOperation = ops.get(0); - - long csId = mainOperation.getCSId(); - - ManagementSupport management = session.getService(ManagementSupport.class); - Collection ids = management.getChangeSetIdentifiers(csId, csId); - - return "Undo reverted " + ids.size() + " change sets."; - - } - - public static String redo() throws DatabaseException { - - Session session = SimanticsInternal.getSession(); - - UndoRedoSupport support = session.getService(UndoRedoSupport.class); - - List ops = support.redo(session, 1); - if(ops.isEmpty()) - return "Redo history is empty."; - - Operation mainOperation = ops.get(0); - - long csId = mainOperation.getCSId(); - - ManagementSupport management = session.getService(ManagementSupport.class); - Collection ids = management.getChangeSetIdentifiers(csId, csId); - - return "Redo redid " + ids.size() + " change sets."; - - } - - public static String getComment(Session session, ChangeSetIdentifier id) { - byte[] data = id.getMetadata().get(CommentMetadata.class.getName()); - if(data == null) - return "Undescribed operation."; - String comment = CommentMetadata.deserialise(session, data).toString().trim(); - if(comment.isEmpty()) - return "Undescribed operation."; - return comment; - } - - /** - * This method adds CommentMetadata for write transaction. CommentMetadata is used e.g. in Undo view. - * @param graph - * graph handle - * @param string - * comment - * @throws ServiceException - */ - public static void addCommentMetadata(WriteOnlyGraph graph, String string) throws ServiceException { - // Add a comment to metadata. - CommentMetadata cm = graph.getMetadata(CommentMetadata.class); - graph.addMetadata(cm.add(ObjectUtils.toString(string))); - } - - //------------------------------------------------------------------------- - - /** - * Copy the specified source resource into the specified container using the - * specified write transaction handle. - * - * @param graph write transaction handle - * @param targetContainer target container resource of the created copy. The - * exact logic of how the copy will be contained by the target - * container is up to the PasteHandler to decide - * @param source the source resource to copy - * @throws DatabaseException - * @since 1.8 - */ - public static Collection copyTo(WriteGraph graph, Resource targetContainer, Resource source) throws DatabaseException { - return copyTo(graph, targetContainer, source, null, null, null); - } - - public static Collection copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler) throws DatabaseException { - return copyTo(graph, targetContainer, source, handler, null, null); - } - - public static Collection copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException { - if(copyHandler == null) copyHandler = graph.adapt(source, CopyHandler.class); - return copyTo(graph, targetContainer, handler, copyHandler, pasteHandler); - } - - public static Collection copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException { - SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl(); - copyHandler.copyToClipboard(graph, clipboard); - if(targetContainer != null) { - if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class); - return pasteHandler.pasteFromClipboard(graph, clipboard, handler); - } else { - DefaultPasteHandler ph = new DefaultPasteHandler(null); - return ph.pasteFromClipboard(graph, clipboard, handler); - } - } - - public static CopyHandler2 getPossibleCopyHandler(ReadGraph graph, Collection rs) throws DatabaseException { - CopyHandler2 ch = null; - for(Resource r : rs) { - if(ch == null) { - CopyHandler ch2_ = graph.adapt(r, CopyHandler.class); - if(ch2_ instanceof CopyHandler2) { - ch = (CopyHandler2)ch2_; - } - } else { - CopyHandler ch2_ = graph.adapt(r, CopyHandler.class); - if(ch2_ instanceof CopyHandler2) { - CopyHandler2 ch2 = (CopyHandler2)ch2_; - ch = ch.combine(ch2); - } - } - } - return ch; - } - - public static ClusterCollectorPolicy setClusterCollectorPolicy(ClusterCollectorPolicy policy) { - Session session = SimanticsInternal.getSession(); - ClusterControl cc = session.getService(ClusterControl.class); - return cc.setPolicy(policy); - } - - private static String decodeType(ReadGraph graph, Variable variable) throws DatabaseException { - Datatype dt = getDatatype(graph, variable); - return dt.toSingleLineString(); - } - - private static boolean isAsserted(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException { - Statement stm = graph.getPossibleStatement(subject, predicate); - return stm != null && stm.isAsserted(subject); - } - - public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException { - - Resource value = context.getRepresents(graph); - Resource predicateResource = context.getPredicateResource(graph); - Variable parent = context.getParent(graph); - Resource parentResource = parent.getRepresents(graph); - setExpression(graph, parentResource, predicateResource, value, text, expressionValueType); - - } - - public static void setExpression(WriteGraph graph, Resource parentResource, Resource predicateResource, Resource value, String text, Resource expressionValueType) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - boolean hasExpression = graph.isInstanceOf(value, expressionValueType); - String t = getSCLTypeString(graph, predicateResource, value); - String expression = text.substring(1).trim(); - if(isAsserted(graph, parentResource, predicateResource)) { - Resource newValue = graph.newResource(); - graph.claim(newValue, L0.InstanceOf, expressionValueType); - graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING); - graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING); - graph.claim(parentResource, predicateResource, newValue); - } else { - if(hasExpression) { - graph.claimLiteral(value, L0.SCLValue_expression, expression, Bindings.STRING); - } else { - Resource newValue = graph.newResource(); - graph.claim(newValue, L0.InstanceOf, expressionValueType); - graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING); - graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING); - graph.deny(parentResource, predicateResource); - graph.claim(parentResource, predicateResource, newValue); - } - } - - } - - public static void clearExpression(WriteGraph graph, Variable property, Resource expressionValueType) throws DatabaseException { - - Resource object = property.getPossibleRepresents(graph); - if(object != null) { - boolean hasExpression = graph.isInstanceOf(object, expressionValueType); - if(hasExpression) { - // There was an expression and now we go back to a value - Resource subject = property.getParent(graph).getPossibleRepresents(graph); - if(subject != null) { - Resource predicate = property.getPossiblePredicateResource(graph); - if(predicate != null) { - graph.deny(subject, predicate, object); - RemoverUtil.remove(graph, object); - } - } - } - } - - } - - public static boolean setOrClearExpression(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException { - - if(text.startsWith("=")) { - setExpression(graph, property, text, expressionValueType); - return true; - } - - clearExpression(graph, property, expressionValueType); - - return false; - - } - - public static void setValueAsString(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException { - - try { - - if (setOrClearExpression(graph, property, text, expressionValueType)) - return; - - Object value = text; - Datatype type = property.getPossibleDatatype(graph); - if (type != null) { - - Binding binding = Bindings.getBinding(type); - - if (binding instanceof StringBinding) { - - if (binding instanceof MutableStringBinding) - value = new MutableString(text); - else - value = text; - - } else { - - if (binding instanceof NumberBinding) { - text = text.replace(",", "."); - } - - value = binding.parseValue(text, new DataValueRepository()); - - } - - property.setValue(graph, value, binding); - - } else { - - property.setValue(graph, value); - - } - - // Add a comment to metadata. - CommentMetadata cm = graph.getMetadata(CommentMetadata.class); - graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value))); - - } catch (DataTypeSyntaxError e) { - throw new DatabaseException(e); - } catch (BindingException e) { - throw new DatabaseException(e); - } - - } - - - public static String queryDebugSupport(String query) { - Session session = SimanticsInternal.getSession(); - DebugSupport ds = session.getService(DebugSupport.class); - return ds.query(session, "exec " + query); - } - - public static String queryListSupport (String query) { - Session session = SimanticsInternal.getSession(); - DebugSupport ds = session.getService(DebugSupport.class); - return ds.query(session, "list " + query); - } - - final public static Function1 resourceCluster = new FunctionImpl1() { - @Override - public Resource apply(Resource p0) { - return p0; - } - }; - - public static void sort(ReadGraph graph, List collection) { - CollectionSupport cos = graph.getService(CollectionSupport.class); - cos.sort(collection); - } - - public static List sortByCluster(ReadGraph graph, Collection collection) { - CollectionSupport cos = graph.getService(CollectionSupport.class); - return cos.asSortedList(collection); - } - - public static List sortByCluster(final ReadGraph graph, List list, final Function1 fn) { - final ClusteringSupport cs = graph.getService(ClusteringSupport.class); - ArrayList result = new ArrayList(list); - Collections.sort(result, new Comparator() { - - @Override - public int compare(Object o1, Object o2) { - Resource r1 = fn.apply(o1); - Resource r2 = fn.apply(o2); - long l1 = cs.getCluster(r1); - long l2 = cs.getCluster(r2); - if(l1 < l2) return -1; - else if (l1 > l2) return 1; - else return 0; - } - - }); - return result; - } - - public static List sortByClusterT(final ReadGraph graph, Collection list, final Function1 fn) { - final ClusteringSupport cs = graph.getService(ClusteringSupport.class); - ArrayList result = new ArrayList(list); - Collections.sort(result, new Comparator() { - - @Override - public int compare(Object o1, Object o2) { - Resource r1 = fn.apply((T)o1); - Resource r2 = fn.apply((T)o2); - long l1 = cs.getCluster(r1); - long l2 = cs.getCluster(r2); - if(l1 < l2) return -1; - else if (l1 > l2) return 1; - else return 0; - } - - }); - return result; - } - - public static void makeSynchronous(ReadGraph graph, boolean value) throws DatabaseException { - graph.setSynchronous(value); - } - - public static Set listIndexRoots(ReadGraph graph) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - - Set indexRoots = new TreeSet(); - indexRoots.addAll(Layer0Utils.listOntologies(graph)); - indexRoots.addAll(graph.syncRequest(new ObjectsWithType(SimanticsInternal.getProject(), L0.ConsistsOf, L0.IndexRoot))); - return indexRoots; - - } - - public static List listOntologies(ReadGraph graph) throws DatabaseException { - return graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary())); - } - - public static List listGlobalOntologies(ReadGraph graph) throws DatabaseException { - return graph.syncRequest(new GlobalOntologies(graph.getRootLibrary())); - } - - public static T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException { - - try { - SCL_GRAPH.set(graph); - T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module + "/" + function)).applyArray(args); - SCL_GRAPH.set(null); - return t; - } catch (Throwable t) { - throw new DatabaseException(t); - } - - } - - public static boolean isContainerPublished(ReadGraph graph, Variable variable) throws DatabaseException { - - Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable)); - if(indexRoot == null) return false; - if(variable.equals(indexRoot)) return false; - return isPublished(graph, indexRoot); - - } - - public static boolean isContainerPublished(ReadGraph graph, Resource resource) throws DatabaseException { - - Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resource)); - if(indexRoot == null) return false; - if(resource.equals(indexRoot)) return false; - return isPublished(graph, indexRoot); - - } - - public static boolean isPublished(ReadGraph graph, Resource resource) throws DatabaseException { - - Layer0 L0 = Layer0.getInstance(graph); - Boolean value = graph.getPossibleRelatedValue(resource, L0.Entity_published, Bindings.BOOLEAN); - if(value != null && value) return true; - - // This is safety - root should not be published it child is not - Resource root = graph.syncRequest(new PossibleIndexRoot(resource)); - if(root != null) { - value = graph.getPossibleRelatedValue(root, L0.Entity_published, Bindings.BOOLEAN); - if(value != null && value) return true; - } - - return false; - - } - - private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException { - - SimanticsClipboardImpl cp = new SimanticsClipboardImpl(); - CopyHandler c1 = graph.adapt(r, CopyHandler.class); - c1.copyToClipboard(graph, cp); - Collection> reps = cp.getContents(); - if(reps.size() != 1) return null; - return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH); - - } - - private static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException { - - SimanticsClipboardImpl cp = new SimanticsClipboardImpl(); - CopyHandler c1 = graph.adapt(r, CopyHandler.class); - c1.copyToClipboard(graph, cp); - Collection> reps = cp.getContents(); - if(reps.size() != 1) return null; - return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE); - - } - - /* - * Modifies target to resemble source. - */ - public static boolean merge(WriteGraph graph, Resource source, Resource target) throws DatabaseException { - - TransferableGraphSource tgs1 = makeTGSource(graph, target); - TransferableGraph1 tg1 = TransferableGraphs.create(graph, tgs1); - TransferableGraph1 tg2 = makeTG(graph, source); - - GraphRefactoringUtils.fixIncorrectRoot(tg1.identities); - GraphRefactoringUtils.fixIncorrectRoot(tg2.identities); - - ModelTransferableGraphSource mtgs = (ModelTransferableGraphSource)tgs1; - - Diff diff = new Diff(tg1, tg2); - TransferableGraphDelta1 delta = diff.diff(); - - long[] oldResources = mtgs.getResourceArray(graph); - if(TransferableGraphs.hasChanges(graph, oldResources, delta)) { - TransferableGraphs.applyDelta(graph, mtgs.getResourceArray(graph), delta); - return true; - } else { - return false; - } - - } - - public static Resource inferLiteralTypeFromString(ReadGraph graph, String text) { - return Layer0.getInstance(graph).String; - } - - public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException { - emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject()); - } - - public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project) throws ServiceException { - final SubMonitor mon = SubMonitor.convert(monitor, "Emptying Trash Bin...", 10000); - try { - session.syncRequest(new DelayedWriteRequest() { - @Override - public void perform(WriteGraph graph) throws DatabaseException { - Layer0Utils.setDependenciesIndexingDisabled(graph, true); - Layer0 L0 = Layer0.getInstance(graph); - Layer0X L0X = Layer0X.getInstance(graph); - Resource parent = graph.getSingleObject(project, L0.PartOf); - Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin"); - Collection trashes = trashBin != null - ? graph.getObjects(trashBin, L0.ConsistsOf) - : Collections.emptyList(); - if (trashes.isEmpty()) - throw new CancelTransactionException(); - mon.setWorkRemaining((2 + trashes.size()) * 1000); - for(Resource trash : trashes) { - if (mon.isCanceled()) - throw new CancelTransactionException(); - mon.subTask(NameUtils.getSafeName(graph, trash)); - TGRemover remo = new TGRemover(mon.newChild(1000, SubMonitor.SUPPRESS_ALL_LABELS), trash); - remo.remove(graph); - if(graph.isInstanceOf(trash, L0.IndexRoot)) { - // TODO: this should be an utility - GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class); - IndexedRelations ir = graph.getService(IndexedRelations.class); - // Deletes index files - ir.reset(null, graph, L0X.DependenciesRelation, trash); - // Notifies DB listeners - index.reset(graph, trash); - } - } - if (mon.isCanceled()) - throw new CancelTransactionException(); - mon.subTask("Committing Changes"); - mon.newChild(1000); - } - }); - if (mon.isCanceled()) - return; - mon.subTask("Purging Database"); - mon.newChild(1000); - XSupport xs = session.getService(XSupport.class); - xs.purge(); - } catch (CancelTransactionException e) { - // Ignore. - } catch (DatabaseException e) { - throw new ServiceException(e); - } - } - - public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException { - Resource result = null; - for(Resource candidate : getDomainOf(graph, type).values()) { - if(graph.isInstanceOf(candidate, target)) { - if(result != null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type)); - else result = candidate; - } - } - if(result == null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type)); - return result; - } - - public static Map getDomainOf(ReadGraph graph, Resource type) throws DatabaseException { - CollectionSupport cs = graph.getService(CollectionSupport.class); - Map result = cs.createObjectResourceMap(String.class); - Layer0 L0 = Layer0.getInstance(graph); - for(Resource r : graph.getObjects(type, L0.DomainOf)) { - String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); - if(name != null) result.put(name, r); - } - for(Resource t : graph.getSupertypes(type)) { - for(Resource r : graph.getObjects(t, L0.DomainOf)) { - String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); - if(name != null) result.put(name, r); - } - } - return result; - } - - public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException { - for(Resource type : graph.getPrincipalTypes(instance)) { - Map domainOf = getDomainOf(graph, type); - Resource predicate = domainOf.get(predicateName); - if(predicate != null) return predicate; - } - return null; - } - - - public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException { - - try { - PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(property)); - if(pi.literalRange == null) throw new DatabaseException("No suitable literal type defined as range for property."); - if(pi.defaultBinding == null) throw new DatabaseException("No suitable default binding for property."); - Object value = pi.defaultBinding.parseValue(valueText, new DataValueRepository()); - graph.claimLiteral(container, property, pi.literalRange, value, pi.defaultBinding); - } catch (DataTypeSyntaxError e) { - throw new DatabaseException(e); - } catch (BindingException e) { - throw new DatabaseException(e); - } - - } - -} +/******************************************************************************* + * Copyright (c) 2012 Association for Decentralized Information Management in + * Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.db.layer0.util; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.core.runtime.SubMonitor; +import org.simantics.databoard.Bindings; +import org.simantics.databoard.Datatypes; +import org.simantics.databoard.adapter.AdaptException; +import org.simantics.databoard.adapter.Adapter; +import org.simantics.databoard.adapter.AdapterConstructionException; +import org.simantics.databoard.binding.Binding; +import org.simantics.databoard.binding.NumberBinding; +import org.simantics.databoard.binding.StringBinding; +import org.simantics.databoard.binding.error.BindingException; +import org.simantics.databoard.binding.mutable.MutableStringBinding; +import org.simantics.databoard.parser.repository.DataTypeSyntaxError; +import org.simantics.databoard.parser.repository.DataValueRepository; +import org.simantics.databoard.primitives.MutableString; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.BooleanType; +import org.simantics.databoard.type.ByteType; +import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.type.DoubleType; +import org.simantics.databoard.type.FloatType; +import org.simantics.databoard.type.IntegerType; +import org.simantics.databoard.type.LongType; +import org.simantics.databoard.type.MapType; +import org.simantics.databoard.type.NumberType; +import org.simantics.databoard.type.OptionalType; +import org.simantics.databoard.type.RecordType; +import org.simantics.databoard.type.StringType; +import org.simantics.databoard.type.UnionType; +import org.simantics.databoard.type.VariantType; +import org.simantics.databoard.util.ObjectUtils; +import org.simantics.db.ChangeSetIdentifier; +import org.simantics.db.Operation; +import org.simantics.db.ReadGraph; +import org.simantics.db.RelationContext; +import org.simantics.db.Resource; +import org.simantics.db.Session; +import org.simantics.db.Statement; +import org.simantics.db.WriteGraph; +import org.simantics.db.WriteOnlyGraph; +import org.simantics.db.common.CommentMetadata; +import org.simantics.db.common.Indexing; +import org.simantics.db.common.StandardStatement; +import org.simantics.db.common.primitiverequest.PossibleRelatedValue; +import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener; +import org.simantics.db.common.request.DelayedWriteRequest; +import org.simantics.db.common.request.ObjectsWithType; +import org.simantics.db.common.request.PossibleChild; +import org.simantics.db.common.request.PossibleIndexRoot; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.CancelTransactionException; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.exception.ServiceException; +import org.simantics.db.layer0.adapter.CopyHandler; +import org.simantics.db.layer0.adapter.CopyHandler2; +import org.simantics.db.layer0.adapter.GenericRelationIndex; +import org.simantics.db.layer0.adapter.PasteHandler; +import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler; +import org.simantics.db.layer0.adapter.impl.TGRemover; +import org.simantics.db.layer0.genericrelation.IndexedRelations; +import org.simantics.db.layer0.internal.SimanticsInternal; +import org.simantics.db.layer0.migration.OntologiesFromLibrary; +import org.simantics.db.layer0.property.OrderedResource; +import org.simantics.db.layer0.request.GlobalOntologies; +import org.simantics.db.layer0.request.PossibleVariableIndexRoot; +import org.simantics.db.layer0.request.PropertyInfo; +import org.simantics.db.layer0.request.PropertyInfoRequest; +import org.simantics.db.layer0.util.SimanticsClipboard.Representation; +import org.simantics.db.layer0.variable.StandardGraphPropertyVariable; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.db.service.ClusterCollectorPolicy; +import org.simantics.db.service.ClusterControl; +import org.simantics.db.service.ClusteringSupport; +import org.simantics.db.service.CollectionSupport; +import org.simantics.db.service.DebugSupport; +import org.simantics.db.service.ManagementSupport; +import org.simantics.db.service.UndoRedoSupport; +import org.simantics.db.service.XSupport; +import org.simantics.graph.db.TransferableGraphSource; +import org.simantics.graph.db.TransferableGraphs; +import org.simantics.graph.diff.Diff; +import org.simantics.graph.diff.TransferableGraphDelta1; +import org.simantics.graph.refactoring.GraphRefactoringUtils; +import org.simantics.graph.representation.PrettyPrintTG; +import org.simantics.graph.representation.TransferableGraph1; +import org.simantics.layer0.Layer0; +import org.simantics.operation.Layer0X; +import org.simantics.scl.compiler.environment.Environments; +import org.simantics.scl.compiler.runtime.RuntimeEnvironment; +import org.simantics.scl.compiler.top.SCLExpressionCompilationException; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.osgi.SCLOsgi; +import org.simantics.scl.runtime.function.Function; +import org.simantics.scl.runtime.function.Function1; +import org.simantics.scl.runtime.function.FunctionImpl1; + +public class Layer0Utils { + + @SuppressWarnings("rawtypes") + public static final ThreadLocal SCL_GRAPH = new ThreadLocal(); + + final public static Binding datatype_binging = Bindings.getBindingUnchecked(Datatype.class); + + public static Resource literal(WriteGraph g, String value) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource r = g.newResource(); + g.claimValue(r, value, Bindings.STRING); + g.claim(r, L0.InstanceOf, L0.String); + return r; + } + + public static Resource literal(WriteGraph g, double value) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource r = g.newResource(); + g.claimValue(r, value, Bindings.DOUBLE); + g.claim(r, L0.InstanceOf, L0.Double); + return r; + } + + public static Resource literal(WriteGraph g, int value) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource r = g.newResource(); + g.claimValue(r, value, Bindings.INTEGER); + g.claim(r, L0.InstanceOf, L0.Integer); + return r; + } + + public static void assert_(WriteGraph g, Resource type, Resource predicate, Resource object) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource assertion = g.newResource(); + g.claim(type, L0.Asserts, assertion); + g.claim(assertion, L0.InstanceOf, L0.Assertion); + g.claim(assertion, L0.HasPredicate, predicate); + g.claim(assertion, L0.HasObject, object); + } + + public static Resource relation(WriteGraph g, Resource parent, String name, Resource superrelation) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(g); + Resource relation = g.newResource(); + g.claim(relation, L0.SubrelationOf, superrelation); + g.claim(relation, L0.HasName, literal(g, name)); + g.claim(parent, L0.ConsistsOf, relation); + + Resource superrelationInverse = g.getInverse(superrelation); + if(superrelationInverse != null) { + Resource inverse = g.newResource(); + g.claim(inverse, L0.SubrelationOf, superrelationInverse); + g.claim(relation, L0.ConsistsOf, inverse); + g.claim(inverse, L0.HasName, literal(g, "Inverse")); + } + return relation; + } + + private static Resource getLiteralType(ReadGraph graph, Datatype type) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + if(type instanceof DoubleType) return L0.Double; + else if(type instanceof StringType) return L0.String; + else if(type instanceof IntegerType) return L0.Integer; + else if(type instanceof LongType) return L0.Long; + else if(type instanceof FloatType) return L0.Float; + else if(type instanceof ByteType) return L0.Byte; + else if(type instanceof BooleanType) return L0.Boolean; + else if(type instanceof ArrayType) { + ArrayType at = (ArrayType)type; + if(at.componentType instanceof DoubleType) return L0.DoubleArray; + else if(at.componentType instanceof StringType) return L0.StringArray; + else if(at.componentType instanceof IntegerType) return L0.IntegerArray; + else if(at.componentType instanceof LongType) return L0.LongArray; + else if(at.componentType instanceof FloatType) return L0.FloatArray; + else if(at.componentType instanceof ByteType) return L0.ByteArray; + else if(at.componentType instanceof BooleanType) return L0.BooleanArray; + else if(at.componentType instanceof VariantType) return L0.VariantArray; + } + throw new DatabaseException("Unidentified literal type for datatype " + type); + } + + private static Resource getPossibleLiteralType(ReadGraph graph, String type) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + if("Double".equals(type)) return L0.Double; + else if("String".equals(type)) return L0.String; + else if("Integer".equals(type)) return L0.Integer; + else if("Long".equals(type)) return L0.Long; + else if("Float".equals(type)) return L0.Float; + else if("Byte".equals(type)) return L0.Byte; + else if("Boolean".equals(type)) return L0.Boolean; + else if("[Double]".equals(type)) return L0.DoubleArray; + else if("[String]".equals(type)) return L0.StringArray; + else if("[Integer]".equals(type)) return L0.IntegerArray; + else if("[Long]".equals(type)) return L0.LongArray; + else if("[Float]".equals(type)) return L0.FloatArray; + else if("[Byte]".equals(type)) return L0.ByteArray; + else if("[Boolean]".equals(type)) return L0.BooleanArray; + else if("[Variant]".equals(type)) return L0.VariantArray; + else if("Array Double".equals(type)) return L0.DoubleArray; + else if("Array String".equals(type)) return L0.StringArray; + else if("Array Integer".equals(type)) return L0.IntegerArray; + else if("Array Long".equals(type)) return L0.LongArray; + else if("Array Float".equals(type)) return L0.FloatArray; + else if("Array Byte".equals(type)) return L0.ByteArray; + else if("Array Boolean".equals(type)) return L0.BooleanArray; + else if("Array Variant".equals(type)) return L0.VariantArray; + else if("Vector Double".equals(type)) return L0.DoubleArray; + else if("Vector String".equals(type)) return L0.StringArray; + else if("Vector Integer".equals(type)) return L0.IntegerArray; + else if("Vector Long".equals(type)) return L0.LongArray; + else if("Vector Float".equals(type)) return L0.FloatArray; + else if("Vector Byte".equals(type)) return L0.ByteArray; + else if("Vector Boolean".equals(type)) return L0.BooleanArray; + else if("Vector Variant".equals(type)) return L0.VariantArray; + else if("Datatype".equals(type)) return L0.DataType; + else if("Variant".equals(type)) return L0.Variant; + else return null; + } + + public static Resource getPossibleLiteralType(ReadGraph graph, Variable variable) throws DatabaseException { + Resource predicate = variable.getPossiblePredicateResource(graph); + if(predicate == null) return null; + return getPossibleLiteralType(graph, predicate); + } + + public static Resource getLiteralType(ReadGraph graph, Variable variable) throws DatabaseException { + Resource result = getPossibleLiteralType(graph, variable); + if(result == null) throw new DatabaseException("Unidentified literal type for variable " + variable.getURI(graph)); + return result; + } + + public static Resource getLiteralType(ReadGraph graph, Resource property) throws DatabaseException { + Resource result = getPossibleLiteralType(graph, property); + if(result == null) throw new DatabaseException("Unidentified literal type for property " + graph.getURI(property)); + return result; + } + + public static Resource getPossibleLiteralType(ReadGraph graph, Resource property) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + + Resource defaultLiteralType = graph.getPossibleObject(property, L0.HasDefaultLiteralType); + if(defaultLiteralType != null) return defaultLiteralType; + + Resource range = graph.getPossibleObject(property, L0.HasRange); + if(range != null && !L0.Value.equals(range)) return range; + + Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); + if(requiredDataType != null) return getLiteralType(graph, requiredDataType); + + String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); + if(requiredValueType == null) return null; + + return getPossibleLiteralType(graph, requiredValueType); + + } + + /** + * @param type any data type definition + * @return SCL type that matches the specified data type on a basic level. + * Data type metadata is/cannot be converted into SCL types. + * @throws IllegalArgumentException + * if the input datatype can't be converted into an SCL type + */ + public static String getSCLType(Datatype type) throws IllegalArgumentException { + return buildSCLType(type, null).toString(); + } + + /** + * Only used internally by {@link #buildSCLType(Datatype, StringBuilder)} + * @param s + * @param toBuilder + * @return + * @see #buildSCLType(Datatype, StringBuilder) + */ + private static StringBuilder append(StringBuilder toBuilder, String s) { + return toBuilder != null ? toBuilder.append(s) : new StringBuilder(s); + } + + private static CharSequence append(CharSequence to, String s) { + if (to instanceof StringBuilder) + return ((StringBuilder) to).append(s); + return new StringBuilder(to.length() + s.length()).append(to).append(s); + } + + private static CharSequence stringOrBuilder(StringBuilder toBuilder, String s) { + return toBuilder != null ? toBuilder.append(s) : s; + } + + /** + * @param type any data type definition + * @return SCL type that matches the specified data type on a basic level. + * Data type metadata is/cannot be converted into SCL types. + * @throws IllegalArgumentException + * if the input datatype can't be converted into an SCL type + */ + private static CharSequence buildSCLType(Datatype type, StringBuilder result) throws IllegalArgumentException { + if(type instanceof DoubleType) return stringOrBuilder(result, "Double"); + else if(type instanceof StringType) return stringOrBuilder(result, "String"); + else if(type instanceof IntegerType) return stringOrBuilder(result, "Integer"); + else if(type instanceof FloatType) return stringOrBuilder(result, "Float"); + else if(type instanceof BooleanType) return stringOrBuilder(result, "Boolean"); + else if(type instanceof ByteType) return stringOrBuilder(result, "Byte"); + else if(type instanceof LongType) return stringOrBuilder(result, "Long"); + else if(type instanceof VariantType) return stringOrBuilder(result, "Variant"); + else if(type instanceof ArrayType) { + ArrayType at = (ArrayType) type; + // Optimization to prevent allocations in the most basic array cases + if(at.componentType instanceof DoubleType) return stringOrBuilder(result, "Vector Double"); + else if(at.componentType instanceof StringType) return stringOrBuilder(result, "Vector String"); + else if(at.componentType instanceof IntegerType) return stringOrBuilder(result, "Vector Integer"); + else if(at.componentType instanceof FloatType) return stringOrBuilder(result, "Vector Float"); + else if(at.componentType instanceof BooleanType) return stringOrBuilder(result, "Vector Boolean"); + else if(at.componentType instanceof ByteType) return stringOrBuilder(result, "Vector Byte"); + else if(at.componentType instanceof LongType) return stringOrBuilder(result, "Vector Long"); + else if(at.componentType instanceof VariantType) return stringOrBuilder(result, "Vector Variant"); + else return buildSCLType(at.componentType, append(result, "Vector ")); + } else if(type instanceof OptionalType) { + OptionalType ot = (OptionalType) type; + return append(buildSCLType(ot.componentType, append(result, "Maybe (")), ")"); + } else if (type instanceof RecordType) { + throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); + } else if (type instanceof MapType) { + throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); + } else if (type instanceof UnionType) { + throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); + } + throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); + } + + + public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException { + try { + return Environments.getType(runtimeEnvironment.getEnvironment(), typeText); + } catch (SCLExpressionCompilationException e) { + throw new DatabaseException(e); + } + } + + public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException { + + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(property.getIndexRoot(graph))); + return getSCLType(graph, runtimeEnvironment, getSCLTypeString(graph, property)); + + } + + + public static String getSCLTypeString(ReadGraph graph, Variable context) throws DatabaseException { + return getSCLTypeString(graph, context.getPossiblePredicateResource(graph), context.getRepresents(graph)); + } + + + public static String getSCLTypeString(ReadGraph graph, Resource predicate, Resource value) throws DatabaseException { + + if(predicate != null) { + String requiredValueTypes = graph.getPossibleRelatedValue(predicate, Layer0.getInstance(graph).RequiresValueType, Bindings.STRING); + if(requiredValueTypes != null) + return requiredValueTypes; + } + + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + + Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, datatype_binging); + if(literalDatatype != null) return getSCLType(literalDatatype); + + String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING); + if(literalValueType != null) return literalValueType; + + if(predicate != null) { + + Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, datatype_binging); + if(requiredDataType != null) return getSCLType(requiredDataType); + + throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate)); + + } + + throw new DatabaseException("Unidentified literal data type"); + + } + + public static Datatype getDatatype(ReadGraph graph, Variable variable) throws DatabaseException { + Datatype result = getPossibleDatatype(graph, variable); + if(result != null) return result; + throw new DatabaseException("Unidentified literal data type for property " + variable.getURI(graph)); + } + + public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + + Resource property = variable.getPossiblePredicateResource(graph); + if(property != null) { +// Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); + Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging)); + if(requiredDataType != null) return requiredDataType; + } + + Resource literal = variable.getPossibleRepresents(graph); + if(literal != null) { + Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging); + if(literalDatatype != null) return literalDatatype; + } + + if(property != null) { + + String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); + if(requiredValueType != null) { + Datatype datatype = getPossibleDatatypeForValueType(requiredValueType); + if(datatype != null) return datatype; + } + + Resource subject = variable.getParent(graph).getPossibleRepresents(graph); + if(subject != null) { + Set asses = new HashSet(); + for(Resource type : graph.getTypes(subject)) { + asses.addAll(graph.getAssertedObjects(type, property)); + } + if(asses.size() == 1) { + Resource ass = asses.iterator().next(); + Datatype dt = graph.getPossibleRelatedValue(ass, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class)); + if(dt != null) return dt; + } + } + + } + + return null; + + } + + private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException { + + String[] split = requiredValueType.split(" "); + String arrayType = null; + if(split.length == 2 && "Array".equals(split[0])) { + arrayType = split[1]; + } else if(requiredValueType.startsWith("[") && requiredValueType.endsWith("]")) { + arrayType = requiredValueType.substring(1, requiredValueType.length()-1); + } + + if(arrayType != null) { + Datatype arrayDataType = getArrayDataTypeForType(arrayType); + if(arrayDataType != null) + return arrayDataType; + } + + Datatype dt = Datatypes.getDatatype(requiredValueType); + if(dt != null) return dt; + + try { + return Datatypes.translate(requiredValueType); + } catch (DataTypeSyntaxError e) { + return null; + } + + + } + + private static Datatype getArrayDataTypeForType(String type) { + if("Double".equals(type)) return Datatypes.DOUBLE_ARRAY; + else if("String".equals(type)) return Datatypes.STRING_ARRAY; + else if("Integer".equals(type)) return Datatypes.INTEGER_ARRAY; + else if("Long".equals(type)) return Datatypes.LONG_ARRAY; + else if("Float".equals(type)) return Datatypes.FLOAT_ARRAY; + else if("Byte".equals(type)) return Datatypes.BYTE_ARRAY; + else if("Boolean".equals(type)) return Datatypes.BOOLEAN_ARRAY; + else if("Variant".equals(type)) return Datatypes.VARIANT_ARRAY; + return null; + } + + public static Binding getDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException { + + Resource property = variable.getPossiblePredicateResource(graph); + if(property != null) { + PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.instance()); + if(info.defaultBinding != null) return info.defaultBinding; + } + + Datatype type = getDatatype(graph, variable); + if (type == null) + throw new DatabaseException("No datatype available for variable " + variable.getURI(graph)); + return Bindings.getBinding(type); + + } + + public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException { + + Resource property = variable.getPossiblePredicateResource(graph); + if(property != null) { + PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.instance()); + if(info.defaultBinding != null) return info.defaultBinding; + } + + Datatype type = getPossibleDatatype(graph, variable); + if (type == null) return null; + + return Bindings.getBinding(type); + + } + + public static String getPossibleUnit(Datatype dt) { + if (dt == null) + return null; + else if (dt instanceof NumberType) { + return ((NumberType) dt).getUnit(); + } else if (dt instanceof ArrayType) { + ArrayType at = (ArrayType) dt; + Datatype cdt = at.componentType(); + if (cdt instanceof NumberType) { + return ((NumberType) cdt).getUnit(); + } + } + return null; + + } + + public static String getUnit(ReadGraph graph, Variable variable) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + + Resource literal = variable.getPossibleRepresents(graph); + if(literal == null) + return ""; + + Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging); + if(literalDatatype != null) { + String unit = getPossibleUnit(literalDatatype); + if(unit != null) return unit; + } + + Resource property = variable.getPossiblePredicateResource(graph); + if(property != null) { + + Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); + if(requiredDataType != null) { + String unit = getPossibleUnit(requiredDataType); + if(unit != null) return unit; + } + + } + + return ""; + + } + + public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype datatype) throws DatabaseException { + + try { + + Datatype source = binding.type(); + if(source.equals(datatype)) { + graph.claimValue(objectResource, value, binding); + } else { + Binding target = Bindings.getBinding(datatype); + Adapter adapter = Bindings.getAdapter(binding, target); + graph.claimValue(objectResource, adapter.adapt(value), target); + } + + } catch (AdapterConstructionException e) { + throw new DatabaseException(e); + } catch (AdaptException e) { + throw new DatabaseException(e); + } + + } + + public static String toString(Object value, Binding binding) throws DatabaseException { + try { + if(value instanceof String) return (String)value; + StringBuilder sb = new StringBuilder(); + DataValueRepository rep = new DataValueRepository(); + binding.printValue(value, sb, rep, false); + return sb.toString(); + } catch (BindingException e) { + throw new DatabaseException(e); + } catch (IOException e) { + throw new DatabaseException(e); + } + } + + public static Object parseValue(String text, Binding binding) throws DatabaseException { + try { + if(binding.isInstance(text)) return text; + DataValueRepository rep = new DataValueRepository(); + return binding.parseValue(text, rep); + } catch (BindingException e) { + throw new DatabaseException(e); + } catch (DataTypeSyntaxError e) { + throw new DatabaseException(e); + } + } + + @SuppressWarnings("unchecked") + public static T getValueAdaptedToBinding(ReadGraph graph, Resource literal, Binding targetBinding) throws DatabaseException { + Datatype sourceDatatype = graph.getDataType(literal); + Datatype targetDatatype = targetBinding.type(); + if (sourceDatatype.equals(targetDatatype)) + return graph.getValue(literal, targetBinding); + + Binding sourceBinding = Bindings.getBinding(sourceDatatype); + try { + Adapter adapter = Bindings.adapterFactory.getAdapter(Bindings.getBinding(sourceDatatype), targetBinding, true, false); + Object value = graph.getValue(literal, sourceBinding); + return (T) adapter.adaptUnchecked(value); + } catch (AdapterConstructionException e) { + throw new DatabaseException(e); + } + } + + public static Statement getStatementInLocal(Resource subject, Statement statement) { + if(statement.isAsserted(subject)) return new StandardStatement(subject, statement.getPredicate(), statement.getObject()); + else return statement; + } + + public static Resource browsePossible(ReadGraph graph, Resource root, String suffix) throws DatabaseException { + return graph.getPossibleResource(graph.getURI(root) + suffix); + } + + public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException { + return graph.sync(new PossibleChild(resource, name)); + } + + public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException { + Resource child = graph.sync(new PossibleChild(resource, name)); + if(child == null) return null; + if(!graph.isInstanceOf(child, type)) return null; + return child; + } + + public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException { + Statement stm = graph.getSingleStatement(subject, predicate); + return new RelationContextImpl(subject, stm); + } + + public static RelationContext relationContext(Statement stm) throws DatabaseException { + return new RelationContextImpl(stm.getSubject(), stm); + } + + public static T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm) throws DatabaseException { + return graph.getValue2(subject, Layer0Utils.relationContext(stm)); + } + + public static T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm, Binding binding) throws DatabaseException { + return graph.getValue2(subject, Layer0Utils.relationContext(stm), binding); + } + + public static T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException { + Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation)); + return valueInRelationContext(graph, stm.getObject(), stm); + } + + public static T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation, Binding binding) throws DatabaseException { + Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation)); + return valueInRelationContext(graph, stm.getObject(), stm, binding); + } + + public static Statement possibleObtainedStatementInternal(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException { + + Layer0X L0X = Layer0X.getInstance(graph); + + for(Resource ob : graph.getObjects(subject, L0X.DefinesObtainedStatement)) { + Resource pred = graph.getSingleObject(ob, L0X.ObtainedStatement_predicate); + if(graph.isSubrelationOf(pred, relation)) { + Resource object = graph.getSingleObject(ob, L0X.ObtainedStatement_object); + return new StandardStatement(subject, pred, object); + } + } + + ArrayList order = new ArrayList(); + for(Statement stm : graph.getStatements(subject, L0X.ObtainsProperty)) { + Integer position = graph.getRelatedValue(stm.getPredicate(), L0X.NaturalNumberOrderRelation, Bindings.INTEGER); + order.add(new OrderedResource(position, stm.getObject())); + } + + for(OrderedResource or : order) { + Statement stm = possibleObtainedStatementInternal(graph, or.r, relation); + if(stm != null) return stm; + } + + return null; + + } + + public static T possibleObtainedValue(ReadGraph graph, RelationContext ctx, Binding binding) throws DatabaseException { + + Statement stm = ctx.getStatement(); + Statement obj = Layer0Utils.possibleObtainedStatementInternal(graph, stm.getSubject(), stm.getPredicate()); + + if(obj != null) { + return Layer0Utils.valueInRelationContext(graph, obj.getObject(), obj, binding); + } else { + return null; + } + + } + + public static void addObtainedStatement(WriteGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + Resource ob = graph.newResource(); + graph.claim(ob, L0.InstanceOf, null, L0X.ObtainedStatement); + graph.claim(ob, L0X.ObtainedStatement_predicate, null, predicate); + graph.claim(ob, L0X.ObtainedStatement_object, null, object); + graph.claim(subject, L0X.DefinesObtainedStatement, null, ob); + } + + public static void addObtainedValue(WriteGraph graph, Resource subject, Resource predicate, Resource type, Object value, Binding binding) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Resource object = graph.newResource(); + graph.claim(object, L0.InstanceOf, type); + graph.claimValue(object, value, binding); + Layer0Utils.addObtainedStatement(graph, subject, predicate, object); + } + + //------------------------------------------------------------------------- + // Indexing state query utilities idle handling utilities + //------------------------------------------------------------------------- + + /** + * This method waits until the indexing engine becomes idle. + * @since 1.8 + */ + public static void waitIndexPending() { + Indexing.waitIndexPending(); + } + + /** + * @param graph an active database write handle to prove one is in a write + * transaction and wants to disable dependencies indexing for this + * transaction only. + * @return previous value + * @since 1.8 + */ + public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) { + return Indexing.setDependenciesIndexingDisabled(graph, disabled); + } + + public static String undo() throws DatabaseException { + + Session session = SimanticsInternal.getSession(); + + UndoRedoSupport support = session.getService(UndoRedoSupport.class); + + List ops = support.undoAndReturnOperations(session, 1); + if(ops.isEmpty()) + return "Undo history is empty."; + + Operation mainOperation = ops.get(0); + + long csId = mainOperation.getCSId(); + + ManagementSupport management = session.getService(ManagementSupport.class); + Collection ids = management.getChangeSetIdentifiers(csId, csId); + + return "Undo reverted " + ids.size() + " change sets."; + + } + + public static String undoOperations(int amountOfOperations) throws DatabaseException { + + Session session = SimanticsInternal.getSession(); + + UndoRedoSupport support = session.getService(UndoRedoSupport.class); + + List ops = support.undoAndReturnOperations(session, amountOfOperations); + if(ops.isEmpty()) + return "Undo history is empty."; + + Operation mainOperation = ops.get(0); + + long csId = mainOperation.getCSId(); + + ManagementSupport management = session.getService(ManagementSupport.class); + Collection ids = management.getChangeSetIdentifiers(csId, csId); + + return "Undo reverted " + ids.size() + " change sets."; + + } + + public static String redo() throws DatabaseException { + + Session session = SimanticsInternal.getSession(); + + UndoRedoSupport support = session.getService(UndoRedoSupport.class); + + List ops = support.redo(session, 1); + if(ops.isEmpty()) + return "Redo history is empty."; + + Operation mainOperation = ops.get(0); + + long csId = mainOperation.getCSId(); + + ManagementSupport management = session.getService(ManagementSupport.class); + Collection ids = management.getChangeSetIdentifiers(csId, csId); + + return "Redo redid " + ids.size() + " change sets."; + + } + + public static String getComment(Session session, ChangeSetIdentifier id) { + byte[] data = id.getMetadata().get(CommentMetadata.class.getName()); + if(data == null) + return "Undescribed operation."; + String comment = CommentMetadata.deserialise(session, data).toString().trim(); + if(comment.isEmpty()) + return "Undescribed operation."; + return comment; + } + + /** + * This method adds CommentMetadata for write transaction. CommentMetadata is used e.g. in Undo view. + * @param graph + * graph handle + * @param string + * comment + * @throws ServiceException + */ + public static void addCommentMetadata(WriteOnlyGraph graph, String string) throws ServiceException { + // Add a comment to metadata. + CommentMetadata cm = graph.getMetadata(CommentMetadata.class); + graph.addMetadata(cm.add(ObjectUtils.toString(string))); + } + + //------------------------------------------------------------------------- + + /** + * Copy the specified source resource into the specified container using the + * specified write transaction handle. + * + * @param graph write transaction handle + * @param targetContainer target container resource of the created copy. The + * exact logic of how the copy will be contained by the target + * container is up to the PasteHandler to decide + * @param source the source resource to copy + * @throws DatabaseException + * @since 1.8 + */ + public static Collection copyTo(WriteGraph graph, Resource targetContainer, Resource source) throws DatabaseException { + return copyTo(graph, targetContainer, source, null, null, null); + } + + public static Collection copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler) throws DatabaseException { + return copyTo(graph, targetContainer, source, handler, null, null); + } + + public static Collection copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException { + if(copyHandler == null) copyHandler = graph.adapt(source, CopyHandler.class); + return copyTo(graph, targetContainer, handler, copyHandler, pasteHandler); + } + + public static Collection copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException { + SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl(); + copyHandler.copyToClipboard(graph, clipboard); + if(targetContainer != null) { + if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class); + return pasteHandler.pasteFromClipboard(graph, clipboard, handler); + } else { + DefaultPasteHandler ph = new DefaultPasteHandler(null); + return ph.pasteFromClipboard(graph, clipboard, handler); + } + } + + public static CopyHandler2 getPossibleCopyHandler(ReadGraph graph, Collection rs) throws DatabaseException { + CopyHandler2 ch = null; + for(Resource r : rs) { + if(ch == null) { + CopyHandler ch2_ = graph.adapt(r, CopyHandler.class); + if(ch2_ instanceof CopyHandler2) { + ch = (CopyHandler2)ch2_; + } + } else { + CopyHandler ch2_ = graph.adapt(r, CopyHandler.class); + if(ch2_ instanceof CopyHandler2) { + CopyHandler2 ch2 = (CopyHandler2)ch2_; + ch = ch.combine(ch2); + } + } + } + return ch; + } + + public static ClusterCollectorPolicy setClusterCollectorPolicy(ClusterCollectorPolicy policy) { + Session session = SimanticsInternal.getSession(); + ClusterControl cc = session.getService(ClusterControl.class); + return cc.setPolicy(policy); + } + + private static String decodeType(ReadGraph graph, Variable variable) throws DatabaseException { + Datatype dt = getDatatype(graph, variable); + return dt.toSingleLineString(); + } + + private static boolean isAsserted(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException { + Statement stm = graph.getPossibleStatement(subject, predicate); + return stm != null && stm.isAsserted(subject); + } + + public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException { + + Resource value = context.getRepresents(graph); + Resource predicateResource = context.getPredicateResource(graph); + Variable parent = context.getParent(graph); + Resource parentResource = parent.getRepresents(graph); + setExpression(graph, parentResource, predicateResource, value, text, expressionValueType); + + } + + public static void setExpression(WriteGraph graph, Resource parentResource, Resource predicateResource, Resource value, String text, Resource expressionValueType) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + boolean hasExpression = graph.isInstanceOf(value, expressionValueType); + String t = getSCLTypeString(graph, predicateResource, value); + String expression = text.substring(1).trim(); + if(isAsserted(graph, parentResource, predicateResource)) { + Resource newValue = graph.newResource(); + graph.claim(newValue, L0.InstanceOf, expressionValueType); + graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING); + graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING); + graph.claim(parentResource, predicateResource, newValue); + } else { + if(hasExpression) { + graph.claimLiteral(value, L0.SCLValue_expression, expression, Bindings.STRING); + } else { + Resource newValue = graph.newResource(); + graph.claim(newValue, L0.InstanceOf, expressionValueType); + graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING); + graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING); + graph.deny(parentResource, predicateResource); + graph.claim(parentResource, predicateResource, newValue); + } + } + + } + + public static void clearExpression(WriteGraph graph, Variable property, Resource expressionValueType) throws DatabaseException { + + Resource object = property.getPossibleRepresents(graph); + if(object != null) { + boolean hasExpression = graph.isInstanceOf(object, expressionValueType); + if(hasExpression) { + // There was an expression and now we go back to a value + Resource subject = property.getParent(graph).getPossibleRepresents(graph); + if(subject != null) { + Resource predicate = property.getPossiblePredicateResource(graph); + if(predicate != null) { + graph.deny(subject, predicate, object); + RemoverUtil.remove(graph, object); + } + } + } + } + + } + + public static boolean setOrClearExpression(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException { + + if(text.startsWith("=")) { + setExpression(graph, property, text, expressionValueType); + return true; + } + + clearExpression(graph, property, expressionValueType); + + return false; + + } + + public static void setValueAsString(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException { + + try { + + if (setOrClearExpression(graph, property, text, expressionValueType)) + return; + + Object value = text; + Datatype type = property.getPossibleDatatype(graph); + if (type != null) { + + Binding binding = Bindings.getBinding(type); + + if (binding instanceof StringBinding) { + + if (binding instanceof MutableStringBinding) + value = new MutableString(text); + else + value = text; + + } else { + + if (binding instanceof NumberBinding) { + text = text.replace(",", "."); + } + + value = binding.parseValue(text, new DataValueRepository()); + + } + + property.setValue(graph, value, binding); + + } else { + + property.setValue(graph, value); + + } + + // Add a comment to metadata. + CommentMetadata cm = graph.getMetadata(CommentMetadata.class); + graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value))); + + } catch (DataTypeSyntaxError e) { + throw new DatabaseException(e); + } catch (BindingException e) { + throw new DatabaseException(e); + } + + } + + + public static String queryDebugSupport(String query) { + Session session = SimanticsInternal.getSession(); + DebugSupport ds = session.getService(DebugSupport.class); + return ds.query(session, "exec " + query); + } + + public static String queryListSupport (String query) { + Session session = SimanticsInternal.getSession(); + DebugSupport ds = session.getService(DebugSupport.class); + return ds.query(session, "list " + query); + } + + final public static Function1 resourceCluster = new FunctionImpl1() { + @Override + public Resource apply(Resource p0) { + return p0; + } + }; + + public static void sort(ReadGraph graph, List collection) { + CollectionSupport cos = graph.getService(CollectionSupport.class); + cos.sort(collection); + } + + public static List sortByCluster(ReadGraph graph, Collection collection) { + CollectionSupport cos = graph.getService(CollectionSupport.class); + return cos.asSortedList(collection); + } + + public static List sortByCluster(final ReadGraph graph, List list, final Function1 fn) { + final ClusteringSupport cs = graph.getService(ClusteringSupport.class); + ArrayList result = new ArrayList(list); + Collections.sort(result, new Comparator() { + + @Override + public int compare(Object o1, Object o2) { + Resource r1 = fn.apply(o1); + Resource r2 = fn.apply(o2); + long l1 = cs.getCluster(r1); + long l2 = cs.getCluster(r2); + if(l1 < l2) return -1; + else if (l1 > l2) return 1; + else return 0; + } + + }); + return result; + } + + public static List sortByClusterT(final ReadGraph graph, Collection list, final Function1 fn) { + final ClusteringSupport cs = graph.getService(ClusteringSupport.class); + ArrayList result = new ArrayList(list); + Collections.sort(result, new Comparator() { + + @Override + public int compare(Object o1, Object o2) { + Resource r1 = fn.apply((T)o1); + Resource r2 = fn.apply((T)o2); + long l1 = cs.getCluster(r1); + long l2 = cs.getCluster(r2); + if(l1 < l2) return -1; + else if (l1 > l2) return 1; + else return 0; + } + + }); + return result; + } + + public static void makeSynchronous(ReadGraph graph, boolean value) throws DatabaseException { + graph.setSynchronous(value); + } + + public static Set listIndexRoots(ReadGraph graph) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + + Set indexRoots = new TreeSet(); + indexRoots.addAll(Layer0Utils.listOntologies(graph)); + indexRoots.addAll(graph.syncRequest(new ObjectsWithType(SimanticsInternal.getProject(), L0.ConsistsOf, L0.IndexRoot))); + return indexRoots; + + } + + public static List listOntologies(ReadGraph graph) throws DatabaseException { + return graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary())); + } + + public static List listGlobalOntologies(ReadGraph graph) throws DatabaseException { + return graph.syncRequest(new GlobalOntologies(graph.getRootLibrary())); + } + + public static T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException { + + try { + SCL_GRAPH.set(graph); + T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module + "/" + function)).applyArray(args); + SCL_GRAPH.set(null); + return t; + } catch (Throwable t) { + throw new DatabaseException(t); + } + + } + + public static boolean isContainerPublished(ReadGraph graph, Variable variable) throws DatabaseException { + + Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable)); + if(indexRoot == null) return false; + if(variable.equals(indexRoot)) return false; + return isPublished(graph, indexRoot); + + } + + public static boolean isContainerPublished(ReadGraph graph, Resource resource) throws DatabaseException { + + Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resource)); + if(indexRoot == null) return false; + if(resource.equals(indexRoot)) return false; + return isPublished(graph, indexRoot); + + } + + public static boolean isPublished(ReadGraph graph, Resource resource) throws DatabaseException { + + Layer0 L0 = Layer0.getInstance(graph); + Boolean value = graph.getPossibleRelatedValue(resource, L0.Entity_published, Bindings.BOOLEAN); + if(value != null && value) return true; + + // This is safety - root should not be published it child is not + Resource root = graph.syncRequest(new PossibleIndexRoot(resource)); + if(root != null) { + value = graph.getPossibleRelatedValue(root, L0.Entity_published, Bindings.BOOLEAN); + if(value != null && value) return true; + } + + return false; + + } + + private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException { + + SimanticsClipboardImpl cp = new SimanticsClipboardImpl(); + CopyHandler c1 = graph.adapt(r, CopyHandler.class); + c1.copyToClipboard(graph, cp); + Collection> reps = cp.getContents(); + if(reps.size() != 1) return null; + return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH); + + } + + public static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException { + + SimanticsClipboardImpl cp = new SimanticsClipboardImpl(); + CopyHandler c1 = graph.adapt(r, CopyHandler.class); + c1.copyToClipboard(graph, cp); + Collection> reps = cp.getContents(); + if(reps.size() != 1) return null; + return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE); + + } + + /* + * Modifies target to resemble source. + */ + public static boolean merge(WriteGraph graph, Resource source, Resource target) throws DatabaseException { + + TransferableGraphSource tgs1 = makeTGSource(graph, target); + TransferableGraph1 tg1 = TransferableGraphs.create(graph, tgs1); + TransferableGraph1 tg2 = makeTG(graph, source); + + GraphRefactoringUtils.fixIncorrectRoot(tg1.identities); + GraphRefactoringUtils.fixIncorrectRoot(tg2.identities); + + ModelTransferableGraphSource mtgs = (ModelTransferableGraphSource)tgs1; + + Diff diff = new Diff(tg1, tg2); + TransferableGraphDelta1 delta = diff.diff(); + + long[] oldResources = mtgs.getResourceArray(graph); + if(TransferableGraphs.hasChanges(graph, oldResources, delta)) { + TransferableGraphs.applyDelta(graph, mtgs.getResourceArray(graph), delta); + return true; + } else { + return false; + } + + } + + public static Resource inferLiteralTypeFromString(ReadGraph graph, String text) { + return Layer0.getInstance(graph).String; + } + + public static void emptyTrashBin() throws ServiceException { + emptyTrashBin(new NullProgressMonitor()); + } + + public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException { + emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject()); + } + + public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project) throws ServiceException { + final SubMonitor mon = SubMonitor.convert(monitor, "Emptying Trash Bin...", 10000); + try { + session.syncRequest(new DelayedWriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + Layer0Utils.setDependenciesIndexingDisabled(graph, true); + Layer0 L0 = Layer0.getInstance(graph); + Layer0X L0X = Layer0X.getInstance(graph); + Resource parent = graph.getSingleObject(project, L0.PartOf); + Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin"); + Collection trashes = trashBin != null + ? graph.getObjects(trashBin, L0.ConsistsOf) + : Collections.emptyList(); + if (trashes.isEmpty()) + throw new CancelTransactionException(); + mon.setWorkRemaining((2 + trashes.size()) * 1000); + for(Resource trash : trashes) { + if (mon.isCanceled()) + throw new CancelTransactionException(); + mon.subTask(NameUtils.getSafeName(graph, trash)); + TGRemover remo = new TGRemover(mon.newChild(1000, SubMonitor.SUPPRESS_ALL_LABELS), trash); + remo.remove(graph); + if(graph.isInstanceOf(trash, L0.IndexRoot)) { + // TODO: this should be an utility + GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class); + IndexedRelations ir = graph.getService(IndexedRelations.class); + // Deletes index files + ir.reset(null, graph, L0X.DependenciesRelation, trash); + // Notifies DB listeners + index.reset(graph, trash); + } + } + if (mon.isCanceled()) + throw new CancelTransactionException(); + mon.subTask("Committing Changes"); + mon.newChild(1000); + } + }); + if (mon.isCanceled()) + return; + mon.subTask("Purging Database"); + mon.newChild(1000); + purgeDatabase(monitor, session); + } catch (CancelTransactionException e) { + // Ignore. + } catch (DatabaseException e) { + throw new ServiceException(e); + } + } + + public static void purgeDatabase() throws ServiceException { + purgeDatabase(new NullProgressMonitor()); + } + + public static void purgeDatabase(final IProgressMonitor monitor) throws ServiceException { + purgeDatabase(monitor, SimanticsInternal.getSession()); + } + + public static void purgeDatabase(final IProgressMonitor monitor, Session session) throws ServiceException { + try { + XSupport xs = session.getService(XSupport.class); + xs.purge(); + } catch (DatabaseException e) { + throw new ServiceException(e); + } + } + + public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException { + Resource result = null; + for(Resource candidate : getDomainOf(graph, type).values()) { + if(graph.isInstanceOf(candidate, target)) { + if(result != null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type)); + else result = candidate; + } + } + if(result == null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type)); + return result; + } + + public static Map getDomainOf(ReadGraph graph, Resource type) throws DatabaseException { + CollectionSupport cs = graph.getService(CollectionSupport.class); + Map result = cs.createObjectResourceMap(String.class); + Layer0 L0 = Layer0.getInstance(graph); + for(Resource r : graph.getObjects(type, L0.DomainOf)) { + String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); + if(name != null) result.put(name, r); + } + for(Resource t : graph.getSupertypes(type)) { + for(Resource r : graph.getObjects(t, L0.DomainOf)) { + String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING); + if(name != null) result.put(name, r); + } + } + return result; + } + + public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException { + for(Resource type : graph.getPrincipalTypes(instance)) { + Map domainOf = getDomainOf(graph, type); + Resource predicate = domainOf.get(predicateName); + if(predicate != null) return predicate; + } + return null; + } + + public static Resource getPossiblePredicateByLabel(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + for(Resource type : graph.getPrincipalTypes(instance)) { + Map domainOf = getDomainOf(graph, type); + for(Resource r : domainOf.values()) { + String label = graph.getPossibleRelatedValue(r, L0.HasLabel, Bindings.STRING); + if(predicateName.equals(label)) + return r; + } + } + return null; + } + + public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException { + + try { + PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(property)); + if(pi.literalRange == null) throw new DatabaseException("No suitable literal type defined as range for property."); + if(pi.defaultBinding == null) throw new DatabaseException("No suitable default binding for property."); + Object value = pi.defaultBinding.parseValue(valueText, new DataValueRepository()); + graph.claimLiteral(container, property, pi.literalRange, value, pi.defaultBinding); + } catch (DataTypeSyntaxError e) { + throw new DatabaseException(e); + } catch (BindingException e) { + throw new DatabaseException(e); + } + + } + + public static String prettyPrintResource(ReadGraph graph, Resource resource, boolean ignoreIdentifiers) throws Exception { + TransferableGraphSource source = makeTGSource(graph, resource); + TransferableGraph1 tg = TransferableGraphs.create(graph, source); + GraphRefactoringUtils.fixOntologyExport(tg); + System.out.println("Printing resoure " + graph.getURI(resource)); + return PrettyPrintTG.print(tg, ignoreIdentifiers); + } + + public static Resource getPossibleAssertedObject(ReadGraph graph, Resource resource, Resource predicate) throws DatabaseException { + Resource result = null; + for(Resource type : graph.getPrincipalTypes(resource)) { + Collection rs = graph.getAssertedObjects(type, predicate); + if(rs.size() > 1) return null; + if(rs.size() == 1) { + Resource ass = rs.iterator().next(); + if (result != null && !result.equals(ass)) return null; + result = ass; + } + } + return result; + } + +}