Bug 552385 - EMFDeleteServiceImpl contradicts model's item providers
Add an extension protocol for conditional deletion support.
Use it in the UI for delete action enablement.
Change-Id: I83cf91ec2792ad5bf1fd658e37dc88b1dc2d3ec1
Signed-off-by: Christian W. Damus <give.a.damus@gmail.com>
diff --git a/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/ConditionalDeleteService.java b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/ConditionalDeleteService.java
new file mode 100644
index 0000000..b65f506
--- /dev/null
+++ b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/ConditionalDeleteService.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian W. Damus - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emf.ecp.edit.spi;
+
+import java.util.Collections;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emfforms.spi.core.services.view.EMFFormsViewContext;
+
+/**
+ * An extension of the {@link DeleteService} protocol that supports conditional deletion,
+ * respecting a model's edit providers when they provide unexecutable commands to veto
+ * deletion. Implementations of this interface <strong>should be registered</strong> as
+ * OSGi services providing {@code DeleteService} because the framework looks for that
+ * service interface but will test whether the implementation also provides this extension.
+ * Whether the extension interface is also declared to OSGi is left to the provider's discretion.
+ *
+ * @since 1.23
+ */
+public interface ConditionalDeleteService extends DeleteService {
+
+ /**
+ * Queries whether an {@code object} can be deleted. By convention a {@code null} value
+ * cannot be deleted.
+ *
+ * @param object an object to be deleted
+ * @return {@code false} if the {@code object} cannot be deleted or is {@code null}; {@code true}, otherwise
+ */
+ default boolean canDelete(Object object) {
+ return canDelete(Collections.singleton(object));
+ }
+
+ /**
+ * Queries whether <em>all</em> of the given {@code objects} can be deleted.
+ *
+ * @param objects a number of objects to be deleted
+ * @return {@code false} if any of the objects cannot be deleted; {@code true} otherwise, including the case of no
+ * {@code objects}
+ */
+ boolean canDelete(Iterable<?> objects);
+
+ /**
+ * Obtain a conditional delete service for a given {@code context}, if necessary
+ * {@linkplain #adapt(DeleteService) adapting} its service implementation.
+ *
+ * @param context a form context
+ * @return the delete service, or an adapter if the actual delete service implementation does not provide
+ * the {@link ConditionalDeleteService} protocol or if there isn't a delete service at all (in which case nothing can
+ * be deleted)
+ *
+ * @see #adapt(DeleteService)
+ */
+ static ConditionalDeleteService getDeleteService(EMFFormsViewContext context) {
+ return adapt(context == null ? null : context.getService(DeleteService.class));
+ }
+
+ /**
+ * Obtain a view of a given {@code service} as conditional delete service, if necessary adapting a service
+ * implementation that does not provide the {@link ConditionalDeleteService} protocol with a default deletion condition.
+ * In that case, an object is assumed to be deletable if it is not {@code null} and it is an
+ * {@link EObject} that has some container from which it can be removed (root elements not logically
+ * being deletable).
+ *
+ * @param service a delete service
+ * @return the delete service, or an adapter if the actual delete service implementation does not provide
+ * the {@link ConditionalDeleteService} protocol or if the original {@code service} is {@code null}
+ */
+ static ConditionalDeleteService adapt(DeleteService service) {
+ return service == null
+ ? DeleteServiceAdapter.NULL
+ : service instanceof ConditionalDeleteService
+ ? (ConditionalDeleteService) service
+ : new DeleteServiceAdapter(service);
+ }
+
+}
diff --git a/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteService.java b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteService.java
index d14140b..e222309 100644
--- a/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteService.java
+++ b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteService.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
+ * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,6 +10,7 @@
*
* Contributors:
* Johannes Faltermeier - initial API and implementation
+ * Christian W. Damus - bug 552385
******************************************************************************/
package org.eclipse.emf.ecp.edit.spi;
@@ -18,7 +19,15 @@
import org.eclipse.emf.ecp.view.spi.context.ViewModelService;
/**
+ * <p>
* The DeleteService is used by renderers in order to delete objects from the containment tree.
+ * </p>
+ * <p>
+ * <strong>Note</strong> that since the 1.23 release, it is recommended to implement the
+ * {@link ConditionalDeleteService} interface to support conditional deletion, honouring the model's
+ * edit providers when they veto deletion by providing unexecutable commands.
+ * </p>
+ *
*
* @author jfaltermeier
* @since 1.6
diff --git a/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteServiceAdapter.java b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteServiceAdapter.java
new file mode 100644
index 0000000..45f31f9
--- /dev/null
+++ b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/DeleteServiceAdapter.java
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian W. Damus - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emf.ecp.edit.spi;
+
+import java.util.Collection;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
+
+/**
+ * An adapter for delete services that do not implement the {@link ConditionalDeleteService} protocol.
+ */
+final class DeleteServiceAdapter implements ConditionalDeleteService {
+
+ /** An adapter for the {@code null} service (when there is no delete service at all). */
+ static final ConditionalDeleteService NULL = new DeleteServiceAdapter(null);
+
+ private final DeleteService delegate;
+
+ /**
+ * Initializes me with the real delete service.
+ *
+ * @param delegate the real delete service
+ */
+ DeleteServiceAdapter(DeleteService delegate) {
+ super();
+
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void deleteElements(Collection<Object> toDelete) {
+ if (delegate != null) {
+ delegate.deleteElements(toDelete);
+ } else {
+ throw new IllegalStateException("No deletion service available."); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public void deleteElement(Object toDelete) {
+ if (delegate != null) {
+ delegate.deleteElement(toDelete);
+ } else {
+ throw new IllegalStateException("No deletion service available."); //$NON-NLS-1$
+ }
+ }
+
+ @Override
+ public void instantiate(ViewModelContext context) {
+ if (delegate != null) {
+ delegate.instantiate(context);
+ }
+ }
+
+ @Override
+ public void dispose() {
+ if (delegate != null) {
+ delegate.dispose();
+ }
+ }
+
+ @Override
+ public int getPriority() {
+ return delegate == null ? Integer.MIN_VALUE : delegate.getPriority();
+ }
+
+ @Override
+ public boolean canDelete(Iterable<?> objects) {
+ // Cannot delete if we have no service to effect the deletion
+ boolean result = delegate != null;
+
+ if (result) {
+ for (final Object next : objects) {
+ // Cannot delete a null or a root object
+ if (next == null || next instanceof EObject && ((EObject) next).eContainer() == null) {
+ result = false;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
+}
diff --git a/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/EMFDeleteServiceImpl.java b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/EMFDeleteServiceImpl.java
index 98a844f..dad5963 100644
--- a/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/EMFDeleteServiceImpl.java
+++ b/bundles/org.eclipse.emf.ecp.edit/src/org/eclipse/emf/ecp/edit/spi/EMFDeleteServiceImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
+ * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,11 +10,14 @@
*
* Contributors:
* Johannes Faltermeier - initial API and implementation
+ * Christian W. Damus - bug 552385
******************************************************************************/
package org.eclipse.emf.ecp.edit.spi;
import java.util.Collection;
import java.util.Collections;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.ecore.EObject;
@@ -33,47 +36,26 @@
* @since 1.6
*
*/
-public class EMFDeleteServiceImpl implements DeleteService {
+public class EMFDeleteServiceImpl implements ConditionalDeleteService {
private EditingDomain editingDomain;
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#instantiate(org.eclipse.emf.ecp.view.spi.context.ViewModelContext)
- */
@Override
public void instantiate(ViewModelContext context) {
editingDomain = AdapterFactoryEditingDomain
.getEditingDomainFor(context.getDomainModel());
}
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#dispose()
- */
@Override
public void dispose() {
// no op
}
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.ecp.view.spi.context.ViewModelService#getPriority()
- */
@Override
public int getPriority() {
return 1;
}
- /**
- *
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.ecp.edit.spi.DeleteService#deleteElements(java.util.Collection)
- */
@Override
public void deleteElements(final Collection<Object> toDelete) {
if (toDelete == null || toDelete.isEmpty()) {
@@ -127,12 +109,6 @@
}
}
- /**
- *
- * {@inheritDoc}
- *
- * @see org.eclipse.emf.ecp.edit.spi.DeleteService#deleteElement(java.lang.Object)
- */
@Override
public void deleteElement(Object toDelete) {
if (toDelete == null) {
@@ -142,4 +118,34 @@
deleteElements(Collections.singleton(toDelete));
}
+ @Override
+ public boolean canDelete(Iterable<?> objects) {
+ boolean result;
+
+ if (editingDomain != null) {
+ Collection<?> collection;
+ if (objects instanceof Collection<?>) {
+ collection = (Collection<?>) objects;
+ } else {
+ collection = StreamSupport.stream(objects.spliterator(), false).collect(Collectors.toList());
+ }
+
+ final Command deleteCommand = DeleteCommand.create(editingDomain, collection);
+ result = deleteCommand.canExecute();
+ } else {
+ // Just see whether any object is a root
+ result = true;
+
+ for (final Object next : objects) {
+ if (next instanceof EObject && ((EObject) next).eContainer() == null) {
+ // Cannot delete a root object
+ result = false;
+ break;
+ }
+ }
+ }
+
+ return result;
+ }
+
}
diff --git a/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorActionBarContributor.java b/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorActionBarContributor.java
index 5918aa6..780a383 100644
--- a/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorActionBarContributor.java
+++ b/bundles/org.eclipse.emf.ecp.ide.editor.view/src/org/eclipse/emf/ecp/ide/editor/view/ViewEditorActionBarContributor.java
@@ -14,10 +14,9 @@
package org.eclipse.emf.ecp.ide.editor.view;
import java.util.Collection;
-import java.util.stream.Stream;
-import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.edit.ui.action.DeleteAction;
import org.eclipse.emf.edit.ui.action.EditingDomainActionBarContributor;
@@ -92,16 +91,9 @@
@Override
public boolean updateSelection(IStructuredSelection selection) {
- final DeleteService deleteService = getService(DeleteService.class);
- if (deleteService == null) {
- return super.updateSelection(selection);
- }
+ final ConditionalDeleteService deleteService = ConditionalDeleteService.getDeleteService(getViewModelContext());
- return !selection.isEmpty() && Stream.of(selection.toArray()).noneMatch(this::isRoot);
- }
-
- private boolean isRoot(Object object) {
- return object instanceof EObject && ((EObject) object).eContainer() == null;
+ return !selection.isEmpty() && deleteService.canDelete(selection.toList());
}
}
diff --git a/bundles/org.eclipse.emf.ecp.view.control.multireference/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.control.multireference/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceSWTRenderer.java
index ffcd9d3..ed19456 100644
--- a/bundles/org.eclipse.emf.ecp.view.control.multireference/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceSWTRenderer.java
+++ b/bundles/org.eclipse.emf.ecp.view.control.multireference/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceSWTRenderer.java
@@ -12,7 +12,7 @@
* Eugen Neufeld - initial API and implementation
* Lucas Koehler - use data binding services
* Martin Fleck - bug 487101
- * Christian W. Damus - bugs 527736, 548592
+ * Christian W. Damus - bugs 527736, 548592, 552385
******************************************************************************/
package org.eclipse.emf.ecp.view.internal.control.multireference;
@@ -36,6 +36,7 @@
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecp.edit.internal.swt.controls.TableViewerColumnBuilder;
import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
import org.eclipse.emf.ecp.edit.spi.ReferenceService;
import org.eclipse.emf.ecp.view.model.common.edit.provider.CustomReflectiveItemProviderAdapterFactory;
@@ -779,7 +780,9 @@
private void enableDeleteButton(boolean baseEnable, int listSize, int selectionIndex) {
if (btnDelete != null && showDeleteButton()) {
- btnDelete.setEnabled(baseEnable && listSize > 0 && selectionIndex != -1);
+ btnDelete.setEnabled(baseEnable && listSize > 0 && selectionIndex != -1
+ && ConditionalDeleteService.getDeleteService(getViewModelContext())
+ .canDelete(tableViewer.getStructuredSelection().toList()));
}
}
diff --git a/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java
index c2979c7..1e5358f 100644
--- a/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java
+++ b/bundles/org.eclipse.emf.ecp.view.table.ui.swt/src/org/eclipse/emf/ecp/view/spi/table/swt/TableControlSWTRenderer.java
@@ -11,7 +11,7 @@
* Contributors:
* Eugen Neufeld - initial API and implementation
* Johannes Faltermeier - refactorings
- * Christian W. Damus - bugs 544116, 544537, 545686, 530314, 547271, 547787, 548592
+ * Christian W. Damus - bugs 544116, 544537, 545686, 530314, 547271, 547787, 548592, 552385
******************************************************************************/
package org.eclipse.emf.ecp.view.spi.table.swt;
@@ -63,6 +63,7 @@
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
import org.eclipse.emf.ecp.edit.spi.ReferenceService;
import org.eclipse.emf.ecp.edit.spi.swt.table.ECPCellEditor;
@@ -633,6 +634,12 @@
deleteRowUserConfirmDialog(deletionList, eObject, eStructuralFeature, getAddButton(),
getRemoveButton());
}
+
+ @Override
+ public boolean canExecute() {
+ return super.canExecute() && ConditionalDeleteService.getDeleteService(getViewModelContext())
+ .canDelete(getActionContext().getViewer().getStructuredSelection().toList());
+ }
};
actionConfigBuilder
diff --git a/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java b/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java
index 7afb40c..2dcfaa2 100644
--- a/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java
+++ b/bundles/org.eclipse.emf.ecp.view.treemasterdetail.ui.swt/src/org/eclipse/emf/ecp/view/spi/treemasterdetail/ui/swt/TreeMasterDetailSWTRenderer.java
@@ -13,7 +13,7 @@
* Eugen Neufeld - Refactoring
* Alexandra Buzila - Refactoring
* Johannes Faltermeier - integration with validation service
- * Christian W. Damus - bugs 543376, 545460, 527686, 548592
+ * Christian W. Damus - bugs 543376, 545460, 527686, 548592, 552385
******************************************************************************/
package org.eclipse.emf.ecp.view.spi.treemasterdetail.ui.swt;
@@ -50,6 +50,7 @@
import org.eclipse.emf.ecp.common.spi.ChildrenDescriptorCollector;
import org.eclipse.emf.ecp.edit.internal.swt.util.OverlayImageDescriptor;
import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
import org.eclipse.emf.ecp.edit.spi.ReferenceService;
import org.eclipse.emf.ecp.edit.spi.swt.util.SWTValidationHelper;
@@ -866,6 +867,7 @@
.getBundle()
.getResource(deleteImagePath)));
deleteAction.setText("Delete"); //$NON-NLS-1$
+ deleteAction.setEnabled(ConditionalDeleteService.getDeleteService(getViewModelContext()).canDelete(selection.toList()));
manager.add(deleteAction);
}
diff --git a/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/DeleteServiceAdapter_PTest.java b/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/DeleteServiceAdapter_PTest.java
new file mode 100644
index 0000000..b249e5f
--- /dev/null
+++ b/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/DeleteServiceAdapter_PTest.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2019 Christian W. Damus and others.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Christian W. Damus - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emf.ecp.edit.internal.swt.util;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.verify;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
+import org.eclipse.emf.emfstore.bowling.BowlingFactory;
+import org.eclipse.emf.emfstore.bowling.League;
+import org.eclipse.emf.emfstore.bowling.Player;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+/**
+ * Tests for the {@code DeleteServiceAdapter} class via the {@link ConditionalDeleteService} APIs that provide instances of it.
+ */
+@SuppressWarnings("nls")
+@RunWith(MockitoJUnitRunner.class)
+public class DeleteServiceAdapter_PTest {
+
+ private League league;
+ private Player player;
+
+ @Mock
+ private DeleteService delegate;
+
+ @Mock
+ private ConditionalDeleteService cdelegate;
+
+ /**
+ * Test the null adapter (the adapter for an absent delete service).
+ */
+ @Test
+ public void test_canDelete_null() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(null);
+
+ final Collection<?> objects = Arrays.asList(player, league);
+ assertThat("can delete without delegate", service.canDelete(player), is(false));
+ assertThat("can delete without delegate", service.canDelete(objects), is(false));
+ }
+
+ @Test
+ public void test_canDelete_single() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(delegate);
+
+ assertThat(service.canDelete(player), is(true));
+ assertThat(service.canDelete(league), is(false));
+ }
+
+ @Test
+ public void test_canDelete_multiple() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(delegate);
+
+ assertThat(service.canDelete(Arrays.asList(player)), is(true));
+ assertThat(service.canDelete(Arrays.asList(player, league)), is(false));
+ }
+
+ @Test
+ public void test_canDelete_single2() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(cdelegate);
+
+ service.canDelete(player);
+
+ verify(cdelegate).canDelete(player);
+ }
+
+ @Test
+ public void test_canDelete_multiple2() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(cdelegate);
+
+ final Collection<?> objects = Arrays.asList(player, league);
+ service.canDelete(objects);
+
+ verify(cdelegate).canDelete(objects);
+ }
+
+ @Test
+ public void test_deleteElement() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(delegate);
+
+ service.deleteElement(player);
+
+ verify(delegate).deleteElement(player);
+ }
+
+ @Test
+ public void test_deleteElementse() {
+ final ConditionalDeleteService service = ConditionalDeleteService.adapt(delegate);
+
+ final Collection<Object> objects = Arrays.asList(player, league);
+ service.deleteElements(objects);
+
+ verify(delegate).deleteElements(objects);
+ }
+
+ //
+ // Test framework
+ //
+
+ @Before
+ public void createModel() {
+ league = BowlingFactory.eINSTANCE.createLeague();
+ player = BowlingFactory.eINSTANCE.createPlayer();
+
+ league.getPlayers().add(player);
+ }
+
+}
diff --git a/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/EMFDeleteSerivceImpl_PTest.java b/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/EMFDeleteSerivceImpl_PTest.java
index b3289f0..0344274 100644
--- a/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/EMFDeleteSerivceImpl_PTest.java
+++ b/tests/org.eclipse.emf.ecp.edit.swt.test/src/org/eclipse/emf/ecp/edit/internal/swt/util/EMFDeleteSerivceImpl_PTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2011-2015 EclipseSource Muenchen GmbH and others.
+ * Copyright (c) 2011-2019 EclipseSource Muenchen GmbH and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -10,9 +10,12 @@
*
* Contributors:
* jfaltermeier - initial API and implementation
+ * Christian W. Damus - bug 552385
******************************************************************************/
package org.eclipse.emf.ecp.edit.internal.swt.util;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
@@ -21,19 +24,25 @@
import static org.mockito.Mockito.when;
import java.util.Arrays;
+import java.util.Collection;
import org.eclipse.emf.common.command.BasicCommandStack;
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.common.command.UnexecutableCommand;
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.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
-import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.ConditionalDeleteService;
import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
import org.eclipse.emf.ecp.test.university.Address;
import org.eclipse.emf.ecp.test.university.Professor;
import org.eclipse.emf.ecp.test.university.UniversityFactory;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
+import org.eclipse.emf.edit.command.OverrideableCommand;
+import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.emfstore.bowling.BowlingFactory;
@@ -48,10 +57,12 @@
* @author jfaltermeier
*
*/
+@SuppressWarnings("nls")
public class EMFDeleteSerivceImpl_PTest {
- private DeleteService deleteService;
+ private ConditionalDeleteService deleteService;
private AdapterFactoryEditingDomain domain;
+ private ViewModelContext context;
private Resource resource;
private League league;
private Game game;
@@ -60,13 +71,25 @@
private Player player3;
private Tournament tournament;
+ private EObject denyDeletion;
+
@Before
public void setUp() {
final ResourceSet resourceSet = new ResourceSetImpl();
resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl()); //$NON-NLS-1$
domain = new AdapterFactoryEditingDomain(
new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE),
- new BasicCommandStack(), resourceSet);
+ new BasicCommandStack(), resourceSet) {
+
+ @Override
+ public Command createOverrideCommand(OverrideableCommand command) {
+ if (denyDeletion != null && command instanceof RemoveCommand
+ && ((RemoveCommand) command).getCollection().contains(denyDeletion)) {
+ return UnexecutableCommand.INSTANCE;
+ }
+ return super.createOverrideCommand(command);
+ }
+ };
resourceSet.eAdapters().add(new AdapterFactoryEditingDomain.EditingDomainProvider(domain));
resource = resourceSet.createResource(URI.createURI("VIRTUAL_URI")); //$NON-NLS-1$
@@ -91,7 +114,7 @@
game.setPlayer(player1);
deleteService = new EMFDeleteServiceImpl();
- final ViewModelContext context = mock(ViewModelContext.class);
+ context = mock(ViewModelContext.class);
when(context.getDomainModel()).thenReturn(league);
deleteService.instantiate(context);
}
@@ -143,4 +166,40 @@
assertSame(address1, professor.getAddresses().get(0));
}
+ @Test
+ public void testCanDeleteElement() {
+ assertThat("can delete returns false", deleteService.canDelete(player1), is(true));
+
+ denyDeletion = player1;
+ assertThat("can delete returns true", deleteService.canDelete(player1), is(false));
+ }
+
+ @Test
+ public void testCanDeleteElements() {
+ final Collection<?> objects = Arrays.asList(player1, player2);
+
+ assertThat("can delete returns false", deleteService.canDelete(objects), is(true));
+
+ denyDeletion = player2; // Not the first one
+ assertThat("can delete returns true", deleteService.canDelete(objects), is(false));
+ }
+
+ @Test
+ public void testCanDeleteNoEditingDomain() {
+ // Disconnect everything from the editing domain
+ resource.getContents().clear();
+ resource.getResourceSet().eAdapters().clear();
+ resource.getResourceSet().getResources().clear();
+ resource.unload();
+ resource.eAdapters().clear();
+
+ // Re-initialize to forget the editing domain
+ deleteService.dispose();
+ deleteService.instantiate(context);
+
+ assertThat("cannot delete a contained object", deleteService.canDelete(player1), is(true));
+
+ assertThat("can delete a root object", deleteService.canDelete(league), is(false));
+ }
+
}
diff --git a/tests/org.eclipse.emf.ecp.view.control.multireference.tests/AllPluginTests for view.control.multireference.launch b/tests/org.eclipse.emf.ecp.view.control.multireference.tests/AllPluginTests for view.control.multireference.launch
index 07c47aa..5b8ea3a 100644
--- a/tests/org.eclipse.emf.ecp.view.control.multireference.tests/AllPluginTests for view.control.multireference.launch
+++ b/tests/org.eclipse.emf.ecp.view.control.multireference.tests/AllPluginTests for view.control.multireference.launch
@@ -24,6 +24,7 @@
<booleanAttribute key="org.eclipse.jdt.junit.KEEPRUNNING_ATTR" value="false"/>
<stringAttribute key="org.eclipse.jdt.junit.TESTNAME" value=""/>
<stringAttribute key="org.eclipse.jdt.junit.TEST_KIND" value="org.eclipse.jdt.junit.loader.junit4"/>
+<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.JRE_CONTAINER" value="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.emf.ecp.view.control.multireference.tests.AllPluginTests"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-os ${target.os} -ws ${target.ws} -arch ${target.arch} -nl ${target.nl} -consoleLog"/>
@@ -32,8 +33,8 @@
<stringAttribute key="pde.version" value="3.3"/>
<stringAttribute key="product" value="org.eclipse.platform.ide"/>
<booleanAttribute key="run_in_ui_thread" value="true"/>
-<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,org.apache.batik.constants@default:default,org.apache.batik.css*1.10.0.v20180703-1553@default:default,org.apache.batik.i18n@default:default,org.apache.batik.util*1.10.0.v20180703-1553@default:default,org.apache.commons.codec@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging*1.1.1.v201101211721@default:default,org.apache.commons.logging*1.2.0.v20180409-1502@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.scr@1:true,org.apache.xmlgraphics@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding*1.7.100.v20181030-1443@default:default,org.eclipse.core.databinding.observable*1.6.300.v20180827-2028@default:default,org.eclipse.core.databinding.property*1.6.300.v20180827-2028@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.linux.x86_64@default:false,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions.supplier@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.swt.gtk@default:false,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common.ui@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.databinding.edit@default:default,org.eclipse.emf.databinding@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit.ui@default:default,org.eclipse.emf.edit@default:default,org.eclipse.emf.emfstore.client@default:default,org.eclipse.emf.emfstore.common.model@default:default,org.eclipse.emf.emfstore.common@default:default,org.eclipse.emf.emfstore.examplemodel.edit@default:default,org.eclipse.emf.emfstore.examplemodel@default:default,org.eclipse.emf.emfstore.migration@default:default,org.eclipse.emf.emfstore.server.model@default:default,org.eclipse.emf.emfstore.server@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface@default:default,org.eclipse.net4j.util@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.gtk.linux.x86_64@default:false,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core*1.3.0.v201303031735@default:default,org.hamcrest.core*1.3.0.v20180420-1519@default:default,org.hamcrest.library@default:default,org.junit@default:default,org.mockito.mockito-core-hamcrest-modified@default:default,org.objenesis@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil*1.0.1.v200903091627@default:default,org.w3c.dom.svg@default:default"/>
-<stringAttribute key="selected_workspace_plugins" value="org.eclipse.emf.ecp.common.ui@default:default,org.eclipse.emf.ecp.common@default:default,org.eclipse.emf.ecp.core@default:default,org.eclipse.emf.ecp.edit.swt@default:default,org.eclipse.emf.ecp.edit@default:default,org.eclipse.emf.ecp.editor.e3@default:default,org.eclipse.emf.ecp.emfstore.core@default:default,org.eclipse.emf.ecp.explorereditorbridge@default:default,org.eclipse.emf.ecp.test.common@default:default,org.eclipse.emf.ecp.ui.view.swt@default:default,org.eclipse.emf.ecp.ui.view.test@default:default,org.eclipse.emf.ecp.ui.view@default:default,org.eclipse.emf.ecp.ui@default:default,org.eclipse.emf.ecp.view.context@default:default,org.eclipse.emf.ecp.view.control.multireference.tests@default:false,org.eclipse.emf.ecp.view.control.multireference@default:default,org.eclipse.emf.ecp.view.core.swt@default:default,org.eclipse.emf.ecp.view.group.model@default:default,org.eclipse.emf.ecp.view.migrator@default:default,org.eclipse.emf.ecp.view.model.common@default:default,org.eclipse.emf.ecp.view.model.provider.generator@default:default,org.eclipse.emf.ecp.view.model.provider.xmi@default:default,org.eclipse.emf.ecp.view.model@default:default,org.eclipse.emf.ecp.view.swt.layout@default:default,org.eclipse.emf.ecp.view.table.model.test@default:false,org.eclipse.emf.ecp.view.table.model@default:default,org.eclipse.emf.ecp.view.template.model@default:default,org.eclipse.emf.ecp.view.test.common.swt@default:default,org.eclipse.emf.ecp.view.test.common@default:default,org.eclipse.emf.ecp.view.util.swt@default:default,org.eclipse.emf.ecp.view.validation@default:default,org.eclipse.emf.ecp.view.vertical.model@default:default,org.eclipse.emfforms.common.prevalidation@default:default,org.eclipse.emfforms.common.validation@default:default,org.eclipse.emfforms.common@default:default,org.eclipse.emfforms.core.bazaar@default:default,org.eclipse.emfforms.core.services.databinding.testmodel@default:default,org.eclipse.emfforms.core.services.domainexpander.default@default:default,org.eclipse.emfforms.core.services.domainexpander.table@default:default,org.eclipse.emfforms.core.services.editsupport@default:default,org.eclipse.emfforms.core.services.emf@default:default,org.eclipse.emfforms.core.services.emfspecificservice@default:default,org.eclipse.emfforms.core.services.legacy@default:default,org.eclipse.emfforms.core.services.locale.default@default:default,org.eclipse.emfforms.core.services.mappingprovider.default@default:default,org.eclipse.emfforms.core.services.mappingprovider.table@default:default,org.eclipse.emfforms.core.services.structuralchange.default@default:default,org.eclipse.emfforms.core.services.structuralchange@default:default,org.eclipse.emfforms.core.services@default:default,org.eclipse.emfforms.localization@default:default,org.eclipse.emfforms.swt.core.di@default:default,org.eclipse.emfforms.swt.core@default:default,org.eclipse.emfforms.view.annotation.model@default:default,org.eclipse.emfforms.view.multisegment.model@default:default"/>
+<stringAttribute key="selected_target_plugins" value="com.ibm.icu@default:default,javax.annotation@default:default,javax.inject@default:default,org.apache.batik.constants*1.11.0.v20190515-0436@default:default,org.apache.batik.css*1.11.0.v20190515-0436@default:default,org.apache.batik.i18n*1.11.0.v20190515-0436@default:default,org.apache.batik.util*1.11.0.v20190515-0436@default:default,org.apache.commons.codec@default:default,org.apache.commons.jxpath@default:default,org.apache.commons.logging*1.1.1.v201101211721@default:default,org.apache.commons.logging*1.2.0.v20180409-1502@default:default,org.apache.felix.gogo.command@default:default,org.apache.felix.gogo.runtime@default:default,org.apache.felix.scr@1:true,org.apache.xmlgraphics@default:default,org.eclipse.compare.core@default:default,org.eclipse.core.commands@default:default,org.eclipse.core.contenttype@default:default,org.eclipse.core.databinding.observable@default:default,org.eclipse.core.databinding.property@default:default,org.eclipse.core.databinding@default:default,org.eclipse.core.expressions@default:default,org.eclipse.core.filesystem.macosx@default:default,org.eclipse.core.filesystem@default:default,org.eclipse.core.jobs@default:default,org.eclipse.core.resources@default:default,org.eclipse.core.runtime@default:true,org.eclipse.e4.core.commands@default:default,org.eclipse.e4.core.contexts@default:default,org.eclipse.e4.core.di.annotations@default:default,org.eclipse.e4.core.di.extensions.supplier@default:default,org.eclipse.e4.core.di.extensions@default:default,org.eclipse.e4.core.di@default:default,org.eclipse.e4.core.services@default:default,org.eclipse.e4.emf.xpath@default:default,org.eclipse.e4.ui.bindings@default:default,org.eclipse.e4.ui.css.core@default:default,org.eclipse.e4.ui.css.swt.theme@default:default,org.eclipse.e4.ui.css.swt@default:default,org.eclipse.e4.ui.di@default:default,org.eclipse.e4.ui.dialogs@default:default,org.eclipse.e4.ui.model.workbench@default:default,org.eclipse.e4.ui.services@default:default,org.eclipse.e4.ui.widgets@default:default,org.eclipse.e4.ui.workbench.addons.swt@default:default,org.eclipse.e4.ui.workbench.renderers.swt@default:default,org.eclipse.e4.ui.workbench.swt@default:default,org.eclipse.e4.ui.workbench3@default:default,org.eclipse.e4.ui.workbench@default:default,org.eclipse.emf.common.ui@default:default,org.eclipse.emf.common@default:default,org.eclipse.emf.databinding.edit@default:default,org.eclipse.emf.databinding@default:default,org.eclipse.emf.ecore.change@default:default,org.eclipse.emf.ecore.xmi@default:default,org.eclipse.emf.ecore@default:default,org.eclipse.emf.edit.ui@default:default,org.eclipse.emf.edit@default:default,org.eclipse.emf.emfstore.client@default:default,org.eclipse.emf.emfstore.common.model@default:default,org.eclipse.emf.emfstore.common@default:default,org.eclipse.emf.emfstore.examplemodel.edit@default:default,org.eclipse.emf.emfstore.examplemodel@default:default,org.eclipse.emf.emfstore.migration@default:default,org.eclipse.emf.emfstore.server.model@default:default,org.eclipse.emf.emfstore.server@default:default,org.eclipse.equinox.app@default:default,org.eclipse.equinox.common@2:true,org.eclipse.equinox.ds@1:true,org.eclipse.equinox.event@default:default,org.eclipse.equinox.preferences@default:default,org.eclipse.equinox.region@default:false,org.eclipse.equinox.registry@default:default,org.eclipse.equinox.transforms.hook@default:false,org.eclipse.equinox.weaving.hook@default:false,org.eclipse.help@default:default,org.eclipse.jface.databinding@default:default,org.eclipse.jface.text@default:default,org.eclipse.jface@default:default,org.eclipse.net4j.util@default:default,org.eclipse.osgi.compatibility.state@default:false,org.eclipse.osgi.services@default:default,org.eclipse.osgi.util@default:default,org.eclipse.osgi@-1:true,org.eclipse.swt.cocoa.macosx.x86_64@default:default,org.eclipse.swt@default:default,org.eclipse.team.core@default:default,org.eclipse.text@default:default,org.eclipse.ui.forms@default:default,org.eclipse.ui.trace@default:default,org.eclipse.ui.views@default:default,org.eclipse.ui.workbench@default:default,org.eclipse.ui@default:default,org.hamcrest.core@default:default,org.hamcrest.library@default:default,org.junit@default:default,org.mockito.mockito-core-hamcrest-modified@default:default,org.objenesis@default:default,org.w3c.css.sac@default:default,org.w3c.dom.events@default:default,org.w3c.dom.smil*1.0.1.v200903091627@default:default,org.w3c.dom.svg@default:default"/>
+<stringAttribute key="selected_workspace_plugins" value="org.eclipse.emf.ecp.common.ui@default:default,org.eclipse.emf.ecp.common@default:default,org.eclipse.emf.ecp.core@default:default,org.eclipse.emf.ecp.edit.swt@default:default,org.eclipse.emf.ecp.edit@default:default,org.eclipse.emf.ecp.editor.e3@default:default,org.eclipse.emf.ecp.emfstore.core@default:default,org.eclipse.emf.ecp.explorereditorbridge@default:default,org.eclipse.emf.ecp.test.common@default:default,org.eclipse.emf.ecp.ui.view.swt@default:default,org.eclipse.emf.ecp.ui.view.test@default:default,org.eclipse.emf.ecp.ui.view@default:default,org.eclipse.emf.ecp.ui@default:default,org.eclipse.emf.ecp.view.context@default:default,org.eclipse.emf.ecp.view.control.multireference.tests@default:false,org.eclipse.emf.ecp.view.control.multireference@default:default,org.eclipse.emf.ecp.view.core.swt@default:default,org.eclipse.emf.ecp.view.group.model@default:default,org.eclipse.emf.ecp.view.label.model@default:default,org.eclipse.emf.ecp.view.migrator@default:default,org.eclipse.emf.ecp.view.model.common.di@default:default,org.eclipse.emf.ecp.view.model.common@default:default,org.eclipse.emf.ecp.view.model.provider.generator@default:default,org.eclipse.emf.ecp.view.model.provider.xmi@default:default,org.eclipse.emf.ecp.view.model@default:default,org.eclipse.emf.ecp.view.swt.layout@default:default,org.eclipse.emf.ecp.view.table.model.test@default:false,org.eclipse.emf.ecp.view.table.model@default:default,org.eclipse.emf.ecp.view.template.model@default:default,org.eclipse.emf.ecp.view.template.service@default:default,org.eclipse.emf.ecp.view.test.common.swt@default:default,org.eclipse.emf.ecp.view.test.common@default:default,org.eclipse.emf.ecp.view.util.swt@default:default,org.eclipse.emf.ecp.view.validation@default:default,org.eclipse.emf.ecp.view.vertical.model@default:default,org.eclipse.emfforms.common.prevalidation@default:default,org.eclipse.emfforms.common.validation@default:default,org.eclipse.emfforms.common@default:default,org.eclipse.emfforms.core.bazaar@default:default,org.eclipse.emfforms.core.services.databinding.testmodel@default:default,org.eclipse.emfforms.core.services.domainexpander.default@default:default,org.eclipse.emfforms.core.services.domainexpander.table@default:default,org.eclipse.emfforms.core.services.editsupport@default:default,org.eclipse.emfforms.core.services.emf@default:default,org.eclipse.emfforms.core.services.emfspecificservice@default:default,org.eclipse.emfforms.core.services.legacy@default:default,org.eclipse.emfforms.core.services.locale.default@default:default,org.eclipse.emfforms.core.services.mappingprovider.default@default:default,org.eclipse.emfforms.core.services.mappingprovider.table@default:default,org.eclipse.emfforms.core.services.segments@default:default,org.eclipse.emfforms.core.services.structuralchange.default@default:default,org.eclipse.emfforms.core.services.structuralchange@default:default,org.eclipse.emfforms.core.services@default:default,org.eclipse.emfforms.localization@default:default,org.eclipse.emfforms.swt.core.di@default:default,org.eclipse.emfforms.swt.core@default:default,org.eclipse.emfforms.view.annotation.model@default:default,org.eclipse.emfforms.view.multisegment.model@default:default"/>
<booleanAttribute key="show_selected_only" value="false"/>
<booleanAttribute key="tracing" value="false"/>
<booleanAttribute key="useCustomFeatures" value="false"/>
diff --git a/tests/org.eclipse.emf.ecp.view.control.multireference.tests/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceRenderer_PTest.java b/tests/org.eclipse.emf.ecp.view.control.multireference.tests/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceRenderer_PTest.java
index 3861602..95a846d 100644
--- a/tests/org.eclipse.emf.ecp.view.control.multireference.tests/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceRenderer_PTest.java
+++ b/tests/org.eclipse.emf.ecp.view.control.multireference.tests/src/org/eclipse/emf/ecp/view/internal/control/multireference/MultiReferenceRenderer_PTest.java
@@ -10,7 +10,7 @@
*
* Contributors:
* Lucas Koehler - initial API and implementation
- * Christian W. Damus - bug 527736
+ * Christian W. Damus - bugs 527736, 552385
******************************************************************************/
package org.eclipse.emf.ecp.view.internal.control.multireference;
@@ -56,6 +56,8 @@
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecp.edit.spi.DeleteService;
+import org.eclipse.emf.ecp.edit.spi.EMFDeleteServiceImpl;
import org.eclipse.emf.ecp.view.model.common.AbstractGridCell.Alignment;
import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
import org.eclipse.emf.ecp.view.spi.model.VControl;
@@ -177,6 +179,8 @@
when(viewContext.getDomainModel()).thenReturn(eObject);
when(viewContext.getViewModel()).thenReturn(vControl);
+ // Required for delete button enablement
+ when(viewContext.getService(DeleteService.class)).thenReturn(new EMFDeleteServiceImpl());
when(vControl.getDomainModelReference()).thenReturn(domainModelReference);