Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian W. Damus2014-02-13 21:28:59 +0000
committerChristian W. Damus2014-02-20 19:38:53 +0000
commit4d9b5f1786a1a311b4df7379c419d56a5d58bd74 (patch)
treea721388b28551912f2e3d3f1e7271877b6f9d7b1 /plugins/infra
parentb1841729809bb3a0d045f72ae1ef17056522d3e3 (diff)
downloadorg.eclipse.papyrus-4d9b5f1786a1a311b4df7379c419d56a5d58bd74.tar.gz
org.eclipse.papyrus-4d9b5f1786a1a311b4df7379c419d56a5d58bd74.tar.xz
org.eclipse.papyrus-4d9b5f1786a1a311b4df7379c419d56a5d58bd74.zip
323802: [General] Papyrus shall provide a read only mode
https://bugs.eclipse.org/bugs/show_bug.cgi?id=323802 Implement a custom TransactionChangeRecorder that aborting the transaction if a read-only object is modified. Add a new extension point oep.infra.gmfdiag.commands.historyListeners for registration of listeners to be added to the Papyrus operation history. Implement a listener that detects operations that failed because of rollback and presents a status dialog explaining the rollback. Add a new label provider for EMF Resources to support presentation of the rollback dialog when an affected object is a resource.
Diffstat (limited to 'plugins/infra')
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IRollbackStatus.java41
-rw-r--r--plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/RollbackStatus.java158
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java58
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml4
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/Messages.java26
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/messages.properties19
-rw-r--r--plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/ResourceFilteredLabelProvider.java135
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.properties6
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.xml2
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/schema/historyListeners.exsd91
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/CheckedOperationHistory.java23
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml356
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/listener/RollbackNotificationHistoryListener.java119
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/Messages.java28
-rw-r--r--plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/messages.properties20
15 files changed, 906 insertions, 180 deletions
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IRollbackStatus.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IRollbackStatus.java
new file mode 100644
index 00000000000..8451f1ce2c6
--- /dev/null
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/IRollbackStatus.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.infra.core.resource;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IStatus;
+
+
+/**
+ * A specialized status that indicates that execution of a command was rolled back. Additional context that it provides includes model elements that
+ * triggered rollback.
+ */
+public interface IRollbackStatus extends IStatus {
+
+ /** A {@linkplain IStatus#getCode() status code} indicating that the reason for the rollback could not be determined or is otherwise unclassified. */
+ int UNKNOWN_REASON = 0;
+
+ /** A {@linkplain IStatus#getCode() status code} indicating that rollback occurred because of an uncaught exception in command execution. */
+ int UNCAUGHT_EXCEPTION = 1;
+
+ /** A {@linkplain IStatus#getCode() status code} indicating that rollback occurred to revert modifications to an object that is read-only. */
+ int READ_ONLY_OBJECT = 2;
+
+ /**
+ * Queries the set of objects (if known) that caused the rollback, such as because they are are {@linkplain #READ_ONLY_OBJECT read-only}.
+ *
+ * @return the set (possibly empty, but not {@code null}) of objects that caused the rollback
+ */
+ Collection<?> getCausalObjects();
+}
diff --git a/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/RollbackStatus.java b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/RollbackStatus.java
new file mode 100644
index 00000000000..0f78f43371a
--- /dev/null
+++ b/plugins/infra/core/org.eclipse.papyrus.infra.core/src/org/eclipse/papyrus/infra/core/resource/RollbackStatus.java
@@ -0,0 +1,158 @@
+/*
+ * 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.infra.core.resource;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.MultiStatus;
+import org.eclipse.core.runtime.Status;
+
+import com.google.common.collect.ImmutableSet;
+
+
+/**
+ * An useful default implementation of the {@link IRollbackStatus} interface.
+ * Rollback is always an {@linkplain IStatus#ERROR error} condition, so the constructors do not require the severity.
+ */
+public class RollbackStatus extends Status implements IRollbackStatus {
+
+ private final Set<?> causalObjects;
+
+ /**
+ * Initializes me with the source bundle ID, reason code, and message.
+ *
+ * @param pluginId
+ * the source bundle ID
+ * @param reason
+ * the {@linkplain IRollbackStatus#UNKNOWN_REASON reason code} indicating why rollback occurred
+ * @param message
+ * the human-readable message
+ */
+ public RollbackStatus(String pluginId, int reason, String message) {
+ this(pluginId, reason, message, null, null);
+ }
+
+ /**
+ * Initializes me with the source bundle ID, reason code, and message.
+ *
+ * @param pluginId
+ * the source bundle ID
+ * @param reason
+ * the {@linkplain IRollbackStatus#UNKNOWN_REASON reason code} indicating why rollback occurred
+ * @param message
+ * the human-readable message
+ * @param exception
+ * an exception that somehow caused the rollback to occur
+ */
+ public RollbackStatus(String pluginId, int reason, String message, Throwable exception) {
+ this(pluginId, reason, message, null, exception);
+ }
+
+ /**
+ * Initializes me with the source bundle ID, reason code, and message.
+ *
+ * @param pluginId
+ * the source bundle ID
+ * @param reason
+ * the {@linkplain IRollbackStatus#UNKNOWN_REASON reason code} indicating why rollback occurred
+ * @param message
+ * the human-readable message
+ * @param causalObjects
+ * the objects that caused the rollback (may be {@code null} if not needed)
+ */
+ public RollbackStatus(String pluginId, int reason, String message, Iterable<?> causalObjects) {
+ this(pluginId, reason, message, causalObjects, null);
+ }
+
+ /**
+ * Initializes me with the source bundle ID, reason code, and message.
+ *
+ * @param pluginId
+ * the source bundle ID
+ * @param reason
+ * the {@linkplain IRollbackStatus#UNKNOWN_REASON reason code} indicating why rollback occurred
+ * @param message
+ * the human-readable message
+ * @param causalObjects
+ * the objects that caused the rollback (may be {@code null} if not needed)
+ * @param exception
+ * an exception that somehow caused the rollback to occur
+ */
+ public RollbackStatus(String pluginId, int reason, String message, Iterable<?> causalObjects, Throwable exception) {
+ super(IStatus.ERROR, pluginId, reason, message, exception);
+
+ this.causalObjects = (causalObjects == null) ? Collections.emptySet() : ImmutableSet.copyOf(causalObjects);
+ }
+
+ @Override
+ public Collection<?> getCausalObjects() {
+ return causalObjects;
+ }
+
+ /**
+ * Dig through a possibly {@linkplain #isMultiStatus() multi} status to get a rollback status out of it.
+ *
+ * @param status
+ * a status
+ *
+ * @return the embedded rollback status, if any (which could be the {@code status}, itself, in the simplest case)
+ */
+ public static IRollbackStatus findRollbackStatus(IStatus status) {
+ IRollbackStatus result = null;
+
+ if(status instanceof IRollbackStatus) {
+ result = (IRollbackStatus)status;
+ } else if(status.isMultiStatus()) {
+ IStatus[] children = status.getChildren();
+ for(int i = 0; (result == null) && (i < children.length); i++) {
+ result = findRollbackStatus(children[i]);
+ }
+ }
+
+ return result;
+ }
+
+ //
+ // Nested types
+ //
+
+ public static class Multi extends MultiStatus implements IRollbackStatus {
+
+ private IRollbackStatus rollback;
+
+ public Multi(String pluginId, int code, IStatus[] newChildren, String message, Throwable exception) {
+ super(pluginId, code, newChildren, message, exception);
+ }
+
+ public Multi(String pluginId, int code, String message, Throwable exception) {
+ super(pluginId, code, message, exception);
+ }
+
+ IRollbackStatus getRollback() {
+ if(rollback == null) {
+ rollback = findRollbackStatus(this);
+ }
+
+ return rollback;
+ }
+
+ @Override
+ public Collection<?> getCausalObjects() {
+ IRollbackStatus rollback = getRollback();
+ return (rollback == null) ? Collections.emptySet() : rollback.getCausalObjects();
+ }
+ }
+}
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java
index 3beab6d2fac..e97955ca0b6 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf.readonly/src/org/eclipse/papyrus/infra/emf/readonly/PapyrusROTransactionalEditingDomain.java
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2011, 2013 Atos Origin, CEA, and others.
+ * Copyright (c) 2011, 2014 Atos Origin, CEA, and others.
*
*
* All rights reserved. This program and the accompanying materials
@@ -10,17 +10,27 @@
* Contributors:
* Mathieu Velten (Atos Origin) mathieu.velten@atosorigin.com - Initial API and implementation
* Christian W. Damus (CEA) - Support object-level read/write controls (CDO)
+ * Christian W. Damus (CEA) - bug 323802
*
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.readonly;
+import java.util.Collection;
+import java.util.Collections;
+
import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.transaction.NotificationFilter;
import org.eclipse.emf.transaction.TransactionalCommandStack;
+import org.eclipse.emf.transaction.impl.InternalTransaction;
+import org.eclipse.emf.transaction.impl.TransactionChangeRecorder;
import org.eclipse.emf.transaction.impl.TransactionalEditingDomainImpl;
+import org.eclipse.papyrus.infra.core.resource.IRollbackStatus;
+import org.eclipse.papyrus.infra.core.resource.RollbackStatus;
public class PapyrusROTransactionalEditingDomain extends TransactionalEditingDomainImpl {
@@ -40,6 +50,52 @@ public class PapyrusROTransactionalEditingDomain extends TransactionalEditingDom
public boolean isReadOnly(EObject eObject) {
return ReadOnlyManager.getReadOnlyHandler(this).isReadOnly(eObject).get();
}
+
+ @Override
+ protected TransactionChangeRecorder createChangeRecorder(ResourceSet rset) {
+ return new TransactionChangeRecorder(this, rset) {
+ @Override
+ protected void appendNotification(Notification notification) {
+ // Append to the transaction first
+ super.appendNotification(notification);
+
+ if (!NotificationFilter.READ.matches(notification)) {
+ // Check whether we are modifying a read-only object
+ assertNotReadOnly(notification.getNotifier());
+ }
+ }
+ };
+ }
+
+ protected void assertNotReadOnly(Object object) {
+ InternalTransaction tx = getActiveTransaction();
+
+ // If there's no transaction, then there will be nothing to roll back
+ if(tx != null) {
+ boolean readOnly;
+
+ // Check for Resource first because CDO resources *are* EObjects
+ if(object instanceof Resource) {
+ Resource.Internal resource = (Resource.Internal)object;
+ if(resource.isLoading()) {
+ // We must be able to modify read-only resources in order to load them
+ return;
+ }
+ readOnly = isReadOnly(resource);
+ } else if(object instanceof EObject) {
+ readOnly = isReadOnly((EObject)object);
+ } else {
+ // If it's not an EMF-managed object, we don't care
+ readOnly = false;
+ }
+
+ if(readOnly) {
+ String message = "Attempt to modify object(s) in a read-only model."; //$NON-NLS-1$
+ Collection<?> offenders = Collections.singleton(object);
+ tx.abort(new RollbackStatus(Activator.PLUGIN_ID, IRollbackStatus.READ_ONLY_OBJECT, message, offenders));
+ }
+ }
+ }
@Override
public void dispose() {
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml
index d9b6cb0f5d1..22c5b0373c6 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml
@@ -17,6 +17,10 @@
<extension
point="org.eclipse.papyrus.infra.services.labelprovider.labelProvider">
<labelProvider
+ priority="110"
+ provider="org.eclipse.papyrus.infra.emf.providers.ResourceFilteredLabelProvider">
+ </labelProvider>
+ <labelProvider
priority="100"
provider="org.eclipse.papyrus.infra.emf.providers.EMFFilteredLabelProvider">
</labelProvider>
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/Messages.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/Messages.java
index 04d8fa9b5a0..77ff3cbd56b 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/Messages.java
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/Messages.java
@@ -1,3 +1,16 @@
+/*
+ * Copyright (c) 2012, 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:
+ * Vincent Lorenzo (CEA LIST) - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 323802
+ *
+ */
package org.eclipse.papyrus.infra.emf.messages;
import org.eclipse.osgi.util.NLS;
@@ -6,7 +19,20 @@ public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.emf.messages.messages"; //$NON-NLS-1$
+ public static String ResourceFilteredLabelProvider_local;
+
+ public static String ResourceFilteredLabelProvider_localExt;
+
+ public static String ResourceFilteredLabelProvider_system;
+
+ public static String ResourceFilteredLabelProvider_systemExt;
+
+ public static String ResourceFilteredLabelProvider_workspace;
+
+ public static String ResourceFilteredLabelProvider_workspaceExt;
+
public static String UnsetCommand_UnsetCommand;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/messages.properties b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/messages.properties
index b5119e19f07..7a50929b818 100644
--- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/messages.properties
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/messages/messages.properties
@@ -1 +1,20 @@
+#
+# Copyright (c) 2012, 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:
+# Vincent Lorenzo (CEA LIST) - Initial API and implementation
+# Christian W. Damus (CEA) - bug 323802
+#
+
+ResourceFilteredLabelProvider_local=Local model file "{0}"
+ResourceFilteredLabelProvider_localExt=Local model file "{0}" ({1} component)
+ResourceFilteredLabelProvider_system=System resource "{0}"
+ResourceFilteredLabelProvider_systemExt=Resource "{0}"
+ResourceFilteredLabelProvider_workspace=Workspace model file "{0}"
+ResourceFilteredLabelProvider_workspaceExt=Workspace model file "{0}" ({1} component)
UnsetCommand_UnsetCommand=Unset Command
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/ResourceFilteredLabelProvider.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/ResourceFilteredLabelProvider.java
new file mode 100644
index 00000000000..b776f51de5a
--- /dev/null
+++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/providers/ResourceFilteredLabelProvider.java
@@ -0,0 +1,135 @@
+/*
+ * 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.infra.emf.providers;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.core.runtime.content.IContentType;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ContentHandler;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.JFaceResources;
+import org.eclipse.jface.resource.LocalResourceManager;
+import org.eclipse.jface.resource.ResourceManager;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.emf.Activator;
+import org.eclipse.papyrus.infra.emf.messages.Messages;
+import org.eclipse.papyrus.infra.services.labelprovider.service.IFilteredLabelProvider;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.IEditorDescriptor;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * A label provider for EMF {@link Resource}s.
+ */
+public class ResourceFilteredLabelProvider extends EMFLabelProvider implements IFilteredLabelProvider {
+
+ private ResourceManager images;
+
+ public boolean accept(Object element) {
+ return element instanceof Resource;
+ }
+
+ @Override
+ public void dispose() {
+ if(images != null) {
+ images.dispose();
+ images = null;
+ }
+
+ super.dispose();
+ }
+
+ @Override
+ public String getText(Object element) {
+ return (element instanceof Resource) ? getText((Resource)element) : super.getText(element);
+ }
+
+ protected String getText(Resource resource) {
+ String result;
+
+ URI uri = resource.getURI();
+
+ if(uri.isPlatformResource()) {
+ String ext = uri.fileExtension();
+ if(ext == null) {
+ result = NLS.bind(Messages.ResourceFilteredLabelProvider_workspace, uri.toPlatformString(true));
+ } else {
+ result = NLS.bind(Messages.ResourceFilteredLabelProvider_workspaceExt, uri.toPlatformString(true), uri.fileExtension());
+ }
+ } else if(uri.isFile()) {
+ String ext = uri.fileExtension();
+ if(ext == null) {
+ result = NLS.bind(Messages.ResourceFilteredLabelProvider_local, uri.toFileString());
+ } else {
+ result = NLS.bind(Messages.ResourceFilteredLabelProvider_localExt, uri.toFileString(), uri.fileExtension());
+ }
+ } else if(uri.isHierarchical()) {
+ result = NLS.bind(Messages.ResourceFilteredLabelProvider_system, uri.lastSegment());
+ } else {
+ result = NLS.bind(Messages.ResourceFilteredLabelProvider_systemExt, uri.toString());
+ }
+
+ return result;
+ }
+
+ @Override
+ public Image getImage(Object element) {
+ return (element instanceof Resource) ? getImage((Resource)element) : super.getImage(element);
+ }
+
+ protected Image getImage(Resource resource) {
+ URI uri = resource.getURI();
+ URIConverter converter = (resource.getResourceSet() == null) ? URIConverter.INSTANCE : resource.getResourceSet().getURIConverter();
+
+ IContentType contentType = null;
+ try {
+ Map<String, ?> description = converter.contentDescription(uri, null);
+ contentType = (description.get(ContentHandler.CONTENT_TYPE_PROPERTY) == null) ? null : Platform.getContentTypeManager().getContentType((String)description.get(ContentHandler.CONTENT_TYPE_PROPERTY));
+ } catch (IOException e) {
+ Activator.log.error(e);
+ }
+
+ IEditorDescriptor[] editors;
+ if(contentType != null) {
+ editors = PlatformUI.getWorkbench().getEditorRegistry().getEditors(uri.lastSegment(), contentType);
+ } else {
+ editors = PlatformUI.getWorkbench().getEditorRegistry().getEditors(uri.lastSegment());
+ }
+
+ ImageDescriptor result = null;
+ for(int i = 0; (result == null) && (i < editors.length); i++) {
+ result = editors[0].getImageDescriptor();
+ }
+
+ return convert(result);
+ }
+
+ protected Image convert(ImageDescriptor descriptor) {
+ Image result = null;
+
+ if(descriptor != null) {
+ if(images == null) {
+ images = new LocalResourceManager(JFaceResources.getResources());
+ }
+
+ result = (Image)images.get(descriptor);
+ }
+
+ return result;
+ }
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.properties b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.properties
index 7b616a5ac05..7324564d6df 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.properties
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.properties
@@ -1,5 +1,5 @@
#################################################################################
-# Copyright (c) 2011 Atos.
+# Copyright (c) 2011, 2014 Atos, 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
@@ -7,6 +7,10 @@
#
# Contributors:
# Vincent Hemery - Initial API and implementation
+# Christian W. Damus (CEA) - bug 323802
+#
##################################################################################
pluginName=Papyrus Commands Tools (Incubation)
providerName=Eclipse Modeling Project
+
+historyListeners-extpt=Operation History Listeners
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.xml b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.xml
index f8f60be4ccb..98f0fc190ef 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.xml
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/plugin.xml
@@ -2,6 +2,8 @@
<?eclipse version="3.4"?>
<plugin>
<extension-point id="operationApprover" name="operationApprover" schema="schema/operationApprover.exsd"/>
+ <extension-point id="historyListeners" name="%historyListeners-extpt" schema="schema/historyListeners.exsd"/>
+
<extension
point="org.eclipse.ui.handlers">
<handler
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/schema/historyListeners.exsd b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/schema/historyListeners.exsd
new file mode 100644
index 00000000000..16f042831a6
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/schema/historyListeners.exsd
@@ -0,0 +1,91 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.papyrus.infra.gmfdiag.commands" xmlns="http://www.w3.org/2001/XMLSchema">
+<annotation>
+ <appinfo>
+ <meta.schema plugin="org.eclipse.papyrus.infra.gmfdiag.commands" id="historyListeners" name="historyListeners"/>
+ </appinfo>
+ <documentation>
+ Registration of history listeners to be attached to the operation history used by the Papyrus GMF diagrams (and transactional editing domains in general).
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <annotation>
+ <appinfo>
+ <meta.element />
+ </appinfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ <element ref="historyListener" minOccurs="1" maxOccurs="unbounded"/>
+ </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="historyListener">
+ <complexType>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ The Java class implementing of the history listener.
+ </documentation>
+ <appinfo>
+ <meta.attribute kind="java" basedOn=":org.eclipse.core.commands.operations.IOperationHistoryListener"/>
+ </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/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/CheckedOperationHistory.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/CheckedOperationHistory.java
index 5973347c169..179be3fdc44 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/CheckedOperationHistory.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.commands/src/org/eclipse/papyrus/commands/CheckedOperationHistory.java
@@ -9,7 +9,7 @@
*
* Contributors:
* Mathieu Velten (Atos) - Initial API and implementation
- * Christian W. Damus (CEA) - bug 357250
+ * Christian W. Damus (CEA) - bug 357250, bug 323802
*
*****************************************************************************/
package org.eclipse.papyrus.commands;
@@ -80,8 +80,8 @@ public class CheckedOperationHistory implements IOperationHistory {
if("operationApprover".equals(elem.getName())) { //$NON-NLS-1$
try {
ApproverPriorityPair approverPriorityPair = new ApproverPriorityPair();
- approverPriorityPair.approver = (IOperationApprover2)elem.createExecutableExtension("class");
- approverPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority"));
+ approverPriorityPair.approver = (IOperationApprover2)elem.createExecutableExtension("class"); //$NON-NLS-1$
+ approverPriorityPair.priority = Integer.parseInt(elem.getAttribute("priority")); //$NON-NLS-1$
approverPriorityPairs.add(approverPriorityPair);
} catch (Exception e) {
@@ -101,6 +101,8 @@ public class CheckedOperationHistory implements IOperationHistory {
private CheckedOperationHistory() {
history = OperationHistoryFactory.getOperationHistory();
+
+ addRegisteredListeners(history);
}
/*
@@ -218,6 +220,21 @@ public class CheckedOperationHistory implements IOperationHistory {
return history.redo(context, monitor, info);
}
+ private static void addRegisteredListeners(IOperationHistory history) {
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(Activator.PLUGIN_ID, "historyListeners"); //$NON-NLS-1$
+
+ for(IConfigurationElement elem : configElements) {
+ if("historyListener".equals(elem.getName())) { //$NON-NLS-1$
+ try {
+ IOperationHistoryListener listener = (IOperationHistoryListener)elem.createExecutableExtension("class"); //$NON-NLS-1$
+ history.addOperationHistoryListener(listener);
+ } catch (Exception e) {
+ Activator.log.error("Uncaught exception in instantiation of operation history listener.", e); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+
// all the following methods are pure delegation
public IStatus undoOperation(IUndoableOperation operation, IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml
index 7021ed3753b..ac6c78cbdbf 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/plugin.xml
@@ -1,179 +1,179 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<?eclipse version="3.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.0"?>
+
+<plugin>
+ <extension-point id="nestedEditor" name="NestedEditor" schema="schema/nestedEditor.exsd"/>
+ <extension-point id="initializeView" name="initializeView" schema="schema/initializeView.exsd"/>
+ <extension-point id="shapeProvider" name="ShapeProvider" schema="schema/shapeProvider.exsd"/>
+ <extension-point id="notationTypesMapping" name="notationTypesMapping" schema="schema/notationTypesMapping.exsd"/>
+ <extension-point id="svgPostProcessors" name="svgPostProcessors" schema="schema/svgPostProcessors.exsd"/>
+ <extension-point id="pasteCommandProvider" name="pasteCommandProvider" schema="schema/pasteCommandProvider.exsd"/>
-<plugin>
- <extension-point id="nestedEditor" name="NestedEditor" schema="schema/nestedEditor.exsd"/>
- <extension-point id="initializeView" name="initializeView" schema="schema/initializeView.exsd"/>
- <extension-point id="shapeProvider" name="ShapeProvider" schema="schema/shapeProvider.exsd"/>
- <extension-point id="notationTypesMapping" name="notationTypesMapping" schema="schema/notationTypesMapping.exsd"/>
- <extension-point id="svgPostProcessors" name="svgPostProcessors" schema="schema/svgPostProcessors.exsd"/>
- <extension-point id="pasteCommandProvider" name="pasteCommandProvider" schema="schema/pasteCommandProvider.exsd"/>
-
-<extension
- point="org.eclipse.ui.handlers">
- <handler
- class="org.eclipse.papyrus.infra.gmfdiag.common.handler.RefreshHandler"
- commandId="org.eclipse.ui.file.refresh">
- <activeWhen>
- <with
- variable="activePartId">
- <equals
- value="org.eclipse.papyrus.infra.core.papyrusEditor">
- </equals>
- </with>
- </activeWhen>
- </handler>
-</extension>
-<extension
- point="org.eclipse.ui.menus">
- <menuContribution
- allPopups="false"
- locationURI="toolbar:org.eclipes.papyrus.menu.toolbar">
- <command
- commandId="org.eclipse.ui.file.refresh"
- icon="icons/refresh.gif"
- label="Refresh"
- style="push"
- tooltip="Refresh the current diagram">
- <visibleWhen
- checkEnabled="false">
- <with
- variable="activeEditorId">
- <equals
- value="org.eclipse.papyrus.infra.core.papyrusEditor">
- </equals>
- </with>
- </visibleWhen>
- </command>
- </menuContribution>
-</extension>
-<extension
- point="org.eclipse.ui.preferencePages">
- <page
- category="org.eclipse.papyrus.infra.core.sasheditor.preferences.generalcategory"
- class="org.eclipse.papyrus.infra.gmfdiag.common.preferences.ConnectionToolPreferencePage"
- id="org.eclipse.papyrus.infra.gmfdiag.common.connectionTools"
- name="Connection Tools">
- </page>
-</extension>
-<extension
- point="org.eclipse.core.runtime.preferences">
- <initializer
- class="org.eclipse.papyrus.infra.gmfdiag.common.preferences.ConnectionToolPreferenceInitializer">
- </initializer>
-</extension>
- <extension
- point="org.eclipse.papyrus.infra.core.model">
- <model
- classname="org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel"
- description="Model for notation">
- </model>
- </extension>
-
-
- <extension
- point="org.eclipse.emf.ecore.extension_parser">
- <parser
- class="org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory"
- type="notation">
- </parser>
- </extension>
-<extension
- point="org.eclipse.papyrus.infra.core.service">
- <serviceFactory
- classname="org.eclipse.papyrus.infra.gmfdiag.common.undocontext.UndoContextServiceFactory"
- description="The shared IUndoContext used to tag command in the CommandStack"
- id="org.eclipse.core.commands.operations.IUndoContext"
- priority="1"
- startKind="lazy">
- <dependsOn
- serviceKeyRef="org.eclipse.emf.transaction.TransactionalEditingDomain">
- </dependsOn>
- </serviceFactory>
- <service
- classname="org.eclipse.papyrus.infra.gmfdiag.common.DefaultGraphicalEditorSupport"
- description="The default diagram editor support implementation."
- id="org.eclipse.papyrus.infra.gmfdiag.common.IGraphicalEditorSupport"
- priority="1"
- startKind="lazy">
- </service>
- </extension>
-<extension
- point="org.eclipse.papyrus.infra.services.labelprovider.labelProvider">
- <labelProvider
- priority="40"
- provider="org.eclipse.papyrus.infra.gmfdiag.common.providers.NotationFilteredLabelProvider">
- </labelProvider>
-</extension>
-<extension
- point="org.eclipse.gmf.runtime.diagram.ui.decoratorProviders">
- <decoratorProvider
- class="org.eclipse.papyrus.infra.gmfdiag.common.providers.ShapeDecoratorProvider">
- <Priority
- name="Lowest">
- </Priority>
- </decoratorProvider>
-</extension>
-<extension
- point="org.eclipse.core.runtime.adapters">
- <factory
- adaptableType="org.eclipse.gmf.runtime.notation.Diagram"
- class="org.eclipse.papyrus.infra.gmfdiag.common.adapter.DiagramAdapterFactory">
- <adapter
- type="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IOpenable">
- </adapter>
- </factory>
-</extension>
-
-<!-- ElementType bindings for diagram duplication with paste command -->
- <extension
- point="org.eclipse.gmf.runtime.emf.type.core.elementTypes">
- <metamodel
- nsURI="http://www.eclipse.org/emf/2002/Ecore">
- <adviceBinding
- class="org.eclipse.papyrus.infra.gmfdiag.common.advice.GMFDiagramDuplicateEditHelperAdvice"
- id="org.eclipse.papyrus.infra.gmfdiag.common.advice.GMFDiagramDuplicateEditHelperAdvice"
- inheritance="none"
- typeId="*">
- </adviceBinding>
- </metamodel>
- </extension>
-
-<extension point="org.eclipse.gmf.runtime.emf.type.core.elementTypeBindings">
-
- <!-- Bindings declaration -->
- <binding context="org.eclipse.papyrus.infra.services.edit.TypeContext">
- <advice ref="org.eclipse.papyrus.infra.gmfdiag.common.advice.GMFDiagramDuplicateEditHelperAdvice" />
- </binding>
-</extension>
-<extension
- point="org.eclipse.core.expressions.propertyTesters">
- <propertyTester
- class="org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramPropertyTester"
- id="org.eclipse.papyrus.infra.gmfdiag.common.diagram.tester"
- namespace="org.eclipse.papyrus.infra.gmfdiag.common.diagram.tester"
- properties="isDiagramEditor"
- type="org.eclipse.jface.viewers.IStructuredSelection">
- </propertyTester>
- <propertyTester
- class="org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramPropertyTester"
- id="org.eclipse.papyrus.infra.gmfdiag.common.diagram.context.tester"
- namespace="org.eclipse.papyrus.infra.gmfdiag.common.diagram.context.tester"
- properties="isGmfDiagramContextActive"
- type="java.util.Collection">
+<extension
+ point="org.eclipse.ui.handlers">
+ <handler
+ class="org.eclipse.papyrus.infra.gmfdiag.common.handler.RefreshHandler"
+ commandId="org.eclipse.ui.file.refresh">
+ <activeWhen>
+ <with
+ variable="activePartId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </activeWhen>
+ </handler>
+</extension>
+<extension
+ point="org.eclipse.ui.menus">
+ <menuContribution
+ allPopups="false"
+ locationURI="toolbar:org.eclipes.papyrus.menu.toolbar">
+ <command
+ commandId="org.eclipse.ui.file.refresh"
+ icon="icons/refresh.gif"
+ label="Refresh"
+ style="push"
+ tooltip="Refresh the current diagram">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="activeEditorId">
+ <equals
+ value="org.eclipse.papyrus.infra.core.papyrusEditor">
+ </equals>
+ </with>
+ </visibleWhen>
+ </command>
+ </menuContribution>
+</extension>
+<extension
+ point="org.eclipse.ui.preferencePages">
+ <page
+ category="org.eclipse.papyrus.infra.core.sasheditor.preferences.generalcategory"
+ class="org.eclipse.papyrus.infra.gmfdiag.common.preferences.ConnectionToolPreferencePage"
+ id="org.eclipse.papyrus.infra.gmfdiag.common.connectionTools"
+ name="Connection Tools">
+ </page>
+</extension>
+<extension
+ point="org.eclipse.core.runtime.preferences">
+ <initializer
+ class="org.eclipse.papyrus.infra.gmfdiag.common.preferences.ConnectionToolPreferenceInitializer">
+ </initializer>
+</extension>
+ <extension
+ point="org.eclipse.papyrus.infra.core.model">
+ <model
+ classname="org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel"
+ description="Model for notation">
+ </model>
+ </extension>
+
+
+ <extension
+ point="org.eclipse.emf.ecore.extension_parser">
+ <parser
+ class="org.eclipse.gmf.runtime.emf.core.resources.GMFResourceFactory"
+ type="notation">
+ </parser>
+ </extension>
+<extension
+ point="org.eclipse.papyrus.infra.core.service">
+ <serviceFactory
+ classname="org.eclipse.papyrus.infra.gmfdiag.common.undocontext.UndoContextServiceFactory"
+ description="The shared IUndoContext used to tag command in the CommandStack"
+ id="org.eclipse.core.commands.operations.IUndoContext"
+ priority="1"
+ startKind="lazy">
+ <dependsOn
+ serviceKeyRef="org.eclipse.emf.transaction.TransactionalEditingDomain">
+ </dependsOn>
+ </serviceFactory>
+ <service
+ classname="org.eclipse.papyrus.infra.gmfdiag.common.DefaultGraphicalEditorSupport"
+ description="The default diagram editor support implementation."
+ id="org.eclipse.papyrus.infra.gmfdiag.common.IGraphicalEditorSupport"
+ priority="1"
+ startKind="lazy">
+ </service>
+ </extension>
+<extension
+ point="org.eclipse.papyrus.infra.services.labelprovider.labelProvider">
+ <labelProvider
+ priority="40"
+ provider="org.eclipse.papyrus.infra.gmfdiag.common.providers.NotationFilteredLabelProvider">
+ </labelProvider>
+</extension>
+<extension
+ point="org.eclipse.gmf.runtime.diagram.ui.decoratorProviders">
+ <decoratorProvider
+ class="org.eclipse.papyrus.infra.gmfdiag.common.providers.ShapeDecoratorProvider">
+ <Priority
+ name="Lowest">
+ </Priority>
+ </decoratorProvider>
+</extension>
+<extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.gmf.runtime.notation.Diagram"
+ class="org.eclipse.papyrus.infra.gmfdiag.common.adapter.DiagramAdapterFactory">
+ <adapter
+ type="org.eclipse.papyrus.infra.core.sasheditor.di.contentprovider.IOpenable">
+ </adapter>
+ </factory>
+</extension>
+
+<!-- ElementType bindings for diagram duplication with paste command -->
+ <extension
+ point="org.eclipse.gmf.runtime.emf.type.core.elementTypes">
+ <metamodel
+ nsURI="http://www.eclipse.org/emf/2002/Ecore">
+ <adviceBinding
+ class="org.eclipse.papyrus.infra.gmfdiag.common.advice.GMFDiagramDuplicateEditHelperAdvice"
+ id="org.eclipse.papyrus.infra.gmfdiag.common.advice.GMFDiagramDuplicateEditHelperAdvice"
+ inheritance="none"
+ typeId="*">
+ </adviceBinding>
+ </metamodel>
+ </extension>
+
+<extension point="org.eclipse.gmf.runtime.emf.type.core.elementTypeBindings">
+
+ <!-- Bindings declaration -->
+ <binding context="org.eclipse.papyrus.infra.services.edit.TypeContext">
+ <advice ref="org.eclipse.papyrus.infra.gmfdiag.common.advice.GMFDiagramDuplicateEditHelperAdvice" />
+ </binding>
+</extension>
+<extension
+ point="org.eclipse.core.expressions.propertyTesters">
+ <propertyTester
+ class="org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramPropertyTester"
+ id="org.eclipse.papyrus.infra.gmfdiag.common.diagram.tester"
+ namespace="org.eclipse.papyrus.infra.gmfdiag.common.diagram.tester"
+ properties="isDiagramEditor"
+ type="org.eclipse.jface.viewers.IStructuredSelection">
+ </propertyTester>
+ <propertyTester
+ class="org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramPropertyTester"
+ id="org.eclipse.papyrus.infra.gmfdiag.common.diagram.context.tester"
+ namespace="org.eclipse.papyrus.infra.gmfdiag.common.diagram.context.tester"
+ properties="isGmfDiagramContextActive"
+ type="java.util.Collection">
</propertyTester>
-</extension>
-<extension
- point="org.eclipse.papyrus.infra.gmfdiag.common.shapeProvider">
- <shapeProvider
- class="org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider"
- description="Provides shapes based on the applied styles."
- id="org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider"
- name="StyleBasedShapeProvider">
- <Priority
- name="Low"></Priority>
- </shapeProvider>
-</extension>
+</extension>
+<extension
+ point="org.eclipse.papyrus.infra.gmfdiag.common.shapeProvider">
+ <shapeProvider
+ class="org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider"
+ description="Provides shapes based on the applied styles."
+ id="org.eclipse.papyrus.infra.gmfdiag.common.providers.StyleBasedShapeProvider"
+ name="StyleBasedShapeProvider">
+ <Priority
+ name="Low"></Priority>
+ </shapeProvider>
+</extension>
<extension
point="org.eclipse.papyrus.infra.gmfdiag.common.notationTypesMapping">
<mapping
@@ -181,4 +181,10 @@
type="compartment_shape_display">
</mapping>
</extension>
-</plugin>
+<extension
+ point="org.eclipse.papyrus.infra.gmfdiag.commands.historyListeners">
+ <historyListener
+ class="org.eclipse.papyrus.infra.gmfdiag.common.listener.RollbackNotificationHistoryListener">
+ </historyListener>
+</extension>
+</plugin>
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/listener/RollbackNotificationHistoryListener.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/listener/RollbackNotificationHistoryListener.java
new file mode 100644
index 00000000000..38964e06c5d
--- /dev/null
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/listener/RollbackNotificationHistoryListener.java
@@ -0,0 +1,119 @@
+/*
+ * 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.infra.gmfdiag.common.listener;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IOperationHistoryListener;
+import org.eclipse.core.commands.operations.OperationHistoryEvent;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.infra.core.resource.IRollbackStatus;
+import org.eclipse.papyrus.infra.core.resource.RollbackStatus;
+import org.eclipse.papyrus.infra.core.services.ServiceException;
+import org.eclipse.papyrus.infra.emf.providers.EMFLabelProvider;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
+import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForResource;
+import org.eclipse.papyrus.infra.gmfdiag.common.messages.Messages;
+import org.eclipse.papyrus.infra.services.labelprovider.service.LabelProviderService;
+import org.eclipse.ui.statushandlers.IStatusAdapterConstants;
+import org.eclipse.ui.statushandlers.StatusAdapter;
+import org.eclipse.ui.statushandlers.StatusManager;
+
+
+/**
+ * An operation history listener that detects execution failures due to transaction rollback and presents dialogs to explain.
+ */
+public class RollbackNotificationHistoryListener implements IOperationHistoryListener {
+
+ public RollbackNotificationHistoryListener() {
+ super();
+ }
+
+ public void historyNotification(OperationHistoryEvent event) {
+ switch(event.getEventType()) {
+ case OperationHistoryEvent.OPERATION_NOT_OK:
+ final long now = System.currentTimeMillis();
+
+ IRollbackStatus rollback = RollbackStatus.findRollbackStatus(event.getStatus());
+ if(rollback != null) {
+ Collection<?> causalObjects = rollback.getCausalObjects();
+ Collection<String> labels = getObjectLabels(causalObjects);
+
+ String message;
+ switch(rollback.getCode()) {
+ case IRollbackStatus.UNCAUGHT_EXCEPTION:
+ message = labels.isEmpty() ? Messages.RollbackNotificationHistoryListener_exception : NLS.bind(Messages.RollbackNotificationHistoryListener_exceptionWithCause, labels);
+ break;
+ case IRollbackStatus.READ_ONLY_OBJECT:
+ message = labels.isEmpty() ? Messages.RollbackNotificationHistoryListener_readOnly : NLS.bind(Messages.RollbackNotificationHistoryListener_readOnlyWithCause, labels);
+ break;
+ default:
+ message = labels.isEmpty() ? Messages.RollbackNotificationHistoryListener_unknown : NLS.bind(Messages.RollbackNotificationHistoryListener_unknownWithCause, labels);
+ break;
+ }
+
+ // Eclipse doesn't seem to use the status adapter explanation property, so we must create a new status with our message
+ StatusAdapter adapter = new StatusAdapter(new Status(rollback.getSeverity(), rollback.getPlugin(), rollback.getCode(), message, rollback.getException()));
+ adapter.setProperty(IStatusAdapterConstants.TITLE_PROPERTY, Messages.RollbackNotificationHistoryListener_title);
+ adapter.setProperty(IStatusAdapterConstants.TIMESTAMP_PROPERTY, now);
+
+ StatusManager.getManager().handle(adapter, StatusManager.SHOW);
+ }
+ break;
+ }
+ }
+
+ protected List<String> getObjectLabels(Iterable<?> objects) {
+ List<String> result = new ArrayList<String>();
+ ILabelProvider labels = null;
+
+ try {
+ for(Object next : objects) {
+ if(labels == null) {
+ try {
+ LabelProviderService labelService = null;
+ if(next instanceof EObject) {
+ labelService = ServiceUtilsForEObject.getInstance().getService(LabelProviderService.class, (EObject)next);
+ } else if(next instanceof Resource) {
+ labelService = ServiceUtilsForResource.getInstance().getService(LabelProviderService.class, (Resource)next);
+ }
+
+ if(labelService != null) {
+ labels = labelService.getLabelProvider();
+ }
+ } catch (ServiceException e) {
+ // not in an editor context. Fine
+ labels = new EMFLabelProvider();
+ }
+ }
+
+ if(labels != null) {
+ result.add(labels.getText(next));
+ }
+ }
+ } finally {
+ if(labels != null) {
+ labels.dispose();
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/Messages.java b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/Messages.java
index 0843a4eafb7..80509fc4975 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/Messages.java
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/Messages.java
@@ -1,3 +1,16 @@
+/*
+ * Copyright (c) 2013, 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:
+ * Vincent Lorenzo (CEA LIST) - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 323802
+ *
+ */
package org.eclipse.papyrus.infra.gmfdiag.common.messages;
import org.eclipse.osgi.util.NLS;
@@ -6,11 +19,26 @@ public class Messages extends NLS {
private static final String BUNDLE_NAME = "org.eclipse.papyrus.infra.gmfdiag.common.messages.messages"; //$NON-NLS-1$
+ public static String RollbackNotificationHistoryListener_exception;
+
+ public static String RollbackNotificationHistoryListener_exceptionWithCause;
+
+ public static String RollbackNotificationHistoryListener_readOnly;
+
+ public static String RollbackNotificationHistoryListener_readOnlyWithCause;
+
+ public static String RollbackNotificationHistoryListener_title;
+
+ public static String RollbackNotificationHistoryListener_unknown;
+
+ public static String RollbackNotificationHistoryListener_unknownWithCause;
+
public static String UnitsUtils_Centimeters;
public static String UnitsUtils_Inches;
public static String UnitsUtils_Pixels;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/messages.properties b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/messages.properties
index 1d8adde52ab..700f3e214d5 100644
--- a/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/messages.properties
+++ b/plugins/infra/gmfdiag/org.eclipse.papyrus.infra.gmfdiag.common/src/org/eclipse/papyrus/infra/gmfdiag/common/messages/messages.properties
@@ -1,3 +1,23 @@
+#
+# Copyright (c) 2013, 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:
+# Vincent Lorenzo (CEA LIST) - Initial API and implementation
+# Christian W. Damus (CEA) - bug 323802
+#
+
+RollbackNotificationHistoryListener_exception=The operation was rolled back due to an uncaught exception.
+RollbackNotificationHistoryListener_exceptionWithCause=The operation was rolled back due to an uncaught exception relating to the following objects: {0}
+RollbackNotificationHistoryListener_readOnly=The operation was rolled back because it modified read-only objects.
+RollbackNotificationHistoryListener_readOnlyWithCause=The operation was rolled back because it modified read-only objects: {0}
+RollbackNotificationHistoryListener_title=Operation Rolled Back
+RollbackNotificationHistoryListener_unknown=The operation was rolled back for an unknown reason.
+RollbackNotificationHistoryListener_unknownWithCause=The operation was rolled back for an unknown reason relating to the following objects: {0}
UnitsUtils_Centimeters=Centimeters
UnitsUtils_Inches=Inches
UnitsUtils_Pixels=Pixels

Back to the top