*******************************************************************************/\r
package org.simantics.modeling.ui.wizard;\r
\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
+import java.lang.reflect.InvocationTargetException;\r
import java.util.ArrayList;\r
import java.util.Collection;\r
import java.util.Collections;\r
import java.util.Map;\r
import java.util.Set;\r
\r
+import org.eclipse.core.runtime.IStatus;\r
+import org.eclipse.core.runtime.OperationCanceledException;\r
+import org.eclipse.core.runtime.Status;\r
+import org.eclipse.core.runtime.SubMonitor;\r
import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
import org.eclipse.core.runtime.preferences.InstanceScope;\r
import org.eclipse.jface.dialogs.IDialogSettings;\r
import org.eclipse.swt.widgets.Button;\r
import org.eclipse.swt.widgets.Composite;\r
import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
import org.eclipse.swt.widgets.Event;\r
import org.eclipse.swt.widgets.Label;\r
import org.eclipse.swt.widgets.List;\r
import org.simantics.db.common.request.WriteResultRequest;\r
import org.simantics.db.common.utils.Logger;\r
import org.simantics.db.common.utils.Versions;\r
+import org.simantics.db.exception.CancelTransactionException;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.diagram.stubs.DiagramResource;\r
import org.simantics.layer0.Layer0;\r
import org.simantics.utils.datastructures.Triple;\r
import org.simantics.utils.strings.AlphanumComparator;\r
\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.set.hash.THashSet;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
/**\r
* @author Antti Villberg\r
*/\r
\r
Collection<MigrationOperation> ops = migratePage.model.sortedShownInstances;\r
int index = 0;\r
- final ArrayList<MigrationOperation> result = new ArrayList<MigrationOperation>();\r
+ final ArrayList<MigrationOperation> result = new ArrayList<>();\r
for(MigrationOperation op : ops) {\r
if(sels.contains(index)) result.add(op);\r
index++;\r
if(result.isEmpty()) return true;\r
\r
try {\r
- \r
- final String report = Simantics.getSession().syncRequest(new WriteResultRequest<String>() {\r
- @Override\r
- public String perform(WriteGraph graph) throws DatabaseException {\r
- graph.markUndoPoint();\r
- String report = UserComponentMigration.doMigration(graph, result);\r
- UserComponentMigration.doPostMigration(graph, result);\r
- return report;\r
+ String[] report = { null };\r
+ getContainer().run(true, true, monitor -> {\r
+ SubMonitor mon = SubMonitor.convert(monitor, 1000);\r
+ try {\r
+ report[0] = Simantics.getSession().syncRequest(new WriteResultRequest<String>() {\r
+ @Override\r
+ public String perform(WriteGraph graph) throws DatabaseException {\r
+ graph.markUndoPoint();\r
+ String report = UserComponentMigration.doMigration(mon.newChild(500, SubMonitor.SUPPRESS_NONE), graph, result);\r
+ UserComponentMigration.doPostMigration(mon.newChild(500, SubMonitor.SUPPRESS_NONE), graph, result);\r
+ mon.setTaskName("Committing Changes");\r
+ mon.subTask("");\r
+ return report;\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ throw new InvocationTargetException(e);\r
+ } finally {\r
+ monitor.done();\r
}\r
});\r
\r
- class InfoMessageDialog extends MessageDialog {\r
-\r
- public InfoMessageDialog(Shell shell) {\r
- super(shell, \r
- "Migration report", null, \r
- "", \r
- MessageDialog.INFORMATION, new String[] { "Continue" }, 0);\r
- }\r
- \r
- @Override\r
- protected boolean isResizable() {\r
- return true;\r
- }\r
- \r
- @Override\r
- protected Point getInitialSize() {\r
- return new Point(800, 500);\r
- }\r
-\r
- @Override\r
- protected Control createCustomArea(Composite composite) {\r
- \r
- GridLayoutFactory.fillDefaults().applyTo(composite);\r
- Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);\r
- text.setText(report);\r
- GridDataFactory.fillDefaults().grab(true, true).applyTo(text);\r
- return composite;\r
- \r
- }\r
-\r
- }\r
-\r
- InfoMessageDialog md = new InfoMessageDialog(Display.getCurrent().getActiveShell());\r
- md.open();\r
- \r
- \r
- } catch (DatabaseException e) {\r
- Logger.defaultLogError(e);\r
- }\r
- \r
- return true;\r
+\r
+ ReportDialog md = new ReportDialog(getShell(), report[0], 800, 500);\r
+ md.open();\r
+\r
+ return true;\r
+ } catch (InvocationTargetException e) {\r
+ // Don't show user cancellations as errors.\r
+ Throwable cause = e.getCause();\r
+ if (!(cause instanceof CancelTransactionException || cause instanceof OperationCanceledException)) {\r
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,\r
+ "Migration failed, see Error Log for details.", e.getCause()));\r
+ }\r
+ } catch (InterruptedException e) {\r
+ Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,\r
+ "Migration interrupted, see Error Log for details.", e));\r
+ }\r
+ return false;\r
+ }\r
+\r
+ static class ReportDialog extends MessageDialog {\r
+ private final String report;\r
+ private final int initialWidth;\r
+ private final int initialHeight;\r
+\r
+ public ReportDialog(Shell shell, String report, int width, int height) {\r
+ super(shell, \r
+ "Migration report", null, \r
+ "", \r
+ MessageDialog.INFORMATION, new String[] { "Continue" }, 0);\r
+ this.report = report;\r
+ this.initialWidth = width;\r
+ this.initialHeight = height;\r
+ }\r
+\r
+ @Override\r
+ protected boolean isResizable() {\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ protected Point getInitialSize() {\r
+ return new Point(initialWidth, initialHeight);\r
+ }\r
+\r
+ @Override\r
+ protected Control createCustomArea(Composite composite) {\r
+ GridLayoutFactory.fillDefaults().applyTo(composite);\r
+ Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);\r
+ text.setText(report);\r
+ GridDataFactory.fillDefaults().grab(true, true).applyTo(text);\r
+ return composite;\r
+ }\r
}\r
\r
abstract static class SelectionAdapter implements SelectionListener {\r
result.add(new NamedResource(name, symbol));\r
}\r
\r
- return new ArrayList<NamedResource>(result);\r
+ return new ArrayList<>(result);\r
\r
}\r
\r
int locationIndex = locations.getSelectionIndex();\r
if(locationIndex == -1) return;\r
\r
- model.sortedShownInstances = new ArrayList<MigrationOperation>();\r
+ model.sortedShownInstances = new ArrayList<>();\r
for(MigrationOperation o : model.instances.get(locationIndex).third)\r
model.sortedShownInstances.add(o);\r
Collections.sort(model.sortedShownInstances, MIGRATION_OP_COMPARATOR);\r
import java.util.Comparator;\r
import java.util.Set;\r
\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
+import org.eclipse.core.runtime.NullProgressMonitor;\r
import org.simantics.Simantics;\r
import org.simantics.databoard.Bindings;\r
import org.simantics.databoard.util.URIStringUtils;\r
import org.simantics.db.common.utils.NameUtils;\r
import org.simantics.db.common.utils.VersionMap;\r
import org.simantics.db.common.utils.Versions;\r
+import org.simantics.db.exception.CancelTransactionException;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.layer0.adapter.Instances;\r
import org.simantics.db.layer0.request.ActiveModels;\r
}\r
}\r
if (!result.isEmpty())\r
- doMigration(graph, result);\r
+ doMigration(new NullProgressMonitor(), graph, result);\r
}\r
\r
- public static String doMigration(WriteGraph graph, final ArrayList<MigrationOperation> result) throws DatabaseException {\r
+ public static String doMigration(IProgressMonitor monitor, WriteGraph graph, final ArrayList<MigrationOperation> operations) throws DatabaseException {\r
graph.markUndoPoint();\r
StringBuilder b = new StringBuilder();\r
int success = 0;\r
int problem = 0;\r
- for(MigrationOperation op : result) {\r
+ int no = 1;\r
+ int count = operations.size();\r
+ monitor.setTaskName("Migrating " + count + " User Components");\r
+ for(MigrationOperation op : operations) {\r
+ if (monitor.isCanceled())\r
+ throw new CancelTransactionException();\r
+ monitor.subTask("(" + (no++) + "/" + count + ") " + op.toString());\r
String problems = op.perform(graph);\r
if(problems != null) {\r
b.insert(0, problems);\r
return b.toString();\r
}\r
\r
- public static void doPostMigration(WriteGraph graph, ArrayList<MigrationOperation> result) throws DatabaseException {\r
+ public static void doPostMigration(IProgressMonitor monitor, WriteGraph graph, ArrayList<MigrationOperation> result) throws DatabaseException {\r
THashSet<Resource> roots = new THashSet<>();\r
for(MigrationOperation op : result) {\r
Resource root = graph.syncRequest(new PossibleIndexRoot(op.instanceToMigrate.getResource()));\r
if(root != null)\r
roots.add(root);\r
}\r
+ if (monitor.isCanceled())\r
+ throw new CancelTransactionException();\r
for(Resource root : roots) {\r
UserComponentPostMigrationAction action = graph.getPossibleAdapter(root, UserComponentPostMigrationAction.class);\r
if(action != null)\r
- action.perform(graph);\r
+ action.perform(monitor, graph);\r
}\r
}\r
\r
package org.simantics.structural.synchronization.base;\r
\r
+import org.eclipse.core.runtime.IProgressMonitor;\r
import org.simantics.db.ReadGraph;\r
+import org.simantics.db.exception.CancelTransactionException;\r
import org.simantics.db.exception.DatabaseException;\r
import org.simantics.db.layer0.variable.Variable;\r
\r
* and resource ids have been changed.\r
* \r
* @author Hannu Niemistö\r
+ * @author Tuukka Lehtonen\r
*/\r
-public class UpdateComponentUids {\r
- \r
- public static <T extends ComponentBase<T>> void update(ReadGraph graph, T component, Variable variable) throws DatabaseException {\r
+public class UpdateComponentUids<T extends ComponentBase<T>> {\r
+\r
+ public static interface ComponentUpdateProgressMonitor {\r
+ void componentsDone(int components, int componentCount);\r
+ }\r
+\r
+ private IProgressMonitor monitor;\r
+ private ComponentUpdateProgressMonitor componentMonitor;\r
+ private ReadGraph graph;\r
+ private int componentCount;\r
+ private int counter;\r
+\r
+ private UpdateComponentUids(IProgressMonitor monitor, ReadGraph graph, int componentCount) {\r
+ this.monitor = monitor;\r
+ this.componentMonitor = monitor instanceof ComponentUpdateProgressMonitor ? (ComponentUpdateProgressMonitor) monitor : null;\r
+ this.graph = graph;\r
+ this.componentCount = componentCount;\r
+ }\r
+\r
+ private void update(T component, Variable variable) throws DatabaseException {\r
component.uid = variable.getRVI(graph).toString();\r
+\r
+ // Handle progress monitoring and cancellation\r
+ counter++;\r
+ if (monitor != null) {\r
+ if (componentMonitor != null)\r
+ componentMonitor.componentsDone(counter, componentCount);\r
+ if (monitor.isCanceled())\r
+ throw new CancelTransactionException();\r
+ }\r
+\r
for(Variable childVariable : variable.getChildren(graph)) {\r
String childName = childVariable.getName(graph);\r
T childComponent = component.getChild(childName);\r
if(childComponent != null)\r
- update(graph, childComponent, childVariable);\r
+ update(childComponent, childVariable);\r
}\r
}\r
- \r
+\r
+ public static <T extends ComponentBase<T>> void update(ReadGraph graph, T component, Variable variable) throws DatabaseException {\r
+ update(null, graph, component, variable);\r
+ }\r
+\r
+ public static <T extends ComponentBase<T>> void update(IProgressMonitor monitor, ReadGraph graph, T component, Variable variable) throws DatabaseException {\r
+ new UpdateComponentUids<T>(monitor, graph, countComponents(component)).update(component, variable);\r
+ }\r
+\r
+ public static <T extends ComponentBase<T>> int countComponents(T component) {\r
+ return new Counter<T>().count(component);\r
+ }\r
+\r
+ private static class Counter<T extends ComponentBase<T>> {\r
+ int counter;\r
+ int count(T component) {\r
+ ++counter;\r
+ for (T child : component.getChildren())\r
+ count(child);\r
+ return counter;\r
+ }\r
+ }\r
+\r
}\r