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=ad8676f813bdb83d4da1adde8aed547c31541ddb;hp=538f22478d00f1708a4b0c89e2059adae754f1a4;hb=06aeb7cad707d1fed2c21c1ad9413aa97e901da7;hpb=f9b0a9c48dd040142414f8d3e7ac43b502d3e203 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 538f22478..ad8676f81 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 @@ -54,6 +54,7 @@ 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.datatypes.literal.GUID; import org.simantics.db.ChangeSetIdentifier; import org.simantics.db.Operation; import org.simantics.db.ReadGraph; @@ -70,9 +71,11 @@ 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.request.WriteRequest; +import org.simantics.db.common.utils.CommonDBUtils; import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.event.ChangeListener; import org.simantics.db.exception.CancelTransactionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ServiceException; @@ -81,6 +84,7 @@ 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.EntityRemover; import org.simantics.db.layer0.adapter.impl.TGRemover; import org.simantics.db.layer0.genericrelation.IndexedRelations; import org.simantics.db.layer0.internal.SimanticsInternal; @@ -98,6 +102,7 @@ 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.GraphChangeListenerSupport; import org.simantics.db.service.ManagementSupport; import org.simantics.db.service.UndoRedoSupport; import org.simantics.db.service.XSupport; @@ -106,12 +111,11 @@ 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; @@ -123,8 +127,6 @@ 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(); @@ -266,7 +268,7 @@ public class Layer0Utils { 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); + Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, Bindings.DATATYPE); if(requiredDataType != null) return getLiteralType(graph, requiredDataType); String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); @@ -349,13 +351,9 @@ public class Layer0Utils { throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type); } - + @Deprecated 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); - } + return CommonDBUtils.getSCLType(graph, runtimeEnvironment, typeText); } public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException { @@ -382,7 +380,7 @@ public class Layer0Utils { Layer0 L0 = Layer0.getInstance(graph); Layer0X L0X = Layer0X.getInstance(graph); - Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, datatype_binging); + Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, Bindings.DATATYPE); if(literalDatatype != null) return getSCLType(literalDatatype); String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING); @@ -390,7 +388,7 @@ public class Layer0Utils { if(predicate != null) { - Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, datatype_binging); + Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, Bindings.DATATYPE); if(requiredDataType != null) return getSCLType(requiredDataType); throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate)); @@ -408,26 +406,30 @@ public class Layer0Utils { } public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException { + return getPossibleDatatype(graph, variable, null, true); + } + private static Datatype getPossibleDatatype(ReadGraph graph, Variable variable, PropertyInfo info, boolean checkPropertyDatatype) 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(checkPropertyDatatype && property != null) { + Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue(property, L0X.RequiresDataType, Bindings.DATATYPE)); 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; + Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), Bindings.DATATYPE); + if(literalDatatype != null) return literalDatatype; } if(property != null) { - String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); + String requiredValueType = info != null + ? info.requiredValueType + : graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING); if(requiredValueType != null) { Datatype datatype = getPossibleDatatypeForValueType(requiredValueType); if(datatype != null) return datatype; @@ -449,7 +451,6 @@ public class Layer0Utils { } return null; - } private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException { @@ -462,11 +463,9 @@ public class Layer0Utils { arrayType = requiredValueType.substring(1, requiredValueType.length()-1); } - if(arrayType != null) { - Datatype arrayDataType = getArrayDataTypeForType(arrayType); - if(arrayDataType != null) - return arrayDataType; - } + Datatype arrayDataType = getDatatypeForType(arrayType != null ? arrayType : requiredValueType, arrayType != null); + if(arrayDataType != null) + return arrayDataType; Datatype dt = Datatypes.getDatatype(requiredValueType); if(dt != null) return dt; @@ -477,18 +476,19 @@ public class Layer0Utils { 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; + private static Datatype getDatatypeForType(String type, boolean isArray) { + switch (type) { + case "Double": return isArray ? Datatypes.DOUBLE_ARRAY : Datatypes.DOUBLE; + case "String": return isArray ? Datatypes.STRING_ARRAY : Datatypes.STRING; + case "Integer": return isArray ? Datatypes.INTEGER_ARRAY : Datatypes.INTEGER; + case "Long": return isArray ? Datatypes.LONG_ARRAY : Datatypes.LONG; + case "Float": return isArray ? Datatypes.FLOAT_ARRAY : Datatypes.FLOAT; + case "Byte": return isArray ? Datatypes.BYTE_ARRAY : Datatypes.BYTE; + case "Boolean": return isArray ? Datatypes.BOOLEAN_ARRAY : Datatypes.BOOLEAN; + case "Variant": return isArray ? Datatypes.VARIANT_ARRAY : Datatypes.VARIANT; + } return null; } @@ -501,8 +501,6 @@ public class Layer0Utils { } Datatype type = getDatatype(graph, variable); - if (type == null) - throw new DatabaseException("No datatype available for variable " + variable.getURI(graph)); return Bindings.getBinding(type); } @@ -510,12 +508,13 @@ public class Layer0Utils { public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException { Resource property = variable.getPossiblePredicateResource(graph); + PropertyInfo info = null; if(property != null) { - PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.instance()); + info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.instance()); if(info.defaultBinding != null) return info.defaultBinding; } - Datatype type = getPossibleDatatype(graph, variable); + Datatype type = getPossibleDatatype(graph, variable, info, false); if (type == null) return null; return Bindings.getBinding(type); @@ -547,7 +546,7 @@ public class Layer0Utils { if(literal == null) return ""; - Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging); + Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), Bindings.DATATYPE); if(literalDatatype != null) { String unit = getPossibleUnit(literalDatatype); if(unit != null) return unit; @@ -556,7 +555,7 @@ public class Layer0Utils { Resource property = variable.getPossiblePredicateResource(graph); if(property != null) { - Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging); + Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, Bindings.DATATYPE); if(requiredDataType != null) { String unit = getPossibleUnit(requiredDataType); if(unit != null) return unit; @@ -568,16 +567,16 @@ public class Layer0Utils { } - public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype datatype) throws DatabaseException { + public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype targetDatatype) throws DatabaseException { try { - Datatype source = binding.type(); - if(source.equals(datatype)) { + Datatype sourceDatatype = binding.type(); + if(sourceDatatype.equals(targetDatatype)) { graph.claimValue(objectResource, value, binding); } else { - Binding target = Bindings.getBinding(datatype); - Adapter adapter = Bindings.getAdapter(binding, target); + Binding target = Bindings.getBinding(targetDatatype); + Adapter adapter = Bindings.getTypeAdapter(binding, target); graph.claimValue(objectResource, adapter.adapt(value), target); } @@ -641,15 +640,14 @@ public class Layer0Utils { return graph.getPossibleResource(graph.getURI(root) + suffix); } + @Deprecated public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException { - return graph.sync(new PossibleChild(resource, name)); + return CommonDBUtils.getPossibleChild(graph, resource, name); } + @Deprecated 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; + return CommonDBUtils.getPossibleChild(graph, resource, type, name); } public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException { @@ -876,7 +874,7 @@ public class Layer0Utils { public static Collection copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException { SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl(); - copyHandler.copyToClipboard(graph, clipboard); + copyHandler.copyToClipboard(graph, clipboard, new NullProgressMonitor()); if(targetContainer != null) { if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class); return pasteHandler.pasteFromClipboard(graph, clipboard, handler); @@ -921,6 +919,27 @@ public class Layer0Utils { return stm != null && stm.isAsserted(subject); } + /* + * Works around problems in WriteGraph methods with similar signature. + * Especially handles better some cases with existing literals. + * + */ + public static void claimLiteral(WriteGraph graph, Resource r, Resource p, Resource i, Resource t, Object value, Binding binding) throws DatabaseException { + Statement stm = graph.getPossibleStatement(r, p); + if(stm != null && !stm.isAsserted(r)) { + if(graph.isInstanceOf(stm.getObject(), t)) { + // Existing statement is compatible, reuse the literal + graph.claimValue(stm.getObject(), value, binding); + return; + } else { + // Existing statement is incompatible - remove it + graph.deny(stm); + } + } + // Create new statement + graph.claimLiteral(r, p, i, t, value, binding); + } + public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException { Resource value = context.getRepresents(graph); @@ -1151,7 +1170,8 @@ public class Layer0Utils { Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable)); if(indexRoot == null) return false; - if(variable.equals(indexRoot)) return false; + Resource represents = variable.getPossibleRepresents(graph); + if(represents != null && represents.equals(indexRoot)) return false; return isPublished(graph, indexRoot); } @@ -1182,22 +1202,26 @@ public class Layer0Utils { } + public static boolean isMarkedReadOnly(ReadGraph graph, Resource r) throws DatabaseException { + return Boolean.TRUE.equals( graph.getPossibleRelatedValue(r, graph.l0().readOnly, Bindings.BOOLEAN) ); + } + 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); + c1.copyToClipboard(graph, cp, null); 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 { + 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); + c1.copyToClipboard(graph, cp, null); Collection> reps = cp.getContents(); if(reps.size() != 1) return null; return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE); @@ -1243,9 +1267,11 @@ public class Layer0Utils { emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject()); } - public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project) throws ServiceException { + 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 { + ArrayList unhandled = new ArrayList(); session.syncRequest(new DelayedWriteRequest() { @Override public void perform(WriteGraph graph) throws DatabaseException { @@ -1254,26 +1280,34 @@ public class Layer0Utils { 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(); + 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) { + for (Resource trash : trashes) { if (mon.isCanceled()) throw new CancelTransactionException(); mon.subTask(NameUtils.getSafeName(graph, trash)); + boolean isIndexRoot = graph.isInstanceOf(trash, L0.IndexRoot); 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); + try { + remo.remove(graph); + unhandled.addAll(remo.getRoots()); + } catch (DatabaseException e) { + // Something went wrong - try to remove this later + // with EntityRemover + unhandled.add(trash); + } + if (isIndexRoot) { + // 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()) @@ -1282,6 +1316,15 @@ public class Layer0Utils { mon.newChild(1000); } }); + + session.syncRequest(new WriteRequest() { + @Override + public void perform(WriteGraph graph) throws DatabaseException { + for (Resource r : unhandled) + EntityRemover.remove(graph, r); + } + }); + if (mon.isCanceled()) return; mon.subTask("Purging Database"); @@ -1339,6 +1382,46 @@ public class Layer0Utils { } return result; } + + public static Resource possibleObjectForType(ReadGraph graph, Resource type, Resource relation) throws DatabaseException { + PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(relation)); + return possibleObjectForType(graph, type, relation, pi.isFunctional); + } + + public static Resource possibleObjectForType(ReadGraph graph, Resource type, Resource relation, boolean functional) throws DatabaseException { + if(functional) { + Layer0 L0 = Layer0.getInstance(graph); + Resource result = graph.getPossibleObject(type, relation); + if(result != null) + return result; + for(Resource su : graph.getObjects(L0.Inherits, type)) { + Resource r = possibleObjectForType(graph, su, relation, functional); + if(r != null) { + if(result != null) + return null; + result = r; + } + } + return result; + } else { + Set found = objectsForTypeNonFunctional(graph, type, relation, new HashSet<>()); + return found.size() == 1 ? found.iterator().next() : null; + } + } + + private static Set objectsForTypeNonFunctional(ReadGraph graph, Resource type, Resource relation, Set found) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + found.addAll(graph.getObjects(type, relation)); + for(Resource su : graph.getObjects(L0.Inherits, type)) { + objectsForTypeNonFunctional(graph, su, relation, found); + } + return found; + } + + public static Resource getPossiblePredicateByNameFromType(ReadGraph graph, Resource type, String name) throws DatabaseException { + Map domain = getDomainOf(graph, type); + return domain.get(name); + } public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException { for(Resource type : graph.getPrincipalTypes(instance)) { @@ -1349,6 +1432,18 @@ public class Layer0Utils { 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 { @@ -1366,4 +1461,63 @@ public class Layer0Utils { } + 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); + } + + /** + * Adds a random {@link GUID} as a value for L0.identifier + * + * @param graph + * @param component + * for which the identifier is added + * @param add + * true to invoke addLiteral, false to + * invoke claimLiteral + * @throws DatabaseException + */ + public static void claimNewIdentifier(WriteGraph graph, Resource component, boolean add) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + GUID guid = GUID.random(); + if (add) + graph.addLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, guid, GUID.BINDING); + else + graph.claimLiteral(component, L0.identifier, L0.identifier_Inverse, L0.GUID, guid, GUID.BINDING); + } + + /** + * Sets a new random unique identifier for the specified entity if it already + * has an identifier. If the entity does not have a previous identifier, nothing + * is done. + * + * @param graph + * @param entity + * for which the identifier is added + * @return true if the identifier was renewed, false + * otherwise + * @throws DatabaseException + * @see {@link #claimNewIdentifier(WriteGraph, Resource, boolean)} + */ + public static boolean renewIdentifier(WriteGraph graph, Resource entity) throws DatabaseException { + Layer0 L0 = Layer0.getInstance(graph); + Statement stm = graph.getPossibleStatement(entity, L0.identifier); + if (stm != null) { + graph.claimValue(stm.getObject(), GUID.random(), GUID.BINDING); + return true; + } + return false; + } + + public static void addMetadataListener(ChangeListener listener) { + SimanticsInternal.getSession().getService(GraphChangeListenerSupport.class).addMetadataListener(listener); + } + + public static void removeMetadataListener(ChangeListener listener) { + SimanticsInternal.getSession().getService(GraphChangeListenerSupport.class).removeMetadataListener(listener); + } + }