diff options
Diffstat (limited to 'plugins/infra/emf/org.eclipse.papyrus.infra.emf')
5 files changed, 237 insertions, 2 deletions
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF index b2fdcac9a08..b4c9fd570ce 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/META-INF/MANIFEST.MF @@ -30,6 +30,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.gmf.runtime.emf.type.core;bundle-version="1.7.0",
com.google.guava;bundle-version="11.0.0"
Export-Package: org.eclipse.papyrus.infra.emf,
+ org.eclipse.papyrus.infra.emf.adapters,
org.eclipse.papyrus.infra.emf.commands,
org.eclipse.papyrus.infra.emf.databinding,
org.eclipse.papyrus.infra.emf.dialog,
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 a5a77a29959..d9b6cb0f5d1 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/plugin.xml @@ -57,5 +57,15 @@ </elementType>
</binding>
</extension>
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.emf.ecore.EObject"
+ class="org.eclipse.papyrus.infra.emf.adapters.EObjectAdapterFactory">
+ <adapter
+ type="org.eclipse.papyrus.infra.widgets.creation.IAtomicOperationExecutor">
+ </adapter>
+ </factory>
+ </extension>
</plugin>
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/adapters/EObjectAdapterFactory.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/adapters/EObjectAdapterFactory.java new file mode 100644 index 00000000000..e16b485fc3b --- /dev/null +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/adapters/EObjectAdapterFactory.java @@ -0,0 +1,85 @@ +/* + * 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.adapters; + +import org.eclipse.core.runtime.IAdapterFactory; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.ResourceSet; +import org.eclipse.emf.transaction.RecordingCommand; +import org.eclipse.emf.transaction.TransactionalEditingDomain; +import org.eclipse.emf.transaction.util.TransactionUtil; +import org.eclipse.papyrus.infra.emf.dialog.NestedEditingDialogContext; +import org.eclipse.papyrus.infra.widgets.creation.IAtomicOperationExecutor; + + +/** + * This is the EObjectAdapterFactory type. Enjoy. + */ +public class EObjectAdapterFactory implements IAdapterFactory { + + private final Class<?>[] adapterTypes = { IAtomicOperationExecutor.class }; + + public EObjectAdapterFactory() { + super(); + } + + public Object getAdapter(Object adaptable, @SuppressWarnings("rawtypes") Class adapterType) { + Object result = null; + + if(adaptable instanceof EObject) { + if(adapterType == IAtomicOperationExecutor.class) { + TransactionalEditingDomain domain = TransactionUtil.getEditingDomain((EObject)adaptable); + if(domain == null) { + ResourceSet rset = NestedEditingDialogContext.getInstance().getResourceSet(); + if(rset != null) { + domain = TransactionUtil.getEditingDomain(rset); + } + } + if(domain != null) { + result = new EMFAtomicOperationExecutor(domain); + } + } + } + + return result; + } + + @SuppressWarnings("rawtypes") + public Class[] getAdapterList() { + return adapterTypes; + } + + // + // Nested types + // + + private static final class EMFAtomicOperationExecutor extends IAtomicOperationExecutor.Default { + + private final TransactionalEditingDomain domain; + + EMFAtomicOperationExecutor(TransactionalEditingDomain domain) { + this.domain = domain; + } + + @Override + public void execute(final Runnable operation, String label) { + domain.getCommandStack().execute(new RecordingCommand(domain, label) { + + @Override + protected void doExecute() { + operation.run(); + } + }); + } + } +} diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableList.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableList.java index 6af566f79ad..beb832a0015 100644 --- a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableList.java +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/databinding/EMFObservableList.java @@ -1,5 +1,5 @@ /*****************************************************************************
- * Copyright (c) 2010 CEA LIST.
+ * Copyright (c) 2010, 2014 CEA LIST and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -8,6 +8,8 @@ *
* Contributors:
* Camille Letavernier (CEA LIST) camille.letavernier@cea.fr - Initial API and implementation
+ * Christian W. Damus (CEA) - bug 402525
+ *
*****************************************************************************/
package org.eclipse.papyrus.infra.emf.databinding;
@@ -17,6 +19,7 @@ import java.util.List; import org.eclipse.core.databinding.observable.ChangeEvent;
import org.eclipse.core.databinding.observable.IChangeListener;
+import org.eclipse.core.databinding.observable.IObserving;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ObservableList;
import org.eclipse.emf.common.command.Command;
@@ -41,7 +44,7 @@ import org.eclipse.papyrus.infra.widgets.editors.ICommitListener; * @author Camille Letavernier
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
-public class EMFObservableList extends ObservableList implements ICommitListener, IChangeListener {
+public class EMFObservableList extends ObservableList implements ICommitListener, IChangeListener, IObserving {
/**
* The list of commands that haven't been executed yet
@@ -106,6 +109,10 @@ public class EMFObservableList extends ObservableList implements ICommitListener }
}
+ public Object getObserved() {
+ return source;
+ }
+
@Override
public synchronized void dispose() {
if(concreteList instanceof IObservableList) {
diff --git a/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/dialog/NestedEditingDialogContext.java b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/dialog/NestedEditingDialogContext.java new file mode 100644 index 00000000000..813e5524574 --- /dev/null +++ b/plugins/infra/emf/org.eclipse.papyrus.infra.emf/src/org/eclipse/papyrus/infra/emf/dialog/NestedEditingDialogContext.java @@ -0,0 +1,132 @@ +/* + * 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.dialog; + +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.resource.ResourceSet; + +/** + * A tracker of nested editing-dialog context information required by various components that have no direct access to the context. + */ +public class NestedEditingDialogContext { + + private static final NestedEditingDialogContext INSTANCE = new NestedEditingDialogContext(); + + private final ThreadLocal<Integer> nesting = new ThreadLocal<Integer>(); + + private final ThreadLocal<ResourceSet> resourceSet = new ThreadLocal<ResourceSet>(); + + public static NestedEditingDialogContext getInstance() { + return INSTANCE; + } + + /** + * Queries whether the current editing dialog is nested in (created by) a higher-level dialog editing some other object. + * + * @return whether the current thread is presenting a nested editing dialog + */ + public boolean isNested() { + Integer depth = nesting.get(); + return (depth != null) && (depth.intValue() > 0); + } + + /** + * Signals entry of an editing dialog context (the current thread is now presenting a dialog). Must be matched by a subsequent + * call to {@linkplain #exit() exit} the context. + * + * @see #exit() + */ + public void enter() { + Integer depth = nesting.get(); + if((depth == null) || (depth.intValue() < 1)) { + depth = 1; + } else { + depth = depth.intValue() + 1; + } + nesting.set(depth); + } + + /** + * Signals the end of an editing dialog context (the current thread is no longer presenting a dialog). Must match an earlier + * call to {@linkplain #enter() enter} the context. + * + * @see #enter() + */ + public void exit() { + Integer depth = nesting.get(); + if(depth != null) { + if(depth.intValue() <= 1) { + depth = null; + } else { + depth = depth.intValue() - 1; + } + nesting.set(depth); + } + } + + /** + * Obtains the resource set in the editing-dialog context of the current thread. + * + * @return the current contextual resource set + */ + public ResourceSet getResourceSet() { + return resourceSet.get(); + } + + /** + * Determines, if possible, the resource set containing the given {@code context} object being edited and pushes it onto the + * current thread's context stack. + * + * @param context + * the object currently being edited in a dialog + * + * @return the resource set that was previously the context (which may be the same as the new one being pushed). This + * must be {@linkplain #pop(ResourceSet) popped} from the context subsequently + * + * @see #pop(ResourceSet) + */ + public ResourceSet push(Object context) { + final ResourceSet previous = resourceSet.get(); + + if(context instanceof EObject) { + Resource res = ((EObject)context).eResource(); + if(res != null) { + ResourceSet current = res.getResourceSet(); + if(current != null) { + // put it in context + resourceSet.set(current); + } + } + } + + return previous; + } + + /** + * Pops the current resource set from the context, restoring the given resource set that was returned by a previous {@linkplain #push(Object) + * push}, even if it was {@code null}. + * + * @param previous + * a resource set returned by an earlier push (may be {@code null}) + * + * @see #push(Object) + */ + public void pop(ResourceSet previous) { + if(previous == null) { + resourceSet.remove(); + } else { + resourceSet.set(previous); + } + } +} |