]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/wizard/MigrateWizard.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / wizard / MigrateWizard.java
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/wizard/MigrateWizard.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/wizard/MigrateWizard.java
new file mode 100644 (file)
index 0000000..f0eee75
--- /dev/null
@@ -0,0 +1,672 @@
+/*******************************************************************************\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