Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2014-04-22 19:59:18 +0000
committerChristian W. Damus2014-04-22 20:13:22 +0000
commit307a6a646538632e385b271f1a14457e7fc38b5a (patch)
tree8b6833649a4187f919be229bcf4defc3a72f408f
parent1cdf16f1d80b19b78c558aa2258284b6c05daaad (diff)
downloadorg.eclipse.papyrus-307a6a646538632e385b271f1a14457e7fc38b5a.tar.gz
org.eclipse.papyrus-307a6a646538632e385b271f1a14457e7fc38b5a.tar.xz
org.eclipse.papyrus-307a6a646538632e385b271f1a14457e7fc38b5a.zip
408491: [Profile] Papyrus shall enable to easily switch between local and registered profiles.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=408491 Hook stereotype-application repair as a precondition of profile switch. This employs a new extension point that can be used to register additional pre-condition checks not yet identified.
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF4
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/build.properties3
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml7
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileSwitchPreconditions.exsd95
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/handler/SwitchProfileHandler.java35
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationPrecondition.java41
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationRepairSnippet.java68
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/validation/ProfileSwitchValidator.java145
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/ui/ZombieStereotypeDialogPresenter.java77
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/IProfileSwitchPrecondition.java35
-rw-r--r--plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/ProfileSwitchContext.java63
11 files changed, 534 insertions, 39 deletions
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF
index 55c14b8b9b8..d91d071bbc6 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/META-INF/MANIFEST.MF
@@ -3,8 +3,10 @@ Export-Package: org.eclipse.papyrus.uml.modelrepair,
org.eclipse.papyrus.uml.modelrepair.handler,
org.eclipse.papyrus.uml.modelrepair.internal.participants;x-internal:=true,
org.eclipse.papyrus.uml.modelrepair.internal.stereotypes;x-internal:=true,
+ org.eclipse.papyrus.uml.modelrepair.internal.validation;x-internal:=true,
org.eclipse.papyrus.uml.modelrepair.ui,
- org.eclipse.papyrus.uml.modelrepair.ui.providers
+ org.eclipse.papyrus.uml.modelrepair.ui.providers,
+ org.eclipse.papyrus.uml.modelrepair.validation
Require-Bundle: org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.papyrus.infra.core;bundle-version="1.0.0",
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/build.properties b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/build.properties
index 1231c5219cc..56b67bb9b85 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/build.properties
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/build.properties
@@ -5,4 +5,5 @@ bin.includes = META-INF/,\
about.html,\
plugin.xml,\
icons/
-src.includes = about.html
+src.includes = about.html,\
+ schema/
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml
index 1445b6a5011..6a5f236c044 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/plugin.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
+ <extension-point id="org.eclipse.papyrus.uml.modelrepair.profileSwitchPreconditions" name="Profile Switch Preconditions" schema="schema/profileSwitchPreconditions.exsd"/>
<extension
point="org.eclipse.ui.menus">
<menuContribution
@@ -117,5 +118,11 @@
description="Initiates repair of zombie stereotype applications on load of a UML resource.">
</modelSetSnippet>
</extension>
+ <extension
+ point="org.eclipse.papyrus.uml.modelrepair.profileSwitchPreconditions">
+ <precondition
+ class="org.eclipse.papyrus.uml.modelrepair.internal.stereotypes.StereotypeApplicationPrecondition">
+ </precondition>
+ </extension>
</plugin>
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileSwitchPreconditions.exsd b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileSwitchPreconditions.exsd
new file mode 100644
index 00000000000..6fd5c3e6fa2
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/schema/profileSwitchPreconditions.exsd
@@ -0,0 +1,95 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.uml.modelrepair" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.papyrus.uml.modelrepair" id="profileSwitchPrecondition" name="Profiel Switch Preconditions"/>
+ </appinfo>
+ <documentation>
+ Initial-conditions checkers for profile switch procedure.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence minOccurs="1" maxOccurs="unbounded">
+ <element ref="precondition"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+
+ </documentation>
+ <appinfo>
+ <meta.attribute translatable="true"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="precondition">
+ <annotation>
+ <documentation>
+ Registration of a pre-condition check for the profile switch procedure.
+ </documentation>
+ </annotation>
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The class implementing the precondition.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.papyrus.uml.modelrepair.validation.IProfileSwitchPrecondition"/>
+ </appinfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appinfo>
+ <meta.section type="since"/>
+ </appinfo>
+ <documentation>
+ 1.0
+ </documentation>
+ </annotation>
+
+
+
+
+ <annotation>
+ <appinfo>
+ <meta.section type="copyright"/>
+ </appinfo>
+ <documentation>
+ Copyright (c) 2014 CEA 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
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/handler/SwitchProfileHandler.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/handler/SwitchProfileHandler.java
index e677ec989a3..420abce3208 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/handler/SwitchProfileHandler.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/handler/SwitchProfileHandler.java
@@ -33,7 +33,9 @@ import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
import org.eclipse.papyrus.uml.modelrepair.Activator;
+import org.eclipse.papyrus.uml.modelrepair.internal.validation.ProfileSwitchValidator;
import org.eclipse.papyrus.uml.modelrepair.ui.SwitchProfileDialog;
+import org.eclipse.papyrus.uml.modelrepair.validation.ProfileSwitchContext;
import org.eclipse.papyrus.uml.tools.util.ProfileHelper;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.handlers.HandlerUtil;
@@ -99,25 +101,26 @@ public class SwitchProfileHandler extends AbstractHandler {
final Collection<Profile> allAppliedProfiles = ProfileHelper.getAllAppliedProfiles(modelSet);
+ ProfileSwitchValidator validator = new ProfileSwitchValidator();
+ if(validator.validate(new ProfileSwitchContext(activeShell, modelSet, editingDomain, profiledPackage, allAppliedProfiles))) {
+ //Go back to the UI thread and open a dialog
+ activeShell.getDisplay().asyncExec(new Runnable() {
- //Go back to the UI thread and open a dialog
- activeShell.getDisplay().asyncExec(new Runnable() {
-
- public void run() {
- if(allAppliedProfiles.isEmpty()) {
- MessageDialog.openInformation(activeShell, "Switch Profiles", "The selected model has no profiles applied.");
- return;
- }
+ public void run() {
+ if(allAppliedProfiles.isEmpty()) {
+ MessageDialog.openInformation(activeShell, "Switch Profiles", "The selected model has no profiles applied.");
+ return;
+ }
- try {
- SwitchProfileDialog dialog = new SwitchProfileDialog(activeShell, modelSet, editingDomain);
- dialog.open();
- } catch (ServiceException e) {
- StatusManager.getManager().handle(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to open profile switching dialog.", e), StatusManager.SHOW);
+ try {
+ SwitchProfileDialog dialog = new SwitchProfileDialog(activeShell, modelSet, editingDomain);
+ dialog.open();
+ } catch (ServiceException e) {
+ StatusManager.getManager().handle(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to open profile switching dialog.", e), StatusManager.SHOW);
+ }
}
- }
- });
-
+ });
+ }
}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationPrecondition.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationPrecondition.java
new file mode 100644
index 00000000000..9f35c54dedd
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationPrecondition.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.uml.modelrepair.internal.stereotypes;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.uml.modelrepair.validation.IProfileSwitchPrecondition;
+import org.eclipse.papyrus.uml.modelrepair.validation.ProfileSwitchContext;
+
+
+/**
+ * This is the StereotypeApplicationPrecondition type. Enjoy.
+ */
+public class StereotypeApplicationPrecondition implements IProfileSwitchPrecondition {
+
+ public StereotypeApplicationPrecondition() {
+ super();
+ }
+
+ public IStatus validateProfileSwitch(ProfileSwitchContext ctx) {
+ IStatus result = Status.OK_STATUS;
+
+ StereotypeApplicationRepairSnippet snippet = StereotypeApplicationRepairSnippet.getInstance(ctx.getModelSet());
+ if(snippet != null) {
+ result = snippet.repair(ctx.getModelSet());
+ }
+
+ return result;
+ }
+
+}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationRepairSnippet.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationRepairSnippet.java
index 43f580e5840..f9b43cbb024 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationRepairSnippet.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/stereotypes/StereotypeApplicationRepairSnippet.java
@@ -15,6 +15,8 @@ package org.eclipse.papyrus.uml.modelrepair.internal.stereotypes;
import java.util.Collection;
import java.util.Set;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
@@ -29,6 +31,7 @@ import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.emf.utils.EMFHelper;
import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForResourceSet;
+import org.eclipse.papyrus.uml.modelrepair.Activator;
import org.eclipse.papyrus.uml.modelrepair.ui.ZombieStereotypeDialogPresenter;
import org.eclipse.ui.IEditorPart;
import org.eclipse.uml2.uml.Element;
@@ -47,10 +50,10 @@ import com.google.common.collect.Sets;
*/
public class StereotypeApplicationRepairSnippet implements IModelSetSnippet {
- private final UMLResourceLoadAdaper adapter = new UMLResourceLoadAdaper();
+ private final UMLResourceLoadAdapter adapter = new UMLResourceLoadAdapter();
private final Supplier<Profile> dynamicProfileSupplier;
-
+
private ZombieStereotypeDialogPresenter presenter;
public StereotypeApplicationRepairSnippet() {
@@ -63,16 +66,58 @@ public class StereotypeApplicationRepairSnippet implements IModelSetSnippet {
this.dynamicProfileSupplier = dynamicProfileSupplier;
}
+ public static StereotypeApplicationRepairSnippet getInstance(ModelSet modelSet) {
+ UMLResourceLoadAdapter adapter = (UMLResourceLoadAdapter)EcoreUtil.getExistingAdapter(modelSet, StereotypeApplicationRepairSnippet.class);
+ return (adapter == null) ? null : adapter.getSnippet();
+ }
+
+ public IStatus repair(ModelSet modelSet) {
+ IStatus result = Status.OK_STATUS;
+
+ if(presenter != null) {
+ for(Resource next : ImmutableList.copyOf(modelSet.getResources())) {
+ if(next.isLoaded()) {
+ handleResourceLoaded(next);
+ }
+ }
+
+ // Wait for the presenter to have shown its dialog and finished
+ try {
+ presenter.awaitPending(false);
+
+ // Did we fix all of the zombies?
+ for(Resource next : ImmutableList.copyOf(modelSet.getResources())) {
+ if(next.isLoaded() && (getZombieStereotypes(next) != null)) {
+ result = new Status(IStatus.WARNING, Activator.PLUGIN_ID, "Stereotype repair did not successfully repair all stereotype application problems.");
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ result = new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Stereotype repair was interrupted while waiting for user input.", e);
+ }
+ }
+
+ return result;
+ }
+
protected void handleResourceLoaded(Resource resource) {
+ ZombieStereotypesDescriptor zombies = getZombieStereotypes(resource);
+
+ if((zombies != null) && (presenter != null)) {
+ presenter.addZombies(zombies);
+ }
+ }
+
+ protected ZombieStereotypesDescriptor getZombieStereotypes(Resource resource) {
+ ZombieStereotypesDescriptor result = null;
Element root = getRootUMLElement(resource);
// Only check for zombies in resources that we can modify (those being the resources in the user model opened in the editor)
if((root != null) && !EMFHelper.isReadOnly(resource, EMFHelper.resolveEditingDomain(root))) {
- ZombieStereotypesDescriptor zombies = getZombieStereotypes(resource, root);
- if((zombies != null) && (presenter != null)) {
- presenter.addZombies(zombies);
- }
+ result = getZombieStereotypes(resource, root);
}
+
+ return result;
}
protected Element getRootUMLElement(Resource resource) {
@@ -149,7 +194,16 @@ public class StereotypeApplicationRepairSnippet implements IModelSetSnippet {
// Nested types
//
- private class UMLResourceLoadAdaper extends AdapterImpl {
+ private class UMLResourceLoadAdapter extends AdapterImpl {
+
+ public StereotypeApplicationRepairSnippet getSnippet() {
+ return StereotypeApplicationRepairSnippet.this;
+ }
+
+ @Override
+ public boolean isAdapterForType(Object type) {
+ return type == StereotypeApplicationRepairSnippet.class;
+ }
@Override
public void notifyChanged(Notification msg) {
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/validation/ProfileSwitchValidator.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/validation/ProfileSwitchValidator.java
new file mode 100644
index 00000000000..17c4da8cae7
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/internal/validation/ProfileSwitchValidator.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.uml.modelrepair.internal.validation;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.ErrorDialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.window.Window;
+import org.eclipse.papyrus.uml.modelrepair.Activator;
+import org.eclipse.papyrus.uml.modelrepair.validation.IProfileSwitchPrecondition;
+import org.eclipse.papyrus.uml.modelrepair.validation.ProfileSwitchContext;
+import org.eclipse.swt.widgets.Composite;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+
+/**
+ * This is the ProfileSwitchValidator type. Enjoy.
+ */
+public class ProfileSwitchValidator {
+
+ private static final String EXT_PT = "profileSwitchPreconditions"; //$NON-NLS-1$
+
+ private static final String E_PRECONDITION = "precondition"; //$NON-NLS-1$
+
+ private static final String A_CLASS = "class"; //$NON-NLS-1$
+
+ private final List<IProfileSwitchPrecondition> preconditions;
+
+ public ProfileSwitchValidator() {
+ super();
+
+ preconditions = loadPreconditions();
+ }
+
+ public boolean validate(final ProfileSwitchContext ctx) {
+ final boolean[] result = { true };
+
+ if(!preconditions.isEmpty()) {
+ List<IStatus> statuses = Lists.newArrayListWithCapacity(preconditions.size());
+
+ for(IProfileSwitchPrecondition next : preconditions) {
+ try {
+ IStatus status = next.validateProfileSwitch(ctx);
+
+ if((status != null) && !status.isOK()) {
+ statuses.add(status);
+ }
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in profile switch pre-condition.", e); //$NON-NLS-1$
+ }
+ }
+
+ final IStatus status = statuses.isEmpty() ? Status.OK_STATUS : (statuses.size() == 1) ? statuses.get(0) : new MultiStatus(Activator.PLUGIN_ID, 0, Iterables.toArray(statuses, IStatus.class), "Problems in profile switch initial conditions check.", null);
+
+ switch(status.getSeverity()) {
+ case IStatus.OK:
+ case IStatus.INFO:
+ // All's well. Don't bother the user.
+ break;
+ case IStatus.WARNING:
+ // Get confirmation before proceeding
+ final ErrorDialog dlg = new ErrorDialog(ctx.getShell(), "Profile Switch", "Profile switch initial conditions check found problems in the model that may cause the switch to fail or be incomplete. Are you sure you want to proceed?", status, IStatus.INFO | IStatus.WARNING) {
+
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ createDetailsButton(parent);
+ createButton(parent, IDialogConstants.YES_ID, IDialogConstants.YES_LABEL, false);
+ createButton(parent, IDialogConstants.NO_ID, IDialogConstants.NO_LABEL, true);
+ }
+
+ @Override
+ protected void buttonPressed(int id) {
+ switch(id) {
+ case IDialogConstants.YES_ID:
+ setReturnCode(OK);
+ close();
+ break;
+ case IDialogConstants.NO_ID:
+ setReturnCode(CANCEL);
+ close();
+ break;
+ default:
+ super.buttonPressed(id);
+ break;
+ }
+ }
+ };
+
+ ctx.getShell().getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ result[0] = dlg.open() == Window.OK;
+ }
+ });
+ break;
+ default:
+ // Errors. Don't proceed
+ ctx.getShell().getDisplay().syncExec(new Runnable() {
+
+ public void run() {
+ result[0] = false;
+ ErrorDialog.openError(ctx.getShell(), "Profile Switch", "Profile switch cannot be performed until problems in the model are corrected.", status);
+ }
+ });
+ break;
+ }
+ }
+
+ return result[0];
+ }
+
+ private static List<IProfileSwitchPrecondition> loadPreconditions() {
+ List<IProfileSwitchPrecondition> result = Lists.newArrayList();
+
+ for(IConfigurationElement next : Platform.getExtensionRegistry().getConfigurationElementsFor(Activator.PLUGIN_ID, EXT_PT)) {
+ if(E_PRECONDITION.equals(next.getName())) {
+ try {
+ result.add((IProfileSwitchPrecondition)next.createExecutableExtension(A_CLASS));
+ } catch (Exception e) {
+ Activator.log.error("Invalid profile switch precondition extension in bundle " + next.getContributor().getName(), e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/ui/ZombieStereotypeDialogPresenter.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/ui/ZombieStereotypeDialogPresenter.java
index 2ebb808daaa..3512627e1ce 100644
--- a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/ui/ZombieStereotypeDialogPresenter.java
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/ui/ZombieStereotypeDialogPresenter.java
@@ -13,6 +13,9 @@
package org.eclipse.papyrus.uml.modelrepair.ui;
import java.util.List;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@@ -50,6 +53,12 @@ public class ZombieStereotypeDialogPresenter {
private Runnable presentation;
+ private final Lock lock = new ReentrantLock();
+
+ private final Condition pendingCond = lock.newCondition();
+
+ private volatile boolean pending = false;
+
public ZombieStereotypeDialogPresenter(Shell parentShell, ModelSet modelSet) {
super();
@@ -58,9 +67,12 @@ public class ZombieStereotypeDialogPresenter {
}
public void dispose() {
- synchronized(zombieDescriptors) {
+ lock.lock();
+ try {
zombieDescriptors.clear();
presentation = null;
+ } finally {
+ lock.unlock();
}
}
@@ -69,41 +81,78 @@ public class ZombieStereotypeDialogPresenter {
}
public void addZombies(ZombieStereotypesDescriptor zombies) {
- synchronized(zombieDescriptors) {
+ lock.lock();
+ try {
zombieDescriptors.add(zombies);
if(presentation == null) {
+ internalSetPending(true);
+
presentation = new Runnable() {
public void run() {
List<ZombieStereotypesDescriptor> zombies;
- synchronized(zombieDescriptors) {
+ lock.lock();
+ try {
if(presentation != this) {
- // I have been cancelled
+ internalSetPending(false);
return;
}
zombies = ImmutableList.copyOf(zombieDescriptors);
dispose();
+ } finally {
+ lock.unlock();
}
- if(!zombies.isEmpty()) {
- try {
- ZombieStereotypesDialog zombieDialog = new ZombieStereotypesDialog(parentShell, modelSet, zombies);
- dynamicProfileSupplier.setParentWindow(zombieDialog);
- zombieDialog.setBlockOnOpen(true);
- zombieDialog.open();
- } catch (ServiceException e) {
- StatusManager.getManager().handle(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to open model repair dialog.", e), StatusManager.SHOW);
- } finally {
- dynamicProfileSupplier.setParentWindow(null);
+ try {
+ if(!zombies.isEmpty()) {
+ try {
+ ZombieStereotypesDialog zombieDialog = new ZombieStereotypesDialog(parentShell, modelSet, zombies);
+ dynamicProfileSupplier.setParentWindow(zombieDialog);
+ zombieDialog.setBlockOnOpen(true);
+ zombieDialog.open();
+ } catch (ServiceException e) {
+ StatusManager.getManager().handle(new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Failed to open model repair dialog.", e), StatusManager.SHOW);
+ } finally {
+ dynamicProfileSupplier.setParentWindow(null);
+ }
}
+ } finally {
+ internalSetPending(false);
}
}
};
parentShell.getDisplay().asyncExec(presentation);
}
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ public boolean isPending() {
+ return pending;
+ }
+
+ public void awaitPending(boolean expected) throws InterruptedException {
+ lock.lock();
+ try {
+ while(pending != expected) {
+ pendingCond.await();
+ }
+ } finally {
+ lock.unlock();
+ }
+ }
+
+ private void internalSetPending(boolean pending) {
+ lock.lock();
+ try {
+ this.pending = pending;
+ pendingCond.signalAll();
+ } finally {
+ lock.unlock();
}
}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/IProfileSwitchPrecondition.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/IProfileSwitchPrecondition.java
new file mode 100644
index 00000000000..29c174f6feb
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/IProfileSwitchPrecondition.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.uml.modelrepair.validation;
+
+import org.eclipse.core.runtime.IStatus;
+
+
+/**
+ * A pluggable validation check that runs before the profile switch operation is performed.
+ */
+public interface IProfileSwitchPrecondition {
+
+ /**
+ * Validates the profile switch operation described by the given context. This method is invoked on a background thread, so any UI
+ * interaction performed by the pre-condition check needs to take that into account.
+ *
+ * @param ctx
+ * the profile-switch context
+ *
+ * @return a status describing the readiness of the context for a profile switch. An error status will prevent the profile switch from proceeding.
+ * A warning status will be reported to the user and require confirmation before proceeding with the profile switch. An informational
+ * status may be displayed to the user but needs not be acknowledged
+ */
+ IStatus validateProfileSwitch(ProfileSwitchContext ctx);
+}
diff --git a/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/ProfileSwitchContext.java b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/ProfileSwitchContext.java
new file mode 100644
index 00000000000..4b242da5097
--- /dev/null
+++ b/plugins/uml/org.eclipse.papyrus.uml.modelrepair/src/org/eclipse/papyrus/uml/modelrepair/validation/ProfileSwitchContext.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2014 CEA 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:
+ * Christian W. Damus (CEA) - Initial API and implementation
+ *
+ */
+package org.eclipse.papyrus.uml.modelrepair.validation;
+
+import java.util.Collection;
+
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.uml2.uml.Package;
+import org.eclipse.uml2.uml.Profile;
+
+
+/**
+ * The context in which a Profile Switch operation is being performed.
+ */
+public class ProfileSwitchContext {
+ private final ModelSet modelSet;
+ private final TransactionalEditingDomain editingDomain;
+ private final Package package_;
+ private final Collection<Profile> appliedProfiles;
+ private final Shell shell;
+
+ public ProfileSwitchContext(Shell shell, ModelSet modelSet, TransactionalEditingDomain editingDomain, Package package_, Collection<Profile> appliedProfiles) {
+ super();
+ this.shell = shell;
+ this.modelSet = modelSet;
+ this.editingDomain = editingDomain;
+ this.package_ = package_;
+ this.appliedProfiles = appliedProfiles;
+ }
+
+ public ModelSet getModelSet() {
+ return modelSet;
+ }
+
+ public TransactionalEditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ public Package getPackage_() {
+ return package_;
+ }
+
+ public Collection<Profile> getAppliedProfiles() {
+ return appliedProfiles;
+ }
+
+ public Shell getShell() {
+ return shell;
+ }
+
+}

Back to the top