*******************************************************************************/
package org.simantics.db.layer0.migration;
+import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
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;
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;
import org.simantics.db.service.ManagementSupport;
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 {
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) {
} 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)) {
}
} 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);
-
- TransferableGraphs.importGraph1WithMonitor(session, 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.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);
-
- 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.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)) {
}
}
- private static void uncheckedClose(ByteFileReader closeable) {
+ private static void uncheckedClose(Closeable closeable) {
try {
if (closeable != null)
closeable.close();
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);
+ TransferableGraphs.importGraph1(session, tgs, advisor, new TGImportMonitor(monitor, task));
+
+ 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 + "%)");
+ }
+ }
+
}