--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2014, 2015 Association for Decentralized Information Management\r
+ * in 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
+ * Semantum Oy - initial API and implementation\r
+ *******************************************************************************/\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.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+import java.util.Map;\r
+import java.util.Set;\r
+\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.jface.dialogs.MessageDialog;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.layout.RowLayoutFactory;\r
+import org.eclipse.jface.resource.ImageDescriptor;\r
+import org.eclipse.jface.window.Window;\r
+import org.eclipse.jface.wizard.Wizard;\r
+import org.eclipse.jface.wizard.WizardPage;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.custom.CCombo;\r
+import org.eclipse.swt.events.ModifyEvent;\r
+import org.eclipse.swt.events.ModifyListener;\r
+import org.eclipse.swt.events.SelectionEvent;\r
+import org.eclipse.swt.events.SelectionListener;\r
+import org.eclipse.swt.graphics.Point;\r
+import org.eclipse.swt.layout.GridLayout;\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.eclipse.swt.widgets.Listener;\r
+import org.eclipse.swt.widgets.Shell;\r
+import org.eclipse.swt.widgets.Text;\r
+import org.simantics.Simantics;\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.util.URIStringUtils;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.NamedResource;\r
+import org.simantics.db.common.request.ObjectsWithType;\r
+import org.simantics.db.common.request.UnaryRead;\r
+import org.simantics.db.common.request.UniqueRead;\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.DatabaseException;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.modeling.MigrateModel;\r
+import org.simantics.modeling.MigrateModel.MigrationOperation;\r
+import org.simantics.modeling.ModelingResources;\r
+import org.simantics.modeling.UserComponentMigration;\r
+import org.simantics.modeling.ui.Activator;\r
+import org.simantics.structural.stubs.StructuralResource2;\r
+import org.simantics.ui.workbench.dialogs.ResourceSelectionDialog3;\r
+import org.simantics.utils.datastructures.Pair;\r
+import org.simantics.utils.datastructures.Triple;\r
+import org.simantics.utils.strings.AlphanumComparator;\r
+\r
+/**\r
+ * @author Antti Villberg\r
+ */\r
+public class MigrateWizard extends Wizard {\r
+\r
+ final String initial;\r
+ \r
+ MigratePage migratePage;\r
+\r
+ IEclipsePreferences prefnode;\r
+ \r
+ public MigrateWizard(String initial) {\r
+ \r
+ this.initial = initial;\r
+\r
+ setWindowTitle("Perform migration");\r
+ setNeedsProgressMonitor(true);\r
+ setForcePreviousAndNextButtons(false);\r
+ setDialogSettings(Activator.getDefault().getDialogSettings());\r
+\r
+ prefnode = InstanceScope.INSTANCE.getNode( "org.simantics.modeling.ui.wizard.MigrateWizard" );\r
+ \r
+ }\r
+\r
+ @Override\r
+ public void addPages() {\r
+ migratePage = new MigratePage(initial);\r
+ addPage(migratePage);\r
+ }\r
+\r
+ @Override\r
+ public boolean canFinish() {\r
+// if (model.spec.name.isEmpty())\r
+// return false;\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public boolean performFinish() {\r
+\r
+ int locationIndex = migratePage.locations.getSelectionIndex();\r
+ if(locationIndex == -1) return true;\r
+\r
+ if(migratePage.model == null || migratePage.model.instances.isEmpty()) return true;\r
+\r
+ int[] sel = migratePage.instances.getSelectionIndices();\r
+ TIntHashSet sels = new TIntHashSet();\r
+ for(int i : sel) sels.add(i);\r
+\r
+ Collection<MigrationOperation> ops = migratePage.model.sortedShownInstances;\r
+ int index = 0;\r
+ final ArrayList<MigrationOperation> result = new ArrayList<MigrationOperation>();\r
+ for(MigrationOperation op : ops) {\r
+ if(sels.contains(index)) result.add(op);\r
+ index++;\r
+ }\r
+ \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
+ }\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
+\r
+ abstract static class SelectionAdapter implements SelectionListener {\r
+ @Override\r
+ public void widgetDefaultSelected(SelectionEvent e) {\r
+ widgetSelected(e);\r
+ }\r
+ }\r
+\r
+ class MigratePage extends WizardPage {\r
+\r
+ String initial;\r
+ \r
+ MigrateModel model;\r
+\r
+ Text source;\r
+ Button browseSource;\r
+ Text target;\r
+ Button browseTarget;\r
+ Label symbolsLabel;\r
+ CCombo symbols;\r
+ Label instanceLabel;\r
+ Label locationsLabel;\r
+ CCombo locations;\r
+ Composite buttonBar;\r
+ Label instancesLabel;\r
+ List instances;\r
+\r
+ /**\r
+ * ID of the location that has been previously selected by the user.\r
+ * Used to prevent the location from being reset every time the user\r
+ * makes a change in any of the other selections.\r
+ * \r
+ * See first field of {@link MigrateModel#instances}.\r
+ */\r
+ String previouslySelectedLocationId = null;\r
+\r
+ public MigratePage(String initial) {\r
+ super("Perform migration", "Perform migration", null);\r
+ this.initial = initial;\r
+ }\r
+\r
+ @Override\r
+ public void createControl(Composite parent) {\r
+ Composite container = new Composite(parent, SWT.NONE);\r
+ {\r
+ GridLayout layout = new GridLayout();\r
+ layout.horizontalSpacing = 20;\r
+ layout.verticalSpacing = 10;\r
+ layout.numColumns = 10;\r
+ container.setLayout(layout);\r
+ }\r
+\r
+ new Label(container, SWT.NONE).setText("&Source:");\r
+ source = new Text(container, SWT.BORDER);\r
+ source.setText(initial);\r
+ source.addModifyListener(new ModifyListener() {\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ refreshModel();\r
+ refreshInstances();\r
+ }\r
+ });\r
+ GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(source);\r
+\r
+ browseSource = new Button(container, SWT.NONE);\r
+ browseSource.setText("&Browse");\r
+ GridDataFactory.fillDefaults().grab(false, false).applyTo(browseSource);\r
+ browseSource.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e_) {\r
+ try {\r
+ Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseSourceContentRequest(target.getText()));\r
+ String uri = queryTargetSelection("Select Source Type", map);\r
+ if (uri != null)\r
+ source.setText(uri);\r
+ } catch (DatabaseException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ }\r
+ });\r
+\r
+ new Label(container, SWT.NONE).setText("&Target:");\r
+ target = new Text(container, SWT.BORDER);\r
+ target.setText(initial);\r
+ target.addModifyListener(new ModifyListener() {\r
+ @Override\r
+ public void modifyText(ModifyEvent e) {\r
+ refreshSymbols();\r
+ refreshModel();\r
+ refreshInstances();\r
+ }\r
+ });\r
+ GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(target);\r
+\r
+ browseTarget = new Button(container, SWT.NONE);\r
+ browseTarget.setText("B&rowse");\r
+ GridDataFactory.fillDefaults().grab(false, false).applyTo(browseTarget);\r
+ browseTarget.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e_) {\r
+ try {\r
+ Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseTargetContentRequest(source.getText()));\r
+ String uri = queryTargetSelection("Select Target Type", map);\r
+ if (uri != null)\r
+ target.setText(uri);\r
+ } catch (DatabaseException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ }\r
+ });\r
+\r
+ symbolsLabel = new Label(container, SWT.NONE);\r
+ symbolsLabel.setText("Target &symbol:");\r
+ GridDataFactory.fillDefaults().applyTo(symbolsLabel);\r
+\r
+ symbols = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
+ symbols.setVisibleItemCount(10);\r
+ symbols.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ refreshModel();\r
+ refreshInstances();\r
+ }\r
+ });\r
+ GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);\r
+\r
+ instanceLabel = new Label(container, SWT.NONE);\r
+ GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instanceLabel);\r
+ instanceLabel.setText("");\r
+\r
+ locationsLabel = new Label(container, SWT.NONE);\r
+ locationsLabel.setText("&Locations:");\r
+ locations = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
+ locations.setVisibleItemCount(25);\r
+ locations.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ int index = locations.getSelectionIndex();\r
+ if (index >= 0 && index < model.instances.size()) {\r
+ previouslySelectedLocationId = model.instances.get(index).first;\r
+ }\r
+ refreshInstances();\r
+ }\r
+ });\r
+ GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);\r
+\r
+ instancesLabel = new Label(container, SWT.NONE);\r
+ instancesLabel.setText("&Select instances to migrate:");\r
+ GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instancesLabel);\r
+\r
+ buttonBar = new Composite(container, SWT.NONE);\r
+ RowLayoutFactory.fillDefaults().type(SWT.HORIZONTAL).applyTo(buttonBar);\r
+ GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);\r
+ Button selectAll = new Button(buttonBar, SWT.PUSH);\r
+ selectAll.setText("Select &All");\r
+ Button selectNone = new Button(buttonBar, SWT.PUSH);\r
+ selectNone.setText("Select &None");\r
+ selectAll.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ instances.selectAll();\r
+ }\r
+ });\r
+ selectNone.addSelectionListener(new SelectionAdapter() {\r
+ @Override\r
+ public void widgetSelected(SelectionEvent e) {\r
+ instances.deselectAll();\r
+ }\r
+ });\r
+\r
+ instances = new List(container, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
+ GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);\r
+ instances.addListener(SWT.Modify, validateListener);\r
+\r
+ refreshSymbols();\r
+ refreshModel();\r
+ refreshInstances();\r
+\r
+ setControl(container);\r
+ validatePage();\r
+ }\r
+\r
+ String queryTargetSelection(String title, Map<String, Pair<String, ImageDescriptor>> map) {\r
+ Shell shell = source.getShell();\r
+ ResourceSelectionDialog3<String> dialog = new ResourceSelectionDialog3<String>(shell, map, title, false) {\r
+ @Override\r
+ protected IDialogSettings getBaseDialogSettings() {\r
+ return Activator.getDefault().getDialogSettings();\r
+ }\r
+ };\r
+ if (dialog.open() == Window.OK)\r
+ return (String) dialog.getFirstResult();\r
+ return null;\r
+ }\r
+\r
+ void refreshSymbols() {\r
+ try {\r
+\r
+ final String uri = target.getText();\r
+\r
+ Collection<NamedResource> syms = Simantics.getSession().syncRequest(new UniqueRead<Collection<NamedResource>>() {\r
+\r
+ @Override\r
+ public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {\r
+\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ DiagramResource DIA = DiagramResource.getInstance(graph);\r
+ ModelingResources MOD = ModelingResources.getInstance(graph);\r
+\r
+ Set<NamedResource> result = new THashSet<>();\r
+ Resource componentType = graph.getResource(uri);\r
+\r
+ Set<Resource> potentialSymbols = new THashSet<>();\r
+ potentialSymbols.addAll(graph.syncRequest(new ObjectsWithType(componentType, L0.ConsistsOf, DIA.ElementClass)));\r
+ potentialSymbols.addAll(graph.getObjects(componentType, MOD.ComponentTypeToSymbol));\r
+\r
+ for(Resource symbol : potentialSymbols) {\r
+ if(!graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType)) continue;\r
+ String name = graph.getRelatedValue(symbol, L0.HasName, Bindings.STRING);\r
+ if(graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType))\r
+ result.add(new NamedResource(name, symbol));\r
+ }\r
+\r
+ return new ArrayList<NamedResource>(result);\r
+\r
+ }\r
+\r
+ });\r
+\r
+ symbols.removeAll();\r
+ symbols.add("<retain symbol name>");\r
+ for(NamedResource nr : syms) {\r
+ symbols.add(nr.getName());\r
+ }\r
+ symbols.setData(syms);\r
+ symbols.select(0);\r
+\r
+ if(syms.isEmpty()) {\r
+ symbolsLabel.setVisible(false);\r
+ symbols.setVisible(false);\r
+ GridDataFactory.fillDefaults().exclude(true).applyTo(symbolsLabel);\r
+ GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(symbols);\r
+ } else {\r
+ symbolsLabel.setVisible(true);\r
+ symbols.setVisible(true);\r
+ GridDataFactory.fillDefaults().applyTo(symbolsLabel);\r
+ GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);\r
+ }\r
+\r
+ symbols.getParent().layout();\r
+\r
+ } catch (DatabaseException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+ }\r
+\r
+ void refreshModel() {\r
+ final String sourceText = source.getText();\r
+ final String targetText = target.getText();\r
+ int symbolIndex = symbols.getSelectionIndex();\r
+ Resource symbol = null;\r
+ if(symbolIndex > 0) {\r
+ @SuppressWarnings("unchecked")\r
+ java.util.List<NamedResource> nrs = (java.util.List<NamedResource>)symbols.getData();\r
+ symbol = nrs.get(symbolIndex-1).getResource();\r
+ }\r
+ final Resource finalSymbol = symbol;\r
+\r
+ try {\r
+ model = Simantics.getSession().syncRequest(new UniqueRead<MigrateModel>() {\r
+ @Override\r
+ public MigrateModel perform(ReadGraph graph) throws DatabaseException {\r
+ Layer0 L0 = Layer0.getInstance(graph);\r
+ StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
+\r
+ Resource source = graph.getPossibleResource(sourceText);\r
+ if(source == null) return model;\r
+ Resource target = graph.getPossibleResource(targetText);\r
+ if(target == null) return model;\r
+\r
+ if(graph.isInstanceOf(source, STR.ComponentType)) {\r
+ return UserComponentMigration.getComponentTypeModel(graph, source, target, finalSymbol);\r
+ } else if(graph.isInstanceOf(source, L0.SharedOntology)) {\r
+ return UserComponentMigration.getSharedOntologyModel(graph, source, target);\r
+ } else {\r
+ return null;\r
+ }\r
+ }\r
+ });\r
+ } catch (DatabaseException e) {\r
+ Logger.defaultLogError(e);\r
+ }\r
+\r
+ instances.removeAll();\r
+ locations.removeAll();\r
+\r
+ if (model == null)\r
+ return;\r
+\r
+ int preSelect = -1, i = 0;\r
+ for (Triple<String,NamedResource,Collection<MigrationOperation>> r : model.instances) {\r
+ locations.add(r.second.getName() + " (" + r.third.size() + " instances)");\r
+ if (r.first.equals(previouslySelectedLocationId))\r
+ preSelect = i;\r
+ if (preSelect < 0 && model.activeModels.contains(r.second.getResource()))\r
+ preSelect = i;\r
+ ++i;\r
+ }\r
+ if (locations.getItemCount() == 0) {\r
+ locations.add("<no instances were found>");\r
+ locations.select(0);\r
+ } else {\r
+ locations.select(preSelect > -1 ? preSelect : 0);\r
+ }\r
+ }\r
+\r
+ void refreshInstances() {\r
+\r
+ int toMigrate = 0;\r
+ for(Triple<String,NamedResource,Collection<MigrationOperation>> pair : model.instances) {\r
+ toMigrate += pair.third.size();\r
+ }\r
+\r
+ if(model.instanceCount == 0)\r
+ instanceLabel.setText("No instances were found.");\r
+ else if(model.instanceCount == 1) {\r
+ if(toMigrate == 1) {\r
+ instanceLabel.setText("1 migratable instance found.");\r
+ } else {\r
+ instanceLabel.setText("1 instance found, but it cannot be migrated with current settings.");\r
+ }\r
+ } else {\r
+ if(toMigrate < model.instanceCount) {\r
+ if(toMigrate == 0) {\r
+ instanceLabel.setText(model.instanceCount + " instances were found. None of them can be migrated with current settings.");\r
+ } else {\r
+ instanceLabel.setText(model.instanceCount + " instances were found. " + (model.instanceCount-toMigrate) + " of them cannot be migrated with current settings.");\r
+ }\r
+ } else {\r
+ instanceLabel.setText(model.instanceCount + " migratable instances found. ");\r
+ }\r
+ }\r
+\r
+ instances.removeAll();\r
+\r
+ if (model == null)\r
+ return;\r
+\r
+ if(toMigrate == 0) {\r
+ locationsLabel.setVisible(false);\r
+ locations.setVisible(false);\r
+ GridDataFactory.fillDefaults().exclude(true).applyTo(locationsLabel);\r
+ GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(locations);\r
+ } else {\r
+ locationsLabel.setVisible(true);\r
+ locations.setVisible(true);\r
+ GridDataFactory.fillDefaults().applyTo(locationsLabel);\r
+ GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);\r
+ }\r
+\r
+ if(!model.instances.isEmpty()) {\r
+\r
+ int locationIndex = locations.getSelectionIndex();\r
+ if(locationIndex == -1) return;\r
+\r
+ model.sortedShownInstances = new ArrayList<MigrationOperation>();\r
+ for(MigrationOperation o : model.instances.get(locationIndex).third)\r
+ model.sortedShownInstances.add(o);\r
+ Collections.sort(model.sortedShownInstances, MIGRATION_OP_COMPARATOR);\r
+ for(MigrationOperation o : model.sortedShownInstances) {\r
+ String uri = o.toString();\r
+ uri = uri.replace("http://Projects/Development%20Project/", "");\r
+ uri = URIStringUtils.unescape(uri);\r
+ instances.add(uri);\r
+ }\r
+\r
+ }\r
+\r
+ if(model.sortedShownInstances.isEmpty()) {\r
+ instancesLabel.setVisible(false);\r
+ instances.setVisible(false);\r
+ buttonBar.setVisible(false);\r
+ GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(instancesLabel);\r
+ GridDataFactory.fillDefaults().exclude(true).grab(true, true).span(10, 1).applyTo(instances);\r
+ GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(10, 1).applyTo(buttonBar);\r
+ } else {\r
+ GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(instancesLabel);\r
+ GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);\r
+ GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);\r
+ instancesLabel.setVisible(true);\r
+ instances.setVisible(true);\r
+ buttonBar.setVisible(true);\r
+ }\r
+\r
+ locations.getParent().layout();\r
+\r
+ }\r
+\r
+ Listener validateListener = new Listener() {\r
+ @Override\r
+ public void handleEvent(Event event) {\r
+ switch (event.type) {\r
+ case SWT.Modify:\r
+ validatePage();\r
+ case SWT.Selection:\r
+ validatePage();\r
+ break;\r
+ case SWT.FocusIn:\r
+ {\r
+ if (event.widget instanceof Text) {\r
+ Text t = (Text) event.widget;\r
+ t.selectAll();\r
+ }\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ };\r
+\r
+ private void validatePage() {\r
+ setMessage(null);\r
+ setErrorMessage(null);\r
+ setPageComplete(true);\r
+ }\r
+\r
+ }\r
+\r
+ private static final Comparator<MigrationOperation> MIGRATION_OP_COMPARATOR = new Comparator<MigrateModel.MigrationOperation>() {\r
+ @Override\r
+ public int compare(MigrationOperation o1, MigrationOperation o2) {\r
+ return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(o1.instanceToMigrate.getName(), o2.instanceToMigrate.getName());\r
+ }\r
+ };\r
+\r
+ private static abstract class BrowseContentRequest extends UnaryRead<String, Map<String, Pair<String, ImageDescriptor>>> {\r
+\r
+ public BrowseContentRequest(String uri) {\r
+ super(uri);\r
+ }\r
+\r
+ @Override\r
+ public Map<String, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {\r
+ Resource root = graph.getPossibleResource(parameter);\r
+ if (root == null)\r
+ return null;\r
+\r
+ Map<String, Pair<String, ImageDescriptor>> result = new THashMap<>();\r
+ Collection<NamedResource> infos = getVersions(graph, root); \r
+ for (NamedResource info : infos)\r
+ result.put(graph.getURI(info.getResource()), Pair.<String,ImageDescriptor>make(Versions.getStandardPathNameString(graph, info.getResource()), null));\r
+\r
+ return result;\r
+ }\r
+\r
+ protected abstract Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException;\r
+\r
+ }\r
+\r
+ private static class BrowseSourceContentRequest extends BrowseContentRequest {\r
+ public BrowseSourceContentRequest(String uri) {\r
+ super(uri);\r
+ }\r
+ @Override\r
+ protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {\r
+ return Versions.getOlderVersions(graph, root);\r
+ }\r
+ }\r
+\r
+ private static class BrowseTargetContentRequest extends BrowseContentRequest {\r
+ public BrowseTargetContentRequest(String uri) {\r
+ super(uri);\r
+ }\r
+ @Override\r
+ protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {\r
+ return Versions.getNewerVersions(graph, root);\r
+ }\r
+ }\r
+\r
+}\r