]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelDependenciesBean.java
Collect model dependencies in reversed topological order
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / ModelDependenciesBean.java
index f448340dd8847300ad3564560e7ab3b3fadaa744..8b8e86b52adcbc2e24a932d9f7bd57fbf774490a 100644 (file)
@@ -1,6 +1,9 @@
 package org.simantics.db.layer0.util;
 
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -35,32 +38,52 @@ public class ModelDependenciesBean {
                this.dependencies = dependencies;
        }
 
-       private static void collectDependencies(ReadGraph graph, Resource resource, LinkedList<ModelDependency> modelDependencies) throws DatabaseException {
-
+       /*
+        * Returns the linked shared ontologies in topological order. 
+        */
+       public static List<Resource> collectDependencies(ReadGraph graph, Resource resource) throws DatabaseException {
+               LinkedList<Resource> order = new LinkedList<>();
+               collectDependencies(graph, resource, order, new HashSet<>());
+               return order;
+       }
+       
+       private static void collectDependencies(ReadGraph graph, Resource resource, LinkedList<Resource> order, Set<Resource> visited) throws DatabaseException {
                Layer0 L0 = Layer0.getInstance(graph);
-               libs: for(Resource library : graph.syncRequest(new ObjectsWithType(resource, L0.IsLinkedTo, L0.SharedOntology))) {
+               for(Resource library : graph.syncRequest(new ObjectsWithType(resource, L0.IsLinkedTo, L0.SharedOntology))) {
+                       if (order.contains(library)) continue;
+                       if (visited.contains(library)) throw new DatabaseException("Cyclic dependency detected.");
+                       visited.add(library);
+                       collectDependencies(graph, library, order, visited);
+                       order.addFirst(library);
+               }
+       }
+       
+       private static List<ModelDependency> collectModelDependencies(ReadGraph graph, Resource resource) throws DatabaseException {
+               List<Resource> order = collectDependencies(graph, resource);
+               Collections.reverse(order);
+
+               List<ModelDependency> modelDependencies = new LinkedList<>();
+
+               for (Resource library : order) {
                        String uri = graph.getPossibleURI(library);
                        if(uri == null) continue;
-                       for(ModelDependency dep : modelDependencies)
-                               if(dep.uri.equals(uri)) continue libs;
                        CopyHandler ch = graph.adapt(library, CopyHandler.class);
                        SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
                        ch.copyToClipboard(graph, clipboard);
                        for (Set<Representation> object : clipboard.getContents()) {
                                TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
                                if(tg != null) {
-                                       modelDependencies.addFirst(new ModelDependency(uri, tg));
+                                       modelDependencies.add(new ModelDependency(uri, tg));
                                }
                        }
-                       collectDependencies(graph, library, modelDependencies);
                }
+               return modelDependencies;
 
        }
 
        public static ModelDependenciesBean create(ReadGraph graph, Resource resource) throws DatabaseException {
 
-               LinkedList<ModelDependency> dependencies = new LinkedList<>();
-               collectDependencies(graph, resource, dependencies);
+               List<ModelDependency> dependencies = collectModelDependencies(graph, resource);
                return new ModelDependenciesBean(dependencies.toArray(new ModelDependency[dependencies.size()]));
 
        }