]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
Utility function for claiming literals
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / Layer0Utils.java
index 538f22478d00f1708a4b0c89e2059adae754f1a4..d89d7165226e7522fdf0a015a7209418e5185847 100644 (file)
@@ -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;
@@ -72,7 +73,9 @@ 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.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,6 +111,7 @@ 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;
@@ -568,16 +574,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);
                        }
 
@@ -876,7 +882,7 @@ public class Layer0Utils {
 
        public static Collection<Resource> 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 +927,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 +1178,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);
 
     }
@@ -1186,18 +1214,18 @@ public class Layer0Utils {
 
        SimanticsClipboardImpl cp = new SimanticsClipboardImpl();
        CopyHandler c1 = graph.adapt(r, CopyHandler.class);
-       c1.copyToClipboard(graph, cp);
+       c1.copyToClipboard(graph, cp, null);
        Collection<Set<Representation>> 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<Set<Representation>> reps = cp.getContents();
        if(reps.size() != 1) return null;
        return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE);
@@ -1243,9 +1271,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<Resource> unhandled = new ArrayList<Resource>();
             session.syncRequest(new DelayedWriteRequest() {
                 @Override
                 public void perform(WriteGraph graph) throws DatabaseException {
@@ -1254,26 +1284,34 @@ public class Layer0Utils {
                     Layer0X L0X = Layer0X.getInstance(graph);
                     Resource parent = graph.getSingleObject(project, L0.PartOf);
                     Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin");
-                    Collection<Resource> trashes = trashBin != null
-                            ? graph.getObjects(trashBin, L0.ConsistsOf)
-                            : Collections.<Resource>emptyList();
+                    Collection<Resource> trashes = trashBin != null ? graph.getObjects(trashBin, L0.ConsistsOf)
+                            : Collections.<Resource> 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 +1320,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 +1386,11 @@ public class Layer0Utils {
        }
        return result;
     }
+
+    public static Resource getPossiblePredicateByNameFromType(ReadGraph graph, Resource type, String name) throws DatabaseException {
+       Map<String,Resource> 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 +1401,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<String, Resource> 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 +1430,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 <code>L0.identifier</code>
+     * 
+     * @param graph
+     * @param component
+     *            for which the identifier is added
+     * @param add
+     *            <code>true</code> to invoke addLiteral, <code>false</code> 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 <code>true</code> if the identifier was renewed, <code>false</code>
+     *         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);
+    }
+
 }