]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationUtils.java
Disable model activation during model migration
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / migration / MigrationUtils.java
index a026f013e0f03ab4a443d5ba17f4284519f99cd9..58197619a7a25f8c002ac6460e166ff299b1919d 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.layer0.migration;\r
-\r
-import java.io.File;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.NullProgressMonitor;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.databoard.container.DataContainer;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.WriteOnlyGraph;\r
-import org.simantics.db.common.CommentMetadata;\r
-import org.simantics.db.common.request.BinaryRead;\r
-import org.simantics.db.common.request.FreshEscapedName;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.VersionMap;\r
-import org.simantics.db.common.utils.VersionMapRequest;\r
-import org.simantics.db.common.utils.Versions;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.adapter.Instances;\r
-import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
-import org.simantics.db.layer0.adapter.impl.SharedOntologyImportAdvisor;\r
-import org.simantics.db.layer0.adapter.impl.TrashBinRemover;\r
-import org.simantics.db.layer0.internal.SimanticsInternal;\r
-import org.simantics.db.layer0.util.Layer0Utils;\r
-import org.simantics.db.layer0.util.TGTransferableGraphSource;\r
-import org.simantics.db.service.XSupport;\r
-import org.simantics.graph.db.IImportAdvisor;\r
-import org.simantics.graph.db.MissingDependencyException;\r
-import org.simantics.graph.db.TransferableGraphException;\r
-import org.simantics.graph.representation.Identity;\r
-import org.simantics.graph.representation.Root;\r
-import org.simantics.graph.representation.TransferableGraph1;\r
-import org.simantics.graph.representation.TransferableGraphUtils;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.utils.datastructures.Pair;\r
-import org.simantics.utils.datastructures.collections.CollectionUtils;\r
-\r
-public class MigrationUtils {\r
-       \r
-       public static final boolean DEBUG = false;\r
-\r
-    public static MigrationState newState() {\r
-        return new MigrationStateImpl();\r
-    }\r
-\r
-    public static MigrationStep getStep(Session session, String uri) throws DatabaseException {\r
-        return session.sync(new UnaryRead<String, MigrationStep>(uri) {\r
-\r
-            @Override\r
-            public MigrationStep perform(ReadGraph graph) throws DatabaseException {\r
-                Resource r = graph.getResource(parameter);\r
-                return graph.adapt(r, MigrationStep.class);\r
-            }\r
-\r
-        });\r
-    }\r
-\r
-//    public static TransferableGraph1 getTG(Session session, MigrationState state) {\r
-//        return getTG(session, state, true, false);\r
-//    }\r
-    \r
-    public static void clearTempResource(Session session, final Resource resource) {\r
-        session.asyncRequest(new WriteRequest() {\r
-\r
-            @Override\r
-            public void perform(WriteGraph graph) throws DatabaseException {\r
-                graph.deny(resource, Layer0.getInstance(graph).PartOf);\r
-            }\r
-        });\r
-    }\r
-\r
-    public static Collection<Resource> importTo(IProgressMonitor monitor, Session session, MigrationState state, final Resource parent, final IImportAdvisor advisor) throws DatabaseException, TransferableGraphException {\r
-        final Resource resource = getResource(monitor, session, state);\r
-        final ArrayList<Resource> result = new ArrayList<Resource>();\r
-        if(resource != null) {\r
-            session.syncRequest(new WriteRequest() {\r
-                \r
-                @Override\r
-                public void perform(WriteGraph graph) throws DatabaseException {\r
-                    \r
-                       Layer0 L0 = Layer0.getInstance(graph);\r
-                       \r
-                       for(Resource root : graph.getObjects(resource, L0.ConsistsOf)) {\r
-                               \r
-                               String baseName = Versions.getBaseName(graph, root);\r
-                           String version = Versions.getVersion(graph, root);\r
-                           if(version != null) {\r
-                                       VersionMap map = graph.syncRequest(new VersionMapRequest(parent));\r
-                                       if(map.contains(baseName, version)) {\r
-                                   String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));\r
-                                       graph.claimLiteral(root, L0.HasName, newName + "@1", Bindings.STRING);\r
-                                       }\r
-                           } else {\r
-                           String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));\r
-                           if(!newName.equals(baseName)) {\r
-                               graph.claimLiteral(root, L0.HasName, newName, Bindings.STRING);\r
-                           }\r
-                           }\r
-\r
-                           graph.deny(root, L0.PartOf);\r
-                           graph.claim(root, L0.PartOf, parent);\r
-\r
-                           CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-                           graph.addMetadata(cm.add("Imported " + graph.getURI(root) + ", resource " + root));\r
-                           \r
-                           result.add(root);\r
-                    \r
-                       }\r
-                       \r
-                       graph.deny(resource, L0.PartOf);\r
-\r
-                }\r
-            });\r
-        } else {\r
-            TransferableGraph1 tg = getTG(session, state);\r
-            if(tg != null) {\r
-                DefaultPasteHandler.defaultExecute(tg, parent, new IImportAdvisor() {\r
-                    \r
-                    @Override\r
-                    public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {\r
-                        Resource r = advisor.createRoot(graph, root);\r
-                        result.add(r);\r
-                        return r;\r
-                    }\r
-                    \r
-                    @Override\r
-                    public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {\r
-                        return advisor.analyzeRoot(graph, root);\r
-                    }\r
-                });\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-    \r
-    \r
-    @SuppressWarnings("deprecation")\r
-       public static Collection<MigrationStep> getMigrationSteps(DataContainer header) throws DatabaseException {\r
-       \r
-       return SimanticsInternal.sync(new BinaryRead<String,Integer,Collection<MigrationStep>>(header.format, header.version) {\r
-\r
-                       @Override\r
-                       public Collection<MigrationStep> perform(ReadGraph graph) throws DatabaseException {\r
-                               \r
-                               Layer0 L0 = Layer0.getInstance(graph);\r
-                               ArrayList<Pair<Double,MigrationStep>> steps = new ArrayList<Pair<Double,MigrationStep>>();\r
-                       Instances query = graph.adapt(L0.Migration, Instances.class);\r
-                       Set<Resource> migrations = new HashSet<Resource>();\r
-                               for(Resource ontology : Layer0Utils.listOntologies(graph)) {\r
-                                       migrations.addAll(Layer0Utils.sortByCluster(graph, query.find(graph, ontology)));\r
-                               }\r
-                               for(Resource migration : migrations) {\r
-                                       if(DEBUG)\r
-                                               System.err.println("getMigrationSteps: " + graph.getURI(migration));\r
-                                       String format = graph.getRelatedValue(migration, L0.Migration_format);\r
-                                       if(DEBUG)\r
-                                               System.err.println("-format=" + format);\r
-                                       if(parameter.equals(format)) {\r
-                                               Integer from = graph.getRelatedValue(migration, L0.Migration_from);\r
-                                               if(DEBUG)\r
-                                                       System.err.println("-from=" + from);\r
-                                               Resource step = graph.getSingleObject(migration, L0.Migration_step);\r
-                                               if(parameter2.equals(from)) {\r
-                                                       Double priority = graph.getRelatedValue(migration, L0.Migration_priority);\r
-                                                       steps.add(Pair.make(-priority, graph.adapt(step, MigrationStep.class))); \r
-                                                       if(DEBUG)\r
-                                                               System.err.println("=> ACCEPT");\r
-                                               } else {\r
-                                                       if(DEBUG)\r
-                                                               System.err.println("=> REJECT");\r
-                                               }\r
-                                       }\r
-                               }\r
-                               /*\r
-                               Resource base = graph.getResource(baseURI);\r
-                       if(DEBUG)\r
-                               System.err.println("getMigrationSteps format=" + parameter + ", version=" + parameter2);\r
-                               for(Resource migration : graph.sync(new ObjectsWithType(base, L0.ConsistsOf, L0.Migration))) {\r
-                               }*/\r
-                               return CollectionUtils.sortByFirst(steps);\r
-                       }\r
-               \r
-       });\r
-    }\r
-    \r
-    public static Resource importMigrated(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {\r
-       Collection<Resource> roots = importMigratedMany(monitor, session, modelFile, state, advisor, target);\r
-        if(roots.size() == 1) {\r
-            return roots.iterator().next();\r
-        } else {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    public static Collection<Resource> importMigratedMany(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {\r
-\r
-       //assert(target != null);\r
-       assert(advisor != null);\r
-       \r
-       if(monitor == null) monitor = new NullProgressMonitor();\r
-       \r
-       if(DEBUG)\r
-               System.err.println("importMigrated: file=" + (modelFile != null ? modelFile.getAbsolutePath() : null));\r
-       \r
-       //String baseURI = state.getProperty(MigrationStateKeys.BASE_URI);\r
-//     if(DEBUG)\r
-//             System.err.println("importMigrated: baseURI=" + baseURI);\r
-\r
-        state.setProperty(MigrationStateKeys.MODEL_FILE, modelFile);\r
-        state.setProperty(MigrationStateKeys.SESSION, session);\r
-        state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);\r
-        state.setProperty(MigrationStateKeys.IMPORT_ADVISOR, advisor);\r
-\r
-        DataContainer dc = state.getProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER);\r
-        Collection<MigrationStep> migration = getMigrationSteps(dc);\r
-\r
-//        TransferableGraph1 tg = state.getProperty(MigrationStateKeys.CURRENT_TG);\r
-//        state.setProperty(MigrationStateKeys.TG_EXTENSIONS, tg.extensions);\r
-       \r
-        for(MigrationStep step : migration) {\r
-            step.applyTo(monitor, session, state);\r
-            if (monitor.isCanceled())\r
-                break;\r
-        }\r
-\r
-        if (monitor.isCanceled()) {\r
-            // Move possibly created material into TrashBin and quit.\r
-            final Resource root = state.probeProperty(MigrationStateKeys.CURRENT_RESOURCE);\r
-            if (root != null) {\r
-                session.syncRequest(new WriteRequest() {\r
-                    @Override\r
-                    public void perform(WriteGraph graph) throws DatabaseException {\r
-                        new TrashBinRemover(root).remove(graph);\r
-                    }\r
-                });\r
-            }\r
-            return Collections.emptyList();\r
-        }\r
-\r
-        // Absolute path imports end up here\r
-        if(target == null) {\r
-               Collection<Resource> roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);\r
-               return roots;\r
-        }\r
-                       \r
-        // Finally import model into final destination\r
-        return importTo(monitor, session, state, target, advisor);\r
-        \r
-    }\r
-    \r
-    public static TransferableGraph1 getTG(Session session, MigrationState state) throws DatabaseException {\r
-        return state.getProperty(MigrationStateKeys.CURRENT_TG);\r
-    }\r
-    \r
-    public static Resource getResource(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {\r
-        return state.getProperty(MigrationStateKeys.CURRENT_RESOURCE);\r
-    }\r
-\r
-    public static Collection<Resource> getRootResources(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {\r
-        return state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);\r
-    }\r
-\r
-    /**\r
-     * Get a property from the specified MigrationState and return specified\r
-     * default value if the property value is <code>null</code>.\r
-     * \r
-     * @param state the state to get the property from\r
-     * @param key the property to get\r
-     * @param defaultValue\r
-     *            the default value to return if the property value is\r
-     *            <code>null</code>\r
-     * @return the property value\r
-     * @throws DatabaseException\r
-     *             if fetching the property fails for some reason\r
-     */\r
-    public static <T> T getProperty(MigrationState state, String key, T defaultValue) throws DatabaseException {\r
-        T t = state.getProperty(key);\r
-        return t != null ? t : defaultValue;\r
-    }\r
-\r
-    public static Resource importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {\r
-       return importSharedOntology(null, session, tg, published);\r
-    }\r
-\r
-    public static Resource importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {\r
-       \r
-       if(monitor == null) monitor = new NullProgressMonitor();\r
-       \r
-        Collection<Identity> roots = TransferableGraphUtils.getRoots(tg);\r
-        if(roots.size() == 1) {\r
-//             Identity id = roots.iterator().next();\r
-//             final Root root = (Root)id.definition;\r
-//             Resource rootResource = session.syncRequest(new WriteResultRequest<Resource>() {\r
-//                             @Override\r
-//                             public Resource perform(WriteGraph graph) throws DatabaseException {\r
-//                                     Resource type = graph.getResource(root.type);\r
-//                                     Resource existing = graph.getPossibleResource(root.name);\r
-//                                     if(existing != null) throw new DatabaseException("Shared library " + root.name + " exists already.");\r
-//                                     return Layer0Utils.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, root.name, type);\r
-//                             }\r
-//             });\r
-            try {\r
-               \r
-                TGTransferableGraphSource tgSource = new TGTransferableGraphSource(tg);\r
-                SharedOntologyImportAdvisor advisor = new SharedOntologyImportAdvisor(published);\r
-//                TransferableGraphs.importGraph1(session, tgSource, advisor);\r
-                \r
-//                if (advisor.getRoots().size() == 1) {\r
-//                     return advisor.getRoots().iterator().next();\r
-//                }\r
-                               //TransferableGraphs.importGraph1(session, tg, new SharedOntologyImportAdvisor(), null);\r
-\r
-                MigrationState state = newState();\r
-                //state.setProperty(MigrationStateKeys.BASE_URI, AprosBuiltins.URIs.Migration);\r
-                state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, false);\r
-                state.setProperty(MigrationStateKeys.CURRENT_TGS, tgSource);\r
-                state.setProperty(MigrationStateKeys.SESSION, session);\r
-                state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);\r
-                state.setProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER, new DataContainer("sharedLibrary", 1, new Variant(TransferableGraph1.BINDING, tg)));\r
-\r
-                return MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);\r
-                \r
-                       } catch (TransferableGraphException e) {\r
-                               throw new DatabaseException(e);\r
-                       } catch (MissingDependencyException e) {\r
-                               throw e;\r
-                       } catch (Exception e) {\r
-                           throw new DatabaseException(e);\r
-            } finally {\r
-                session.getService(XSupport.class).setServiceMode(false, false);\r
-            }\r
-            \r
-        }\r
-        \r
-        return null;\r
-        \r
-    }\r
-    \r
-}\r
+/*******************************************************************************
+ * 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.migration;
+
+import java.io.DataInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.container.DataContainer;
+import org.simantics.databoard.container.DataContainers;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.WriteOnlyGraph;
+import org.simantics.db.common.CommentMetadata;
+import org.simantics.db.common.primitiverequest.PossibleResource;
+import org.simantics.db.common.request.BinaryRead;
+import org.simantics.db.common.request.FreshEscapedName;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.VersionMap;
+import org.simantics.db.common.utils.VersionMapRequest;
+import org.simantics.db.common.utils.Versions;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
+import org.simantics.db.layer0.adapter.impl.SharedOntologyImportAdvisor;
+import org.simantics.db.layer0.adapter.impl.TrashBinRemover;
+import org.simantics.db.layer0.internal.SimanticsInternal;
+import org.simantics.db.layer0.util.ExternalDownloadBean;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.layer0.util.TGTransferableGraphSource;
+import org.simantics.db.service.XSupport;
+import org.simantics.graph.db.IImportAdvisor;
+import org.simantics.graph.db.ImportResult;
+import org.simantics.graph.db.MissingDependencyException;
+import org.simantics.graph.db.TransferableGraphException;
+import org.simantics.graph.representation.Identity;
+import org.simantics.graph.representation.Root;
+import org.simantics.graph.representation.TransferableGraph1;
+import org.simantics.graph.representation.TransferableGraphUtils;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.simantics.simulation.ontology.SimulationResource;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.datastructures.collections.CollectionUtils;
+
+public class MigrationUtils {
+       
+       public static final boolean DEBUG = false;
+
+    public static MigrationState newState() {
+        return new MigrationStateImpl();
+    }
+
+    public static MigrationStep getStep(Session session, String uri) throws DatabaseException {
+        return session.sync(new UnaryRead<String, MigrationStep>(uri) {
+
+            @Override
+            public MigrationStep perform(ReadGraph graph) throws DatabaseException {
+                Resource r = graph.getResource(parameter);
+                return graph.adapt(r, MigrationStep.class);
+            }
+
+        });
+    }
+
+//    public static TransferableGraph1 getTG(Session session, MigrationState state) {
+//        return getTG(session, state, true, false);
+//    }
+    
+    public static void clearTempResource(Session session, final Resource resource) {
+        session.asyncRequest(new WriteRequest() {
+
+            @Override
+            public void perform(WriteGraph graph) throws DatabaseException {
+                graph.deny(resource, Layer0.getInstance(graph).PartOf);
+            }
+        });
+    }
+
+    /**
+     * Activate the imported resource, if there are no other active models and the resource is a Model. 
+     */
+    private static void activateIfNoActiveModel(WriteGraph graph, Resource root, Resource parent) throws DatabaseException {
+        Layer0X L0X = Layer0X.getInstance(graph);
+        SimulationResource SIMU = SimulationResource.getInstance(graph);
+        if(!graph.hasStatement(parent, L0X.Activates) && graph.isInstanceOf(root, SIMU.Model))
+            graph.claim(parent, L0X.Activates, root);
+    }
+
+    public static Collection<Resource> importTo(IProgressMonitor monitor, Session session, MigrationState state, final Resource parent, final IImportAdvisor advisor) throws DatabaseException, TransferableGraphException {
+        final Resource resource = getResource(monitor, session, state);
+        final ArrayList<Resource> result = new ArrayList<Resource>();
+        if(resource != null) {
+            session.syncRequest(new WriteRequest() {
+                
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    
+                       Layer0 L0 = Layer0.getInstance(graph);
+                       
+                       for(Resource root : graph.getObjects(resource, L0.ConsistsOf)) {
+                               
+                               String baseName = Versions.getBaseName(graph, root);
+                           String version = Versions.getVersion(graph, root);
+                           if(version != null) {
+                                       VersionMap map = graph.syncRequest(new VersionMapRequest(parent));
+                                       if(map.contains(baseName, version)) {
+                                   String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));
+                                       graph.claimLiteral(root, L0.HasName, newName + "@1", Bindings.STRING);
+                                       }
+                           } else {
+                           String newName = graph.syncRequest(new FreshEscapedName(parent, Layer0.getInstance(graph).ConsistsOf, baseName));
+                           if(!newName.equals(baseName)) {
+                               graph.claimLiteral(root, L0.HasName, newName, Bindings.STRING);
+                           }
+                           }
+
+                           graph.deny(root, L0.PartOf);
+                           graph.claim(root, L0.PartOf, parent);
+                           
+                           // FIXME : Model activation must be done in "activations" virtual graph.
+                           // FIXME : This step should be optional, not all the products use active models.
+                           //activateIfNoActiveModel(graph, root, parent);
+
+                           CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+                           graph.addMetadata(cm.add("Imported " + graph.getURI(root) + ", resource " + root));
+                           
+                           result.add(root);
+                    
+                       }
+                       
+                       graph.deny(resource, L0.PartOf);
+
+                }
+            });
+        } else {
+            TransferableGraph1 tg = getTG(session, state);
+            if(tg != null) {
+                DefaultPasteHandler.defaultExecute(tg, parent, new IImportAdvisor() {
+                    
+                    @Override
+                    public Resource createRoot(WriteOnlyGraph graph, Root root) throws DatabaseException {
+                        Resource r = advisor.createRoot(graph, root);
+                        result.add(r);
+                        return r;
+                    }
+                    
+                    @Override
+                    public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
+                        return advisor.analyzeRoot(graph, root);
+                    }
+                });
+            }
+        }
+        return result;
+    }
+    
+    
+       public static Collection<MigrationStep> getMigrationSteps(DataContainer header) throws DatabaseException {
+       
+       return SimanticsInternal.sync(new BinaryRead<String,Integer,Collection<MigrationStep>>(header.format, header.version) {
+
+                       @Override
+                       public Collection<MigrationStep> perform(ReadGraph graph) throws DatabaseException {
+                               
+                               Layer0 L0 = Layer0.getInstance(graph);
+                               ArrayList<Pair<Double,MigrationStep>> steps = new ArrayList<Pair<Double,MigrationStep>>();
+                       Instances query = graph.adapt(L0.Migration, Instances.class);
+                       Set<Resource> migrations = new HashSet<Resource>();
+                               for(Resource ontology : Layer0Utils.listOntologies(graph)) {
+                                       migrations.addAll(Layer0Utils.sortByCluster(graph, query.find(graph, ontology)));
+                               }
+                               for(Resource migration : migrations) {
+                                       if(DEBUG)
+                                               System.err.println("getMigrationSteps: " + graph.getURI(migration));
+                                       String format = graph.getRelatedValue(migration, L0.Migration_format);
+                                       if(DEBUG)
+                                               System.err.println("-format=" + format);
+                                       if(parameter.equals(format)) {
+                                               Integer from = graph.getRelatedValue(migration, L0.Migration_from);
+                                               if(DEBUG)
+                                                       System.err.println("-from=" + from);
+                                               Resource step = graph.getSingleObject(migration, L0.Migration_step);
+                                               if(parameter2.equals(from)) {
+                                                       Double priority = graph.getRelatedValue(migration, L0.Migration_priority);
+                                                       steps.add(Pair.make(-priority, graph.adapt(step, MigrationStep.class))); 
+                                                       if(DEBUG)
+                                                               System.err.println("=> ACCEPT");
+                                               } else {
+                                                       if(DEBUG)
+                                                               System.err.println("=> REJECT");
+                                               }
+                                       }
+                               }
+                               /*
+                               Resource base = graph.getResource(baseURI);
+                       if(DEBUG)
+                               System.err.println("getMigrationSteps format=" + parameter + ", version=" + parameter2);
+                               for(Resource migration : graph.sync(new ObjectsWithType(base, L0.ConsistsOf, L0.Migration))) {
+                               }*/
+                               return CollectionUtils.sortByFirst(steps);
+                       }
+               
+       });
+    }
+    
+    public static Resource importMigrated(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {
+       Collection<Resource> roots = importMigratedMany(monitor, session, modelFile, state, advisor, target);
+        if(roots.size() == 1) {
+            return roots.iterator().next();
+        } else {
+            return null;
+        }
+    }
+
+    public static Collection<Resource> importMigratedMany(IProgressMonitor monitor, Session session, File modelFile, MigrationState state, IImportAdvisor advisor, Resource target) throws Exception {
+
+       //assert(target != null);
+       assert(advisor != null);
+       
+       if(monitor == null) monitor = new NullProgressMonitor();
+       
+       if(DEBUG)
+               System.err.println("importMigrated: file=" + (modelFile != null ? modelFile.getAbsolutePath() : null));
+       
+       //String baseURI = state.getProperty(MigrationStateKeys.BASE_URI);
+//     if(DEBUG)
+//             System.err.println("importMigrated: baseURI=" + baseURI);
+
+        state.setProperty(MigrationStateKeys.MODEL_FILE, modelFile);
+        state.setProperty(MigrationStateKeys.SESSION, session);
+        state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
+        state.setProperty(MigrationStateKeys.IMPORT_ADVISOR, advisor);
+
+        DataContainer dc = state.getProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER);
+        Collection<MigrationStep> migration = getMigrationSteps(dc);
+
+//        TransferableGraph1 tg = state.getProperty(MigrationStateKeys.CURRENT_TG);
+//        state.setProperty(MigrationStateKeys.TG_EXTENSIONS, tg.extensions);
+       
+        for(MigrationStep step : migration) {
+            step.applyTo(monitor, session, state);
+            if (monitor.isCanceled())
+                break;
+        }
+
+        if (monitor.isCanceled()) {
+            // Move possibly created material into TrashBin and quit.
+            final Resource root = state.probeProperty(MigrationStateKeys.CURRENT_RESOURCE);
+            if (root != null) {
+                session.syncRequest(new WriteRequest() {
+                    @Override
+                    public void perform(WriteGraph graph) throws DatabaseException {
+                        new TrashBinRemover(root).remove(graph);
+                    }
+                });
+            }
+            return Collections.emptyList();
+        }
+
+        // Absolute path imports end up here
+        if(target == null) {
+               Collection<Resource> roots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
+               return roots;
+        }
+                       
+        // Finally import model into final destination
+        return importTo(monitor, session, state, target, advisor);
+        
+    }
+    
+    public static TransferableGraph1 getTG(Session session, MigrationState state) throws DatabaseException {
+        return state.getProperty(MigrationStateKeys.CURRENT_TG);
+    }
+    
+    public static Resource getResource(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
+        return state.getProperty(MigrationStateKeys.CURRENT_RESOURCE);
+    }
+
+    public static Collection<Resource> getRootResources(IProgressMonitor monitor, Session session, MigrationState state) throws DatabaseException {
+        return state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
+    }
+
+    /**
+     * Get a property from the specified MigrationState and return specified
+     * default value if the property value is <code>null</code>.
+     * 
+     * @param state the state to get the property from
+     * @param key the property to get
+     * @param defaultValue
+     *            the default value to return if the property value is
+     *            <code>null</code>
+     * @return the property value
+     * @throws DatabaseException
+     *             if fetching the property fails for some reason
+     */
+    public static <T> T getProperty(MigrationState state, String key, T defaultValue) throws DatabaseException {
+        T t = state.getProperty(key);
+        return t != null ? t : defaultValue;
+    }
+
+    public static MigratedImportResult importSharedOntology(Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
+       return importSharedOntology(null, session, tg, published);
+    }
+
+    public static MigratedImportResult importSharedOntology(IProgressMonitor monitor, Session session, TransferableGraph1 tg, boolean published) throws DatabaseException {
+       
+       if(monitor == null) monitor = new NullProgressMonitor();
+       
+       Variant edbVariant = tg.extensions.get(ExternalDownloadBean.EXTENSION_KEY);
+       if(edbVariant != null) {
+               try {
+                               ExternalDownloadBean edb = (ExternalDownloadBean)edbVariant.getValue(ExternalDownloadBean.BINDING);
+                               for(Map.Entry<String, String> entry : edb.downloads.entrySet()) {
+                                       String uri = entry.getKey();
+                                       Resource existing = session.syncRequest(new PossibleResource(uri));
+                                       if(existing == null) {
+                                               String download = entry.getValue();
+                                                URL url = new URL(download);
+                                                DataContainer container = DataContainers.readFile(new DataInputStream(url.openStream()));
+                                                TransferableGraph1 dependencyTg = (TransferableGraph1) container.content.getValue(TransferableGraph1.BINDING);
+                                                importSharedOntology(monitor, session, dependencyTg, true);
+                                       }
+                               }
+                       } catch (AdaptException e) {
+                               throw new DatabaseException(e);
+                       } catch (MalformedURLException e) {
+                               throw new DatabaseException(e);
+                       } catch (IOException e) {
+                               throw new DatabaseException(e);
+                       }
+               
+       }
+       
+        Collection<Identity> roots = TransferableGraphUtils.getRoots(tg);
+        if(roots.size() == 1) {
+            try {
+                TGTransferableGraphSource tgSource = new TGTransferableGraphSource(tg);
+                SharedOntologyImportAdvisor advisor = new SharedOntologyImportAdvisor(published);
+
+                MigrationState state = newState();
+                state.setProperty(MigrationStateKeys.UPDATE_DEPENDENCIES, false);
+                state.setProperty(MigrationStateKeys.CURRENT_TGS, tgSource);
+                state.setProperty(MigrationStateKeys.SESSION, session);
+                state.setProperty(MigrationStateKeys.PROGRESS_MONITOR, monitor);
+                state.setProperty(MigrationStateKeys.CURRENT_DATA_CONTAINER, new DataContainer("sharedLibrary", 1, new Variant(TransferableGraph1.BINDING, tg)));
+
+                MigrationUtils.importMigrated(monitor, session, null, state, advisor, null);
+
+                Collection<Resource> resultRoots = state.getProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES);
+                ImportResult result = state.getProperty(MigrationStateKeys.IMPORT_RESULT);
+                return new MigratedImportResult(resultRoots, result);
+                       } catch (TransferableGraphException e) {
+                               throw new DatabaseException(e);
+                       } catch (MissingDependencyException e) {
+                               throw e;
+                       } catch (DatabaseException e) {
+                               throw e;
+                       } catch (Exception e) {
+                           throw new DatabaseException(e);
+            } finally {
+                session.getService(XSupport.class).setServiceMode(false, false);
+            }
+            
+        }
+        
+        return null;
+        
+    }
+    
+}