package org.simantics.db.layer0.util; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import org.eclipse.core.runtime.NullProgressMonitor; import org.simantics.databoard.Bindings; import org.simantics.databoard.adapter.AdaptException; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.mutable.Variant; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.CopyHandler; import org.simantics.db.layer0.migration.MigrationState; import org.simantics.db.layer0.migration.MigrationStateKeys; import org.simantics.db.layer0.util.SimanticsClipboard.Representation; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; public class ModelDependenciesBean { public static final String EXTENSION_KEY = ModelDependenciesBean.class.getSimpleName(); public static final Binding BINDING = Bindings.getBindingUnchecked(ModelDependenciesBean.class); public ModelDependency[] dependencies; public ModelDependenciesBean() { dependencies = new ModelDependency[0]; } public ModelDependenciesBean(ModelDependency[] dependencies) { this.dependencies = dependencies; } /* * Returns the linked shared ontologies in topological order. */ public static List collectDependencies(ReadGraph graph, Resource resource) throws DatabaseException { LinkedList order = new LinkedList<>(); collectDependencies(graph, resource, order, new HashSet<>()); return order; } private static void collectDependencies(ReadGraph graph, Resource resource, LinkedList order, Set visited) throws DatabaseException { Layer0 L0 = Layer0.getInstance(graph); 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 collectModelDependencies(ReadGraph graph, Resource resource) throws DatabaseException { List order = collectDependencies(graph, resource); Collections.reverse(order); List modelDependencies = new ArrayList<>(order.size()); for (Resource library : order) { String uri = graph.getPossibleURI(library); if(uri == null) continue; CopyHandler ch = graph.adapt(library, CopyHandler.class); SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl(); ch.copyToClipboard(graph, clipboard, new NullProgressMonitor()); for (Set object : clipboard.getContents()) { TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH); if(tg != null) { modelDependencies.add(new ModelDependency(uri, tg)); } } } return modelDependencies; } public static ModelDependenciesBean create(ReadGraph graph, Resource resource) throws DatabaseException { List dependencies = collectModelDependencies(graph, resource); return new ModelDependenciesBean(dependencies.toArray(new ModelDependency[dependencies.size()])); } public static ModelDependenciesBean fromMigrationState(MigrationState state) throws DatabaseException, AdaptException { Map extensions = state.getProperty(MigrationStateKeys.TG_EXTENSIONS); final Variant variant = extensions.get(ModelDependenciesBean.EXTENSION_KEY); return variant != null ? (ModelDependenciesBean) variant.getValue(ModelDependenciesBean.BINDING) : null; } }