]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/migration/MigrationStateImpl.java
Fixed migrating import temporary folder creation to prevent name overlap
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / migration / MigrationStateImpl.java
index 2b19da58607dd66fa9368296ccf99a11100f30c2..d7f6b4e95497fe0a1ac0991cf27c38720f316681 100644 (file)
@@ -11,6 +11,7 @@
  *******************************************************************************/
 package org.simantics.db.layer0.migration;
 
+import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
 import java.text.DateFormat;
@@ -24,6 +25,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
 import org.simantics.databoard.Bindings;
 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;
@@ -31,12 +33,14 @@ import org.simantics.db.WriteGraph;
 import org.simantics.db.WriteOnlyGraph;
 import org.simantics.db.common.request.WriteResultRequest;
 import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.utils.NameUtils;
 import org.simantics.db.exception.AssumptionException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
 import org.simantics.db.layer0.internal.SimanticsInternal;
 import org.simantics.db.layer0.util.Layer0Utils;
 import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
+import org.simantics.db.layer0.util.TGProgressMonitor;
 import org.simantics.db.layer0.util.TGTransferableGraphSource;
 import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
 import org.simantics.db.request.Read;
@@ -51,10 +55,10 @@ import org.simantics.graph.db.TransferableGraphImporter;
 import org.simantics.graph.db.TransferableGraphSource;
 import org.simantics.graph.db.TransferableGraphs;
 import org.simantics.graph.db.WrapperAdvisor;
-import org.simantics.graph.representation.ByteFileReader;
 import org.simantics.graph.representation.TransferableGraph1;
 import org.simantics.graph.representation.TransferableGraphFileReader;
 import org.simantics.layer0.Layer0;
+import org.simantics.utils.logging.TimeLogger;
 
 public class MigrationStateImpl implements MigrationState {
 
@@ -106,7 +110,9 @@ public class MigrationStateImpl implements MigrationState {
             try {
                 File modelFile = getProperty(MigrationStateKeys.MODEL_FILE);
                 reader = new TransferableGraphFileReader(modelFile);
+                TimeLogger.log(MigrationStateImpl.class, "reading TG into memory from " + modelFile);
                 TransferableGraph1 tg = reader.readTG();
+                TimeLogger.log(MigrationStateImpl.class, "read TG into memory from " + modelFile);
                 setProperty(MigrationStateKeys.CURRENT_TG, tg);
                 return (T)tg;
             } catch (DatabaseException e) {
@@ -120,20 +126,7 @@ public class MigrationStateImpl implements MigrationState {
         } else if (MigrationStateKeys.CURRENT_TGS.equals(key)) {
 
             File modelFile = getProperty(MigrationStateKeys.MODEL_FILE);
-            
-            try {
-                StreamingTransferableGraphFileReader reader = new StreamingTransferableGraphFileReader(modelFile);
-                TransferableGraphSource tgs = reader.readTG();
-                setProperty(MigrationStateKeys.CURRENT_TGS_READER, reader);
-                setProperty(MigrationStateKeys.CURRENT_TGS, tgs);
-                return (T)tgs;
-            } catch (DatabaseException e) {
-                throw e;
-            } catch (IOException e) {
-               throw new DatabaseException("An I/O exception occurred during reading '" + modelFile.getAbsolutePath() + "'", e);
-            } catch (Throwable t) {
-                throw new DatabaseException(t);
-            }
+            return (T) initializeTransferableGraphSource(modelFile);
 
         } else if (MigrationStateKeys.CURRENT_DATA_CONTAINER.equals(key)) {
             
@@ -166,120 +159,22 @@ public class MigrationStateImpl implements MigrationState {
             }
 
         } else if (MigrationStateKeys.CURRENT_RESOURCE.equals(key) || MigrationStateKeys.CURRENT_ROOT_RESOURCES.equals(key)) {
-            
+
             final Session session = getProperty(MigrationStateKeys.SESSION);
             final IProgressMonitor monitor = probeProperty(MigrationStateKeys.PROGRESS_MONITOR);
             final boolean updateDependencies = MigrationUtils.getProperty(this, MigrationStateKeys.UPDATE_DEPENDENCIES, Boolean.TRUE);
-            
-            final TransferableGraph1 tg = probeProperty(MigrationStateKeys.CURRENT_TG);
-            if(tg != null) {
-               
-                final Resource indexRoot = session.syncRequest(new WriteResultRequest<Resource>() {
-                    @Override
-                    public Resource perform(WriteGraph graph) throws DatabaseException {
-                        if(!updateDependencies)
-                            Layer0Utils.setDependenciesIndexingDisabled(graph, true);
-                        return createTemporaryRoot(graph);
-                    }
-                });
-
-                IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot));
-                IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) {
-                       @Override
-                    public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {
-                       super.beforeWrite(graph, process);
-                        if(!updateDependencies)
-                            Layer0Utils.setDependenciesIndexingDisabled(graph, true);
-                    }
-                       @Override
-                    public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {
-                       super.afterWrite(graph, process);
-                       Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS);
-                       if(storeResources != null && storeResources) {
-                               long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class));
-                               setProperty(MigrationStateKeys.RESOURCE_IDS, ids);
-                       }
-                    }
-                               };
-                               // Make sure that the supplied advisor is redirected to temp
-                               advisor.redirect(indexRoot);
-
-                ImportResult ir = TransferableGraphs.importGraph1(session, new TGTransferableGraphSource(tg), advisor, new TGStatusMonitor() {
-                    @Override
-                    public void status(int percentage) {
-                        monitor.subTask("Importing model from file (" + percentage + "%)");
-                    }
-                    @Override
-                    public boolean isCanceled() {
-                        return monitor.isCanceled();
-                    }
-                });
-
-                setProperty(MigrationStateKeys.IMPORT_RESULT, ir);
-                setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);
-                setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));
-                setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());
-                setProperty(MigrationStateKeys.CURRENT_TG, null);
-
-                return getProperty(key);
-            }
 
-            final TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS);
-            if(tgs != null) {
-
-                final Resource indexRoot = session.syncRequest(new WriteResultRequest<Resource>() {
-                    @Override
-                    public Resource perform(WriteGraph graph) throws DatabaseException {
-                        if(!updateDependencies)
-                            Layer0Utils.setDependenciesIndexingDisabled(graph, true);
-                        return createTemporaryRoot(graph);
-                    }
-                });
-
-                IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot));
-                IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) {
-                       @Override
-                       public Resource getTarget() {
-                               return indexRoot;
-                       }
-                       @Override
-                    public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {
-                       super.beforeWrite(graph, process);
-                        if(!updateDependencies)
-                            Layer0Utils.setDependenciesIndexingDisabled(graph, true);
-                    }
-                       @Override
-                    public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {
-                       super.afterWrite(graph, process);
-                       Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS);
-                       if(storeResources != null && storeResources) {
-                               long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class));
-                               setProperty(MigrationStateKeys.RESOURCE_IDS, ids);
-                       }
-                    }
-                               };
-                               // Make sure that the supplied advisor is redirected to temp
-                               advisor.redirect(indexRoot);
-                               
-                ImportResult ir = TransferableGraphs.importGraph1(session, tgs, advisor, new TGStatusMonitor() {
-                    @Override
-                    public void status(int percentage) {
-                        monitor.subTask("Importing model from file (" + percentage + "%)");
-                    }
-                    @Override
-                    public boolean isCanceled() {
-                        return monitor.isCanceled();
-                    }
-                });
-
-                setProperty(MigrationStateKeys.IMPORT_RESULT, ir);
-                setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);
-                setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));
-                setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());
-                setProperty(MigrationStateKeys.CURRENT_TG, null);
+            File temporaryTg = exportCurrentTgAsTemporaryFile(session, monitor);
+            if (temporaryTg != null)
+                setProperty(MigrationStateKeys.CURRENT_TGS, initializeTransferableGraphSource(temporaryTg));
 
+            TransferableGraphSource tgs = getProperty(MigrationStateKeys.CURRENT_TGS);
+            if (tgs != null) {
+                importTransferableGraphSource(monitor, session, updateDependencies, tgs);
+                // Delete temporary file if necessary
+                if (temporaryTg != null)
+                    temporaryTg.delete();
                 return getProperty(key);
-
             }
 
         } else if (MigrationStateKeys.UPDATE_DEPENDENCIES.equals(key)) {
@@ -308,7 +203,7 @@ public class MigrationStateImpl implements MigrationState {
                }
        }
 
-       private static void uncheckedClose(ByteFileReader closeable) {
+       private static void uncheckedClose(Closeable closeable) {
                try {
                        if (closeable != null)
                                closeable.close();
@@ -327,10 +222,133 @@ public class MigrationStateImpl implements MigrationState {
 
         Resource indexRoot = graph.newResource();
         String indexRootName = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date());
+        indexRootName = NameUtils.findFreshName(graph, indexRootName, temp, L0.ConsistsOf, "%s-%d");
         graph.claim(indexRoot, L0.InstanceOf, L0.IndexRoot);
         graph.addLiteral(indexRoot, L0.HasName, L0.String, indexRootName, Bindings.STRING);
         graph.claim(temp, L0.ConsistsOf, indexRoot);
         return indexRoot;
     }
 
+       private File exportCurrentTgAsTemporaryFile(Session session, IProgressMonitor monitor) throws DatabaseException {
+               TransferableGraph1 tg = probeProperty(MigrationStateKeys.CURRENT_TG);
+               if (tg == null)
+                       return null;
+
+               try {
+                       // Write TG back to disk and initialize CURRENT_TGS for the migrated TG.
+                       File modelFile = getProperty(MigrationStateKeys.MODEL_FILE);
+                       File tempFile = File.createTempFile("temporary-tgs", ".tg", SimanticsInternal.getTemporaryDirectory());
+                       TimeLogger.log(MigrationStateImpl.class, "export temporary TG " + tempFile);
+
+                       DataContainer dc = DataContainers.readHeader(modelFile);
+                       TransferableGraphs.writeTransferableGraph(session, dc.format, dc.version, dc.metadata,
+                                       new TGTransferableGraphSource(tg),
+                                       tempFile,
+                                       new TGExportMonitor(monitor, "Exporting temporary transferable graph"));
+
+                       // Allow potentially large TG structure to be GC'ed.
+                       setProperty(MigrationStateKeys.CURRENT_TG, null);
+
+                       TimeLogger.log(MigrationStateImpl.class, "export temporary TG done " + tempFile);
+                       return tempFile;
+               } catch (Exception e) {
+                       throw new DatabaseException(e);
+               }
+       }
+
+       private TransferableGraphSource initializeTransferableGraphSource(File dataContainer) throws DatabaseException {
+               try {
+                       StreamingTransferableGraphFileReader reader = new StreamingTransferableGraphFileReader(dataContainer);
+                       TransferableGraphSource tgs = reader.readTG();
+                       setProperty(MigrationStateKeys.CURRENT_TGS_READER, reader);
+                       setProperty(MigrationStateKeys.CURRENT_TGS, tgs);
+                       return tgs;
+               } catch (DatabaseException e) {
+                       throw e;
+               } catch (IOException e) {
+                       throw new DatabaseException("An I/O exception occurred during reading '" + dataContainer.getAbsolutePath() + "'", e);
+               } catch (Throwable t) {
+                       throw new DatabaseException(t);
+               }
+       }
+
+       private void importTransferableGraphSource(IProgressMonitor monitor, Session session, boolean updateDependencies, TransferableGraphSource tgs) throws DatabaseException {
+               TimeLogger.log(MigrationStateImpl.class, "import TGS " + tgs);
+               final Resource indexRoot = session.syncRequest(new WriteResultRequest<Resource>() {
+                       @Override
+                       public Resource perform(WriteGraph graph) throws DatabaseException {
+                               if(!updateDependencies)
+                                       Layer0Utils.setDependenciesIndexingDisabled(graph, true);
+                               return createTemporaryRoot(graph);
+                       }
+               });
+
+               IImportAdvisor baseAdvisor = MigrationUtils.getProperty(this, MigrationStateKeys.IMPORT_ADVISOR, new DefaultPasteImportAdvisor(indexRoot));
+               IImportAdvisor2 advisor = new WrapperAdvisor(baseAdvisor) {
+                       @Override
+                       public Resource getTarget() {
+                               return indexRoot;
+                       }
+                       @Override
+                       public void beforeWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {
+                               super.beforeWrite(graph, process);
+                               if(!updateDependencies)
+                                       Layer0Utils.setDependenciesIndexingDisabled(graph, true);
+                       }
+                       @Override
+                       public void afterWrite(WriteOnlyGraph graph, TransferableGraphImporter process) throws DatabaseException {
+                               super.afterWrite(graph, process);
+                               Boolean storeResources = probeProperty(MigrationStateKeys.GET_RESOURCE_IDS);
+                               if(storeResources != null && storeResources) {
+                                       long[] ids = process.getResourceIds(session.getService(SerialisationSupport.class));
+                                       setProperty(MigrationStateKeys.RESOURCE_IDS, ids);
+                               }
+                       }
+               };
+
+               // Make sure that the supplied advisor is redirected to temp
+               advisor.redirect(indexRoot);
+
+               String task = "Importing model into database";
+               monitor.subTask(task);
+               ImportResult ir = TransferableGraphs.importGraph1(session, tgs, advisor, new TGImportMonitor(monitor, task));
+               monitor.subTask("");
+
+               setProperty(MigrationStateKeys.IMPORT_RESULT, ir);
+               setProperty(MigrationStateKeys.CURRENT_RESOURCE, indexRoot);
+               setProperty(MigrationStateKeys.CURRENT_ROOT_RESOURCES, new ArrayList<>(advisor.getRoots()));
+               setProperty(MigrationStateKeys.DATABASE_REVISION_AFTER_TG_IMPORT, session.getService(ManagementSupport.class).getHeadRevisionId());
+               TimeLogger.log(MigrationStateImpl.class, "imported TGS " + tgs);
+       }
+
+       
+       static class TGImportMonitor implements TGStatusMonitor {
+               private final IProgressMonitor monitor;
+               private final String message;
+               public TGImportMonitor(IProgressMonitor monitor, String message) {
+                       this.monitor = monitor;
+                       this.message = message;
+               }
+               @Override
+               public void status(int percentage) {
+                       monitor.subTask(message + " (" + percentage + "%)");
+               }
+               @Override
+               public boolean isCanceled() {
+                       return monitor.isCanceled();
+               }
+       }
+
+       static class TGExportMonitor extends TGProgressMonitor {
+               private final String message;
+               public TGExportMonitor(IProgressMonitor monitor, String message) {
+                       super(monitor);
+                       this.message = message;
+               }
+               @Override
+               protected void workDone(int percentage) {
+                       monitor.subTask(message + " (" + percentage + "%)");
+               }
+       }
+
 }