Bug 550799 - Improve DataTemplate Editor reference handling
* Add a DataTemplate specific CreateNewModelElementStrategy which
forbids to add objects for non containment references
* Add a DataTemplate specific EObjectSelectionStrategy which only allows
objects from the same template
* Add RCPTT smoke test
Change-Id: I057c30f842d9a80fb1eed6b999312fd524d4c260
Signed-off-by: Eugen Neufeld <eneufeld@eclipsesource.com>
diff --git a/bundles/org.eclipse.emfforms.datatemplate.tooling/META-INF/MANIFEST.MF b/bundles/org.eclipse.emfforms.datatemplate.tooling/META-INF/MANIFEST.MF
index 443eb32..db5f121 100644
--- a/bundles/org.eclipse.emfforms.datatemplate.tooling/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.emfforms.datatemplate.tooling/META-INF/MANIFEST.MF
@@ -33,7 +33,10 @@
org.eclipse.emf.databinding;bundle-version="[1.3.0,2.0.0)",
org.eclipse.emfforms.swt.core.di;bundle-version="[1.22.0,1.23.0)"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
-Service-Component: OSGI-INF/org.eclipse.emfforms.internal.datatemplate.tooling.editor.TemplateInstanceRendererService.xml,OSGI-INF/org.eclipse.emfforms.internal.datatemplate.tooling.editor.DataTemplateEClassSelectionStrategyProvider.xml
+Service-Component: OSGI-INF/org.eclipse.emfforms.internal.datatemplate.tooling.editor.TemplateInstanceRendererService.xml,
+ OSGI-INF/org.eclipse.emfforms.internal.datatemplate.tooling.editor.DataTemplateEClassSelectionStrategyProvider.xml,
+ OSGI-INF/org.eclipse.emfforms.internal.datatemplate.tooling.editor.DataTemplateEObjectSelectionStrategyProvider.xml,
+ OSGI-INF/org.eclipse.emfforms.internal.datatemplate.tooling.editor.DataTemplateCreateNewModelElementStrategyProvider.xml
Bundle-ActivationPolicy: lazy
Import-Package: javax.inject;version="1.0.0",
org.eclipse.emf.ecp.ui.view.swt.reference;version="[1.22.0,1.23.0)",
diff --git a/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/DataTemplateCreateNewModelElementStrategyProvider.java b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/DataTemplateCreateNewModelElementStrategyProvider.java
new file mode 100644
index 0000000..eb7d4cc
--- /dev/null
+++ b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/DataTemplateCreateNewModelElementStrategyProvider.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * 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
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Eugen Neufeld - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emfforms.internal.datatemplate.tooling.editor;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecp.ui.view.swt.reference.CreateNewModelElementStrategy;
+import org.eclipse.emf.ecp.ui.view.swt.reference.CreateNewModelElementStrategy.Provider;
+import org.eclipse.emf.ecp.ui.view.swt.reference.ReferenceServiceCustomizationVendor;
+import org.eclipse.emfforms.bazaar.Create;
+import org.eclipse.emfforms.common.Optional;
+import org.eclipse.emfforms.datatemplate.Template;
+import org.eclipse.emfforms.datatemplate.TemplateCollection;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Display;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * Provides a strategy to the DefaultReferenceService
+ * that does not allow to create objects in non containment references inside data templates.
+ *
+ * @author Eugen Neufeld
+ * @since 1.23
+ */
+@Component(property = "service.ranking:Integer=20")
+public class DataTemplateCreateNewModelElementStrategyProvider
+ extends ReferenceServiceCustomizationVendor<CreateNewModelElementStrategy> implements Provider {
+
+ @Override
+ protected boolean handles(EObject owner, EReference reference) {
+ return !(owner instanceof Template) && !reference.isContainment()
+ && EcoreUtil.getRootContainer(owner) instanceof TemplateCollection;
+ }
+
+ /**
+ * Creates the {@link CreateNewModelElementStrategy}.
+ *
+ * @return The created {@link CreateNewModelElementStrategy}
+ */
+ @Create
+ public CreateNewModelElementStrategy createCreateNewModelElementStrategy() {
+ return new Strategy();
+ }
+
+ /**
+ * The actual {@link CreateNewModelElementStrategy strategy} that informes the user, that a new object cannot be
+ * created in a non containment references in a data template.
+ *
+ * @author Eugen Neufeld
+ */
+ class Strategy implements CreateNewModelElementStrategy {
+
+ @Override
+ public Optional<EObject> createNewModelElement(EObject owner, EReference reference) {
+ MessageDialog.openInformation(Display.getDefault().getActiveShell(),
+ Messages.DataTemplateCreateNewModelElement_0,
+ Messages.DataTemplateCreateNewModelElement_1);
+ return Optional.empty();
+ }
+
+ }
+}
diff --git a/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/DataTemplateEObjectSelectionStrategyProvider.java b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/DataTemplateEObjectSelectionStrategyProvider.java
new file mode 100644
index 0000000..2e3f2cd
--- /dev/null
+++ b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/DataTemplateEObjectSelectionStrategyProvider.java
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * 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
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Eugen Neufeld - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emfforms.internal.datatemplate.tooling.editor;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+import org.eclipse.emf.ecp.ui.view.swt.reference.EObjectSelectionStrategy;
+import org.eclipse.emf.ecp.ui.view.swt.reference.ReferenceServiceCustomizationVendor;
+import org.eclipse.emfforms.bazaar.Create;
+import org.eclipse.emfforms.datatemplate.Template;
+import org.eclipse.emfforms.datatemplate.TemplateCollection;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * Provider of an data template specific object selection strategy.
+ * The objects which are allowed to be selected must be from the same template as the object we want to add them to.
+ *
+ * @author Eugen Neufeld
+ * @since 1.23
+ */
+@Component(property = "service.ranking:Integer=5")
+public class DataTemplateEObjectSelectionStrategyProvider
+ extends ReferenceServiceCustomizationVendor<EObjectSelectionStrategy>
+ implements EObjectSelectionStrategy.Provider {
+
+ /**
+ * Initializes me.
+ */
+ public DataTemplateEObjectSelectionStrategyProvider() {
+ super();
+ }
+
+ @Override
+ protected boolean handles(EObject owner, EReference reference) {
+ return EcoreUtil.getRootContainer(owner) instanceof TemplateCollection;
+ }
+
+ /**
+ * Create the selection strategy.
+ *
+ * @return the selection strategy
+ */
+ @Create
+ public EObjectSelectionStrategy createEObjectSelectionStrategy() {
+ return new Strategy();
+ }
+
+ //
+ // Nested types
+ //
+
+ /**
+ * The selection strategy.
+ */
+ private static class Strategy implements EObjectSelectionStrategy {
+ /**
+ * Initializes me.
+ */
+ Strategy() {
+ super();
+ }
+
+ @Override
+ public Collection<EObject> collectExistingObjects(EObject owner, EReference reference,
+ Collection<EObject> existingObjects) {
+ final EObject template = getEnclosingTemplate(owner);
+ return existingObjects.stream().filter(o -> EcoreUtil.isAncestor(template,
+ o)).collect(Collectors.toList());
+ }
+
+ private EObject getEnclosingTemplate(EObject eObject) {
+ EObject parent = eObject.eContainer();
+ while (!(parent instanceof Template)) {
+ parent = parent.eContainer();
+ }
+ return parent;
+ }
+
+ }
+
+}
diff --git a/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/Messages.java b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/Messages.java
new file mode 100644
index 0000000..ba43e24
--- /dev/null
+++ b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * eugen - initial API and implementation
+ ******************************************************************************/
+package org.eclipse.emfforms.internal.datatemplate.tooling.editor;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * @author Eugen Neufeld
+ * @generated
+ */
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.emfforms.internal.datatemplate.tooling.editor.messages"; //$NON-NLS-1$
+ public static String DataTemplateCreateNewModelElement_0;
+ public static String DataTemplateCreateNewModelElement_1;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/messages.properties b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/messages.properties
new file mode 100644
index 0000000..6e48c9b
--- /dev/null
+++ b/bundles/org.eclipse.emfforms.datatemplate.tooling/src/org/eclipse/emfforms/internal/datatemplate/tooling/editor/messages.properties
@@ -0,0 +1,2 @@
+DataTemplateCreateNewModelElement_0=Cannot create element
+DataTemplateCreateNewModelElement_1=Cannot add new objects to non-containment references in a template.
diff --git a/tests/ECPQ7Tests/EPPTests/update-site/project/DataTemplateEditor Smoke.test b/tests/ECPQ7Tests/EPPTests/update-site/project/DataTemplateEditor Smoke.test
new file mode 100644
index 0000000..f76ee19
--- /dev/null
+++ b/tests/ECPQ7Tests/EPPTests/update-site/project/DataTemplateEditor Smoke.test
@@ -0,0 +1,102 @@
+--- RCPTT testcase ---
+Format-Version: 1.0
+Contexts: _ihvnUC3mEeSwhO5Nwx0hPg,_ih4KMC3mEeSwhO5Nwx0hPg,_D4Pj4C3lEeSwhO5Nwx0hPg
+Element-Name: DataTemplateEditor Smoke
+Element-Type: testcase
+Element-Version: 3.0
+External-Reference:
+Id: _XogaUM-8EemDG-PUFK2qgQ
+Runtime-Version: 2.4.2.201905052359
+Save-Time: 9/5/19 12:32 PM
+Testcase-Type: ecl
+
+------=_.content-0a7243a0-75d3-3d5f-9791-539de0e5b7ac
+Content-Type: text/ecl
+Entry-Name: .content
+
+get-view "Project Explorer" | get-tree | select "org.eclipse.emf.ecp.makeithappen.model.viewmodel" | get-menu
+ -path "New/Other..." | click
+get-window New | get-button "Next >" | click
+with [get-window -class WizardDialog] {
+ get-editbox -after [get-label "File name:"] | set-text "test.datatemplate"
+ get-button Finish | click
+}
+with [get-editor "test.datatemplate"] {
+ get-tree | select "Template Collection" | get-menu -path Template | click
+ get-button "Create and link new Instance" | click
+}
+get-window "Select Sub Class and Template" | get-tree | select "template/ViewTemplate" | double-click
+with [get-editor "test.datatemplate"] {
+ get-tree | select "Template Collection/Template/View Template" | get-menu -path Style | click
+ get-button "Link Style Property" | click
+}
+get-window "Select Elements" | get-table | get-property itemCount | equals 0 | verify-true
+get-window "Select Elements" | get-button Cancel | click
+get-editor "test.datatemplate" | get-button "Create and link new Style Property" | click
+with [get-window "Select Sub Class and Template"] {
+ get-tree | select "fontProperties/FontPropertiesStyleProperty"
+ get-button Finish | click
+}
+get-window FontPropertiesStyleProperty | get-button OK | click
+with [get-editor "test.datatemplate"] {
+ get-tree | select "Template Collection/Template/View Template" | get-menu -path Style | click
+ get-button "Link Style Property" | click
+}
+get-window "Select Elements" | get-table | get-property itemCount | equals 1 | verify-true
+get-window "Select Elements" | get-button Cancel | click
+get-editor "test.datatemplate" | get-button "Create and link new Style Property" | click
+with [get-window "Select Sub Class and Template"] {
+ get-tree | select "tableValidation/TableValidationStyleProperty"
+ get-button Finish | click
+}
+with [get-window TableValidationStyleProperty] {
+ get-editbox -after [get-label "Column Width"] | set-focus
+ get-button Cancel | click
+}
+with [get-editor "test.datatemplate"] {
+ get-tree | select "Template Collection" | get-menu -path Template | click
+ get-button "Create and link new Instance" | click
+}
+with [get-window "Select Sub Class and Template"] {
+ get-tree | select "template/ViewTemplate"
+ get-button Finish | click
+}
+with [get-editor "test.datatemplate"] {
+ get-tree | select [get-item -path "Template Collection" | get-item -path Template -index 1 | get-item
+ -path "View Template"] | get-menu -path Style | click
+ get-button "Link Style Property" | click
+}
+get-window "Select Elements" | get-table | get-property itemCount | equals 0 | verify-true
+get-window "Select Elements" | get-button Cancel | click
+with [get-editor "test.datatemplate"] {
+ get-tree | select "Template Collection" | get-menu -path Template | click
+ get-button "Create and link new Instance" | click
+}
+get-window "Select Sub Class and Template" | get-tree | select "bowling/League" | double-click
+with [get-editor "test.datatemplate"] {
+ get-tree | select [get-item -path "Template Collection" | get-item -path Template -index 2 | get-item -path League]
+ get-button "Add an instance of Player" | click
+ get-tree | select [get-item -path "Template Collection" | get-item -path Template -index 2]
+ get-button "Delete Reference" | click
+}
+get-window Confirmation | get-button Yes | click
+get-editor "test.datatemplate" | get-tree | get-item -path "Template Collection" | get-item -path Template -index 2
+ | get-property childCount | equals 0 | verify-true
+with [get-editor "test.datatemplate"] {
+ get-tree | select [get-item -path "Template Collection" | get-item -path Template -index 2]
+ get-button "Create and link new Instance" | click
+}
+with [get-window "Select Sub Class and Template"] {
+ get-tree | select "bowling/Fan"
+ get-button Finish | click
+}
+with [get-editor "test.datatemplate"] {
+ get-tree | select [get-item -path "Template Collection" | get-item -path Template -index 2 | get-item -path Fan]
+ get-button "Create and link new Tournament" | click
+}
+get-window "Cannot create element"
+ | get-label "This is a template, you cannot add new objects to non containment references here."
+ | get-property caption
+ | equals "This is a template, you cannot add new objects to non containment references here." | verify-true
+get-window "Cannot create element" | get-button OK | click
+------=_.content-0a7243a0-75d3-3d5f-9791-539de0e5b7ac--