Sync git svn branch with SVN repository r33364.
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / wizard / MigrateWizard.java
1 /*******************************************************************************\r
2  * Copyright (c) 2014, 2015 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     Semantum Oy - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.modeling.ui.wizard;\r
13 \r
14 import gnu.trove.map.hash.THashMap;\r
15 import gnu.trove.set.hash.THashSet;\r
16 import gnu.trove.set.hash.TIntHashSet;\r
17 \r
18 import java.util.ArrayList;\r
19 import java.util.Collection;\r
20 import java.util.Collections;\r
21 import java.util.Comparator;\r
22 import java.util.Map;\r
23 import java.util.Set;\r
24 \r
25 import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
26 import org.eclipse.core.runtime.preferences.InstanceScope;\r
27 import org.eclipse.jface.dialogs.IDialogSettings;\r
28 import org.eclipse.jface.dialogs.MessageDialog;\r
29 import org.eclipse.jface.layout.GridDataFactory;\r
30 import org.eclipse.jface.layout.GridLayoutFactory;\r
31 import org.eclipse.jface.layout.RowLayoutFactory;\r
32 import org.eclipse.jface.resource.ImageDescriptor;\r
33 import org.eclipse.jface.window.Window;\r
34 import org.eclipse.jface.wizard.Wizard;\r
35 import org.eclipse.jface.wizard.WizardPage;\r
36 import org.eclipse.swt.SWT;\r
37 import org.eclipse.swt.custom.CCombo;\r
38 import org.eclipse.swt.events.ModifyEvent;\r
39 import org.eclipse.swt.events.ModifyListener;\r
40 import org.eclipse.swt.events.SelectionEvent;\r
41 import org.eclipse.swt.events.SelectionListener;\r
42 import org.eclipse.swt.graphics.Point;\r
43 import org.eclipse.swt.layout.GridLayout;\r
44 import org.eclipse.swt.widgets.Button;\r
45 import org.eclipse.swt.widgets.Composite;\r
46 import org.eclipse.swt.widgets.Control;\r
47 import org.eclipse.swt.widgets.Display;\r
48 import org.eclipse.swt.widgets.Event;\r
49 import org.eclipse.swt.widgets.Label;\r
50 import org.eclipse.swt.widgets.List;\r
51 import org.eclipse.swt.widgets.Listener;\r
52 import org.eclipse.swt.widgets.Shell;\r
53 import org.eclipse.swt.widgets.Text;\r
54 import org.simantics.Simantics;\r
55 import org.simantics.databoard.Bindings;\r
56 import org.simantics.databoard.util.URIStringUtils;\r
57 import org.simantics.db.ReadGraph;\r
58 import org.simantics.db.Resource;\r
59 import org.simantics.db.WriteGraph;\r
60 import org.simantics.db.common.NamedResource;\r
61 import org.simantics.db.common.request.ObjectsWithType;\r
62 import org.simantics.db.common.request.UnaryRead;\r
63 import org.simantics.db.common.request.UniqueRead;\r
64 import org.simantics.db.common.request.WriteResultRequest;\r
65 import org.simantics.db.common.utils.Logger;\r
66 import org.simantics.db.common.utils.Versions;\r
67 import org.simantics.db.exception.DatabaseException;\r
68 import org.simantics.diagram.stubs.DiagramResource;\r
69 import org.simantics.layer0.Layer0;\r
70 import org.simantics.modeling.MigrateModel;\r
71 import org.simantics.modeling.MigrateModel.MigrationOperation;\r
72 import org.simantics.modeling.ModelingResources;\r
73 import org.simantics.modeling.UserComponentMigration;\r
74 import org.simantics.modeling.ui.Activator;\r
75 import org.simantics.structural.stubs.StructuralResource2;\r
76 import org.simantics.ui.workbench.dialogs.ResourceSelectionDialog3;\r
77 import org.simantics.utils.datastructures.Pair;\r
78 import org.simantics.utils.datastructures.Triple;\r
79 import org.simantics.utils.strings.AlphanumComparator;\r
80 \r
81 /**\r
82  * @author Antti Villberg\r
83  */\r
84 public class MigrateWizard extends Wizard {\r
85 \r
86         final String initial;\r
87         \r
88     MigratePage  migratePage;\r
89 \r
90         IEclipsePreferences prefnode;\r
91     \r
92     public MigrateWizard(String initial) {\r
93         \r
94         this.initial = initial;\r
95 \r
96         setWindowTitle("Perform migration");\r
97         setNeedsProgressMonitor(true);\r
98         setForcePreviousAndNextButtons(false);\r
99         setDialogSettings(Activator.getDefault().getDialogSettings());\r
100 \r
101         prefnode = InstanceScope.INSTANCE.getNode( "org.simantics.modeling.ui.wizard.MigrateWizard" );\r
102         \r
103     }\r
104 \r
105     @Override\r
106     public void addPages() {\r
107         migratePage = new MigratePage(initial);\r
108         addPage(migratePage);\r
109     }\r
110 \r
111     @Override\r
112     public boolean canFinish() {\r
113 //        if (model.spec.name.isEmpty())\r
114 //            return false;\r
115         return true;\r
116     }\r
117 \r
118     @Override\r
119     public boolean performFinish() {\r
120 \r
121         int locationIndex = migratePage.locations.getSelectionIndex();\r
122         if(locationIndex == -1) return true;\r
123 \r
124         if(migratePage.model == null || migratePage.model.instances.isEmpty()) return true;\r
125 \r
126         int[] sel = migratePage.instances.getSelectionIndices();\r
127         TIntHashSet sels = new TIntHashSet();\r
128         for(int i : sel) sels.add(i);\r
129 \r
130         Collection<MigrationOperation> ops = migratePage.model.sortedShownInstances;\r
131         int index = 0;\r
132         final ArrayList<MigrationOperation> result = new ArrayList<MigrationOperation>();\r
133         for(MigrationOperation op : ops) {\r
134                 if(sels.contains(index)) result.add(op);\r
135                 index++;\r
136         }\r
137         \r
138         if(result.isEmpty()) return true;\r
139         \r
140         try {\r
141             \r
142             final String report = Simantics.getSession().syncRequest(new WriteResultRequest<String>() {\r
143                 @Override\r
144                 public String perform(WriteGraph graph) throws DatabaseException {\r
145                     graph.markUndoPoint();\r
146                     String report = UserComponentMigration.doMigration(graph, result);\r
147                     UserComponentMigration.doPostMigration(graph, result);\r
148                     return report;\r
149                 }\r
150             });\r
151 \r
152                         class InfoMessageDialog extends MessageDialog {\r
153 \r
154                                 public InfoMessageDialog(Shell shell) {\r
155                                         super(shell, \r
156                                                         "Migration report", null, \r
157                                                         "", \r
158                                                         MessageDialog.INFORMATION, new String[] { "Continue" }, 0);\r
159                                 }\r
160                                 \r
161                                 @Override\r
162                                 protected boolean isResizable() {\r
163                                         return true;\r
164                                 }\r
165                                 \r
166                                 @Override\r
167                                 protected Point getInitialSize() {\r
168                             return new Point(800, 500);\r
169                                 }\r
170 \r
171                                 @Override\r
172                                 protected Control createCustomArea(Composite composite) {\r
173                                         \r
174                                         GridLayoutFactory.fillDefaults().applyTo(composite);\r
175                                         Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);\r
176                                         text.setText(report);\r
177                                         GridDataFactory.fillDefaults().grab(true, true).applyTo(text);\r
178                                         return composite;\r
179                                         \r
180                                 }\r
181 \r
182                         }\r
183 \r
184                         InfoMessageDialog md = new InfoMessageDialog(Display.getCurrent().getActiveShell());\r
185                         md.open();\r
186                         \r
187                         \r
188                 } catch (DatabaseException e) {\r
189                         Logger.defaultLogError(e);\r
190                 }\r
191         \r
192         return true;\r
193     }\r
194 \r
195     abstract static class SelectionAdapter implements SelectionListener {\r
196         @Override\r
197         public void widgetDefaultSelected(SelectionEvent e) {\r
198             widgetSelected(e);\r
199         }\r
200     }\r
201 \r
202     class MigratePage extends WizardPage {\r
203 \r
204         String                initial;\r
205         \r
206         MigrateModel          model;\r
207 \r
208         Text                  source;\r
209         Button                browseSource;\r
210         Text                  target;\r
211         Button                browseTarget;\r
212         Label                 symbolsLabel;\r
213         CCombo                symbols;\r
214         Label                 instanceLabel;\r
215         Label                             locationsLabel;\r
216         CCombo                locations;\r
217         Composite             buttonBar;\r
218         Label                 instancesLabel;\r
219         List                  instances;\r
220 \r
221         /**\r
222          * ID of the location that has been previously selected by the user.\r
223          * Used to prevent the location from being reset every time the user\r
224          * makes a change in any of the other selections.\r
225          * \r
226          * See first field of {@link MigrateModel#instances}.\r
227          */\r
228         String                previouslySelectedLocationId = null;\r
229 \r
230         public MigratePage(String initial) {\r
231             super("Perform migration", "Perform migration", null);\r
232             this.initial = initial;\r
233         }\r
234 \r
235         @Override\r
236         public void createControl(Composite parent) {\r
237             Composite container = new Composite(parent, SWT.NONE);\r
238             {\r
239                 GridLayout layout = new GridLayout();\r
240                 layout.horizontalSpacing = 20;\r
241                 layout.verticalSpacing = 10;\r
242                 layout.numColumns = 10;\r
243                 container.setLayout(layout);\r
244             }\r
245 \r
246             new Label(container, SWT.NONE).setText("&Source:");\r
247             source = new Text(container, SWT.BORDER);\r
248             source.setText(initial);\r
249             source.addModifyListener(new ModifyListener() {\r
250                 @Override\r
251                 public void modifyText(ModifyEvent e) {\r
252                     refreshModel();\r
253                     refreshInstances();\r
254                 }\r
255             });\r
256             GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(source);\r
257 \r
258             browseSource = new Button(container, SWT.NONE);\r
259             browseSource.setText("&Browse");\r
260             GridDataFactory.fillDefaults().grab(false, false).applyTo(browseSource);\r
261             browseSource.addSelectionListener(new SelectionAdapter() {\r
262                 @Override\r
263                 public void widgetSelected(SelectionEvent e_) {\r
264                     try {\r
265                         Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseSourceContentRequest(target.getText()));\r
266                         String uri = queryTargetSelection("Select Source Type", map);\r
267                         if (uri != null)\r
268                             source.setText(uri);\r
269                     } catch (DatabaseException e) {\r
270                         Logger.defaultLogError(e);\r
271                     }\r
272                 }\r
273             });\r
274 \r
275             new Label(container, SWT.NONE).setText("&Target:");\r
276             target = new Text(container, SWT.BORDER);\r
277             target.setText(initial);\r
278             target.addModifyListener(new ModifyListener() {\r
279                 @Override\r
280                 public void modifyText(ModifyEvent e) {\r
281                     refreshSymbols();\r
282                     refreshModel();\r
283                     refreshInstances();\r
284                 }\r
285             });\r
286             GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(target);\r
287 \r
288             browseTarget = new Button(container, SWT.NONE);\r
289             browseTarget.setText("B&rowse");\r
290             GridDataFactory.fillDefaults().grab(false, false).applyTo(browseTarget);\r
291             browseTarget.addSelectionListener(new SelectionAdapter() {\r
292                 @Override\r
293                 public void widgetSelected(SelectionEvent e_) {\r
294                     try {\r
295                         Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseTargetContentRequest(source.getText()));\r
296                         String uri = queryTargetSelection("Select Target Type", map);\r
297                         if (uri != null)\r
298                             target.setText(uri);\r
299                     } catch (DatabaseException e) {\r
300                         Logger.defaultLogError(e);\r
301                     }\r
302                 }\r
303             });\r
304 \r
305             symbolsLabel = new Label(container, SWT.NONE);\r
306             symbolsLabel.setText("Target &symbol:");\r
307             GridDataFactory.fillDefaults().applyTo(symbolsLabel);\r
308 \r
309             symbols = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
310             symbols.setVisibleItemCount(10);\r
311             symbols.addSelectionListener(new SelectionAdapter() {\r
312                 @Override\r
313                 public void widgetSelected(SelectionEvent e) {\r
314                     refreshModel();\r
315                     refreshInstances();\r
316                 }\r
317             });\r
318             GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);\r
319 \r
320             instanceLabel = new Label(container, SWT.NONE);\r
321             GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instanceLabel);\r
322             instanceLabel.setText("");\r
323 \r
324             locationsLabel = new Label(container, SWT.NONE);\r
325             locationsLabel.setText("&Locations:");\r
326             locations = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
327             locations.setVisibleItemCount(25);\r
328             locations.addSelectionListener(new SelectionAdapter() {\r
329                 @Override\r
330                 public void widgetSelected(SelectionEvent e) {\r
331                     int index = locations.getSelectionIndex();\r
332                     if (index >= 0 && index < model.instances.size()) {\r
333                         previouslySelectedLocationId = model.instances.get(index).first;\r
334                     }\r
335                     refreshInstances();\r
336                 }\r
337             });\r
338             GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);\r
339 \r
340             instancesLabel = new Label(container, SWT.NONE);\r
341             instancesLabel.setText("&Select instances to migrate:");\r
342             GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instancesLabel);\r
343 \r
344             buttonBar = new Composite(container, SWT.NONE);\r
345             RowLayoutFactory.fillDefaults().type(SWT.HORIZONTAL).applyTo(buttonBar);\r
346             GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);\r
347             Button selectAll = new Button(buttonBar, SWT.PUSH);\r
348             selectAll.setText("Select &All");\r
349             Button selectNone = new Button(buttonBar, SWT.PUSH);\r
350             selectNone.setText("Select &None");\r
351             selectAll.addSelectionListener(new SelectionAdapter() {\r
352                 @Override\r
353                 public void widgetSelected(SelectionEvent e) {\r
354                     instances.selectAll();\r
355                 }\r
356             });\r
357             selectNone.addSelectionListener(new SelectionAdapter() {\r
358                 @Override\r
359                 public void widgetSelected(SelectionEvent e) {\r
360                     instances.deselectAll();\r
361                 }\r
362             });\r
363 \r
364             instances = new List(container, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
365             GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);\r
366             instances.addListener(SWT.Modify, validateListener);\r
367 \r
368             refreshSymbols();\r
369             refreshModel();\r
370             refreshInstances();\r
371 \r
372             setControl(container);\r
373             validatePage();\r
374         }\r
375 \r
376         String queryTargetSelection(String title, Map<String, Pair<String, ImageDescriptor>> map) {\r
377             Shell shell = source.getShell();\r
378             ResourceSelectionDialog3<String> dialog = new ResourceSelectionDialog3<String>(shell, map, title, false) {\r
379                 @Override\r
380                 protected IDialogSettings getBaseDialogSettings() {\r
381                     return Activator.getDefault().getDialogSettings();\r
382                 }\r
383             };\r
384             if (dialog.open() == Window.OK)\r
385                 return (String) dialog.getFirstResult();\r
386             return null;\r
387         }\r
388 \r
389         void refreshSymbols() {\r
390             try {\r
391 \r
392                 final String uri = target.getText();\r
393 \r
394                 Collection<NamedResource> syms = Simantics.getSession().syncRequest(new UniqueRead<Collection<NamedResource>>() {\r
395 \r
396                     @Override\r
397                     public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {\r
398 \r
399                         Layer0 L0 = Layer0.getInstance(graph);\r
400                         DiagramResource DIA = DiagramResource.getInstance(graph);\r
401                         ModelingResources MOD = ModelingResources.getInstance(graph);\r
402 \r
403                         Set<NamedResource> result = new THashSet<>();\r
404                         Resource componentType = graph.getResource(uri);\r
405 \r
406                         Set<Resource> potentialSymbols = new THashSet<>();\r
407                         potentialSymbols.addAll(graph.syncRequest(new ObjectsWithType(componentType, L0.ConsistsOf, DIA.ElementClass)));\r
408                         potentialSymbols.addAll(graph.getObjects(componentType, MOD.ComponentTypeToSymbol));\r
409 \r
410                         for(Resource symbol : potentialSymbols) {\r
411                             if(!graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType)) continue;\r
412                             String name = graph.getRelatedValue(symbol, L0.HasName, Bindings.STRING);\r
413                             if(graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType))\r
414                                 result.add(new NamedResource(name, symbol));\r
415                         }\r
416 \r
417                         return new ArrayList<NamedResource>(result);\r
418 \r
419                     }\r
420 \r
421                 });\r
422 \r
423                 symbols.removeAll();\r
424                 symbols.add("<retain symbol name>");\r
425                 for(NamedResource nr : syms) {\r
426                     symbols.add(nr.getName());\r
427                 }\r
428                 symbols.setData(syms);\r
429                 symbols.select(0);\r
430 \r
431                 if(syms.isEmpty()) {\r
432                     symbolsLabel.setVisible(false);\r
433                     symbols.setVisible(false);\r
434                     GridDataFactory.fillDefaults().exclude(true).applyTo(symbolsLabel);\r
435                     GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(symbols);\r
436                 } else {\r
437                     symbolsLabel.setVisible(true);\r
438                     symbols.setVisible(true);\r
439                     GridDataFactory.fillDefaults().applyTo(symbolsLabel);\r
440                     GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);\r
441                 }\r
442 \r
443                 symbols.getParent().layout();\r
444 \r
445             } catch (DatabaseException e) {\r
446                 Logger.defaultLogError(e);\r
447             }\r
448         }\r
449 \r
450         void refreshModel() {\r
451             final String sourceText = source.getText();\r
452             final String targetText = target.getText();\r
453             int symbolIndex = symbols.getSelectionIndex();\r
454             Resource symbol = null;\r
455             if(symbolIndex > 0) {\r
456                 @SuppressWarnings("unchecked")\r
457                 java.util.List<NamedResource> nrs = (java.util.List<NamedResource>)symbols.getData();\r
458                 symbol = nrs.get(symbolIndex-1).getResource();\r
459             }\r
460             final Resource finalSymbol = symbol;\r
461 \r
462             try {\r
463                 model = Simantics.getSession().syncRequest(new UniqueRead<MigrateModel>() {\r
464                     @Override\r
465                     public MigrateModel perform(ReadGraph graph) throws DatabaseException {\r
466                         Layer0 L0 = Layer0.getInstance(graph);\r
467                         StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
468 \r
469                         Resource source = graph.getPossibleResource(sourceText);\r
470                         if(source == null) return model;\r
471                         Resource target = graph.getPossibleResource(targetText);\r
472                         if(target == null) return model;\r
473 \r
474                         if(graph.isInstanceOf(source, STR.ComponentType)) {\r
475                             return UserComponentMigration.getComponentTypeModel(graph, source, target, finalSymbol);\r
476                         } else if(graph.isInstanceOf(source, L0.SharedOntology)) {\r
477                             return UserComponentMigration.getSharedOntologyModel(graph, source, target);\r
478                         } else {\r
479                             return null;\r
480                         }\r
481                     }\r
482                 });\r
483             } catch (DatabaseException e) {\r
484                 Logger.defaultLogError(e);\r
485             }\r
486 \r
487             instances.removeAll();\r
488             locations.removeAll();\r
489 \r
490             if (model == null)\r
491                 return;\r
492 \r
493             int preSelect = -1, i = 0;\r
494             for (Triple<String,NamedResource,Collection<MigrationOperation>> r : model.instances) {\r
495                 locations.add(r.second.getName() + " (" + r.third.size() + " instances)");\r
496                 if (r.first.equals(previouslySelectedLocationId))\r
497                     preSelect = i;\r
498                 if (preSelect < 0 && model.activeModels.contains(r.second.getResource()))\r
499                     preSelect = i;\r
500                 ++i;\r
501             }\r
502             if (locations.getItemCount() == 0) {\r
503                 locations.add("<no instances were found>");\r
504                 locations.select(0);\r
505             } else {\r
506                 locations.select(preSelect > -1 ? preSelect : 0);\r
507             }\r
508         }\r
509 \r
510         void refreshInstances() {\r
511 \r
512             int toMigrate = 0;\r
513             for(Triple<String,NamedResource,Collection<MigrationOperation>> pair : model.instances) {\r
514                 toMigrate += pair.third.size();\r
515             }\r
516 \r
517             if(model.instanceCount == 0)\r
518                 instanceLabel.setText("No instances were found.");\r
519             else if(model.instanceCount == 1) {\r
520                 if(toMigrate == 1) {\r
521                     instanceLabel.setText("1 migratable instance found.");\r
522                 } else {\r
523                     instanceLabel.setText("1 instance found, but it cannot be migrated with current settings.");\r
524                 }\r
525             } else {\r
526                 if(toMigrate < model.instanceCount) {\r
527                     if(toMigrate == 0) {\r
528                         instanceLabel.setText(model.instanceCount + " instances were found. None of them can be migrated with current settings.");\r
529                     } else {\r
530                         instanceLabel.setText(model.instanceCount + " instances were found. " + (model.instanceCount-toMigrate) + " of them cannot be migrated with current settings.");\r
531                     }\r
532                 } else {\r
533                     instanceLabel.setText(model.instanceCount + " migratable instances found. ");\r
534                 }\r
535             }\r
536 \r
537             instances.removeAll();\r
538 \r
539             if (model == null)\r
540                 return;\r
541 \r
542             if(toMigrate == 0) {\r
543                 locationsLabel.setVisible(false);\r
544                 locations.setVisible(false);\r
545                 GridDataFactory.fillDefaults().exclude(true).applyTo(locationsLabel);\r
546                 GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(locations);\r
547             } else {\r
548                 locationsLabel.setVisible(true);\r
549                 locations.setVisible(true);\r
550                 GridDataFactory.fillDefaults().applyTo(locationsLabel);\r
551                 GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);\r
552             }\r
553 \r
554             if(!model.instances.isEmpty()) {\r
555 \r
556                 int locationIndex = locations.getSelectionIndex();\r
557                 if(locationIndex == -1) return;\r
558 \r
559                 model.sortedShownInstances = new ArrayList<MigrationOperation>();\r
560                 for(MigrationOperation o : model.instances.get(locationIndex).third)\r
561                     model.sortedShownInstances.add(o);\r
562                 Collections.sort(model.sortedShownInstances, MIGRATION_OP_COMPARATOR);\r
563                 for(MigrationOperation o : model.sortedShownInstances) {\r
564                     String uri = o.toString();\r
565                     uri = uri.replace("http://Projects/Development%20Project/", "");\r
566                     uri = URIStringUtils.unescape(uri);\r
567                     instances.add(uri);\r
568                 }\r
569 \r
570             }\r
571 \r
572             if(model.sortedShownInstances.isEmpty()) {\r
573                 instancesLabel.setVisible(false);\r
574                 instances.setVisible(false);\r
575                 buttonBar.setVisible(false);\r
576                 GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(instancesLabel);\r
577                 GridDataFactory.fillDefaults().exclude(true).grab(true, true).span(10, 1).applyTo(instances);\r
578                 GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(10, 1).applyTo(buttonBar);\r
579             } else {\r
580                 GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(instancesLabel);\r
581                 GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);\r
582                 GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);\r
583                 instancesLabel.setVisible(true);\r
584                 instances.setVisible(true);\r
585                 buttonBar.setVisible(true);\r
586             }\r
587 \r
588             locations.getParent().layout();\r
589 \r
590         }\r
591 \r
592         Listener validateListener = new Listener() {\r
593             @Override\r
594             public void handleEvent(Event event) {\r
595                 switch (event.type) {\r
596                     case SWT.Modify:\r
597                         validatePage();\r
598                     case SWT.Selection:\r
599                         validatePage();\r
600                         break;\r
601                     case SWT.FocusIn:\r
602                     {\r
603                         if (event.widget instanceof Text) {\r
604                             Text t = (Text) event.widget;\r
605                             t.selectAll();\r
606                         }\r
607                         break;\r
608                     }\r
609                 }\r
610             }\r
611         };\r
612 \r
613         private void validatePage() {\r
614             setMessage(null);\r
615             setErrorMessage(null);\r
616             setPageComplete(true);\r
617         }\r
618 \r
619     }\r
620 \r
621     private static final Comparator<MigrationOperation> MIGRATION_OP_COMPARATOR = new Comparator<MigrateModel.MigrationOperation>() {\r
622         @Override\r
623         public int compare(MigrationOperation o1, MigrationOperation o2) {\r
624             return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(o1.instanceToMigrate.getName(), o2.instanceToMigrate.getName());\r
625         }\r
626     };\r
627 \r
628     private static abstract class BrowseContentRequest extends UnaryRead<String, Map<String, Pair<String, ImageDescriptor>>> {\r
629 \r
630         public BrowseContentRequest(String uri) {\r
631             super(uri);\r
632         }\r
633 \r
634         @Override\r
635         public Map<String, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {\r
636             Resource root = graph.getPossibleResource(parameter);\r
637             if (root == null)\r
638                 return null;\r
639 \r
640             Map<String, Pair<String, ImageDescriptor>> result = new THashMap<>();\r
641             Collection<NamedResource> infos = getVersions(graph, root); \r
642             for (NamedResource info : infos)\r
643                 result.put(graph.getURI(info.getResource()), Pair.<String,ImageDescriptor>make(Versions.getStandardPathNameString(graph, info.getResource()), null));\r
644 \r
645             return result;\r
646         }\r
647 \r
648         protected abstract Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException;\r
649 \r
650     }\r
651 \r
652     private static class BrowseSourceContentRequest extends BrowseContentRequest {\r
653         public BrowseSourceContentRequest(String uri) {\r
654             super(uri);\r
655         }\r
656         @Override\r
657         protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {\r
658             return Versions.getOlderVersions(graph, root);\r
659         }\r
660     }\r
661 \r
662     private static class BrowseTargetContentRequest extends BrowseContentRequest {\r
663         public BrowseTargetContentRequest(String uri) {\r
664             super(uri);\r
665         }\r
666         @Override\r
667         protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {\r
668             return Versions.getNewerVersions(graph, root);\r
669         }\r
670     }\r
671 \r
672 }\r