Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo')
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionActionBarContributor.java812
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditor.java3024
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditorPlugin.java96
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionModelWizard.java657
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolution.java138
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolutionGenerator.java36
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DefaultDiagnosticResolutionGenerator.java403
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolution.java120
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolutionRelevance.java19
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixPage.java408
-rw-r--r--plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixWizard.java115
11 files changed, 5828 insertions, 0 deletions
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionActionBarContributor.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionActionBarContributor.java
new file mode 100644
index 0000000000..bb586373cb
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionActionBarContributor.java
@@ -0,0 +1,812 @@
+/**
+ */
+package org.eclipse.emf.cdo.evolution.presentation;
+
+import org.eclipse.emf.cdo.evolution.util.ElementHandler;
+import org.eclipse.emf.cdo.evolution.util.ElementRunnable;
+import org.eclipse.emf.cdo.evolution.util.IDAnnotation;
+
+import org.eclipse.emf.common.ui.action.ViewerFilterAction;
+import org.eclipse.emf.common.ui.viewer.IViewerProvider;
+import org.eclipse.emf.ecore.EAnnotation;
+import org.eclipse.emf.ecore.EGenericType;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.ETypeParameter;
+import org.eclipse.emf.ecore.EcorePackage;
+import org.eclipse.emf.ecore.presentation.EcoreEditorPlugin;
+import org.eclipse.emf.edit.command.ChangeCommand;
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.emf.edit.ui.action.CollapseAllAction;
+import org.eclipse.emf.edit.ui.action.ControlAction;
+import org.eclipse.emf.edit.ui.action.CreateChildAction;
+import org.eclipse.emf.edit.ui.action.CreateSiblingAction;
+import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
+import org.eclipse.emf.edit.ui.action.FindAction;
+import org.eclipse.emf.edit.ui.action.LoadResourceAction;
+import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator;
+
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.ActionContributionItem;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.action.IContributionItem;
+import org.eclipse.jface.action.IContributionManager;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.action.SubContributionItem;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.PartInitException;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * This is the action bar contributor for the Evolution model editor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class EvolutionActionBarContributor extends EditingDomainActionBarContributor implements ISelectionChangedListener
+{
+ /**
+ * This keeps track of the active editor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IEditorPart activeEditorPart;
+
+ /**
+ * This keeps track of the current selection provider.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected ISelectionProvider selectionProvider;
+
+ /**
+ * This action opens the Properties view.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IAction showPropertiesViewAction = new Action(EvolutionEditorPlugin.INSTANCE.getString("_UI_ShowPropertiesView_menu_item"))
+ {
+ @Override
+ public void run()
+ {
+ try
+ {
+ getPage().showView("org.eclipse.ui.views.PropertySheet");
+ }
+ catch (PartInitException exception)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ }
+ }
+ };
+
+ /**
+ * This action refreshes the viewer of the current editor if the editor
+ * implements {@link org.eclipse.emf.common.ui.viewer.IViewerProvider}.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IAction refreshViewerAction = new Action(EvolutionEditorPlugin.INSTANCE.getString("_UI_RefreshViewer_menu_item"))
+ {
+ @Override
+ public boolean isEnabled()
+ {
+ return activeEditorPart instanceof IViewerProvider;
+ }
+
+ @Override
+ public void run()
+ {
+ if (activeEditorPart instanceof IViewerProvider)
+ {
+ Viewer viewer = ((IViewerProvider)activeEditorPart).getViewer();
+ if (viewer != null)
+ {
+ viewer.refresh();
+ }
+ }
+ }
+ };
+
+ protected IAction assignIDsAction = new IDAction("Assign IDs")
+ {
+ @Override
+ protected void handleID(EModelElement modelElement)
+ {
+ IDAnnotation.ensureValue(modelElement);
+ }
+ };
+
+ protected IAction removeIDsAction = new IDAction("Remove IDs")
+ {
+ @Override
+ protected void handleID(EModelElement modelElement)
+ {
+ IDAnnotation.removeFrom(modelElement);
+ }
+ };
+
+ /**
+ * This will contain one {@link org.eclipse.emf.edit.ui.action.CreateChildAction} corresponding to each descriptor
+ * generated for the current selection by the item provider.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<IAction> createChildActions;
+
+ /**
+ * This is the menu manager into which menu contribution items should be added for CreateChild actions.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IMenuManager createChildMenuManager;
+
+ /**
+ * This will contain one {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} corresponding to each descriptor
+ * generated for the current selection by the item provider.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<IAction> createSiblingActions;
+
+ /**
+ * This is the menu manager into which menu contribution items should be added for CreateSibling actions.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IMenuManager createSiblingMenuManager;
+
+ protected SelectionChangedEvent lastSelectionChangedEvent;
+
+ protected ViewerFilterAction showGenericsAction = new ViewerFilterAction(EcoreEditorPlugin.INSTANCE.getString("_UI_ShowGenerics_menu_item"),
+ IAction.AS_CHECK_BOX)
+ {
+ @Override
+ protected void refreshViewers()
+ {
+ if (activeEditorPart instanceof EvolutionEditor)
+ {
+ ((EvolutionEditor)activeEditorPart).ecoreItemProviderAdapterFactory.setShowGenerics(isChecked());
+ }
+
+ super.refreshViewers();
+
+ if (lastSelectionChangedEvent != null && activeEditorPart instanceof EvolutionEditor)
+ {
+ selectionChanged(lastSelectionChangedEvent);
+ }
+ }
+
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element)
+ {
+ return isChecked() || !(element instanceof ETypeParameter || element instanceof EGenericType);
+ }
+ };
+
+ /**
+ * This creates an instance of the contributor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ public EvolutionActionBarContributor()
+ {
+ super(ADDITIONS_LAST_STYLE);
+ loadResourceAction = new LoadResourceAction();
+ // validateAction = new ValidateAction();
+ liveValidationAction = new DiagnosticDecorator.LiveValidator.LiveValidationAction(EvolutionEditorPlugin.getPlugin().getDialogSettings());
+ controlAction = new ControlAction();
+ findAction = FindAction.create();
+ collapseAllAction = new CollapseAllAction();
+
+ showGenericsAction.setChecked(Boolean.parseBoolean(EcoreEditorPlugin.getPlugin().getDialogSettings().get("showGenericsAction")));
+ }
+
+ public void showGenerics(boolean isChecked)
+ {
+ if (showGenericsAction != null)
+ {
+ showGenericsAction.setChecked(isChecked);
+ }
+ }
+
+ @Override
+ public void dispose()
+ {
+ EcoreEditorPlugin.getPlugin().getDialogSettings().put("showGenericsAction", Boolean.toString(showGenericsAction.isChecked()));
+
+ super.dispose();
+ }
+
+ /**
+ * This adds Separators for editor additions to the tool bar.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ @Override
+ public void contributeToToolBar(IToolBarManager toolBarManager)
+ {
+ super.contributeToToolBar(toolBarManager);
+ toolBarManager.add(new Separator("evolution-settings"));
+ toolBarManager.add(new Separator("evolution-additions"));
+ toolBarManager.add(assignIDsAction);
+ toolBarManager.add(removeIDsAction);
+ }
+
+ /**
+ * This adds to the menu bar a menu and some separators for editor additions,
+ * as well as the sub-menus for object creation items.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ @Override
+ public void contributeToMenu(IMenuManager menuManager)
+ {
+ super.contributeToMenu(menuManager);
+
+ IMenuManager submenuManager = new MenuManager(EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionEditor_menu"), "org.eclipse.emf.cdo.evolutionMenuID");
+ menuManager.insertAfter("additions", submenuManager);
+ submenuManager.add(new Separator("settings"));
+ submenuManager.add(new Separator("actions"));
+ submenuManager.add(new Separator("additions"));
+ submenuManager.add(new Separator("additions-end"));
+
+ // Prepare for CreateChild item addition or removal.
+ //
+ createChildMenuManager = new MenuManager(EvolutionEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item"));
+ submenuManager.insertBefore("additions", createChildMenuManager);
+
+ // Prepare for CreateSibling item addition or removal.
+ //
+ createSiblingMenuManager = new MenuManager(EvolutionEditorPlugin.INSTANCE.getString("_UI_CreateSibling_menu_item"));
+ submenuManager.insertBefore("additions", createSiblingMenuManager);
+
+ // Force an update because Eclipse hides empty menus now.
+ //
+ submenuManager.addMenuListener(new IMenuListener()
+ {
+ public void menuAboutToShow(IMenuManager menuManager)
+ {
+ menuManager.updateAll(true);
+ }
+ });
+
+ addGlobalActions(submenuManager);
+ submenuManager.insertBefore("additions-end", showGenericsAction);
+ }
+
+ /**
+ * When the active editor changes, this remembers the change and registers with it as a selection provider.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setActiveEditorGen(IEditorPart part)
+ {
+ super.setActiveEditor(part);
+ activeEditorPart = part;
+
+ // Switch to the new selection provider.
+ //
+ if (selectionProvider != null)
+ {
+ selectionProvider.removeSelectionChangedListener(this);
+ }
+ if (part == null)
+ {
+ selectionProvider = null;
+ }
+ else
+ {
+ selectionProvider = part.getSite().getSelectionProvider();
+ selectionProvider.addSelectionChangedListener(this);
+
+ // Fake a selection changed event to update the menus.
+ //
+ if (selectionProvider.getSelection() != null)
+ {
+ selectionChanged(new SelectionChangedEvent(selectionProvider, selectionProvider.getSelection()));
+ }
+ }
+ }
+
+ /**
+ * When the active editor changes, this remembers the change and registers with it as a selection provider.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ @Override
+ public void setActiveEditor(IEditorPart part)
+ {
+ setActiveEditorGen(part);
+
+ if (part instanceof EvolutionEditor)
+ {
+ showGenericsAction.addViewer(((EvolutionEditor)part).getViewer());
+ showGenericsAction.setEnabled(true);
+ }
+ else
+ {
+ showGenericsAction.setEnabled(false);
+ }
+ }
+
+ /**
+ * This implements {@link org.eclipse.jface.viewers.ISelectionChangedListener},
+ * handling {@link org.eclipse.jface.viewers.SelectionChangedEvent}s by querying for the children and siblings
+ * that can be added to the selected object and updating the menus accordingly.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void selectionChanged(SelectionChangedEvent event)
+ {
+ // Remove any menu items for old selection.
+ //
+ if (createChildMenuManager != null)
+ {
+ depopulateManager(createChildMenuManager, createChildActions);
+ }
+ if (createSiblingMenuManager != null)
+ {
+ depopulateManager(createSiblingMenuManager, createSiblingActions);
+ }
+
+ // Query the new selection for appropriate new child/sibling descriptors
+ //
+ Collection<?> newChildDescriptors = null;
+ Collection<?> newSiblingDescriptors = null;
+
+ ISelection selection = event.getSelection();
+ if (selection instanceof IStructuredSelection && ((IStructuredSelection)selection).size() == 1)
+ {
+ Object object = ((IStructuredSelection)selection).getFirstElement();
+
+ EditingDomain domain = ((IEditingDomainProvider)activeEditorPart).getEditingDomain();
+
+ newChildDescriptors = domain.getNewChildDescriptors(object, null);
+ newSiblingDescriptors = domain.getNewChildDescriptors(null, object);
+ }
+
+ // Generate actions for selection; populate and redraw the menus.
+ //
+ createChildActions = generateCreateChildActions(newChildDescriptors, selection);
+ createSiblingActions = generateCreateSiblingActions(newSiblingDescriptors, selection);
+
+ if (createChildMenuManager != null)
+ {
+ populateManager(createChildMenuManager, createChildActions, null);
+ createChildMenuManager.update(true);
+ }
+ if (createSiblingMenuManager != null)
+ {
+ populateManager(createSiblingMenuManager, createSiblingActions, null);
+ createSiblingMenuManager.update(true);
+ }
+ }
+
+ /**
+ * This generates a {@link org.eclipse.emf.edit.ui.action.CreateChildAction} for each object in <code>descriptors</code>,
+ * and returns the collection of these actions.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ protected Collection<IAction> generateCreateChildActions(Collection<?> descriptors, ISelection selection)
+ {
+ Collection<IAction> actions = new ArrayList<IAction>();
+ if (descriptors != null)
+ {
+ for (Object descriptor : descriptors)
+ {
+ if (!showGenericsAction.isChecked() && descriptor instanceof CommandParameter)
+ {
+ Object feature = ((CommandParameter)descriptor).getFeature();
+ if (isGenericFeature(feature))
+ {
+ continue;
+ }
+ }
+ actions.add(new EcoreCreateChildAction(activeEditorPart, selection, descriptor));
+ }
+ }
+ return actions;
+ }
+
+ /**
+ * This generates a {@link org.eclipse.emf.edit.ui.action.CreateSiblingAction} for each object in <code>descriptors</code>,
+ * and returns the collection of these actions.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ protected Collection<IAction> generateCreateSiblingActions(Collection<?> descriptors, ISelection selection)
+ {
+ Collection<IAction> actions = new ArrayList<IAction>();
+ if (descriptors != null)
+ {
+ for (Object descriptor : descriptors)
+ {
+ if (!showGenericsAction.isChecked() && descriptor instanceof CommandParameter)
+ {
+ Object feature = ((CommandParameter)descriptor).getFeature();
+ if (isGenericFeature(feature))
+ {
+ continue;
+ }
+ }
+ actions.add(new EcoreCreateSiblingAction(activeEditorPart, selection, descriptor));
+ }
+ }
+ return actions;
+ }
+
+ protected boolean isGenericFeature(Object feature)
+ {
+ return feature == EcorePackage.Literals.ECLASS__EGENERIC_SUPER_TYPES || feature == EcorePackage.Literals.ECLASSIFIER__ETYPE_PARAMETERS
+ || feature == EcorePackage.Literals.EOPERATION__EGENERIC_EXCEPTIONS || feature == EcorePackage.Literals.EOPERATION__ETYPE_PARAMETERS
+ || feature == EcorePackage.Literals.ETYPED_ELEMENT__EGENERIC_TYPE;
+ }
+
+ /**
+ * This populates the specified <code>manager</code> with {@link org.eclipse.jface.action.ActionContributionItem}s
+ * based on the {@link org.eclipse.jface.action.IAction}s contained in the <code>actions</code> collection,
+ * by inserting them before the specified contribution item <code>contributionID</code>.
+ * If <code>contributionID</code> is <code>null</code>, they are simply added.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ protected void populateManager(IContributionManager manager, Collection<? extends IAction> actions, String contributionID)
+ {
+ if (actions != null)
+ {
+ // Look for actions that create EAnnotations.
+ //
+ Set<IAction> ignoredActions = new HashSet<IAction>();
+ Set<IAction> annotationActions = new LinkedHashSet<IAction>();
+ for (IAction action : actions)
+ {
+ if (action instanceof EObjectProvider)
+ {
+ EObjectProvider eObjectProvider = (EObjectProvider)action;
+ EObject eObject = eObjectProvider.getEObject();
+ if (eObject instanceof EAnnotation)
+ {
+ annotationActions.add(action);
+ ignoredActions.add(action);
+ }
+ }
+ }
+
+ // If there is more than one action that creates an annotation...
+ //
+ if (annotationActions.size() > 1)
+ {
+ // Create a menu manager to group them.
+ // This assumes the first action is one for the null source.
+ //
+ IAction action = annotationActions.iterator().next();
+ String actionText = action.getText();
+ MenuManager annotationMenuManager = new MenuManager(actionText, action.getImageDescriptor(), "annotations");
+
+ // Add that menu manager instead of the individual actions.
+ if (contributionID != null)
+ {
+ manager.insertBefore(contributionID, annotationMenuManager);
+ }
+ else
+ {
+ manager.add(annotationMenuManager);
+ }
+
+ // Add an item for each annotation action.
+ //
+ for (IAction annotationAction : annotationActions)
+ {
+ annotationMenuManager.add(annotationAction);
+ String source = ((EAnnotation)((EObjectProvider)annotationAction).getEObject()).getSource();
+ if (source != null)
+ {
+ // Set the label to include the source.
+ //
+ annotationAction.setText(actionText + " - " + source);
+ }
+ }
+ }
+ else
+ {
+ ignoredActions.clear();
+ }
+
+ for (IAction action : actions)
+ {
+ if (!ignoredActions.contains(action))
+ {
+ if (contributionID != null)
+ {
+ manager.insertBefore(contributionID, action);
+ }
+ else
+ {
+ manager.add(action);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This removes from the specified <code>manager</code> all {@link org.eclipse.jface.action.ActionContributionItem}s
+ * based on the {@link org.eclipse.jface.action.IAction}s contained in the <code>actions</code> collection.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void depopulateManager(IContributionManager manager, Collection<? extends IAction> actions)
+ {
+ if (actions != null)
+ {
+ IContributionItem[] items = manager.getItems();
+ for (int i = 0; i < items.length; i++)
+ {
+ // Look into SubContributionItems
+ //
+ IContributionItem contributionItem = items[i];
+ while (contributionItem instanceof SubContributionItem)
+ {
+ contributionItem = ((SubContributionItem)contributionItem).getInnerItem();
+ }
+
+ // Delete the ActionContributionItems with matching action.
+ //
+ if (contributionItem instanceof ActionContributionItem)
+ {
+ IAction action = ((ActionContributionItem)contributionItem).getAction();
+ if (actions.contains(action))
+ {
+ manager.remove(contributionItem);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This populates the pop-up menu before it appears.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void menuAboutToShow(IMenuManager menuManager)
+ {
+ super.menuAboutToShow(menuManager);
+ MenuManager submenuManager = null;
+
+ submenuManager = new MenuManager(EvolutionEditorPlugin.INSTANCE.getString("_UI_CreateChild_menu_item"));
+ populateManager(submenuManager, createChildActions, null);
+ menuManager.insertBefore("edit", submenuManager);
+
+ submenuManager = new MenuManager(EvolutionEditorPlugin.INSTANCE.getString("_UI_CreateSibling_menu_item"));
+ populateManager(submenuManager, createSiblingActions, null);
+ menuManager.insertBefore("edit", submenuManager);
+ }
+
+ /**
+ * This inserts global actions before the "additions-end" separator.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected void addGlobalActions(IMenuManager menuManager)
+ {
+ menuManager.insertAfter("additions-end", new Separator("ui-actions"));
+ menuManager.insertAfter("ui-actions", showPropertiesViewAction);
+
+ refreshViewerAction.setEnabled(refreshViewerAction.isEnabled());
+ menuManager.insertAfter("ui-actions", refreshViewerAction);
+
+ super.addGlobalActions(menuManager);
+ }
+
+ /**
+ * This ensures that a delete action will clean up all references to deleted objects.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected boolean removeAllReferencesOnDelete()
+ {
+ return true;
+ }
+
+ /**
+ * An interface implemented by {@link EcoreCreateChildAction} and {@link EcoreCreateSiblingAction} to provide access to the data in the descriptor.
+ */
+ public interface EObjectProvider
+ {
+ public EObject getEObject();
+ }
+
+ /**
+ * A create child action subclass that provides access to the {@link #descriptor} and specializes {@link #run()} to show the properties view.
+ */
+ public class EcoreCreateChildAction extends CreateChildAction implements EObjectProvider
+ {
+ public EcoreCreateChildAction(IWorkbenchPart workbenchPart, ISelection selection, Object descriptor)
+ {
+ super(workbenchPart, selection, descriptor);
+ }
+
+ public EObject getEObject()
+ {
+ if (descriptor instanceof CommandParameter)
+ {
+ CommandParameter commandParameter = (CommandParameter)descriptor;
+ return commandParameter.getEValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public void run()
+ {
+ super.run();
+
+ // This is dispatched twice because the command stack listener dispatches once and then the viewer selection is
+ // also dispatches once,
+ // and we need to delay until the selection is established.
+ //
+ final Display display = getPage().getWorkbenchWindow().getShell().getDisplay();
+ display.asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ display.asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ showPropertiesViewAction.run();
+ }
+ });
+ }
+ });
+ }
+ }
+
+ /**
+ * A create sibling action subclass that provides access to the {@link #descriptor} and specializes {@link #run()} to show the properties view.
+ */
+ public class EcoreCreateSiblingAction extends CreateSiblingAction implements EObjectProvider
+ {
+ public EcoreCreateSiblingAction(IWorkbenchPart workbenchPart, ISelection selection, Object descriptor)
+ {
+ super(workbenchPart, selection, descriptor);
+ }
+
+ public EObject getEObject()
+ {
+ if (descriptor instanceof CommandParameter)
+ {
+ CommandParameter commandParameter = (CommandParameter)descriptor;
+ return commandParameter.getEValue();
+ }
+ else
+ {
+ return null;
+ }
+ }
+
+ @Override
+ public void run()
+ {
+ super.run();
+
+ // This is dispatched twice because the command stack listener dispatches once and then the viewer selection is
+ // also dispatches once,
+ // and we need to delay until the selection is established.
+ //
+ final Display display = getPage().getWorkbenchWindow().getShell().getDisplay();
+ display.asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ display.asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ showPropertiesViewAction.run();
+ }
+ });
+ }
+ });
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private abstract class IDAction extends Action
+ {
+ public IDAction(String text)
+ {
+ super(text);
+ }
+
+ @Override
+ public void run()
+ {
+ if (selectionProvider != null)
+ {
+ ISelection selection = selectionProvider.getSelection();
+ if (selection instanceof IStructuredSelection)
+ {
+ IStructuredSelection ssel = (IStructuredSelection)selection;
+ final Object element = ssel.getFirstElement();
+ if (element instanceof EModelElement)
+ {
+ final EModelElement rootElement = (EModelElement)element;
+
+ EditingDomain domain = ((IEditingDomainProvider)activeEditorPart).getEditingDomain();
+ ChangeCommand command = new ChangeCommand(rootElement)
+ {
+ @Override
+ protected void doExecute()
+ {
+ ElementHandler.execute(rootElement, new ElementRunnable()
+ {
+ public void run(EModelElement modelElement)
+ {
+ handleID(modelElement);
+ }
+ });
+ }
+ };
+
+ domain.getCommandStack().execute(command);
+ }
+ }
+ }
+ }
+
+ protected abstract void handleID(EModelElement modelElement);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditor.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditor.java
new file mode 100644
index 0000000000..bff82ec24b
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditor.java
@@ -0,0 +1,3024 @@
+/**
+ */
+package org.eclipse.emf.cdo.evolution.presentation;
+
+import org.eclipse.emf.cdo.evolution.Change;
+import org.eclipse.emf.cdo.evolution.Evolution;
+import org.eclipse.emf.cdo.evolution.EvolutionPackage;
+import org.eclipse.emf.cdo.evolution.Release;
+import org.eclipse.emf.cdo.evolution.impl.EvolutionImpl;
+import org.eclipse.emf.cdo.evolution.presentation.quickfix.DiagnosticResolution;
+import org.eclipse.emf.cdo.evolution.presentation.quickfix.QuickFixWizard;
+import org.eclipse.emf.cdo.evolution.provider.EvolutionItemProviderAdapterFactory;
+import org.eclipse.emf.cdo.evolution.util.DiagnosticID;
+import org.eclipse.emf.cdo.evolution.util.ElementHandler;
+import org.eclipse.emf.cdo.evolution.util.ValidationContext;
+import org.eclipse.emf.cdo.evolution.util.ValidationPhase;
+
+import org.eclipse.net4j.ui.shared.SharedIcons;
+import org.eclipse.net4j.util.ReflectUtil;
+import org.eclipse.net4j.util.StringUtil;
+import org.eclipse.net4j.util.WrappedException;
+
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.CommandStack;
+import org.eclipse.emf.common.command.CommandStackListener;
+import org.eclipse.emf.common.command.UnexecutableCommand;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.ui.ImageURIRegistry;
+import org.eclipse.emf.common.ui.MarkerHelper;
+import org.eclipse.emf.common.ui.editor.ProblemEditorPart;
+import org.eclipse.emf.common.ui.viewer.ColumnViewerInformationControlToolTipSupport;
+import org.eclipse.emf.common.ui.viewer.IViewerProvider;
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticChain;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EGenericType;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.ETypeParameter;
+import org.eclipse.emf.ecore.InternalEObject;
+import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.util.Diagnostician;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.emf.ecore.util.EObjectValidator;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.edit.command.CommandParameter;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.emf.edit.provider.AdapterFactoryItemDelegator;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
+import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
+import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
+import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
+import org.eclipse.emf.edit.ui.celleditor.AdapterFactoryTreeEditor;
+import org.eclipse.emf.edit.ui.dnd.EditingDomainViewerDropAdapter;
+import org.eclipse.emf.edit.ui.dnd.LocalTransfer;
+import org.eclipse.emf.edit.ui.dnd.ViewerDragAdapter;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.emf.edit.ui.provider.DecoratingColumLabelProvider;
+import org.eclipse.emf.edit.ui.provider.DelegatingStyledCellLabelProvider;
+import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator;
+import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator.DiagnosticAdapter;
+import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator.LiveValidator;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+import org.eclipse.emf.edit.ui.provider.PropertySource;
+import org.eclipse.emf.edit.ui.provider.UnwrappingSelectionProvider;
+import org.eclipse.emf.edit.ui.util.EditUIMarkerHelper;
+import org.eclipse.emf.edit.ui.util.EditUIUtil;
+import org.eclipse.emf.edit.ui.util.FindAndReplaceTarget;
+import org.eclipse.emf.edit.ui.view.ExtendedPropertySheetPage;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceChangeEvent;
+import org.eclipse.core.resources.IResourceChangeListener;
+import org.eclipse.core.resources.IResourceDelta;
+import org.eclipse.core.resources.IResourceDeltaVisitor;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.Adapters;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.IMenuListener;
+import org.eclipse.jface.action.IMenuManager;
+import org.eclipse.jface.action.IStatusLineManager;
+import org.eclipse.jface.action.IToolBarManager;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.action.Separator;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableContext;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.text.IFindReplaceTarget;
+import org.eclipse.jface.util.LocalSelectionTransfer;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.IOpenListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.OpenEvent;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.wizard.IWizard;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CTabFolder;
+import org.eclipse.swt.custom.SashForm;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.FileTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlAdapter;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.IActionBars;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IPartListener;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchPartSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.SaveAsDialog;
+import org.eclipse.ui.ide.IGotoMarker;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.MultiPageEditorPart;
+import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
+import org.eclipse.ui.views.contentoutline.ContentOutline;
+import org.eclipse.ui.views.contentoutline.ContentOutlinePage;
+import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
+import org.eclipse.ui.views.properties.IPropertyDescriptor;
+import org.eclipse.ui.views.properties.IPropertySheetEntry;
+import org.eclipse.ui.views.properties.IPropertySheetPage;
+import org.eclipse.ui.views.properties.IPropertySource;
+import org.eclipse.ui.views.properties.PropertySheet;
+import org.eclipse.ui.views.properties.PropertySheetPage;
+import org.eclipse.ui.views.properties.PropertySheetSorter;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This is an example of a Evolution model editor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class EvolutionEditor extends MultiPageEditorPart implements IEditingDomainProvider, ISelectionProvider, IMenuListener, IViewerProvider, IGotoMarker
+{
+ /**
+ * This keeps track of the editing domain that is used to track all changes to the model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected AdapterFactoryEditingDomain editingDomain;
+
+ /**
+ * This is the one adapter factory used for providing views of the model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected ComposedAdapterFactory adapterFactory;
+
+ /**
+ * This is the content outline page.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IContentOutlinePage contentOutlinePage;
+
+ /**
+ * This is a kludge...
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IStatusLineManager contentOutlineStatusLineManager;
+
+ /**
+ * This is the content outline page's viewer.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected TreeViewer contentOutlineViewer;
+
+ /**
+ * This is the property sheet page.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected List<PropertySheetPage> propertySheetPages = new ArrayList<PropertySheetPage>();
+
+ /**
+ * This is the viewer that shadows the selection in the content outline.
+ * The parent relation must be correctly defined for this to work.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected TreeViewer selectionViewer;
+
+ /**
+ * This keeps track of the active content viewer, which may be either one of the viewers in the pages or the content outline viewer.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Viewer currentViewer;
+
+ /**
+ * This listens to which ever viewer is active.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected ISelectionChangedListener selectionChangedListener;
+
+ /**
+ * This keeps track of all the {@link org.eclipse.jface.viewers.ISelectionChangedListener}s that are listening to this editor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>();
+
+ /**
+ * This keeps track of the selection of the editor as a whole.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected ISelection editorSelection = StructuredSelection.EMPTY;
+
+ /**
+ * The MarkerHelper is responsible for creating workspace resource markers presented
+ * in Eclipse's Problems View.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected MarkerHelper markerHelper = new EditUIMarkerHelper();
+
+ /**
+ * This listens for when the outline becomes active
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IPartListener partListener = new IPartListener()
+ {
+ public void partActivated(IWorkbenchPart p)
+ {
+ if (p instanceof ContentOutline)
+ {
+ if (((ContentOutline)p).getCurrentPage() == contentOutlinePage)
+ {
+ getActionBarContributor().setActiveEditor(EvolutionEditor.this);
+
+ setCurrentViewer(contentOutlineViewer);
+ }
+ }
+ else if (p instanceof PropertySheet)
+ {
+ if (propertySheetPages.contains(((PropertySheet)p).getCurrentPage()))
+ {
+ getActionBarContributor().setActiveEditor(EvolutionEditor.this);
+ handleActivate();
+ }
+ }
+ else if (p == EvolutionEditor.this)
+ {
+ handleActivate();
+ }
+ }
+
+ public void partBroughtToTop(IWorkbenchPart p)
+ {
+ // Ignore.
+ }
+
+ public void partClosed(IWorkbenchPart p)
+ {
+ // Ignore.
+ }
+
+ public void partDeactivated(IWorkbenchPart p)
+ {
+ // Ignore.
+ }
+
+ public void partOpened(IWorkbenchPart p)
+ {
+ // Ignore.
+ }
+ };
+
+ /**
+ * Resources that have been removed since last activation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<Resource> removedResources = new ArrayList<Resource>();
+
+ /**
+ * Resources that have been changed since last activation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<Resource> changedResources = new ArrayList<Resource>();
+
+ /**
+ * Resources that have been saved.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<Resource> savedResources = new ArrayList<Resource>();
+
+ /**
+ * Map to store the diagnostic associated with a resource.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Map<Resource, Diagnostic> resourceToDiagnosticMap = new LinkedHashMap<Resource, Diagnostic>();
+
+ /**
+ * Controls whether the problem indication should be updated.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected boolean updateProblemIndication = true;
+
+ /**
+ * Adapter used to update the problem indication when resources are demanded loaded.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EContentAdapter problemIndicationAdapter = new EContentAdapter()
+ {
+ protected boolean dispatching;
+
+ @Override
+ public void notifyChanged(Notification notification)
+ {
+ if (notification.getNotifier() instanceof Resource)
+ {
+ switch (notification.getFeatureID(Resource.class))
+ {
+ case Resource.RESOURCE__IS_LOADED:
+ case Resource.RESOURCE__ERRORS:
+ case Resource.RESOURCE__WARNINGS:
+ {
+ Resource resource = (Resource)notification.getNotifier();
+ Diagnostic diagnostic = analyzeResourceProblems(resource, null);
+ if (diagnostic.getSeverity() != Diagnostic.OK)
+ {
+ resourceToDiagnosticMap.put(resource, diagnostic);
+ }
+ else
+ {
+ resourceToDiagnosticMap.remove(resource);
+ }
+ dispatchUpdateProblemIndication();
+ break;
+ }
+ }
+ }
+ else
+ {
+ super.notifyChanged(notification);
+ }
+ }
+
+ protected void dispatchUpdateProblemIndication()
+ {
+ if (updateProblemIndication && !dispatching)
+ {
+ dispatching = true;
+ getSite().getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ dispatching = false;
+ updateProblemIndication();
+ }
+ });
+ }
+ }
+
+ @Override
+ protected void setTarget(Resource target)
+ {
+ basicSetTarget(target);
+ }
+
+ @Override
+ protected void unsetTarget(Resource target)
+ {
+ basicUnsetTarget(target);
+ resourceToDiagnosticMap.remove(target);
+ dispatchUpdateProblemIndication();
+ }
+ };
+
+ /**
+ * This listens for workspace changes.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IResourceChangeListener resourceChangeListener = new IResourceChangeListener()
+ {
+ public void resourceChanged(IResourceChangeEvent event)
+ {
+ IResourceDelta delta = event.getDelta();
+ try
+ {
+ class ResourceDeltaVisitor implements IResourceDeltaVisitor
+ {
+ protected ResourceSet resourceSet = editingDomain.getResourceSet();
+
+ protected Collection<Resource> changedResources = new ArrayList<Resource>();
+
+ protected Collection<Resource> removedResources = new ArrayList<Resource>();
+
+ public boolean visit(final IResourceDelta delta)
+ {
+ if (delta.getResource().getType() == IResource.FILE)
+ {
+ if (delta.getKind() == IResourceDelta.REMOVED || delta.getKind() == IResourceDelta.CHANGED)
+ {
+ final Resource resource = resourceSet.getResource(URI.createPlatformResourceURI(delta.getFullPath().toString(), true), false);
+ if (resource != null)
+ {
+ if (delta.getKind() == IResourceDelta.REMOVED)
+ {
+ removedResources.add(resource);
+ }
+ else
+ {
+ if ((delta.getFlags() & IResourceDelta.MARKERS) != 0)
+ {
+ DiagnosticDecorator.Styled.DiagnosticAdapter.update(resource,
+ markerHelper.getMarkerDiagnostics(resource, (IFile)delta.getResource(), false));
+ }
+ if ((delta.getFlags() & IResourceDelta.CONTENT) != 0)
+ {
+ if (!savedResources.remove(resource))
+ {
+ changedResources.add(resource);
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ return true;
+ }
+
+ public Collection<Resource> getChangedResources()
+ {
+ return changedResources;
+ }
+
+ public Collection<Resource> getRemovedResources()
+ {
+ return removedResources;
+ }
+ }
+
+ final ResourceDeltaVisitor visitor = new ResourceDeltaVisitor();
+ delta.accept(visitor);
+
+ if (!visitor.getRemovedResources().isEmpty())
+ {
+ getSite().getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ removedResources.addAll(visitor.getRemovedResources());
+ if (!isDirty())
+ {
+ getSite().getPage().closeEditor(EvolutionEditor.this, false);
+ }
+ }
+ });
+ }
+
+ if (!visitor.getChangedResources().isEmpty())
+ {
+ getSite().getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ changedResources.addAll(visitor.getChangedResources());
+ if (getSite().getPage().getActiveEditor() == EvolutionEditor.this)
+ {
+ handleActivate();
+ }
+ }
+ });
+ }
+ }
+ catch (CoreException exception)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ }
+ }
+ };
+
+ protected EcoreItemProviderAdapterFactory ecoreItemProviderAdapterFactory;
+
+ private TableViewer problemViewer;
+
+ private final Set<Object> readOnlyObjects = new HashSet<Object>();
+
+ private Evolution evolution;
+
+ private Diagnostic[] allDiagnostics;
+
+ /**
+ * Handles activation of the editor or it's associated views.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void handleActivate()
+ {
+ // Recompute the read only state.
+ //
+ if (editingDomain.getResourceToReadOnlyMap() != null)
+ {
+ editingDomain.getResourceToReadOnlyMap().clear();
+
+ // Refresh any actions that may become enabled or disabled.
+ //
+ setSelection(getSelection());
+ }
+
+ if (!removedResources.isEmpty())
+ {
+ if (handleDirtyConflict())
+ {
+ getSite().getPage().closeEditor(EvolutionEditor.this, false);
+ }
+ else
+ {
+ removedResources.clear();
+ changedResources.clear();
+ savedResources.clear();
+ }
+ }
+ else if (!changedResources.isEmpty())
+ {
+ changedResources.removeAll(savedResources);
+ handleChangedResources();
+ changedResources.clear();
+ savedResources.clear();
+ }
+ }
+
+ /**
+ * Handles what to do with changed resources on activation.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void handleChangedResources()
+ {
+ if (!changedResources.isEmpty() && (!isDirty() || handleDirtyConflict()))
+ {
+ ResourceSet resourceSet = editingDomain.getResourceSet();
+ if (isDirty())
+ {
+ changedResources.addAll(resourceSet.getResources());
+ }
+ editingDomain.getCommandStack().flush();
+
+ updateProblemIndication = false;
+ for (Resource resource : changedResources)
+ {
+ if (resource.isLoaded())
+ {
+ resource.unload();
+ try
+ {
+ resource.load(resourceSet.getLoadOptions());
+ }
+ catch (IOException exception)
+ {
+ if (!resourceToDiagnosticMap.containsKey(resource))
+ {
+ resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception));
+ }
+ }
+ }
+ }
+
+ if (AdapterFactoryEditingDomain.isStale(editorSelection))
+ {
+ setSelection(StructuredSelection.EMPTY);
+ }
+
+ updateProblemIndication = true;
+ updateProblemIndication();
+ }
+ }
+
+ /**
+ * Updates the problems indication with the information described in the specified diagnostic.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void updateProblemIndication()
+ {
+ if (updateProblemIndication)
+ {
+ BasicDiagnostic diagnostic = new BasicDiagnostic(Diagnostic.OK, "org.eclipse.emf.cdo.evolution.editor", 0, null,
+ new Object[] { editingDomain.getResourceSet() });
+ for (Diagnostic childDiagnostic : resourceToDiagnosticMap.values())
+ {
+ if (childDiagnostic.getSeverity() != Diagnostic.OK)
+ {
+ diagnostic.add(childDiagnostic);
+ }
+ }
+
+ int lastEditorPage = getPageCount() - 1;
+ if (lastEditorPage >= 0 && getEditor(lastEditorPage) instanceof ProblemEditorPart)
+ {
+ ((ProblemEditorPart)getEditor(lastEditorPage)).setDiagnostic(diagnostic);
+ if (diagnostic.getSeverity() != Diagnostic.OK)
+ {
+ setActivePage(lastEditorPage);
+ }
+ }
+ else if (diagnostic.getSeverity() != Diagnostic.OK)
+ {
+ ProblemEditorPart problemEditorPart = new ProblemEditorPart();
+ problemEditorPart.setDiagnostic(diagnostic);
+ problemEditorPart.setMarkerHelper(markerHelper);
+ try
+ {
+ addPage(++lastEditorPage, problemEditorPart, getEditorInput());
+ setPageText(lastEditorPage, problemEditorPart.getPartName());
+ setActivePage(lastEditorPage);
+ showTabs();
+ }
+ catch (PartInitException exception)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ }
+ }
+
+ if (markerHelper.hasMarkers(editingDomain.getResourceSet()))
+ {
+ try
+ {
+ markerHelper.updateMarkers(diagnostic);
+ }
+ catch (CoreException exception)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ }
+ }
+ }
+ }
+
+ /**
+ * Shows a dialog that asks if conflicting changes should be discarded.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected boolean handleDirtyConflict()
+ {
+ return MessageDialog.openQuestion(getSite().getShell(), getString("_UI_FileConflict_label"), getString("_WARN_FileConflict"));
+ }
+
+ /**
+ * This creates a model editor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EvolutionEditor()
+ {
+ super();
+ initializeEditingDomain();
+ }
+
+ /**
+ * This sets up the editing domain for the model editor.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ protected void initializeEditingDomain()
+ {
+ // Create an adapter factory that yields item providers.
+ //
+ adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+
+ adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());
+ adapterFactory.addAdapterFactory(new EvolutionItemProviderAdapterFactory());
+ ecoreItemProviderAdapterFactory = new EcoreItemProviderAdapterFactory();
+ adapterFactory.addAdapterFactory(ecoreItemProviderAdapterFactory);
+ adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
+
+ // Create the command stack that will notify this editor as commands are executed.
+ //
+ BasicCommandStack commandStack = new BasicCommandStack()
+ {
+ @Override
+ public void execute(Command command)
+ {
+ // Cancel live validation before executing a command that will trigger a new round of validation.
+ //
+ if (!(command instanceof AbstractCommand.NonDirtying))
+ {
+ DiagnosticDecorator.Styled.cancel(editingDomain);
+ }
+ super.execute(command);
+ }
+ };
+
+ // Add a listener to set the most recent command's affected objects to be the selection of the viewer with focus.
+ //
+ commandStack.addCommandStackListener(new CommandStackListener()
+ {
+ public void commandStackChanged(final EventObject event)
+ {
+ ((EvolutionImpl)evolution).invalidateChange();
+
+ getContainer().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ firePropertyChange(IEditorPart.PROP_DIRTY);
+
+ // Try to select the affected objects.
+ //
+ Command mostRecentCommand = ((CommandStack)event.getSource()).getMostRecentCommand();
+ if (mostRecentCommand != null)
+ {
+ setSelectionToViewer(mostRecentCommand.getAffectedObjects());
+ }
+ for (Iterator<PropertySheetPage> i = propertySheetPages.iterator(); i.hasNext();)
+ {
+ PropertySheetPage propertySheetPage = i.next();
+ if (propertySheetPage.getControl().isDisposed())
+ {
+ i.remove();
+ }
+ else
+ {
+ propertySheetPage.refresh();
+ }
+ }
+ }
+ });
+ }
+ });
+
+ // Create the editing domain with a special command stack.
+ //
+ editingDomain = new AdapterFactoryEditingDomain(adapterFactory, commandStack, new HashMap<Resource, Boolean>())
+ {
+ @Override
+ public Command createCommand(Class<? extends Command> commandClass, CommandParameter commandParameter)
+ {
+ Collection<?> collection = commandParameter.getCollection();
+ if (collection != null && !collection.isEmpty())
+ {
+ Object value = collection.iterator().next();
+ if (isReadOnlyObject(value))
+ {
+ return UnexecutableCommand.INSTANCE;
+ }
+ }
+
+ return super.createCommand(commandClass, commandParameter);
+ }
+ };
+ }
+
+ protected boolean isReadOnlyObject(Object object)
+ {
+ if (object instanceof Release)
+ {
+ return true;
+ }
+
+ if (object instanceof Change)
+ {
+ return true;
+ }
+
+ if (readOnlyObjects.contains(object))
+ {
+ return true;
+ }
+
+ if (object instanceof EModelElement)
+ {
+ EModelElement modelElement = (EModelElement)object;
+
+ if (evolution.containsElement(modelElement))
+ {
+ return false;
+ }
+
+ for (Release release : evolution.getReleases())
+ {
+ if (release.containsElement(modelElement))
+ {
+ readOnlyObjects.add(modelElement);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * This is here for the listener to be able to call it.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected void firePropertyChange(int action)
+ {
+ super.firePropertyChange(action);
+ }
+
+ /**
+ * This sets the selection into whichever viewer is active.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setSelectionToViewer(Collection<?> collection)
+ {
+ final Collection<?> theSelection = collection;
+ // Make sure it's okay.
+ //
+ if (theSelection != null && !theSelection.isEmpty())
+ {
+ Runnable runnable = new Runnable()
+ {
+ public void run()
+ {
+ // Try to select the items in the current content viewer of the editor.
+ //
+ if (currentViewer != null)
+ {
+ currentViewer.setSelection(new StructuredSelection(theSelection.toArray()), true);
+ }
+ }
+ };
+ getSite().getShell().getDisplay().asyncExec(runnable);
+ }
+ }
+
+ /**
+ * This returns the editing domain as required by the {@link IEditingDomainProvider} interface.
+ * This is important for implementing the static methods of {@link AdapterFactoryEditingDomain}
+ * and for supporting {@link org.eclipse.emf.edit.ui.action.CommandAction}.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EditingDomain getEditingDomain()
+ {
+ return editingDomain;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public class ReverseAdapterFactoryContentProvider extends AdapterFactoryContentProvider
+ {
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public ReverseAdapterFactoryContentProvider(AdapterFactory adapterFactory)
+ {
+ super(adapterFactory);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object[] getElements(Object object)
+ {
+ Object parent = super.getParent(object);
+ return (parent == null ? Collections.EMPTY_SET : Collections.singleton(parent)).toArray();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object[] getChildren(Object object)
+ {
+ Object parent = super.getParent(object);
+ return (parent == null ? Collections.EMPTY_SET : Collections.singleton(parent)).toArray();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean hasChildren(Object object)
+ {
+ Object parent = super.getParent(object);
+ return parent != null;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public Object getParent(Object object)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * This makes sure that one content viewer, either for the current page or the outline view, if it has focus,
+ * is the current one.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setCurrentViewer(Viewer viewer)
+ {
+ // If it is changing...
+ //
+ if (currentViewer != viewer)
+ {
+ if (selectionChangedListener == null)
+ {
+ // Create the listener on demand.
+ //
+ selectionChangedListener = new ISelectionChangedListener()
+ {
+ // This just notifies those things that are affected by the section.
+ //
+ public void selectionChanged(SelectionChangedEvent selectionChangedEvent)
+ {
+ setSelection(selectionChangedEvent.getSelection());
+ }
+ };
+ }
+
+ // Stop listening to the old one.
+ //
+ if (currentViewer != null)
+ {
+ currentViewer.removeSelectionChangedListener(selectionChangedListener);
+ }
+
+ // Start listening to the new one.
+ //
+ if (viewer != null)
+ {
+ viewer.addSelectionChangedListener(selectionChangedListener);
+ }
+
+ // Remember it.
+ //
+ currentViewer = viewer;
+
+ // Set the editors selection based on the current viewer's selection.
+ //
+ setSelection(currentViewer == null ? StructuredSelection.EMPTY : currentViewer.getSelection());
+ }
+ }
+
+ /**
+ * This returns the viewer as required by the {@link IViewerProvider} interface.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Viewer getViewer()
+ {
+ return currentViewer;
+ }
+
+ /**
+ * This creates a context menu for the viewer and adds a listener as well registering the menu for extension.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ protected void createContextMenuFor(StructuredViewer viewer)
+ {
+ MenuManager contextMenu = new MenuManager("#PopUp");
+ contextMenu.add(new Separator("additions"));
+ contextMenu.setRemoveAllWhenShown(true);
+ contextMenu.addMenuListener(this);
+ Menu menu = contextMenu.createContextMenu(viewer.getControl());
+ viewer.getControl().setMenu(menu);
+ getSite().registerContextMenu(contextMenu, new UnwrappingSelectionProvider(viewer));
+
+ int dndOperations = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK;
+ Transfer[] transfers = new Transfer[] { LocalTransfer.getInstance(), LocalSelectionTransfer.getTransfer(), FileTransfer.getInstance() };
+ viewer.addDragSupport(dndOperations, transfers, new ViewerDragAdapter(viewer));
+ viewer.addDropSupport(dndOperations, transfers, new EditingDomainViewerDropAdapter(editingDomain, viewer)
+ {
+ @Override
+ public void dropAccept(DropTargetEvent event)
+ {
+ super.dropAccept(event);
+ }
+
+ @Override
+ public void drop(DropTargetEvent event)
+ {
+ super.drop(event);
+ }
+ });
+ }
+
+ /**
+ * This is the method called to load a resource into the editing domain's resource set based on the editor's input.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void createModelGen()
+ {
+ URI resourceURI = EditUIUtil.getURI(getEditorInput(), editingDomain.getResourceSet().getURIConverter());
+ Exception exception = null;
+ Resource resource = null;
+ try
+ {
+ // Load the resource through the editing domain.
+ //
+ resource = editingDomain.getResourceSet().getResource(resourceURI, true);
+ }
+ catch (Exception e)
+ {
+ exception = e;
+ resource = editingDomain.getResourceSet().getResource(resourceURI, false);
+ }
+
+ Diagnostic diagnostic = analyzeResourceProblems(resource, exception);
+ if (diagnostic.getSeverity() != Diagnostic.OK)
+ {
+ resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception));
+ }
+ editingDomain.getResourceSet().eAdapters().add(problemIndicationAdapter);
+ }
+
+ /**
+ * This is the method called to load a resource into the editing domain's resource set based on the editor's input.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ public void createModel()
+ {
+ createModelGen();
+
+ ResourceSet resourceSet = editingDomain.getResourceSet();
+ evolution = EvolutionImpl.get(resourceSet);
+ if (evolution != null)
+ {
+ if (hasGenerics(evolution))
+ {
+ ((EvolutionActionBarContributor)getActionBarContributor()).showGenerics(true);
+ }
+ }
+ }
+
+ private boolean hasGenerics(Evolution evolution)
+ {
+ if (hasGenerics(evolution.getRootPackages()))
+ {
+ return true;
+ }
+
+ for (Release release : evolution.getReleases())
+ {
+ if (hasGenerics(release.getRootPackages()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private boolean hasGenerics(EList<EPackage> rootPackages)
+ {
+ for (EPackage rootPackage : rootPackages)
+ {
+ for (Iterator<EObject> i = rootPackage.eAllContents(); i.hasNext();)
+ {
+ EObject eObject = i.next();
+ if (eObject instanceof ETypeParameter || eObject instanceof EGenericType && !((EGenericType)eObject).getETypeArguments().isEmpty())
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a diagnostic describing the errors and warnings listed in the resource
+ * and the specified exception (if any).
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Diagnostic analyzeResourceProblems(Resource resource, Exception exception)
+ {
+ boolean hasErrors = !resource.getErrors().isEmpty();
+ if (hasErrors || !resource.getWarnings().isEmpty())
+ {
+ BasicDiagnostic basicDiagnostic = new BasicDiagnostic(hasErrors ? Diagnostic.ERROR : Diagnostic.WARNING, "org.eclipse.emf.cdo.evolution.editor", 0,
+ getString("_UI_CreateModelError_message", resource.getURI()), new Object[] { exception == null ? (Object)resource : exception });
+ basicDiagnostic.merge(EcoreUtil.computeDiagnostic(resource, true));
+ return basicDiagnostic;
+ }
+ else if (exception != null)
+ {
+ return new BasicDiagnostic(Diagnostic.ERROR, "org.eclipse.emf.cdo.evolution.editor", 0, getString("_UI_CreateModelError_message", resource.getURI()),
+ new Object[] { exception });
+ }
+ else
+ {
+ return Diagnostic.OK_INSTANCE;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static class PhasedLiveValidator extends LiveValidator
+ {
+ public PhasedLiveValidator(EditingDomain editingDomain, IDialogSettings dialogSettings)
+ {
+ super(editingDomain, dialogSettings);
+ }
+
+ @Override
+ public void scheduleValidation()
+ {
+ if (validationJob == null && (dialogSettings == null || dialogSettings.getBoolean(LiveValidationAction.LIVE_VALIDATOR_DIALOG_SETTINGS_KEY)))
+ {
+ validationJob = new Job("Validation Job")
+ {
+ @Override
+ protected IStatus run(final IProgressMonitor monitor)
+ {
+ try
+ {
+ Diagnostician diagnostician = new Diagnostician()
+ {
+ @Override
+ public String getObjectLabel(EObject eObject)
+ {
+ String text = labelProvider != null && eObject.eIsProxy() ? ((InternalEObject)eObject).eProxyURI().toString()
+ : labelProvider.getText(eObject);
+ if (text == null || text.length() == 0)
+ {
+ text = "<i>null</i>";
+ }
+ else
+ {
+ text = DiagnosticDecorator.escapeContent(text);
+ }
+ Image image = labelProvider != null ? labelProvider.getImage(eObject) : null;
+ if (image != null)
+ {
+ URI imageURI = ImageURIRegistry.INSTANCE.getImageURI(image);
+ return DiagnosticDecorator.enquote("<img src='" + imageURI + "'/> " + text);
+ }
+ else
+ {
+ return text;
+ }
+ }
+
+ @Override
+ public boolean validate(EClass eClass, EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context)
+ {
+ if (monitor.isCanceled())
+ {
+ throw new RuntimeException();
+ }
+
+ monitor.worked(1);
+ return super.validate(eClass, eObject, diagnostics, context);
+ }
+
+ @Override
+ protected boolean doValidateContents(EObject eObject, DiagnosticChain diagnostics, Map<Object, Object> context)
+ {
+ Evolution evolution;
+ List<? extends EObject> eContents;
+
+ ValidationContext validationContext = ValidationContext.getFrom(context);
+ if (validationContext != null)
+ {
+ ValidationPhase phase = validationContext.getPhase();
+ evolution = validationContext.getEvolution();
+ eContents = phase.getContentsToValidate(this, evolution, eObject, context);
+ }
+ else
+ {
+ evolution = null;
+ eContents = eObject.eContents();
+ }
+
+ boolean result = true;
+ for (EObject child : eContents)
+ {
+ Resource resource = child.eResource();
+ if (resource == null && evolution != null)
+ {
+ // Change objects are not contained in a resource. Use the evolution's resource.
+ resource = evolution.eResource();
+ }
+
+ DiagnosticChain resourceDiagnostic = resource != null && validationContext != null
+ ? validationContext.getResourceDiagnostics().get(resource)
+ : null;
+
+ result &= validate(child, resourceDiagnostic, context);
+ }
+
+ return result;
+ }
+ };
+
+ final ResourceSet resourceSet = editingDomain.getResourceSet();
+
+ Map<Object, Object> context = diagnostician.createDefaultContext();
+ context.put(EObjectValidator.ROOT_OBJECT, new Object()); // Disable circular containment validation.
+
+ { ///////////////////////////////////////////////////////////////////////////////
+
+ Evolution evolution = EvolutionImpl.get(resourceSet);
+ ValidationContext validationContext = new ValidationContext(evolution);
+ validationContext.putInto(context);
+
+ int count = 0;
+ for (ValidationPhase phase : ValidationPhase.values())
+ {
+ validationContext.setPhase(phase);
+
+ // int xxx;
+ // System.out.println("Count " + phase);
+
+ count += countObjects(diagnostician, evolution, validationContext, context, monitor);
+ }
+
+ scheduledResources.clear();
+ monitor.beginTask("", count);
+
+ Map<Resource, BasicDiagnostic> resourceDiagnostics = validationContext.getResourceDiagnostics();
+ final BasicDiagnostic rootDiagnostic = new BasicDiagnostic(EObjectValidator.DIAGNOSTIC_SOURCE, 0,
+ EMFEditUIPlugin.INSTANCE.getString("_UI_DiagnosisOfNObjects_message", new String[] { "" + resourceDiagnostics.size() }),
+ new Object[] { resourceSet });
+
+ for (BasicDiagnostic resourceDiagnostic : resourceDiagnostics.values())
+ {
+ rootDiagnostic.add(resourceDiagnostic);
+ }
+
+ BasicDiagnostic modelSetResourceDiagnostic = resourceDiagnostics.get(evolution.eResource());
+
+ for (ValidationPhase phase : ValidationPhase.values())
+ {
+ validationContext.setPhase(phase);
+
+ // int xxx;
+ // System.out.println("Validate " + phase);
+
+ monitor
+ .setTaskName(EvolutionEditorPlugin.INSTANCE.getString("_UI_ValidatingPhase_message", new Object[] { Integer.toString(phase.ordinal()) }));
+
+ boolean valid = diagnostician.validate(evolution, modelSetResourceDiagnostic, context);
+ if (!valid)
+ {
+ break;
+ }
+ }
+
+ if (monitor.isCanceled())
+ {
+ throw new RuntimeException();
+ }
+
+ monitor.worked(1);
+
+ DiagnosticAdapter.update(resourceSet, rootDiagnostic);
+
+ } ///////////////////////////////////////////////////////////////////////////////
+
+ Display.getDefault().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ validationJob = null;
+ if (!monitor.isCanceled() && !scheduledResources.isEmpty())
+ {
+ PhasedLiveValidator.this.scheduleValidation();
+ }
+ }
+ });
+
+ return Status.OK_STATUS;
+ }
+ catch (RuntimeException exception)
+ {
+ int xxx;
+ exception.printStackTrace();
+
+ validationJob = null;
+ return Status.CANCEL_STATUS;
+ }
+ }
+
+ private int countObjects(Diagnostician diagnostician, EObject eObject, ValidationContext validationContext, Map<Object, Object> context,
+ IProgressMonitor monitor)
+ {
+ if (monitor.isCanceled())
+ {
+ throw new RuntimeException();
+ }
+
+ for (EReference eReference : eObject.eClass().getEAllReferences())
+ {
+ if (monitor.isCanceled())
+ {
+ throw new RuntimeException();
+ }
+
+ if (eReference == EvolutionPackage.Literals.MODEL_SET__CHANGE)
+ {
+ continue;
+ }
+
+ if (eReference.isContainment() || eReference.isContainer())
+ {
+ continue;
+ }
+
+ // Resolve all proxies.
+ if (eReference.isResolveProxies())
+ {
+ Object value = eObject.eGet(eReference, true);
+ if (eReference.isMany())
+ {
+ @SuppressWarnings("unchecked")
+ List<EObject> list = (List<EObject>)value;
+
+ for (@SuppressWarnings("unused")
+ EObject element : list)
+ {
+ if (monitor.isCanceled())
+ {
+ throw new RuntimeException();
+ }
+ }
+ }
+ }
+ }
+
+ Resource resource = eObject.eResource();
+ if (resource != null)
+ {
+ Map<Resource, BasicDiagnostic> resourceDiagnostics = validationContext.getResourceDiagnostics();
+ if (!resourceDiagnostics.containsKey(resource))
+ {
+ BasicDiagnostic diagnostic = new BasicDiagnostic(EObjectValidator.DIAGNOSTIC_SOURCE, 0,
+ EMFEditUIPlugin.INSTANCE.getString("_UI_DiagnosisOfNObjects_message", new String[] { "1" }), new Object[] { resource });
+ resourceDiagnostics.put(resource, diagnostic);
+ }
+ }
+
+ Evolution evolution = validationContext.getEvolution();
+ ValidationPhase phase = validationContext.getPhase();
+ int count = 1;
+
+ for (EObject child : phase.getContentsToValidate(diagnostician, evolution, eObject, context))
+ {
+ count += countObjects(diagnostician, child, validationContext, context, monitor);
+ }
+
+ return count;
+ }
+ };
+
+ validationJob.setPriority(Job.DECORATE);
+ validationJob.schedule(500);
+ }
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static class DiagnosticContentProvider implements IStructuredContentProvider
+ {
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+ {
+ }
+
+ public Object[] getElements(Object inputElement)
+ {
+ List<Diagnostic> result = new ArrayList<Diagnostic>();
+
+ @SuppressWarnings("unchecked")
+ List<Diagnostic> diagnostics = (List<Diagnostic>)inputElement;
+ for (Diagnostic diagnostic : diagnostics)
+ {
+ collectDiagnostics(diagnostic, result);
+ }
+
+ return result.toArray(new Diagnostic[result.size()]);
+ }
+
+ private void collectDiagnostics(Diagnostic diagnostic, List<Diagnostic> result)
+ {
+ if (isRelevant(diagnostic))
+ {
+ result.add(diagnostic);
+ }
+
+ for (Diagnostic child : diagnostic.getChildren())
+ {
+ collectDiagnostics(child, result);
+ }
+ }
+
+ private boolean isRelevant(Diagnostic diagnostic)
+ {
+ // if (diagnostic.getSeverity() != Diagnostic.ERROR)
+ // {
+ // return false;
+ // }
+
+ List<?> data = diagnostic.getData();
+ if (data.isEmpty())
+ {
+ return false;
+ }
+
+ if (data.get(0) instanceof Resource)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ public void dispose()
+ {
+ }
+ }
+
+ /**
+ * This is the method used by the framework to install your own controls.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ @Override
+ public void createPages()
+ {
+ // Creates the model from the editor input
+ //
+ createModel();
+
+ // Only creates the other pages if there is something that can be edited
+ //
+ if (!getEditingDomain().getResourceSet().getResources().isEmpty())
+ {
+ // Create a page for the selection tree view.
+ //
+
+ SashForm mainSash = new SashForm(getContainer(), SWT.VERTICAL);
+ mainSash.setLayoutData(new GridData(GridData.FILL_BOTH | GridData.GRAB_VERTICAL));
+
+ selectionViewer = createSelectionViewer(mainSash);
+ TableViewer problemViewer = createProblemViewer(mainSash);
+
+ mainSash.setWeights(new int[] { 70, 30 });
+
+ int pageIndex = addPage(mainSash);
+ setPageText(pageIndex, getString("_UI_SelectionPage_label"));
+
+ getSite().getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ if (!getContainer().isDisposed())
+ {
+ setActivePage(0);
+ }
+ }
+ });
+
+ this.problemViewer = problemViewer;
+ }
+
+ // Ensures that this editor will only display the page's tab
+ // area if there are more than one page
+ //
+ getContainer().addControlListener(new ControlAdapter()
+ {
+ boolean guard = false;
+
+ @Override
+ public void controlResized(ControlEvent event)
+ {
+ if (!guard)
+ {
+ guard = true;
+ hideTabs();
+ guard = false;
+ }
+ }
+ });
+
+ getSite().getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ updateProblemIndication();
+ }
+ });
+ }
+
+ private TreeViewer createSelectionViewer(Composite parent)
+ {
+ Tree tree = new Tree(parent, SWT.MULTI);
+ TreeViewer selectionViewer = new TreeViewer(tree);
+ setCurrentViewer(selectionViewer);
+
+ DiagnosticDecorator diagnosticDecorator = new DiagnosticDecorator.Styled(editingDomain, selectionViewer,
+ EvolutionEditorPlugin.getPlugin().getDialogSettings())
+ {
+ @Override
+ protected void redecorate()
+ {
+ super.redecorate();
+ handleDiagnostics(diagnostics);
+ }
+
+ @Override
+ protected LiveValidator getLiveValidator()
+ {
+ if (liveValidator == null && editingDomain != null)
+ {
+ Field field = ReflectUtil.getField(DiagnosticDecorator.class, "LIVE_VALIDATORS");
+
+ @SuppressWarnings("unchecked")
+ Map<EditingDomain, LiveValidator> LIVE_VALIDATORS = (Map<EditingDomain, LiveValidator>)ReflectUtil.getValue(field, null);
+
+ liveValidator = LIVE_VALIDATORS.get(editingDomain);
+ if (liveValidator == null)
+ {
+ liveValidator = new PhasedLiveValidator(editingDomain, dialogSettings);
+
+ LIVE_VALIDATORS.put(editingDomain, liveValidator);
+ }
+
+ liveValidator.register(this);
+ }
+
+ return liveValidator;
+ }
+ };
+
+ selectionViewer.setUseHashlookup(true);
+ selectionViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
+ selectionViewer.setLabelProvider(new DelegatingStyledCellLabelProvider.FontAndColorProvider(new DecoratingColumLabelProvider.StyledLabelProvider(
+ new AdapterFactoryLabelProvider.StyledLabelProvider(adapterFactory, selectionViewer), diagnosticDecorator)));
+ selectionViewer.setInput(editingDomain.getResourceSet().getResources().get(0));
+ selectionViewer.setSelection(new StructuredSelection(editingDomain.getResourceSet().getResources().get(0)), true);
+
+ new AdapterFactoryTreeEditor(selectionViewer.getTree(), adapterFactory);
+ new ColumnViewerInformationControlToolTipSupport(selectionViewer,
+ new DiagnosticDecorator.Styled.EditingDomainLocationListener(editingDomain, selectionViewer));
+
+ createContextMenuFor(selectionViewer);
+ return selectionViewer;
+ }
+
+ private TableViewer createProblemViewer(Composite parent)
+ {
+ final TableViewer problemViewer = new TableViewer(parent, SWT.MULTI);
+ problemViewer.setContentProvider(new DiagnosticContentProvider());
+ problemViewer.setInput(Collections.emptyList());
+
+ Table problemTable = problemViewer.getTable();
+ problemTable.setHeaderVisible(true);
+ problemTable.setLinesVisible(true);
+
+ createDiagnosticMessageColumn(problemViewer);
+ createDiagnosticElementColumn(problemViewer, adapterFactory);
+ createDiagnosticResourceColumn(problemViewer, adapterFactory);
+ // createDiagnosticIDColumn(problemViewer);
+
+ // {
+ // TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ // tableViewerColumn.setLabelProvider(new ColumnLabelProvider()
+ // {
+ // @Override
+ // public String getText(Object element)
+ // {
+ // return ((Diagnostic)element).getSource();
+ // }
+ // });
+ //
+ // TableColumn tableColumn = tableViewerColumn.getColumn();
+ // tableColumn.setResizable(true);
+ // tableColumn.setAlignment(SWT.LEFT);
+ // tableColumn.setWidth(200);
+ // tableColumn.setText("Source");
+ // }
+ //
+ // {
+ // TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ // tableViewerColumn.setLabelProvider(new ColumnLabelProvider()
+ // {
+ //
+ // @Override
+ // public String getText(Object element)
+ // {
+ // return Integer.toString(((Diagnostic)element).getCode());
+ // }
+ // });
+ //
+ // TableColumn tableColumn = tableViewerColumn.getColumn();
+ // tableColumn.setResizable(true);
+ // tableColumn.setAlignment(SWT.LEFT);
+ // tableColumn.setWidth(70);
+ // tableColumn.setText("Code");
+ // }
+ //
+ // {
+ // TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ // tableViewerColumn.setLabelProvider(new ColumnLabelProvider()
+ // {
+ // @Override
+ // public String getText(Object element)
+ // {
+ // StringBuilder builder = new StringBuilder();
+ //
+ // List<?> data = ((Diagnostic)element).getData();
+ // for (Object object : data)
+ // {
+ // if (builder.length() != 0)
+ // {
+ // builder.append(", ");
+ // }
+ //
+ // if (object instanceof Resource)
+ // {
+ // Resource resource = (Resource)object;
+ // builder.append("Resource[");
+ // builder.append(resource.getURI());
+ // builder.append("]");
+ // }
+ // else if (object instanceof ENamedElement)
+ // {
+ // ENamedElement namedElement = (ENamedElement)object;
+ // builder.append(namedElement.getName());
+ // }
+ // else if (object instanceof EObject)
+ // {
+ // EObject eObject = (EObject)object;
+ // builder.append(eObject.eClass().getName());
+ // }
+ // else
+ // {
+ // builder.append(String.valueOf(object));
+ // }
+ // }
+ //
+ // return builder.toString();
+ // }
+ // });
+ //
+ // TableColumn tableColumn = tableViewerColumn.getColumn();
+ // tableColumn.setResizable(true);
+ // tableColumn.setAlignment(SWT.LEFT);
+ // tableColumn.setWidth(400);
+ // tableColumn.setText("Data");
+ // }
+
+ problemTable.addKeyListener(new KeyAdapter()
+ {
+ @Override
+ public void keyPressed(KeyEvent e)
+ {
+ if (e.stateMask == SWT.CTRL && e.character == '1')
+ {
+ showQuickFixes();
+ }
+ }
+ });
+
+ problemViewer.addOpenListener(new IOpenListener()
+ {
+ public void open(OpenEvent event)
+ {
+ IStructuredSelection selection = (IStructuredSelection)event.getSelection();
+ Object element = selection.getFirstElement();
+ if (element instanceof Diagnostic)
+ {
+ List<?> data = ((Diagnostic)element).getData();
+ int size = data.size();
+ if (size != 0)
+ {
+ List<Object> list = new ArrayList<Object>(size);
+ for (Object object : data)
+ {
+ Object wrapper = editingDomain.getWrapper(object);
+ list.add(wrapper);
+ }
+
+ setSelectionToViewer(list);
+ }
+ }
+ }
+ });
+
+ return problemViewer;
+ }
+
+ public static TableViewerColumn createDiagnosticMessageColumn(final TableViewer problemViewer)
+ {
+ TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ tableViewerColumn.setLabelProvider(new ColumnLabelProvider()
+ {
+ @Override
+ public Image getImage(Object element)
+ {
+ switch (((Diagnostic)element).getSeverity())
+ {
+ case Diagnostic.INFO:
+ return SharedIcons.getImage(SharedIcons.OBJ_INFO);
+
+ default:
+ return SharedIcons.getImage(SharedIcons.OBJ_ERROR);
+ }
+ }
+
+ @Override
+ public String getText(Object element)
+ {
+ return ((Diagnostic)element).getMessage();
+ }
+ });
+
+ TableColumn tableColumn = tableViewerColumn.getColumn();
+ tableColumn.setResizable(true);
+ tableColumn.setAlignment(SWT.LEFT);
+ tableColumn.setWidth(400);
+ tableColumn.setText("Message");
+ return tableViewerColumn;
+ }
+
+ public static TableViewerColumn createDiagnosticResourceColumn(TableViewer problemViewer, AdapterFactory adapterFactory)
+ {
+ TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ tableViewerColumn.setLabelProvider(new ResourceColumnLabelProvider(adapterFactory));
+
+ TableColumn tableColumn = tableViewerColumn.getColumn();
+ tableColumn.setResizable(true);
+ tableColumn.setAlignment(SWT.LEFT);
+ tableColumn.setWidth(450);
+ tableColumn.setText("Resource");
+ return tableViewerColumn;
+ }
+
+ public static TableViewerColumn createDiagnosticElementColumn(TableViewer problemViewer, AdapterFactory adapterFactory)
+ {
+ TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ tableViewerColumn.setLabelProvider(new ElementColumnLabelProvider(adapterFactory));
+
+ TableColumn tableColumn = tableViewerColumn.getColumn();
+ tableColumn.setResizable(true);
+ tableColumn.setAlignment(SWT.LEFT);
+ tableColumn.setWidth(200);
+ tableColumn.setText("Element");
+ return tableViewerColumn;
+ }
+
+ public static TableViewerColumn createDiagnosticIDColumn(final TableViewer problemViewer)
+ {
+ TableViewerColumn tableViewerColumn = new TableViewerColumn(problemViewer, SWT.NONE);
+ tableViewerColumn.setLabelProvider(new ColumnLabelProvider()
+ {
+ @Override
+ public String getText(Object element)
+ {
+ DiagnosticID diagnosticID = DiagnosticID.get((Diagnostic)element);
+ if (diagnosticID != null)
+ {
+ return diagnosticID.getValue();
+ }
+
+ return "";
+ }
+ });
+
+ TableColumn tableColumn = tableViewerColumn.getColumn();
+ tableColumn.setResizable(true);
+ tableColumn.setAlignment(SWT.LEFT);
+ tableColumn.setWidth(800);
+ tableColumn.setText("ID");
+ return tableViewerColumn;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class ResourceColumnLabelProvider extends ColumnLabelProvider
+ {
+ protected final AdapterFactory adapterFactory;
+
+ public ResourceColumnLabelProvider(AdapterFactory adapterFactory)
+ {
+ this.adapterFactory = adapterFactory;
+ }
+
+ @Override
+ public Image getImage(Object element)
+ {
+ List<?> data = ((Diagnostic)element).getData();
+ if (!data.isEmpty())
+ {
+ Object object = data.get(0);
+ if (object instanceof EObject)
+ {
+ EObject eObject = (EObject)object;
+ Resource resource = eObject.eResource();
+ if (resource != null)
+ {
+ IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(resource, IItemLabelProvider.class);
+ if (labelProvider != null)
+ {
+ return ExtendedImageRegistry.getInstance().getImage(labelProvider.getImage(resource));
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getText(Object element)
+ {
+ List<?> data = ((Diagnostic)element).getData();
+ if (!data.isEmpty())
+ {
+ Object object = data.get(0);
+ if (object instanceof EObject)
+ {
+ EObject eObject = (EObject)object;
+ Resource resource = eObject.eResource();
+ if (resource != null)
+ {
+ IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(resource, IItemLabelProvider.class);
+ if (labelProvider != null)
+ {
+ return labelProvider.getText(resource);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class ElementColumnLabelProvider extends ColumnLabelProvider
+ {
+ protected final AdapterFactory adapterFactory;
+
+ public ElementColumnLabelProvider(AdapterFactory adapterFactory)
+ {
+ this.adapterFactory = adapterFactory;
+ }
+
+ @Override
+ public Image getImage(Object element)
+ {
+ List<?> data = ((Diagnostic)element).getData();
+ if (!data.isEmpty())
+ {
+ Object object = data.get(0);
+ if (object instanceof EObject)
+ {
+ IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(object, IItemLabelProvider.class);
+ if (labelProvider != null)
+ {
+ return ExtendedImageRegistry.getInstance().getImage(labelProvider.getImage(object));
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String getText(Object element)
+ {
+ List<?> data = ((Diagnostic)element).getData();
+ if (!data.isEmpty())
+ {
+ Object object = data.get(0);
+ if (object instanceof EModelElement)
+ {
+ EModelElement modelElement = (EModelElement)object;
+ return ElementHandler.getLabel(modelElement);
+ }
+
+ if (object instanceof EObject)
+ {
+
+ IItemLabelProvider labelProvider = (IItemLabelProvider)adapterFactory.adapt(object, IItemLabelProvider.class);
+ if (labelProvider != null)
+ {
+ return labelProvider.getText(object);
+ }
+ }
+ }
+
+ return null;
+ }
+ }
+
+ private Diagnostic[] getSelectedDiagnostics()
+ {
+ IStructuredSelection selection = problemViewer.getStructuredSelection();
+ if (selection.isEmpty())
+ {
+ return DiagnosticResolution.NO_DIAGNOSTICS;
+ }
+
+ List<Diagnostic> result = new ArrayList<Diagnostic>();
+ for (Iterator<?> it = selection.iterator(); it.hasNext();)
+ {
+ result.add((Diagnostic)it.next());
+ }
+
+ return result.toArray(new Diagnostic[result.size()]);
+ }
+
+ private void showQuickFixes()
+ {
+ final Map<DiagnosticResolution, Collection<Diagnostic>> resolutionsMap = new LinkedHashMap<DiagnosticResolution, Collection<Diagnostic>>();
+ final Diagnostic[] selectedDiagnostics = getSelectedDiagnostics();
+ if (selectedDiagnostics == null || selectedDiagnostics.length == 0)
+ {
+ return;
+ }
+
+ final Diagnostic firstSelectedDiagnostic = selectedDiagnostics[0];
+
+ IRunnableWithProgress runnable = new IRunnableWithProgress()
+ {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
+ {
+ monitor.beginTask("Finding fixes", 100);
+ monitor.worked(20);
+
+ DiagnosticResolution[] resolutions = DiagnosticResolution.getResolutions(firstSelectedDiagnostic, EvolutionEditor.this);
+ int progressCount = 80;
+ if (resolutions.length > 1)
+ {
+ progressCount = progressCount / resolutions.length;
+ }
+
+ for (DiagnosticResolution resolution : resolutions)
+ {
+ Diagnostic[] other = resolution.findOtherDiagnostics(allDiagnostics);
+ if (containsAllButFirst(other, selectedDiagnostics))
+ {
+ Collection<Diagnostic> diagnostics = new LinkedHashSet<Diagnostic>(other.length + 1);
+ diagnostics.add(firstSelectedDiagnostic);
+ diagnostics.addAll(Arrays.asList(other));
+ resolutionsMap.put(resolution, diagnostics);
+ }
+
+ monitor.worked(progressCount);
+ }
+
+ monitor.done();
+ }
+ };
+
+ IWorkbenchPartSite site = getSite();
+ IWorkbenchSiteProgressService service = Adapters.adapt(site, IWorkbenchSiteProgressService.class);
+
+ Shell shell = site.getShell();
+ IRunnableContext context = new ProgressMonitorDialog(shell);
+
+ try
+ {
+ if (service == null)
+ {
+ PlatformUI.getWorkbench().getProgressService().runInUI(context, runnable, null);
+ }
+ else
+ {
+ service.runInUI(context, runnable, null);
+ }
+ }
+ catch (InvocationTargetException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ catch (InterruptedException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+
+ String description = StringUtil.safe(firstSelectedDiagnostic.getMessage());
+ if (resolutionsMap.isEmpty())
+ {
+ if (selectedDiagnostics.length == 1)
+ {
+ MessageDialog.openInformation(shell, "Quick Fix", NLS.bind("No fixes available for:\n\n {0}.", new Object[] { description }));
+ }
+ else
+ {
+ MessageDialog.openInformation(shell, "Quick Fix", "The selected problems do not have a common applicable quick fix.");
+ }
+ }
+ else
+ {
+ String problemDescription = NLS.bind("Select the fix for ''{0}''.", description);
+
+ Wizard wizard = new QuickFixWizard(problemDescription, selectedDiagnostics, resolutionsMap, editingDomain);
+ wizard.setWindowTitle("Quick Fix");
+
+ WizardDialog dialog = new QuickFixWizardDialog(shell, wizard);
+ dialog.open();
+ }
+ }
+
+ /**
+ * Checks whether the given extent contains all but the first element from the given members array.
+ *
+ * @param extent the array which should contain the elements
+ * @param members the elements to check
+ * @return <code>true</code> if all but the first element are inside the extent
+ */
+ private static boolean containsAllButFirst(Object[] extent, Object[] members)
+ {
+ outer: for (int i = 1; i < members.length; i++)
+ {
+ for (int j = 0; j < extent.length; j++)
+ {
+ if (members[i] == extent[j])
+ {
+ continue outer;
+ }
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static final class QuickFixWizardDialog extends WizardDialog
+ {
+ public QuickFixWizardDialog(Shell parentShell, IWizard newWizard)
+ {
+ super(parentShell, newWizard);
+ setShellStyle(SWT.CLOSE | SWT.MAX | SWT.TITLE | SWT.BORDER | SWT.MODELESS | SWT.RESIZE | getDefaultOrientation());
+ }
+ }
+
+ protected void handleDiagnostics(List<Diagnostic> diagnostics)
+ {
+ List<Diagnostic> result = new ArrayList<Diagnostic>();
+ flattenDiagnostics(diagnostics, result);
+ allDiagnostics = result.toArray(new Diagnostic[result.size()]);
+
+ if (problemViewer != null && !problemViewer.getControl().isDisposed())
+ {
+ problemViewer.setInput(diagnostics);
+ }
+ }
+
+ private void flattenDiagnostics(List<Diagnostic> diagnostics, List<Diagnostic> result)
+ {
+ for (Diagnostic diagnostic : diagnostics)
+ {
+ result.add(diagnostic);
+ flattenDiagnostics(diagnostic.getChildren(), result);
+ }
+ }
+
+ /**
+ * If there is just one page in the multi-page editor part,
+ * this hides the single tab at the bottom.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void hideTabs()
+ {
+ if (getPageCount() <= 1)
+ {
+ setPageText(0, "");
+ if (getContainer() instanceof CTabFolder)
+ {
+ Point point = getContainer().getSize();
+ Rectangle clientArea = getContainer().getClientArea();
+ getContainer().setSize(point.x, 2 * point.y - clientArea.height - clientArea.y);
+ }
+ }
+ }
+
+ /**
+ * If there is more than one page in the multi-page editor part,
+ * this shows the tabs at the bottom.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void showTabs()
+ {
+ if (getPageCount() > 1)
+ {
+ setPageText(0, getString("_UI_SelectionPage_label"));
+ if (getContainer() instanceof CTabFolder)
+ {
+ Point point = getContainer().getSize();
+ Rectangle clientArea = getContainer().getClientArea();
+ getContainer().setSize(point.x, clientArea.height + clientArea.y);
+ }
+ }
+ }
+
+ /**
+ * This is used to track the active viewer.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected void pageChange(int pageIndex)
+ {
+ super.pageChange(pageIndex);
+
+ if (contentOutlinePage != null)
+ {
+ handleContentOutlineSelection(contentOutlinePage.getSelection());
+ }
+ }
+
+ /**
+ * This is how the framework determines which interfaces we implement.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public <T> T getAdapter(Class<T> key)
+ {
+ if (key.equals(IContentOutlinePage.class))
+ {
+ return showOutlineView() ? key.cast(getContentOutlinePage()) : null;
+ }
+ else if (key.equals(IPropertySheetPage.class))
+ {
+ return key.cast(getPropertySheetPage());
+ }
+ else if (key.equals(IGotoMarker.class))
+ {
+ return key.cast(this);
+ }
+ else if (key.equals(IFindReplaceTarget.class))
+ {
+ return FindAndReplaceTarget.getAdapter(key, this, EvolutionEditorPlugin.getPlugin());
+ }
+ else
+ {
+ return super.getAdapter(key);
+ }
+ }
+
+ /**
+ * This accesses a cached version of the content outliner.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public IContentOutlinePage getContentOutlinePage()
+ {
+ if (contentOutlinePage == null)
+ {
+ // The content outline is just a tree.
+ //
+ class MyContentOutlinePage extends ContentOutlinePage
+ {
+ @Override
+ public void createControl(Composite parent)
+ {
+ super.createControl(parent);
+ contentOutlineViewer = getTreeViewer();
+ contentOutlineViewer.addSelectionChangedListener(this);
+
+ // Set up the tree viewer.
+ //
+ contentOutlineViewer.setUseHashlookup(true);
+ contentOutlineViewer.setContentProvider(new AdapterFactoryContentProvider(adapterFactory));
+ contentOutlineViewer.setLabelProvider(new DelegatingStyledCellLabelProvider.FontAndColorProvider(
+ new DecoratingColumLabelProvider.StyledLabelProvider(new AdapterFactoryLabelProvider.StyledLabelProvider(adapterFactory, contentOutlineViewer),
+ new DiagnosticDecorator.Styled(editingDomain, contentOutlineViewer, EvolutionEditorPlugin.getPlugin().getDialogSettings()))));
+ contentOutlineViewer.setInput(editingDomain.getResourceSet());
+
+ new ColumnViewerInformationControlToolTipSupport(contentOutlineViewer,
+ new DiagnosticDecorator.Styled.EditingDomainLocationListener(editingDomain, contentOutlineViewer));
+
+ // Make sure our popups work.
+ //
+ createContextMenuFor(contentOutlineViewer);
+
+ if (!editingDomain.getResourceSet().getResources().isEmpty())
+ {
+ // Select the root object in the view.
+ //
+ contentOutlineViewer.setSelection(new StructuredSelection(editingDomain.getResourceSet().getResources().get(0)), true);
+ }
+ }
+
+ @Override
+ public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager, IStatusLineManager statusLineManager)
+ {
+ super.makeContributions(menuManager, toolBarManager, statusLineManager);
+ contentOutlineStatusLineManager = statusLineManager;
+ }
+
+ @Override
+ public void setActionBars(IActionBars actionBars)
+ {
+ super.setActionBars(actionBars);
+ getActionBarContributor().shareGlobalActions(this, actionBars);
+ }
+ }
+
+ contentOutlinePage = new MyContentOutlinePage();
+
+ // Listen to selection so that we can handle it is a special way.
+ //
+ contentOutlinePage.addSelectionChangedListener(new ISelectionChangedListener()
+ {
+ // This ensures that we handle selections correctly.
+ //
+ public void selectionChanged(SelectionChangedEvent event)
+ {
+ handleContentOutlineSelection(event.getSelection());
+ }
+ });
+ }
+
+ return contentOutlinePage;
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private static class DelegatingItemPropertyDescriptor implements IItemPropertyDescriptor
+ {
+ private final IItemPropertyDescriptor itemPropertyDescriptor;
+
+ private DelegatingItemPropertyDescriptor(IItemPropertyDescriptor itemPropertyDescriptor)
+ {
+ this.itemPropertyDescriptor = itemPropertyDescriptor;
+ }
+
+ public Object getPropertyValue(Object object)
+ {
+ return itemPropertyDescriptor.getPropertyValue(object);
+ }
+
+ public boolean isPropertySet(Object object)
+ {
+ return itemPropertyDescriptor.isPropertySet(object);
+ }
+
+ public boolean canSetProperty(Object object)
+ {
+ return itemPropertyDescriptor.canSetProperty(object);
+ }
+
+ public void resetPropertyValue(Object object)
+ {
+ itemPropertyDescriptor.resetPropertyValue(object);
+ }
+
+ public void setPropertyValue(Object object, Object value)
+ {
+ itemPropertyDescriptor.setPropertyValue(object, value);
+ }
+
+ public String getCategory(Object object)
+ {
+ return itemPropertyDescriptor.getCategory(object);
+ }
+
+ public String getDescription(Object object)
+ {
+ return itemPropertyDescriptor.getDescription(object);
+ }
+
+ public String getDisplayName(Object object)
+ {
+ return itemPropertyDescriptor.getDisplayName(object);
+ }
+
+ public String[] getFilterFlags(Object object)
+ {
+ return itemPropertyDescriptor.getFilterFlags(object);
+ }
+
+ public Object getHelpContextIds(Object object)
+ {
+ return itemPropertyDescriptor.getHelpContextIds(object);
+ }
+
+ public String getId(Object object)
+ {
+ return itemPropertyDescriptor.getId(object);
+ }
+
+ public IItemLabelProvider getLabelProvider(Object object)
+ {
+ return itemPropertyDescriptor.getLabelProvider(object);
+ }
+
+ public boolean isCompatibleWith(Object object, Object anotherObject, IItemPropertyDescriptor anotherPropertyDescriptor)
+ {
+ return itemPropertyDescriptor.isCompatibleWith(object, anotherObject, anotherPropertyDescriptor);
+ }
+
+ public Object getFeature(Object object)
+ {
+ return itemPropertyDescriptor.getFeature(object);
+ }
+
+ public boolean isMany(Object object)
+ {
+ return itemPropertyDescriptor.isMany(object);
+ }
+
+ public Collection<?> getChoiceOfValues(Object object)
+ {
+ return itemPropertyDescriptor.getChoiceOfValues(object);
+ }
+
+ public boolean isMultiLine(Object object)
+ {
+ return itemPropertyDescriptor.isMultiLine(object);
+ }
+
+ public boolean isSortChoices(Object object)
+ {
+ return itemPropertyDescriptor.isSortChoices(object);
+ }
+ }
+
+ /**
+ * This accesses a cached version of the property sheet.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated NOT
+ */
+ public IPropertySheetPage getPropertySheetPage()
+ {
+ PropertySheetPage propertySheetPage = new ExtendedPropertySheetPage(editingDomain, ExtendedPropertySheetPage.Decoration.LIVE,
+ EvolutionEditorPlugin.getPlugin().getDialogSettings(), 0, true)
+ {
+ {
+ setSorter(new PropertySheetSorter()
+ {
+ @Override
+ public void sort(IPropertySheetEntry[] entries)
+ {
+ // Intentionally left empty
+ }
+ });
+ }
+
+ @Override
+ public void setSelectionToViewer(List<?> selection)
+ {
+ EvolutionEditor.this.setSelectionToViewer(selection);
+ EvolutionEditor.this.setFocus();
+ }
+
+ @Override
+ public void setActionBars(IActionBars actionBars)
+ {
+ super.setActionBars(actionBars);
+ getActionBarContributor().shareGlobalActions(this, actionBars);
+ }
+ };
+
+ propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(adapterFactory)
+ {
+ @Override
+ protected IPropertySource createPropertySource(Object object, IItemPropertySource itemPropertySource)
+ {
+ if (isReadOnlyObject(object))
+ {
+ /**
+ * Create no cell editor for read-only objects.
+ */
+ return new PropertySource(object, itemPropertySource)
+ {
+ @Override
+ protected IPropertyDescriptor createPropertyDescriptor(final IItemPropertyDescriptor itemPropertyDescriptor)
+ {
+ return super.createPropertyDescriptor(new DelegatingItemPropertyDescriptor(itemPropertyDescriptor)
+ {
+ @Override
+ public boolean canSetProperty(Object object)
+ {
+ return false;
+ }
+ });
+ }
+ };
+ }
+ else if (object instanceof EModelElement && evolution.containsElement((EModelElement)object))
+ {
+ /**
+ * Eliminate released elements from selection choices.
+ */
+ return new PropertySource(object, itemPropertySource)
+ {
+ @Override
+ protected IPropertyDescriptor createPropertyDescriptor(final IItemPropertyDescriptor itemPropertyDescriptor)
+ {
+ return super.createPropertyDescriptor(new DelegatingItemPropertyDescriptor(itemPropertyDescriptor)
+ {
+ @Override
+ public Collection<?> getChoiceOfValues(Object object)
+ {
+ Collection<?> values = super.getChoiceOfValues(object);
+ if (values != null)
+ {
+ for (Iterator<?> it = values.iterator(); it.hasNext();)
+ {
+ Object value = it.next();
+ if (value instanceof EModelElement)
+ {
+ EModelElement modelElement = (EModelElement)value;
+ if (!evolution.containsElement(modelElement))
+ {
+ it.remove();
+ }
+ }
+ }
+ }
+
+ return values;
+ }
+ });
+ }
+ };
+ }
+
+ return super.createPropertySource(object, itemPropertySource);
+ }
+ });
+
+ propertySheetPages.add(propertySheetPage);
+
+ return propertySheetPage;
+ }
+
+ /**
+ * This deals with how we want selection in the outliner to affect the other views.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void handleContentOutlineSelection(ISelection selection)
+ {
+ if (selectionViewer != null && !selection.isEmpty() && selection instanceof IStructuredSelection)
+ {
+ Iterator<?> selectedElements = ((IStructuredSelection)selection).iterator();
+ if (selectedElements.hasNext())
+ {
+ // Get the first selected element.
+ //
+ Object selectedElement = selectedElements.next();
+
+ ArrayList<Object> selectionList = new ArrayList<Object>();
+ selectionList.add(selectedElement);
+ while (selectedElements.hasNext())
+ {
+ selectionList.add(selectedElements.next());
+ }
+
+ // Set the selection to the widget.
+ //
+ selectionViewer.setSelection(new StructuredSelection(selectionList));
+ }
+ }
+ }
+
+ /**
+ * This is for implementing {@link IEditorPart} and simply tests the command stack.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean isDirty()
+ {
+ return ((BasicCommandStack)editingDomain.getCommandStack()).isSaveNeeded();
+ }
+
+ /**
+ * This is for implementing {@link IEditorPart} and simply saves the model file.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void doSave(IProgressMonitor progressMonitor)
+ {
+ // Save only resources that have actually changed.
+ //
+ final Map<Object, Object> saveOptions = new HashMap<Object, Object>();
+ saveOptions.put(Resource.OPTION_SAVE_ONLY_IF_CHANGED, Resource.OPTION_SAVE_ONLY_IF_CHANGED_MEMORY_BUFFER);
+ saveOptions.put(Resource.OPTION_LINE_DELIMITER, Resource.OPTION_LINE_DELIMITER_UNSPECIFIED);
+
+ // Do the work within an operation because this is a long running activity that modifies the workbench.
+ //
+ WorkspaceModifyOperation operation = new WorkspaceModifyOperation()
+ {
+ // This is the method that gets invoked when the operation runs.
+ //
+ @Override
+ public void execute(IProgressMonitor monitor)
+ {
+ // Save the resources to the file system.
+ //
+ boolean first = true;
+ List<Resource> resources = editingDomain.getResourceSet().getResources();
+ for (int i = 0; i < resources.size(); ++i)
+ {
+ Resource resource = resources.get(i);
+ if ((first || !resource.getContents().isEmpty() || isPersisted(resource)) && !editingDomain.isReadOnly(resource))
+ {
+ try
+ {
+ long timeStamp = resource.getTimeStamp();
+ resource.save(saveOptions);
+ if (resource.getTimeStamp() != timeStamp)
+ {
+ savedResources.add(resource);
+ }
+ }
+ catch (Exception exception)
+ {
+ resourceToDiagnosticMap.put(resource, analyzeResourceProblems(resource, exception));
+ }
+ first = false;
+ }
+ }
+ }
+ };
+
+ updateProblemIndication = false;
+ try
+ {
+ // This runs the options, and shows progress.
+ //
+ new ProgressMonitorDialog(getSite().getShell()).run(true, false, operation);
+
+ // Refresh the necessary state.
+ //
+ ((BasicCommandStack)editingDomain.getCommandStack()).saveIsDone();
+ firePropertyChange(IEditorPart.PROP_DIRTY);
+ }
+ catch (Exception exception)
+ {
+ // Something went wrong that shouldn't.
+ //
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ }
+ updateProblemIndication = true;
+ updateProblemIndication();
+ }
+
+ /**
+ * This returns whether something has been persisted to the URI of the specified resource.
+ * The implementation uses the URI converter from the editor's resource set to try to open an input stream.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected boolean isPersisted(Resource resource)
+ {
+ boolean result = false;
+ try
+ {
+ InputStream stream = editingDomain.getResourceSet().getURIConverter().createInputStream(resource.getURI());
+ if (stream != null)
+ {
+ result = true;
+ stream.close();
+ }
+ }
+ catch (IOException e)
+ {
+ // Ignore
+ }
+ return result;
+ }
+
+ /**
+ * This always returns true because it is not currently supported.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean isSaveAsAllowed()
+ {
+ return true;
+ }
+
+ /**
+ * This also changes the editor's input.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void doSaveAs()
+ {
+ SaveAsDialog saveAsDialog = new SaveAsDialog(getSite().getShell());
+ saveAsDialog.open();
+ IPath path = saveAsDialog.getResult();
+ if (path != null)
+ {
+ IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
+ if (file != null)
+ {
+ doSaveAs(URI.createPlatformResourceURI(file.getFullPath().toString(), true), new FileEditorInput(file));
+ }
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected void doSaveAs(URI uri, IEditorInput editorInput)
+ {
+ editingDomain.getResourceSet().getResources().get(0).setURI(uri);
+ setInputWithNotify(editorInput);
+ setPartName(editorInput.getName());
+ IProgressMonitor progressMonitor = getActionBars().getStatusLineManager() != null ? getActionBars().getStatusLineManager().getProgressMonitor()
+ : new NullProgressMonitor();
+ doSave(progressMonitor);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void gotoMarker(IMarker marker)
+ {
+ List<?> targetObjects = markerHelper.getTargetObjects(editingDomain, marker);
+ if (!targetObjects.isEmpty())
+ {
+ setSelectionToViewer(targetObjects);
+ }
+ }
+
+ /**
+ * This is called during startup.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void init(IEditorSite site, IEditorInput editorInput)
+ {
+ setSite(site);
+ setInputWithNotify(editorInput);
+ setPartName(editorInput.getName());
+ site.setSelectionProvider(this);
+ site.getPage().addPartListener(partListener);
+ ResourcesPlugin.getWorkspace().addResourceChangeListener(resourceChangeListener, IResourceChangeEvent.POST_CHANGE);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void setFocus()
+ {
+ getControl(getActivePage()).setFocus();
+ }
+
+ /**
+ * This implements {@link org.eclipse.jface.viewers.ISelectionProvider}.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void addSelectionChangedListener(ISelectionChangedListener listener)
+ {
+ selectionChangedListeners.add(listener);
+ }
+
+ /**
+ * This implements {@link org.eclipse.jface.viewers.ISelectionProvider}.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void removeSelectionChangedListener(ISelectionChangedListener listener)
+ {
+ selectionChangedListeners.remove(listener);
+ }
+
+ /**
+ * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to return this editor's overall selection.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public ISelection getSelection()
+ {
+ return editorSelection;
+ }
+
+ /**
+ * This implements {@link org.eclipse.jface.viewers.ISelectionProvider} to set this editor's overall selection.
+ * Calling this result will notify the listeners.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setSelection(ISelection selection)
+ {
+ editorSelection = selection;
+
+ for (ISelectionChangedListener listener : selectionChangedListeners)
+ {
+ listener.selectionChanged(new SelectionChangedEvent(this, selection));
+ }
+ setStatusLineManager(selection);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void setStatusLineManager(ISelection selection)
+ {
+ IStatusLineManager statusLineManager = currentViewer != null && currentViewer == contentOutlineViewer ? contentOutlineStatusLineManager
+ : getActionBars().getStatusLineManager();
+
+ if (statusLineManager != null)
+ {
+ if (selection instanceof IStructuredSelection)
+ {
+ Collection<?> collection = ((IStructuredSelection)selection).toList();
+ switch (collection.size())
+ {
+ case 0:
+ {
+ statusLineManager.setMessage(getString("_UI_NoObjectSelected"));
+ break;
+ }
+ case 1:
+ {
+ String text = new AdapterFactoryItemDelegator(adapterFactory).getText(collection.iterator().next());
+ statusLineManager.setMessage(getString("_UI_SingleObjectSelected", text));
+ break;
+ }
+ default:
+ {
+ statusLineManager.setMessage(getString("_UI_MultiObjectSelected", Integer.toString(collection.size())));
+ break;
+ }
+ }
+ }
+ else
+ {
+ statusLineManager.setMessage("");
+ }
+ }
+ }
+
+ /**
+ * This looks up a string in the plugin's plugin.properties file.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private static String getString(String key)
+ {
+ return EvolutionEditorPlugin.INSTANCE.getString(key);
+ }
+
+ /**
+ * This looks up a string in plugin.properties, making a substitution.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private static String getString(String key, Object s1)
+ {
+ return EvolutionEditorPlugin.INSTANCE.getString(key, new Object[] { s1 });
+ }
+
+ /**
+ * This implements {@link org.eclipse.jface.action.IMenuListener} to help fill the context menus with contributions from the Edit menu.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void menuAboutToShow(IMenuManager menuManager)
+ {
+ ((IMenuListener)getEditorSite().getActionBarContributor()).menuAboutToShow(menuManager);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EditingDomainActionBarContributor getActionBarContributor()
+ {
+ return (EditingDomainActionBarContributor)getEditorSite().getActionBarContributor();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public IActionBars getActionBars()
+ {
+ return getActionBarContributor().getActionBars();
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public AdapterFactory getAdapterFactory()
+ {
+ return adapterFactory;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void dispose()
+ {
+ updateProblemIndication = false;
+
+ ResourcesPlugin.getWorkspace().removeResourceChangeListener(resourceChangeListener);
+
+ getSite().getPage().removePartListener(partListener);
+
+ adapterFactory.dispose();
+
+ if (getActionBarContributor().getActiveEditor() == this)
+ {
+ getActionBarContributor().setActiveEditor(null);
+ }
+
+ for (PropertySheetPage propertySheetPage : propertySheetPages)
+ {
+ propertySheetPage.dispose();
+ }
+
+ if (contentOutlinePage != null)
+ {
+ contentOutlinePage.dispose();
+ }
+
+ super.dispose();
+ }
+
+ /**
+ * Returns whether the outline view should be presented to the user.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected boolean showOutlineView()
+ {
+ return false;
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditorPlugin.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditorPlugin.java
new file mode 100644
index 0000000000..8aa42e9f46
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionEditorPlugin.java
@@ -0,0 +1,96 @@
+/**
+ */
+package org.eclipse.emf.cdo.evolution.presentation;
+
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.emf.common.ui.EclipseUIPlugin;
+import org.eclipse.emf.common.util.ResourceLocator;
+import org.eclipse.emf.ecore.provider.EcoreEditPlugin;
+
+/**
+ * This is the central singleton for the Evolution editor plugin.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public final class EvolutionEditorPlugin extends EMFPlugin
+{
+ public static final String PLUGIN_ID = "org.eclipse.emf.cdo.evolution.editor";
+
+ /**
+ * Keep track of the singleton.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final EvolutionEditorPlugin INSTANCE = new EvolutionEditorPlugin();
+
+ /**
+ * Keep track of the singleton.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ private static Implementation plugin;
+
+ /**
+ * Create the instance.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EvolutionEditorPlugin()
+ {
+ super(new ResourceLocator[] { EcoreEditPlugin.INSTANCE, });
+ }
+
+ /**
+ * Returns the singleton instance of the Eclipse plugin.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the singleton instance.
+ * @generated
+ */
+ @Override
+ public ResourceLocator getPluginResourceLocator()
+ {
+ return plugin;
+ }
+
+ /**
+ * Returns the singleton instance of the Eclipse plugin.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @return the singleton instance.
+ * @generated
+ */
+ public static Implementation getPlugin()
+ {
+ return plugin;
+ }
+
+ /**
+ * The actual implementation of the Eclipse <b>Plugin</b>.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static class Implementation extends EclipseUIPlugin
+ {
+ /**
+ * Creates an instance.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public Implementation()
+ {
+ super();
+
+ // Remember the static instance.
+ //
+ plugin = this;
+ }
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionModelWizard.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionModelWizard.java
new file mode 100644
index 0000000000..1e7b23d1f7
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/EvolutionModelWizard.java
@@ -0,0 +1,657 @@
+/**
+ */
+package org.eclipse.emf.cdo.evolution.presentation;
+
+import org.eclipse.emf.cdo.evolution.EvolutionFactory;
+import org.eclipse.emf.cdo.evolution.EvolutionPackage;
+import org.eclipse.emf.cdo.evolution.provider.EvolutionEditPlugin;
+
+import org.eclipse.emf.common.CommonPlugin;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.emf.ecore.xmi.XMLResource;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+
+import org.eclipse.core.resources.IContainer;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.ui.INewWizard;
+import org.eclipse.ui.IWorkbench;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.actions.WorkspaceModifyOperation;
+import org.eclipse.ui.dialogs.WizardNewFileCreationPage;
+import org.eclipse.ui.part.FileEditorInput;
+import org.eclipse.ui.part.ISetSelectionTarget;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.StringTokenizer;
+
+/**
+ * This is a simple wizard for creating a new model file.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+public class EvolutionModelWizard extends Wizard implements INewWizard
+{
+ /**
+ * The supported extensions for created files.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final List<String> FILE_EXTENSIONS = Collections
+ .unmodifiableList(Arrays.asList(EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionEditorFilenameExtensions").split("\\s*,\\s*")));
+
+ /**
+ * A formatted list of supported file extensions, suitable for display.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public static final String FORMATTED_FILE_EXTENSIONS = EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionEditorFilenameExtensions")
+ .replaceAll("\\s*,\\s*", ", ");
+
+ /**
+ * This caches an instance of the model package.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EvolutionPackage evolutionPackage = EvolutionPackage.eINSTANCE;
+
+ /**
+ * This caches an instance of the model factory.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EvolutionFactory evolutionFactory = evolutionPackage.getEvolutionFactory();
+
+ /**
+ * This is the file creation page.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EvolutionModelWizardNewFileCreationPage newFileCreationPage;
+
+ /**
+ * This is the initial object creation page.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EvolutionModelWizardInitialObjectCreationPage initialObjectCreationPage;
+
+ /**
+ * Remember the selection during initialization for populating the default container.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IStructuredSelection selection;
+
+ /**
+ * Remember the workbench during initialization.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected IWorkbench workbench;
+
+ /**
+ * Caches the names of the types that can be created as the root object.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected List<String> initialObjectNames;
+
+ /**
+ * This just records the information.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void init(IWorkbench workbench, IStructuredSelection selection)
+ {
+ this.workbench = workbench;
+ this.selection = selection;
+ setWindowTitle(EvolutionEditorPlugin.INSTANCE.getString("_UI_Wizard_label"));
+ setDefaultPageImageDescriptor(ExtendedImageRegistry.INSTANCE.getImageDescriptor(EvolutionEditorPlugin.INSTANCE.getImage("full/wizban/NewEvolution")));
+ }
+
+ /**
+ * Returns the names of the types that can be created as the root object.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<String> getInitialObjectNames()
+ {
+ if (initialObjectNames == null)
+ {
+ initialObjectNames = new ArrayList<String>();
+ for (EClassifier eClassifier : evolutionPackage.getEClassifiers())
+ {
+ if (eClassifier instanceof EClass)
+ {
+ EClass eClass = (EClass)eClassifier;
+ if (!eClass.isAbstract())
+ {
+ initialObjectNames.add(eClass.getName());
+ }
+ }
+ }
+ Collections.sort(initialObjectNames, CommonPlugin.INSTANCE.getComparator());
+ }
+ return initialObjectNames;
+ }
+
+ /**
+ * Create a new model.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected EObject createInitialModel()
+ {
+ EClass eClass = (EClass)evolutionPackage.getEClassifier(initialObjectCreationPage.getInitialObjectName());
+ EObject rootObject = evolutionFactory.create(eClass);
+ return rootObject;
+ }
+
+ /**
+ * Do the work after everything is specified.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public boolean performFinish()
+ {
+ try
+ {
+ // Remember the file.
+ //
+ final IFile modelFile = getModelFile();
+
+ // Do the work within an operation.
+ //
+ WorkspaceModifyOperation operation = new WorkspaceModifyOperation()
+ {
+ @Override
+ protected void execute(IProgressMonitor progressMonitor)
+ {
+ try
+ {
+ // Create a resource set
+ //
+ ResourceSet resourceSet = new ResourceSetImpl();
+
+ // Get the URI of the model file.
+ //
+ URI fileURI = URI.createPlatformResourceURI(modelFile.getFullPath().toString(), true);
+
+ // Create a resource for this file.
+ //
+ Resource resource = resourceSet.createResource(fileURI);
+
+ // Add the initial model object to the contents.
+ //
+ EObject rootObject = createInitialModel();
+ if (rootObject != null)
+ {
+ resource.getContents().add(rootObject);
+ }
+
+ // Save the contents of the resource to the file system.
+ //
+ Map<Object, Object> options = new HashMap<Object, Object>();
+ options.put(XMLResource.OPTION_ENCODING, initialObjectCreationPage.getEncoding());
+ resource.save(options);
+ }
+ catch (Exception exception)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ }
+ finally
+ {
+ progressMonitor.done();
+ }
+ }
+ };
+
+ getContainer().run(false, false, operation);
+
+ // Select the new file resource in the current view.
+ //
+ IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
+ IWorkbenchPage page = workbenchWindow.getActivePage();
+ final IWorkbenchPart activePart = page.getActivePart();
+ if (activePart instanceof ISetSelectionTarget)
+ {
+ final ISelection targetSelection = new StructuredSelection(modelFile);
+ getShell().getDisplay().asyncExec(new Runnable()
+ {
+ public void run()
+ {
+ ((ISetSelectionTarget)activePart).selectReveal(targetSelection);
+ }
+ });
+ }
+
+ // Open an editor on the new file.
+ //
+ try
+ {
+ page.openEditor(new FileEditorInput(modelFile), workbench.getEditorRegistry().getDefaultEditor(modelFile.getFullPath().toString()).getId());
+ }
+ catch (PartInitException exception)
+ {
+ MessageDialog.openError(workbenchWindow.getShell(), EvolutionEditorPlugin.INSTANCE.getString("_UI_OpenEditorError_label"), exception.getMessage());
+ return false;
+ }
+
+ return true;
+ }
+ catch (Exception exception)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(exception);
+ return false;
+ }
+ }
+
+ /**
+ * This is the one page of the wizard.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public class EvolutionModelWizardNewFileCreationPage extends WizardNewFileCreationPage
+ {
+ /**
+ * Pass in the selection.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EvolutionModelWizardNewFileCreationPage(String pageId, IStructuredSelection selection)
+ {
+ super(pageId, selection);
+ }
+
+ /**
+ * The framework calls this to see if the file is correct.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ protected boolean validatePage()
+ {
+ if (super.validatePage())
+ {
+ String extension = new Path(getFileName()).getFileExtension();
+ if (extension == null || !FILE_EXTENSIONS.contains(extension))
+ {
+ String key = FILE_EXTENSIONS.size() > 1 ? "_WARN_FilenameExtensions" : "_WARN_FilenameExtension";
+ setErrorMessage(EvolutionEditorPlugin.INSTANCE.getString(key, new Object[] { FORMATTED_FILE_EXTENSIONS }));
+ return false;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public IFile getModelFile()
+ {
+ return ResourcesPlugin.getWorkspace().getRoot().getFile(getContainerFullPath().append(getFileName()));
+ }
+ }
+
+ /**
+ * This is the page where the type of object to create is selected.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public class EvolutionModelWizardInitialObjectCreationPage extends WizardPage
+ {
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Combo initialObjectField;
+
+ /**
+ * @generated
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ */
+ protected List<String> encodings;
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Combo encodingField;
+
+ /**
+ * Pass in the selection.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public EvolutionModelWizardInitialObjectCreationPage(String pageId)
+ {
+ super(pageId);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public void createControl(Composite parent)
+ {
+ Composite composite = new Composite(parent, SWT.NONE);
+ {
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 1;
+ layout.verticalSpacing = 12;
+ composite.setLayout(layout);
+
+ GridData data = new GridData();
+ data.verticalAlignment = GridData.FILL;
+ data.grabExcessVerticalSpace = true;
+ data.horizontalAlignment = GridData.FILL;
+ composite.setLayoutData(data);
+ }
+
+ Label containerLabel = new Label(composite, SWT.LEFT);
+ {
+ containerLabel.setText(EvolutionEditorPlugin.INSTANCE.getString("_UI_ModelObject"));
+
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ containerLabel.setLayoutData(data);
+ }
+
+ initialObjectField = new Combo(composite, SWT.BORDER);
+ {
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ initialObjectField.setLayoutData(data);
+ }
+
+ for (String objectName : getInitialObjectNames())
+ {
+ initialObjectField.add(getLabel(objectName));
+ }
+
+ if (initialObjectField.getItemCount() == 1)
+ {
+ initialObjectField.select(0);
+ }
+ initialObjectField.addModifyListener(validator);
+
+ Label encodingLabel = new Label(composite, SWT.LEFT);
+ {
+ encodingLabel.setText(EvolutionEditorPlugin.INSTANCE.getString("_UI_XMLEncoding"));
+
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ encodingLabel.setLayoutData(data);
+ }
+ encodingField = new Combo(composite, SWT.BORDER);
+ {
+ GridData data = new GridData();
+ data.horizontalAlignment = GridData.FILL;
+ data.grabExcessHorizontalSpace = true;
+ encodingField.setLayoutData(data);
+ }
+
+ for (String encoding : getEncodings())
+ {
+ encodingField.add(encoding);
+ }
+
+ encodingField.select(0);
+ encodingField.addModifyListener(validator);
+
+ setPageComplete(validatePage());
+ setControl(composite);
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected ModifyListener validator = new ModifyListener()
+ {
+ public void modifyText(ModifyEvent e)
+ {
+ setPageComplete(validatePage());
+ }
+ };
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected boolean validatePage()
+ {
+ return getInitialObjectName() != null && getEncodings().contains(encodingField.getText());
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void setVisible(boolean visible)
+ {
+ super.setVisible(visible);
+ if (visible)
+ {
+ if (initialObjectField.getItemCount() == 1)
+ {
+ initialObjectField.clearSelection();
+ encodingField.setFocus();
+ }
+ else
+ {
+ encodingField.clearSelection();
+ initialObjectField.setFocus();
+ }
+ }
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getInitialObjectName()
+ {
+ String label = initialObjectField.getText();
+
+ for (String name : getInitialObjectNames())
+ {
+ if (getLabel(name).equals(label))
+ {
+ return name;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public String getEncoding()
+ {
+ return encodingField.getText();
+ }
+
+ /**
+ * Returns the label for the specified type name.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected String getLabel(String typeName)
+ {
+ try
+ {
+ return EvolutionEditPlugin.INSTANCE.getString("_UI_" + typeName + "_type");
+ }
+ catch (MissingResourceException mre)
+ {
+ EvolutionEditorPlugin.INSTANCE.log(mre);
+ }
+ return typeName;
+ }
+
+ /**
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ protected Collection<String> getEncodings()
+ {
+ if (encodings == null)
+ {
+ encodings = new ArrayList<String>();
+ for (StringTokenizer stringTokenizer = new StringTokenizer(EvolutionEditorPlugin.INSTANCE.getString("_UI_XMLEncodingChoices")); stringTokenizer
+ .hasMoreTokens();)
+ {
+ encodings.add(stringTokenizer.nextToken());
+ }
+ }
+ return encodings;
+ }
+ }
+
+ /**
+ * The framework calls this to create the contents of the wizard.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ @Override
+ public void addPages()
+ {
+ // Create a page, set the title, and the initial model file name.
+ //
+ newFileCreationPage = new EvolutionModelWizardNewFileCreationPage("Whatever", selection);
+ newFileCreationPage.setTitle(EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionModelWizard_label"));
+ newFileCreationPage.setDescription(EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionModelWizard_description"));
+ newFileCreationPage.setFileName(EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionEditorFilenameDefaultBase") + "." + FILE_EXTENSIONS.get(0));
+ addPage(newFileCreationPage);
+
+ // Try and get the resource selection to determine a current directory for the file dialog.
+ //
+ if (selection != null && !selection.isEmpty())
+ {
+ // Get the resource...
+ //
+ Object selectedElement = selection.iterator().next();
+ if (selectedElement instanceof IResource)
+ {
+ // Get the resource parent, if its a file.
+ //
+ IResource selectedResource = (IResource)selectedElement;
+ if (selectedResource.getType() == IResource.FILE)
+ {
+ selectedResource = selectedResource.getParent();
+ }
+
+ // This gives us a directory...
+ //
+ if (selectedResource instanceof IFolder || selectedResource instanceof IProject)
+ {
+ // Set this for the container.
+ //
+ newFileCreationPage.setContainerFullPath(selectedResource.getFullPath());
+
+ // Make up a unique new name here.
+ //
+ String defaultModelBaseFilename = EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionEditorFilenameDefaultBase");
+ String defaultModelFilenameExtension = FILE_EXTENSIONS.get(0);
+ String modelFilename = defaultModelBaseFilename + "." + defaultModelFilenameExtension;
+ for (int i = 1; ((IContainer)selectedResource).findMember(modelFilename) != null; ++i)
+ {
+ modelFilename = defaultModelBaseFilename + i + "." + defaultModelFilenameExtension;
+ }
+ newFileCreationPage.setFileName(modelFilename);
+ }
+ }
+ }
+ initialObjectCreationPage = new EvolutionModelWizardInitialObjectCreationPage("Whatever2");
+ initialObjectCreationPage.setTitle(EvolutionEditorPlugin.INSTANCE.getString("_UI_EvolutionModelWizard_label"));
+ initialObjectCreationPage.setDescription(EvolutionEditorPlugin.INSTANCE.getString("_UI_Wizard_initial_object_description"));
+ addPage(initialObjectCreationPage);
+ }
+
+ /**
+ * Get the file from the page.
+ * <!-- begin-user-doc -->
+ * <!-- end-user-doc -->
+ * @generated
+ */
+ public IFile getModelFile()
+ {
+ return newFileCreationPage.getModelFile();
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolution.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolution.java
new file mode 100644
index 0000000000..91cbd8a227
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolution.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2004-2018 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+import org.eclipse.emf.cdo.evolution.util.DiagnosticType;
+
+import org.eclipse.emf.common.util.Diagnostic;
+
+import org.eclipse.swt.graphics.Image;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class BasicDiagnosticResolution extends DiagnosticResolution implements DiagnosticResolutionRelevance
+{
+ private final Image image;
+
+ private final String text;
+
+ private final String description;
+
+ private final boolean multi;
+
+ public BasicDiagnosticResolution(Image image, String text, String description, boolean multi)
+ {
+ this.image = image;
+ this.text = text;
+ this.description = description;
+ this.multi = multi;
+ }
+
+ @Override
+ public Image getImage()
+ {
+ return image;
+ }
+
+ @Override
+ public String getText()
+ {
+ return text;
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return description;
+ }
+
+ public boolean isMulti()
+ {
+ return multi;
+ }
+
+ @Override
+ public Diagnostic[] findOtherDiagnostics(Diagnostic[] diagnostics)
+ {
+ if (multi && diagnostics != null && diagnostics.length != 0)
+ {
+ List<Diagnostic> result = new ArrayList<Diagnostic>();
+ for (int i = 0; i < diagnostics.length; i++)
+ {
+ Diagnostic diagnostic = diagnostics[i];
+ if (isCompatibleDiagnostic(diagnostic))
+ {
+ result.add(diagnostic);
+ }
+ }
+
+ return result.toArray(new Diagnostic[result.size()]);
+ }
+
+ return super.findOtherDiagnostics(diagnostics);
+ }
+
+ protected boolean isCompatibleDiagnostic(Diagnostic diagnostic)
+ {
+ return false;
+ }
+
+ public int getRelevanceForResolution()
+ {
+ return 0;
+ }
+
+ @Override
+ public abstract void run(Diagnostic diagnostic);
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class TypedDiagnosticResolution extends BasicDiagnosticResolution
+ {
+ private final DiagnosticType type;
+
+ public TypedDiagnosticResolution(Image image, String text, String description, boolean multi, String source, int code)
+ {
+ super(image, text, description, multi);
+ type = new DiagnosticType(source, code);
+ }
+
+ public DiagnosticType getType()
+ {
+ return type;
+ }
+
+ protected DiagnosticType[] getCompatibleTypes()
+ {
+ return new DiagnosticType[] { type };
+ }
+
+ @Override
+ protected boolean isCompatibleDiagnostic(Diagnostic diagnostic)
+ {
+ for (int i = 0; i < getCompatibleTypes().length; i++)
+ {
+ DiagnosticType type = getCompatibleTypes()[i];
+ if (type.appliesTo(diagnostic))
+ {
+ return true;
+ }
+ }
+
+ return super.isCompatibleDiagnostic(diagnostic);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolutionGenerator.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolutionGenerator.java
new file mode 100644
index 0000000000..60a5bc7421
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/BasicDiagnosticResolutionGenerator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2004-2018 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+import org.eclipse.emf.cdo.evolution.presentation.EvolutionEditorPlugin;
+
+import org.eclipse.emf.common.util.ResourceLocator;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class BasicDiagnosticResolutionGenerator implements DiagnosticResolution.Generator
+{
+ protected ResourceLocator getResourceLocator()
+ {
+ return EvolutionEditorPlugin.INSTANCE;
+ }
+
+ protected String getString(String key, Object... substitutions)
+ {
+ return getString(getResourceLocator(), key, substitutions);
+ }
+
+ private String getString(ResourceLocator resourceLocator, String key, Object[] substitutions)
+ {
+ return substitutions == null || substitutions.length == 0 ? resourceLocator.getString(key) : resourceLocator.getString(key, substitutions);
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DefaultDiagnosticResolutionGenerator.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DefaultDiagnosticResolutionGenerator.java
new file mode 100644
index 0000000000..75fd4aa4e5
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DefaultDiagnosticResolutionGenerator.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (c) 2004-2018 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+import org.eclipse.emf.cdo.evolution.ChangeKind;
+import org.eclipse.emf.cdo.evolution.ElementChange;
+import org.eclipse.emf.cdo.evolution.Evolution;
+import org.eclipse.emf.cdo.evolution.EvolutionFactory;
+import org.eclipse.emf.cdo.evolution.FeaturePathMigration;
+import org.eclipse.emf.cdo.evolution.Model;
+import org.eclipse.emf.cdo.evolution.Release;
+import org.eclipse.emf.cdo.evolution.impl.EvolutionImpl;
+import org.eclipse.emf.cdo.evolution.impl.ModelSetChangeImpl;
+import org.eclipse.emf.cdo.evolution.presentation.quickfix.DiagnosticResolution.Generator;
+import org.eclipse.emf.cdo.evolution.util.DiagnosticID;
+import org.eclipse.emf.cdo.evolution.util.DiagnosticType;
+import org.eclipse.emf.cdo.evolution.util.ElementHandler;
+import org.eclipse.emf.cdo.evolution.util.ElementRunnable;
+import org.eclipse.emf.cdo.evolution.util.EvolutionValidator;
+import org.eclipse.emf.cdo.evolution.util.IDAnnotation;
+
+import org.eclipse.net4j.util.factory.ProductCreationException;
+
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.EModelElement;
+import org.eclipse.emf.ecore.EPackage;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredResourcesSelectionDialog;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Eike Stepper
+ */
+public class DefaultDiagnosticResolutionGenerator extends BasicDiagnosticResolutionGenerator
+{
+ public DefaultDiagnosticResolutionGenerator()
+ {
+ }
+
+ public void getResolutions(Diagnostic diagnostic, final Context context)
+ {
+ if (EvolutionValidator.DIAGNOSTIC_SOURCE.equals(diagnostic.getSource()))
+ {
+ int code = diagnostic.getCode();
+ switch (code)
+ {
+ case EvolutionValidator.CODE_NO_MODEL:
+ handleNoModel(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_NO_URI:
+ handleNoURI(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_NO_RESOURCE_SET:
+ break;
+
+ case EvolutionValidator.CODE_RESOURCE_NOT_FOUND:
+ break;
+
+ case EvolutionValidator.CODE_LOAD_PROBLEM:
+ break;
+
+ case EvolutionValidator.CODE_CONTENT_PROBLEM:
+ break;
+
+ case EvolutionValidator.CODE_PACKAGE_MISSING:
+ handlePackageMissing(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_PACKAGE_NOT_UNIQUE:
+ break;
+
+ case EvolutionValidator.CODE_NSURI_NOT_UNIQUE:
+ break;
+
+ case EvolutionValidator.CODE_NSURI_NOT_CHANGED:
+ handleNSURINotChanged(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_ID_ANNOTATION_MISSING:
+ case EvolutionValidator.CODE_ID_WITHOUT_VALUE:
+ handleNoID(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_ID_NOT_UNIQUE:
+ handleIDNotUnique(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_FEATURE_PATH_UNKNOWN:
+ handleFeaturePathUnknown(diagnostic, context);
+ break;
+
+ case EvolutionValidator.CODE_RELEASE:
+ handleRelease(diagnostic, context);
+ break;
+ }
+ }
+ }
+
+ protected void handleNoModel(Diagnostic diagnostic, final Context context)
+ {
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_SelectModelsFromWorkspace"), null, false, diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ Shell shell = context.getEditor().getSite().getShell();
+
+ FilteredResourcesSelectionDialog dialog = new FilteredResourcesSelectionDialog(shell, true, ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
+ dialog.setInitialPattern("*.ecore");
+ dialog.open();
+
+ Object[] result = dialog.getResult();
+ if (result == null || result.length == 0)
+ {
+ return;
+ }
+
+ Evolution evolution = (Evolution)diagnostic.getData().get(0);
+ for (Object object : result)
+ {
+ if (object instanceof IFile)
+ {
+ IFile file = (IFile)object;
+
+ Model model = EvolutionFactory.eINSTANCE.createModel(URI.createPlatformResourceURI(file.getFullPath().toString(), true));
+ evolution.getModels().add(model);
+ }
+ }
+ }
+ });
+ }
+
+ protected void handleNoURI(Diagnostic diagnostic, final Context context)
+ {
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_SelectModelFromWorkspace"), null, false, diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ Shell shell = context.getEditor().getSite().getShell();
+
+ FilteredResourcesSelectionDialog dialog = new FilteredResourcesSelectionDialog(shell, false, ResourcesPlugin.getWorkspace().getRoot(), IResource.FILE);
+ dialog.setInitialPattern("*.ecore");
+ dialog.open();
+
+ Object[] result = dialog.getResult();
+ if (result == null || result.length == 0 || !(result[0] instanceof IFile))
+ {
+ return;
+ }
+
+ IFile file = (IFile)result[0];
+ Model model = (Model)diagnostic.getData().get(0);
+ model.setURI(URI.createPlatformResourceURI(file.getFullPath().toString(), true));
+ }
+ });
+ }
+
+ protected void handlePackageMissing(Diagnostic diagnostic, final Context context)
+ {
+ final List<?> data = diagnostic.getData();
+
+ Resource resource = ((EPackage)data.get(2)).eResource();
+ if (resource != null)
+ {
+ final URI uri = resource.getURI();
+ if (uri != null)
+ {
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_PackageMissing", uri), null, true, diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ Model model = EvolutionFactory.eINSTANCE.createModel(uri);
+
+ Evolution evolution = (Evolution)data.get(0);
+ evolution.getModels().add(model);
+ }
+ });
+ }
+ }
+ }
+
+ protected void handleNSURINotChanged(Diagnostic diagnostic, Context context)
+ {
+ Evolution evolution = (Evolution)diagnostic.getData().get(3);
+ final int nextVersion = evolution.getNextReleaseVersion();
+
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_SetVersionIntoNamespace", nextVersion), null, true, diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ EPackage ePackage = (EPackage)diagnostic.getData().get(0);
+ String nsURI = ePackage.getNsURI();
+ if (!nsURI.endsWith("/"))
+ {
+ nsURI += "/";
+ }
+
+ Pattern pattern = Pattern.compile("/v[0-9]+/");
+ Matcher matcher = pattern.matcher(nsURI);
+ if (matcher.find())
+ {
+ int start = matcher.start();
+ int end = matcher.end();
+ String prefix = nsURI.substring(0, start);
+ String suffix = nsURI.substring(end, nsURI.length() - 1);
+
+ nsURI = prefix + "/v" + nextVersion + "/" + suffix;
+ }
+ else
+ {
+ nsURI += "v" + nextVersion;
+ }
+
+ ePackage.setNsURI(nsURI);
+ }
+ });
+
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_DisableUniqueNamespaceEnforcement"), null, false, diagnostic.getCode())
+ {
+ @Override
+ public int getRelevanceForResolution()
+ {
+ return -100;
+ }
+
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ Evolution evolution = (Evolution)diagnostic.getData().get(3);
+ evolution.setUniqueNamespaces(false);
+ }
+ });
+ }
+
+ protected void handleNoID(Diagnostic diagnostic, final Context context)
+ {
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_AssignID"), null, true, diagnostic.getCode())
+ {
+ @Override
+ protected DiagnosticType[] getCompatibleTypes()
+ {
+ return new DiagnosticType[] { getType(), new DiagnosticType(EvolutionValidator.DIAGNOSTIC_SOURCE, EvolutionValidator.CODE_ID_WITHOUT_VALUE) };
+ }
+
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ EModelElement modelElement = (EModelElement)diagnostic.getData().get(0);
+ IDAnnotation.ensureValue(modelElement);
+ }
+ });
+ }
+
+ protected void handleIDNotUnique(Diagnostic diagnostic, final Context context)
+ {
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_RememberID"), null, true, diagnostic.getCode())
+ {
+ @Override
+ public int getRelevanceForResolution()
+ {
+ return 100;
+ }
+
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ EModelElement modelElement = (EModelElement)diagnostic.getData().get(0);
+ String oldValue = IDAnnotation.getValue(modelElement);
+ IDAnnotation.setOldValue(modelElement, oldValue);
+ IDAnnotation.setValue(modelElement, null);
+ IDAnnotation.ensureValue(modelElement);
+ }
+ });
+
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_ReplaceID"), null, true, diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ EModelElement modelElement = (EModelElement)diagnostic.getData().get(0);
+ IDAnnotation.setValue(modelElement, null);
+ IDAnnotation.ensureValue(modelElement);
+ }
+ });
+ }
+
+ protected void handleFeaturePathUnknown(Diagnostic diagnostic, Context context)
+ {
+ final ElementChange elementChange = (ElementChange)diagnostic.getData().get(0);
+ final ChangeKind kind = elementChange.getKind();
+
+ context.add(new EvolutionDiagnosticResolution(null,
+ getString("_QF_SpecifyFeaturePath", kind.getName().toLowerCase(), ElementHandler.getLabel(elementChange.getNewElement())), null, false,
+ diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ FeaturePathMigration migration = EvolutionFactory.eINSTANCE.createFeaturePathMigration();
+ migration.setDiagnosticID(DiagnosticID.get(diagnostic).getValue());
+ migration.setFromClass(((EStructuralFeature)elementChange.getOldElement()).getEContainingClass());
+ migration.setToClass(((EStructuralFeature)elementChange.getNewElement()).getEContainingClass());
+
+ Evolution evolution = (Evolution)elementChange.getNewModelSet();
+ evolution.getMigrations().add(migration);
+ }
+ });
+ }
+
+ protected void handleRelease(Diagnostic diagnostic, final Context context)
+ {
+ final EvolutionImpl evolution = (EvolutionImpl)diagnostic.getData().get(0);
+ final int nextVersion = evolution.getNextReleaseVersion();
+
+ context.add(new EvolutionDiagnosticResolution(null, getString("_QF_CreateRelease", nextVersion), null, false, diagnostic.getCode())
+ {
+ @Override
+ public void run(Diagnostic diagnostic)
+ {
+ Release release = EvolutionFactory.eINSTANCE.createRelease();
+ release.setDate(new Date());
+ release.setVersion(nextVersion);
+
+ evolution.getReleases().add(release);
+
+ Collection<EPackage> rootPackages = EcoreUtil.copyAll(evolution.getRootPackages());
+ release.getRootPackages().addAll(rootPackages);
+
+ for (EPackage rootPackage : evolution.getRootPackages())
+ {
+ ElementHandler.execute(rootPackage, new ElementRunnable()
+ {
+ public void run(EModelElement modelElement)
+ {
+ IDAnnotation.setOldValue(modelElement, null);
+ }
+ });
+ }
+
+ ModelSetChangeImpl change = (ModelSetChangeImpl)evolution.getChange();
+ if (change != null)
+ {
+ change.reset();
+ evolution.setChange(null);
+ }
+ }
+ });
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ protected static abstract class EvolutionDiagnosticResolution extends BasicDiagnosticResolution.TypedDiagnosticResolution
+ {
+ protected EvolutionDiagnosticResolution(Image image, String text, String description, boolean multi, int code)
+ {
+ super(image, text, description, multi, EvolutionValidator.DIAGNOSTIC_SOURCE, code);
+ }
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static class Factory extends DiagnosticResolution.Generator.Factory
+ {
+ public Factory()
+ {
+ }
+
+ @Override
+ public Generator create(String description) throws ProductCreationException
+ {
+ return new DefaultDiagnosticResolutionGenerator();
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolution.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolution.java
new file mode 100644
index 0000000000..603b7467e4
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolution.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2004-2018 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+import org.eclipse.emf.cdo.evolution.presentation.EvolutionEditor;
+import org.eclipse.emf.cdo.evolution.presentation.quickfix.DiagnosticResolution.Generator.Context;
+
+import org.eclipse.net4j.util.container.IPluginContainer;
+import org.eclipse.net4j.util.factory.ProductCreationException;
+
+import org.eclipse.emf.common.util.Diagnostic;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.swt.graphics.Image;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eike Stepper
+ */
+public abstract class DiagnosticResolution
+{
+ public static final Diagnostic[] NO_DIAGNOSTICS = {};
+
+ public abstract Image getImage();
+
+ public abstract String getText();
+
+ public abstract String getDescription();
+
+ public abstract void run(Diagnostic diagnostic);
+
+ public void run(Diagnostic[] diagnostics, IProgressMonitor monitor)
+ {
+ for (Diagnostic diagnostic : diagnostics)
+ {
+ monitor.subTask(diagnostic.getMessage());
+ run(diagnostic);
+ }
+ }
+
+ public Diagnostic[] findOtherDiagnostics(Diagnostic[] diagnostics)
+ {
+ return NO_DIAGNOSTICS;
+ }
+
+ public static DiagnosticResolution[] getResolutions(Diagnostic diagnostic, final EvolutionEditor editor)
+ {
+ final List<DiagnosticResolution> result = new ArrayList<DiagnosticResolution>();
+ Context context = new Generator.Context()
+ {
+ public EvolutionEditor getEditor()
+ {
+ return editor;
+ }
+
+ public void add(DiagnosticResolution resolution)
+ {
+ result.add(resolution);
+ }
+ };
+
+ for (String factoryType : IPluginContainer.INSTANCE.getFactoryTypes(Generator.Factory.PRODUCT_GROUP))
+ {
+ Generator generator = (Generator)IPluginContainer.INSTANCE.getElement(Generator.Factory.PRODUCT_GROUP, factoryType, null);
+ generator.getResolutions(diagnostic, context);
+ }
+
+ return result.toArray(new DiagnosticResolution[result.size()]);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface Generator
+ {
+ public void getResolutions(Diagnostic diagnostic, Context context);
+
+ /**
+ * @author Eike Stepper
+ */
+ public interface Context
+ {
+ public EvolutionEditor getEditor();
+
+ public void add(DiagnosticResolution resolution);
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ public static abstract class Factory extends org.eclipse.net4j.util.factory.Factory
+ {
+ public static final String PRODUCT_GROUP = "org.eclipse.emf.cdo.evolution.diagnosticResolutionGenerators";
+
+ public static final String DEFAULT_TYPE = "default";
+
+ public Factory()
+ {
+ this(DEFAULT_TYPE);
+ }
+
+ public Factory(String type)
+ {
+ super(PRODUCT_GROUP, type);
+ }
+
+ public abstract Generator create(String description) throws ProductCreationException;
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolutionRelevance.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolutionRelevance.java
new file mode 100644
index 0000000000..88f67d482a
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/DiagnosticResolutionRelevance.java
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2004-2018 Eike Stepper (Loehne, Germany) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Eike Stepper - initial API and implementation
+ */
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+/**
+ * @author Eike Stepper
+ */
+public interface DiagnosticResolutionRelevance
+{
+ public int getRelevanceForResolution();
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixPage.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixPage.java
new file mode 100644
index 0000000000..fb48612ff7
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixPage.java
@@ -0,0 +1,408 @@
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+import org.eclipse.emf.cdo.evolution.presentation.EvolutionEditor;
+
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.edit.command.ChangeCommand;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionAdapter;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.FormAttachment;
+import org.eclipse.swt.layout.FormData;
+import org.eclipse.swt.layout.FormLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * QuickFixPage is a page for the quick fixes of a marker.
+ *
+ * @since 3.4
+ *
+ */
+public class QuickFixPage extends WizardPage
+{
+ private Map<DiagnosticResolution, Collection<Diagnostic>> resolutionsMap;
+
+ private TableViewer resolutionsViewer;
+
+ private CheckboxTableViewer diagnosticsViewer;
+
+ private final Diagnostic[] selectedDiagnostics;
+
+ private AdapterFactoryEditingDomain editingDomain;
+
+ public QuickFixPage(String problemDescription, Diagnostic[] selectedDiagnostics, Map<DiagnosticResolution, Collection<Diagnostic>> resolutionsMap,
+ AdapterFactoryEditingDomain editingDomain)
+ {
+ super("QuickFixPage");
+ this.selectedDiagnostics = selectedDiagnostics;
+ this.resolutionsMap = resolutionsMap;
+ this.editingDomain = editingDomain;
+
+ setTitle("Quick Fix");
+ setMessage(problemDescription);
+ }
+
+ public void createControl(Composite parent)
+ {
+ initializeDialogUnits(parent);
+
+ // Create a new composite as there is the title bar separator to deal with
+ Composite control = new Composite(parent, SWT.NONE);
+ control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+ setControl(control);
+
+ // PlatformUI.getWorkbench().getHelpSystem().setHelp(control, IWorkbenchHelpContextIds.PROBLEMS_VIEW);
+
+ FormLayout layout = new FormLayout();
+ layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN);
+ layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN);
+ layout.spacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+ control.setLayout(layout);
+
+ Label resolutionsLabel = new Label(control, SWT.NONE);
+ resolutionsLabel.setText("&Select a fix:");
+ resolutionsLabel.setLayoutData(new FormData());
+
+ createResolutionsList(control);
+
+ FormData listData = new FormData();
+ listData.top = new FormAttachment(resolutionsLabel, 0);
+ listData.left = new FormAttachment(0);
+ listData.right = new FormAttachment(100, 0);
+ listData.height = convertHeightInCharsToPixels(10);
+ resolutionsViewer.getControl().setLayoutData(listData);
+
+ Label title = new Label(control, SWT.NONE);
+ title.setText("&Problems:");
+ FormData labelData = new FormData();
+ labelData.top = new FormAttachment(resolutionsViewer.getControl(), 0);
+ labelData.left = new FormAttachment(0);
+ title.setLayoutData(labelData);
+
+ createDiagnosticsViewer(control);
+
+ Composite buttons = createTableButtons(control);
+ FormData buttonData = new FormData();
+ buttonData.top = new FormAttachment(title, 0);
+ buttonData.right = new FormAttachment(100);
+ buttonData.height = convertHeightInCharsToPixels(10);
+ buttons.setLayoutData(buttonData);
+
+ FormData tableData = new FormData();
+ tableData.top = new FormAttachment(buttons, 0, SWT.TOP);
+ tableData.left = new FormAttachment(0);
+ tableData.bottom = new FormAttachment(100);
+ tableData.right = new FormAttachment(buttons, 0);
+ tableData.height = convertHeightInCharsToPixels(10);
+ diagnosticsViewer.getControl().setLayoutData(tableData);
+
+ Dialog.applyDialogFont(control);
+
+ resolutionsViewer.setSelection(new StructuredSelection(resolutionsViewer.getElementAt(0)));
+
+ diagnosticsViewer.setCheckedElements(selectedDiagnostics);
+
+ setPageComplete(diagnosticsViewer.getCheckedElements().length > 0);
+ }
+
+ private Composite createTableButtons(Composite control)
+ {
+ Composite buttonComposite = new Composite(control, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginWidth = 0;
+ layout.marginHeight = 0;
+ layout.horizontalSpacing = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_SPACING);
+ layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING);
+ buttonComposite.setLayout(layout);
+
+ Button selectAll = new Button(buttonComposite, SWT.PUSH);
+ selectAll.setText("Select &All");
+ selectAll.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
+ selectAll.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent arg0)
+ {
+ diagnosticsViewer.setAllChecked(true);
+ setPageComplete(!resolutionsViewer.getStructuredSelection().isEmpty());
+ }
+ });
+
+ Button deselectAll = new Button(buttonComposite, SWT.PUSH);
+ deselectAll.setText("&Deselect All");
+ deselectAll.setLayoutData(new GridData(SWT.FILL, SWT.NONE, false, false));
+ deselectAll.addSelectionListener(new SelectionAdapter()
+ {
+ @Override
+ public void widgetSelected(SelectionEvent arg0)
+ {
+ diagnosticsViewer.setAllChecked(false);
+ setPageComplete(false);
+ }
+ });
+
+ return buttonComposite;
+ }
+
+ private void createResolutionsList(Composite control)
+ {
+ resolutionsViewer = new TableViewer(control, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL);
+ resolutionsViewer.setContentProvider(new IStructuredContentProvider()
+ {
+ public Object[] getElements(Object inputElement)
+ {
+ return resolutionsMap.keySet().toArray();
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+ {
+ }
+
+ public void dispose()
+ {
+ }
+ });
+
+ resolutionsViewer.setLabelProvider(new LabelProvider()
+ {
+ @Override
+ public String getText(Object element)
+ {
+ return ((DiagnosticResolution)element).getText();
+ }
+
+ @Override
+ public Image getImage(Object element)
+ {
+ return ((DiagnosticResolution)element).getImage();
+ }
+ });
+
+ resolutionsViewer.setComparator(new ViewerComparator()
+ {
+ /**
+ * This comparator compares the resolutions based on the relevance of the
+ * resolutions. Any resolution that doesn't implement DiagnosticResolutionRelevance
+ * will be deemed to have relevance 0 (default value for relevance). If both
+ * resolutions have the same relevance, then marker resolution label string will
+ * be used for comparing the resolutions.
+ *
+ * @see DiagnosticResolutionRelevance#getRelevanceForResolution()
+ */
+ @Override
+ public int compare(Viewer viewer, Object e1, Object e2)
+ {
+ int relevanceMarker1 = e1 instanceof DiagnosticResolutionRelevance ? ((DiagnosticResolutionRelevance)e1).getRelevanceForResolution() : 0;
+ int relevanceMarker2 = e2 instanceof DiagnosticResolutionRelevance ? ((DiagnosticResolutionRelevance)e2).getRelevanceForResolution() : 0;
+ if (relevanceMarker1 != relevanceMarker2)
+ {
+ return Integer.valueOf(relevanceMarker2).compareTo(Integer.valueOf(relevanceMarker1));
+ }
+
+ return ((DiagnosticResolution)e1).getText().compareTo(((DiagnosticResolution)e2).getText());
+ }
+ });
+
+ resolutionsViewer.addSelectionChangedListener(new ISelectionChangedListener()
+ {
+ public void selectionChanged(SelectionChangedEvent event)
+ {
+ diagnosticsViewer.refresh();
+ setPageComplete(diagnosticsViewer.getCheckedElements().length > 0);
+ }
+ });
+
+ resolutionsViewer.setInput(this);
+ }
+
+ private void createDiagnosticsViewer(Composite parent)
+ {
+ diagnosticsViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER | SWT.V_SCROLL | SWT.SINGLE);
+ diagnosticsViewer.setContentProvider(new DiagnosticsContentProvider());
+ diagnosticsViewer.setInput(this);
+
+ Table table = diagnosticsViewer.getTable();
+ table.setHeaderVisible(true);
+ table.setLinesVisible(true);
+
+ EvolutionEditor.createDiagnosticElementColumn(diagnosticsViewer, editingDomain.getAdapterFactory());
+ EvolutionEditor.createDiagnosticResourceColumn(diagnosticsViewer, editingDomain.getAdapterFactory());
+
+ diagnosticsViewer.addCheckStateListener(new ICheckStateListener()
+ {
+ public void checkStateChanged(CheckStateChangedEvent event)
+ {
+ if (event.getChecked() == true)
+ {
+ setPageComplete(true);
+ }
+ else
+ {
+ setPageComplete(diagnosticsViewer.getCheckedElements().length > 0);
+ }
+ }
+ });
+
+ // new OpenAndLinkWithEditorHelper(markersTable)
+ // {
+ // {
+ // setLinkWithEditor(false);
+ // }
+ //
+ // @Override
+ // protected void activate(ISelection selection)
+ // {
+ // open(selection, true);
+ // }
+ //
+ // /** Not supported*/
+ //
+ // @Override
+ // protected void linkToEditor(ISelection selection)
+ // {
+ // }
+ //
+ // @Override
+ // protected void open(ISelection selection, boolean activate)
+ // {
+ // if (selection.isEmpty())
+ // {
+ // return;
+ // }
+ // Diagnostic marker = (Diagnostic)((IStructuredSelection)selection).getFirstElement();
+ // if (marker != null && marker.getResource() instanceof IFile)
+ // {
+ // try
+ // {
+ // IDE.openEditor(site.getPage(), marker, activate);
+ // }
+ // catch (PartInitException e)
+ // {
+ // MarkerSupportInternalUtilities.showViewError(e);
+ // }
+ // }
+ // }
+ // };
+ }
+
+ public Diagnostic getSelectedDiagnostic()
+ {
+ IStructuredSelection selection = diagnosticsViewer.getStructuredSelection();
+ if (!selection.isEmpty())
+ {
+ if (selection.size() == 1)
+ {
+ return (Diagnostic)selection.getFirstElement();
+ }
+ }
+
+ return null;
+ }
+
+ void performFinish(IProgressMonitor monitor)
+ {
+ final DiagnosticResolution resolution = getSelectedResolution();
+ if (resolution == null)
+ {
+ return;
+ }
+
+ final Object[] checked = diagnosticsViewer.getCheckedElements();
+ if (checked.length == 0)
+ {
+ return;
+ }
+
+ try
+ {
+ getWizard().getContainer().run(false, true, new IRunnableWithProgress()
+ {
+ public void run(final IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
+ {
+ final Diagnostic[] diagnostics = new Diagnostic[checked.length];
+ System.arraycopy(checked, 0, diagnostics, 0, checked.length);
+
+ ChangeCommand command = new ChangeCommand(editingDomain.getResourceSet())
+ {
+ @Override
+ protected void doExecute()
+ {
+ resolution.run(diagnostics, monitor);
+ }
+ };
+
+ editingDomain.getCommandStack().execute(command);
+ }
+ });
+ }
+ catch (InvocationTargetException e)
+ {
+ StatusManager.getManager().handle(QuickFixWizard.newStatus(IStatus.ERROR, e.getLocalizedMessage(), e));
+ }
+ catch (InterruptedException e)
+ {
+ StatusManager.getManager().handle(QuickFixWizard.newStatus(IStatus.ERROR, e.getLocalizedMessage(), e));
+ }
+ }
+
+ private DiagnosticResolution getSelectedResolution()
+ {
+ return (DiagnosticResolution)resolutionsViewer.getStructuredSelection().getFirstElement();
+ }
+
+ /**
+ * @author Eike Stepper
+ */
+ private final class DiagnosticsContentProvider implements IStructuredContentProvider
+ {
+ public Object[] getElements(Object inputElement)
+ {
+ DiagnosticResolution selected = getSelectedResolution();
+ if (selected != null && resolutionsMap.containsKey(selected))
+ {
+ return resolutionsMap.get(selected).toArray();
+ }
+
+ return DiagnosticResolution.NO_DIAGNOSTICS;
+ }
+
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
+ {
+ }
+
+ public void dispose()
+ {
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixWizard.java b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixWizard.java
new file mode 100644
index 0000000000..d9a677846f
--- /dev/null
+++ b/plugins/org.eclipse.emf.cdo.evolution.editor/src/org/eclipse/emf/cdo/evolution/presentation/quickfix/QuickFixWizard.java
@@ -0,0 +1,115 @@
+package org.eclipse.emf.cdo.evolution.presentation.quickfix;
+
+import org.eclipse.emf.cdo.evolution.presentation.EvolutionEditorPlugin;
+
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
+import org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.jface.wizard.IWizardPage;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * The wizard for quick fixes.
+ */
+public class QuickFixWizard extends Wizard
+{
+ private Diagnostic[] selectedDiagnostics;
+
+ private Map<DiagnosticResolution, Collection<Diagnostic>> resolutionsMap;
+
+ private String description;
+
+ private AdapterFactoryEditingDomain editingDomain;
+
+ public QuickFixWizard(String description, Diagnostic[] selectedDiagnostics, Map<DiagnosticResolution, Collection<Diagnostic>> resolutionsMap,
+ AdapterFactoryEditingDomain editingDomain)
+ {
+ this.selectedDiagnostics = selectedDiagnostics;
+ this.resolutionsMap = resolutionsMap;
+ this.description = description;
+ this.editingDomain = editingDomain;
+
+ setNeedsProgressMonitor(true);
+ setDefaultPageImageDescriptor(ExtendedImageRegistry.INSTANCE
+ .getImageDescriptor(URI.createPlatformPluginURI(EvolutionEditorPlugin.PLUGIN_ID + "/icons/full/wizban/quick_fix.png", true)));
+ }
+
+ @Override
+ public void addPages()
+ {
+ super.addPages();
+ addPage(new QuickFixPage(description, selectedDiagnostics, resolutionsMap, editingDomain));
+ }
+
+ @Override
+ public boolean performFinish()
+ {
+ IRunnableWithProgress finishRunnable = new IRunnableWithProgress()
+ {
+ public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException
+ {
+ IWizardPage[] pages = getPages();
+ SubMonitor subMonitor = SubMonitor.convert(monitor, "Fixing", 10 * pages.length + 1);
+ subMonitor.worked(1);
+ for (IWizardPage page : pages)
+ {
+ // Allow for cancel event processing
+ getShell().getDisplay().readAndDispatch();
+ QuickFixPage wizardPage = (QuickFixPage)page;
+ wizardPage.performFinish(subMonitor.split(10));
+ }
+ }
+ };
+
+ try
+ {
+ getContainer().run(false, true, finishRunnable);
+ }
+ catch (InvocationTargetException e)
+ {
+ StatusManager.getManager().handle(newStatus(IStatus.ERROR, e.getLocalizedMessage(), e));
+ return false;
+ }
+ catch (InterruptedException e)
+ {
+ StatusManager.getManager().handle(newStatus(IStatus.ERROR, e.getLocalizedMessage(), e));
+ return false;
+ }
+
+ return true;
+ }
+
+ public static IStatus newStatus(int severity, String message, Throwable exception)
+ {
+ String statusMessage = message;
+ if (message == null || message.trim().length() == 0)
+ {
+ if (exception == null)
+ {
+ throw new IllegalArgumentException();
+ }
+ else if (exception.getMessage() == null)
+ {
+ statusMessage = exception.toString();
+ }
+ else
+ {
+ statusMessage = exception.getMessage();
+ }
+ }
+
+ return new Status(severity, EvolutionEditorPlugin.PLUGIN_ID, severity, statusMessage, exception);
+ }
+}

Back to the top