Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmallet2017-08-29 07:24:12 +0000
committerFlorian Barbin2017-09-15 13:08:29 +0000
commite65a98deb661e81239613231cbab291d76e21736 (patch)
tree6d073f1488a624b376df16bccf7943dae6a8425b
parent857b944a503190aa4120c4af16cc5a565ca69c08 (diff)
downloadorg.eclipse.sirius-e65a98deb661e81239613231cbab291d76e21736.tar.gz
org.eclipse.sirius-e65a98deb661e81239613231cbab291d76e21736.tar.xz
org.eclipse.sirius-e65a98deb661e81239613231cbab291d76e21736.zip
[517073] Improve validation and completion for Create Instance fields.
* Add validation that must check that elements with reference "Reference Name" is consistent with type "Type Name". * Update the completion of the "reference name" field to be consistent with the type name if it has been properly set. * Update the completion of the "type" field to be consistent with the reference name if it has been properly set. * Updates documentation and release note. Bug: 517073 Change-Id: Ibb22e07b8b0c381cac49401bcb7eb9b7f22c047c Signed-off-by: jmallet <jessy.mallet@obeo.fr> Signed-off-by: Florian Barbin <florian.barbin@obeo.fr>
-rw-r--r--plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java40
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release_Notes.html11
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile3
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html6
-rw-r--r--plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile1
-rw-r--r--plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceReferenceNamePropertySection.java4
-rw-r--r--plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceTypeNamePropertySection.java19
-rw-r--r--plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceFeatureProposalProvider.java43
-rw-r--r--plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceSiriusFeatureContentProposalProvider.java27
-rw-r--r--plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceTypeContentProposalProvider.java106
-rw-r--r--plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/SiriusFeatureContentProposalProvider.java11
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/invalidTypeVSM.odesign40
-rw-r--r--plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java13
-rw-r--r--plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/editor/vsm/FeatureAssistTest.java16
-rw-r--r--plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/api/assist/TextContentProposalProvider.java7
-rw-r--r--plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidFeatureNameConstraint.java47
16 files changed, 375 insertions, 19 deletions
diff --git a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java
index 9bc555a3ee..5cc255bd48 100644
--- a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java
+++ b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureProposalProvider.java
@@ -11,11 +11,13 @@
package org.eclipse.sirius.common.ui.tools.internal.interpreter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.sirius.common.tools.api.contentassist.ContentContext;
import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext;
@@ -66,7 +68,8 @@ public class FeatureProposalProvider implements IProposalProvider {
IInterpreterContext interpreterContext = context.getInterpreterContext();
for (TypeName type : interpreterContext.getTargetType().getPossibleTypes()) {
for (EClass possibleEClass : Iterables.filter(type.search(interpreterContext.getAvailableEPackages()), EClass.class)) {
- Set<ContentProposal> proposalsForThisType = Sets.newLinkedHashSet(getProposals(context.getContents(), context.getPosition(), possibleEClass));
+ Set<ContentProposal> proposalsForThisType = Sets
+ .newLinkedHashSet(getProposals(context.getContents(), context.getPosition(), possibleEClass, getExpectedFeatureType(interpreterContext)));
if (intersectingProposals == null) {
intersectingProposals = proposalsForThisType;
} else {
@@ -101,7 +104,7 @@ public class FeatureProposalProvider implements IProposalProvider {
} else if (context.getCurrentSelected() == null) {
proposals = Collections.singletonList(getNewEmtpyExpression());
} else {
- proposals = getProposals(context.getTextSoFar(), context.getCursorPosition(), context.getCurrentSelected().eClass());
+ proposals = getProposals(context.getTextSoFar(), context.getCursorPosition(), context.getCurrentSelected().eClass(), Collections.emptyList());
}
return proposals;
}
@@ -115,9 +118,11 @@ public class FeatureProposalProvider implements IProposalProvider {
* The current cursor position to consider only characters before it.
* @param currentElementType
* The current element type in the context.
+ * @param featureType
+ * the feature types.
* @return content proposal list.
*/
- private List<ContentProposal> getProposals(String writtenExpression, int cursorPosition, EClass currentElementType) {
+ private List<ContentProposal> getProposals(String writtenExpression, int cursorPosition, EClass currentElementType, Collection<EClass> featureTypes) {
final List<ContentProposal> proposals = new ArrayList<ContentProposal>();
// Keep only characters before cursor
@@ -136,7 +141,7 @@ public class FeatureProposalProvider implements IProposalProvider {
if (currentElementType != null) {
for (EStructuralFeature eStructuralFeature : currentElementType.getEAllStructuralFeatures()) {
- if (eStructuralFeature.getName().startsWith(userInput)) {
+ if (correctEType(eStructuralFeature, featureTypes) && eStructuralFeature.getName().startsWith(userInput)) {
String displayedName = eStructuralFeature.getName()
+ (eStructuralFeature.isMany() ? "[" + eStructuralFeature.getLowerBound() + ".." //$NON-NLS-1$//$NON-NLS-2$
+ (eStructuralFeature.getUpperBound() == -1 ? "*" : eStructuralFeature.getUpperBound()) + "]" : "") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
@@ -150,6 +155,19 @@ public class FeatureProposalProvider implements IProposalProvider {
return proposals;
}
+ private boolean correctEType(EStructuralFeature eStructuralFeature, Collection<EClass> featureTypes) {
+ boolean value = true;
+ if (!featureTypes.isEmpty()) {
+ EClassifier eType = eStructuralFeature.getEType();
+ if (eType instanceof EClass) {
+ value = featureTypes.stream().filter(featureType -> ((EClass) eType).isSuperTypeOf(featureType)).findFirst().isPresent();
+ } else {
+ value = false;
+ }
+ }
+ return value;
+ }
+
/**
* Return the content of the given string without the prefix handled by this provider.
*
@@ -174,4 +192,18 @@ public class FeatureProposalProvider implements IProposalProvider {
return new ArrayList<ContentProposal>(0);
}
+ /**
+ * If the feature proposal should restrict the list to features with a specific type, the method will return one or
+ * several type EClass according to the {@link IInterpreterContext}. If there is no specific type, the method
+ * returns an empty collection.
+ *
+ * @param context
+ * the {@link IInterpreterContext}.
+ *
+ * @return the {@link Collection} containing EClasses if a specific type is set.
+ */
+ protected Collection<EClass> getExpectedFeatureType(IInterpreterContext context) {
+ return Collections.emptyList();
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
index af42f7b341..f956d16651 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
+++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html
@@ -174,6 +174,16 @@
<em>Force Refresh</em> option of a tool is enabled in your VSM, only the current representation is refreshed when the tool is applied. Before this version, all open representations were refreshed.
</li>
<li><span class="label label-info">Modified</span> The filtering expression variables available in the properties view definition in the &#8216;Extends&#8217; tab were renamed to match the following pattern: featureName+&#8216;Description&#8217;.</li>
+ <li><span class="label label-info">Modified</span> The
+ <em>Reference Name</em> field of
+ <em>Create instance</em> completion will display only features with a consistent type with the one specified in
+ <em>Type Name</em> field (if a type has been specified).
+ </li>
+ <li><span class="label label-info">Modified</span> The
+ <em>Type Name</em> field of
+ <em>Create instance</em> completion will display only types consistent with the feature type specified in
+ <em>Reference Name</em> field (if a valid feature has been specified).
+ </li>
</ul>
<h3 id="DeveloperVisibleChanges">Developer-Visible Changes</h3>
<h4 id="Migrations">Migrations</h4>
@@ -330,6 +340,7 @@
<code>DRepresentation</code> from the
<code>DRepresentationDescriptor.getRepresentation()</code> method instead of performing a direct load.
</li>
+ <li><span class="label label-info">Modified</span> The org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider.getSelectedElement() method is now protected instead of private to let sub-classes retrieving the selected element.</li>
</ul>
<h4 id="Changesinorg.eclipse.sirius.ui.editor">Changes in
<code>org.eclipse.sirius.ui.editor</code>
diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
index 34b2dddb4d..9cca3b7cbf 100644
--- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile
@@ -33,6 +33,8 @@ h3. Specifier-Visible Changes
** Between these 2 limits, the label is considered as distant if the distance between the center of the label and the edge is higher than "four times the size of the nearest segment".
* <span class="label label-info">Modified</span> In manual refresh mode (_Automatic Refresh_ Sirius preference disabled), when the _Force Refresh_ option of a tool is enabled in your VSM, only the current representation is refreshed when the tool is applied. Before this version, all open representations were refreshed.
* <span class="label label-info">Modified</span> The filtering expression variables available in the properties view definition in the 'Extends' tab were renamed to match the following pattern: featureName+'Description'.
+* <span class="label label-info">Modified</span> The _Reference Name_ field of _Create instance_ completion will display only features with a consistent type with the one specified in _Type Name_ field (if a type has been specified).
+* <span class="label label-info">Modified</span> The _Type Name_ field of _Create instance_ completion will display only types consistent with the feature type specified in _Reference Name_ field (if a valid feature has been specified).
h3. Developer-Visible Changes
@@ -84,6 +86,7 @@ h4. Changes in @org.eclipse.sirius.ui@
* <span class="label label-success">Added</span> @org.eclipse.sirius.ui.tools.api.wizards.CreateEMFModelWizard@ is a new wizard that can be invoked to create instances of any metamodel. It will ask the end-user for a metamodel (@EPackage@), a concrete type to instanciate as root element, and finally the local path of the file to create. See the class Javadoc for sample usage. Note that the first two pages of the wizard (EPackage and root type selection) can be customized through the @org.eclipse.sirius.common.package_meta_data@ extension point to provide user-oriented name and documentation for an EPackage, and to suggest specific EClasses as good root candidates.
* <span class="label label-success">Added</span> @org.eclipse.sirius.ui.tools.api.command.AbstractSWTCallback.shouldDeleteRepresentation(Set<DRepresentationDescriptor>)@ default implementation has been added to prompt the confirm dialog.
* <span class="label label-success">Added</span> @org.eclipse.sirius.ui.business.api.session.SessionEditorInput.SessionEditorInput(URI, URI, String, Session)@ has been added to provide the @DRepresentationDescriptor@ URI to retrieve the @DRepresentation@ from the @DRepresentationDescriptor.getRepresentation()@ method instead of performing a direct load.
+* <span class="label label-info">Modified</span> The org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider.getSelectedElement() method is now protected instead of private to let sub-classes retrieving the selected element.
h4. Changes in @org.eclipse.sirius.ui.editor@
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html
index 0ab46ee7f2..2e9806cd6c 100644
--- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html
+++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.html
@@ -345,6 +345,12 @@
</p>
<p>Auto-completion is available in these fields using the
<em>Ctrl+Space</em> shortcut except if the current element type cannot be inferred, usually in the case of a generic tool where the target element will be known only at runtime.
+ <br/>Note that for
+ <em>Create Instance</em>
+ <em>Reference Name</em> field, the completion will display only features that have a type consistent with the one specified in the
+ <em>Type Name</em> field. If no type is specified, all available features will be displayed. In the same way, if a valid
+ <em>Reference Name</em> is set, the completion for the
+ <em>Type Name</em> field will display only types consistent with the feature type.
</p>
<h3 id="translatable_messages">Translatable Messages</h3>
<p>Many
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile
index d8ec433458..896cf1cb97 100644
--- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile
+++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Specifying_Viewpoints.textile
@@ -120,6 +120,7 @@ Some _VSM_ elements will need you to specify a _Feature Name_ (or _Reference Nam
!images/featureName.png!
Auto-completion is available in these fields using the _Ctrl+Space_ shortcut except if the current element type cannot be inferred, usually in the case of a generic tool where the target element will be known only at runtime.
+Note that for _Create Instance_ _Reference Name_ field, the completion will display only features that have a type consistent with the one specified in the _Type Name_ field. If no type is specified, all available features will be displayed. In the same way, if a valid _Reference Name_ is set, the completion for the _Type Name_ field will display only types consistent with the feature type.
h3(#translatable_messages). Translatable Messages
diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceReferenceNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceReferenceNamePropertySection.java
index b00c7064ce..6e52e712c5 100644
--- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceReferenceNamePropertySection.java
+++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceReferenceNamePropertySection.java
@@ -15,7 +15,7 @@ import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.sirius.editor.editorPlugin.SiriusEditor;
import org.eclipse.sirius.editor.properties.sections.common.AbstractTextPropertySection;
import org.eclipse.sirius.editor.tools.api.assist.TypeContentProposalProvider;
-import org.eclipse.sirius.editor.tools.internal.assist.SiriusFeatureContentProposalProvider;
+import org.eclipse.sirius.editor.tools.internal.assist.CreateInstanceSiriusFeatureContentProposalProvider;
import org.eclipse.sirius.ui.tools.api.assist.ContentProposalClient;
import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;
import org.eclipse.swt.SWT;
@@ -113,7 +113,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp
// Start of user code create controls
text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen"));
- TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text);
+ TypeContentProposalProvider.bindCompletionProcessor(this, new CreateInstanceSiriusFeatureContentProposalProvider(), text);
// End of user code create controls
}
diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceTypeNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceTypeNamePropertySection.java
index 771f8ce8a1..3986e38da9 100644
--- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceTypeNamePropertySection.java
+++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/createinstance/CreateInstanceTypeNamePropertySection.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007, 2013 THALES GLOBAL SERVICES.
+ * Copyright (c) 2007, 2017 THALES GLOBAL SERVICES.
* 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
@@ -13,8 +13,12 @@ package org.eclipse.sirius.editor.properties.sections.tool.createinstance;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.sirius.editor.editorPlugin.SiriusEditor;
+import org.eclipse.sirius.editor.editorPlugin.SiriusEditorPlugin;
import org.eclipse.sirius.editor.properties.sections.common.AbstractTextPropertySection;
import org.eclipse.sirius.editor.tools.api.assist.TypeContentProposalProvider;
+import org.eclipse.sirius.editor.tools.internal.assist.CreateInstanceTypeContentProposalProvider;
+import org.eclipse.sirius.editor.tools.internal.assist.TypeAssistant;
+import org.eclipse.sirius.ui.tools.api.assist.ContentProposalClient;
import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
@@ -28,7 +32,7 @@ import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
/**
* A section for the typeName property of a CreateInstance object.
*/
-public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertySection {
+public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertySection implements ContentProposalClient {
/** Help control of the section. */
protected CLabel help;
@@ -36,6 +40,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh()
*/
+ @Override
public void refresh() {
super.refresh();
@@ -48,6 +53,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText()
*/
+ @Override
protected String getDefaultLabelText() {
return "TypeName"; //$NON-NLS-1$
}
@@ -55,6 +61,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText()
*/
+ @Override
protected String getLabelText() {
String labelText;
labelText = super.getLabelText() + ":"; //$NON-NLS-1$
@@ -67,6 +74,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature()
*/
+ @Override
public EAttribute getFeature() {
return ToolPackage.eINSTANCE.getCreateInstance_TypeName();
}
@@ -74,6 +82,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String)
*/
+ @Override
protected Object getFeatureValue(String newText) {
return newText;
}
@@ -81,6 +90,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String)
*/
+ @Override
protected boolean isEqual(String newText) {
return getFeatureAsText().equals(newText);
}
@@ -88,6 +98,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* {@inheritDoc}
*/
+ @Override
public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) {
super.createControls(parent, tabbedPropertySheetPage);
/*
@@ -105,7 +116,8 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
help.setImage(getHelpIcon());
help.setToolTipText(getToolTipText());
- TypeContentProposalProvider.bindCompletionProcessor(this, text);
+ TypeAssistant typeAssistant = new TypeAssistant(SiriusEditorPlugin.getPlugin().getWorkspaceEPackageRegistry(), this);
+ TypeContentProposalProvider.bindCompletionProcessor(this, new CreateInstanceTypeContentProposalProvider(typeAssistant), text);
// Start of user code create controls
@@ -116,6 +128,7 @@ public class CreateInstanceTypeNamePropertySection extends AbstractTextPropertyS
/**
* {@inheritDoc}
*/
+ @Override
protected String getPropertyDescription() {
return "Type name of the instance to create.";
}
diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceFeatureProposalProvider.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceFeatureProposalProvider.java
new file mode 100644
index 0000000000..349efad03f
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceFeatureProposalProvider.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.editor.tools.internal.assist;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
+import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider;
+import org.eclipse.sirius.viewpoint.description.tool.CreateInstance;
+
+/**
+ * A specific {@link CreateInstance} {@link FeatureProposalProvider} to make possible to restrict the feature list
+ * according to the type.
+ *
+ * @author fbarbin
+ *
+ */
+public class CreateInstanceFeatureProposalProvider extends FeatureProposalProvider {
+
+ @Override
+ protected Collection<EClass> getExpectedFeatureType(IInterpreterContext context) {
+ EObject element = context.getElement();
+ if (element instanceof CreateInstance) {
+ String typeString = ((CreateInstance) element).getTypeName();
+ TypeName typeName = TypeName.fromString(typeString);
+ return typeName.search(context.getAvailableEPackages()).stream().filter(EClass.class::isInstance).map(EClass.class::cast).collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceSiriusFeatureContentProposalProvider.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceSiriusFeatureContentProposalProvider.java
new file mode 100644
index 0000000000..8abaaad29b
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceSiriusFeatureContentProposalProvider.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.editor.tools.internal.assist;
+
+import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider;
+
+/**
+ * A Specific {@link SiriusFeatureContentProposalProvider} for the CreateInstance reference name. It overrides the
+ * {@link FeatureProposalProvider} to make possible to restrict the feature proposal according to the type.
+ *
+ * @author fbarbin
+ *
+ */
+public class CreateInstanceSiriusFeatureContentProposalProvider extends SiriusFeatureContentProposalProvider {
+ @Override
+ protected FeatureProposalProvider createFeatureProposalProvider() {
+ return new CreateInstanceFeatureProposalProvider();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceTypeContentProposalProvider.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceTypeContentProposalProvider.java
new file mode 100644
index 0000000000..3662c31040
--- /dev/null
+++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/CreateInstanceTypeContentProposalProvider.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2017 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.sirius.editor.tools.internal.assist;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.jface.fieldassist.IContentProposal;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.util.StringUtil;
+import org.eclipse.sirius.editor.tools.api.assist.TypeContentProposalProvider;
+import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
+import org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider;
+import org.eclipse.sirius.viewpoint.description.tool.CreateInstance;
+import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;
+
+/**
+ * A {@link TypeContentProposalProvider} specific to the {@link CreateInstance} to restrict the type list according to
+ * the "Reference Name" field.
+ *
+ * @author fbarbin
+ *
+ */
+public class CreateInstanceTypeContentProposalProvider extends TextContentProposalProvider {
+
+ private final TypeAssistant assistant;
+
+ /**
+ * Create a new CreateInstanceTypeContentProposalProvider provider from an assistant.
+ *
+ * @param assistant
+ * assistant to use to provide proposals.
+ */
+ public CreateInstanceTypeContentProposalProvider(final TypeAssistant assistant) {
+ this.assistant = assistant;
+ }
+
+ @Override
+ public IContentProposal[] getProposals(final String contents, final int position) {
+ IInterpreterContext interpreterContext = createInterpretedContext();
+ final String incompleteText = contents.substring(0, position);
+ final List<EClassifier> proposals = assistant.proposal(incompleteText);
+
+ // We retrieve the potential type list of the feature specified in the reference name field.
+ Collection<EClass> superTypes = getPotentialSuperTypes(interpreterContext);
+ if (!superTypes.isEmpty()) {
+ for (Iterator<EClassifier> iterator = proposals.iterator(); iterator.hasNext(); /**/) {
+ EClassifier next = iterator.next();
+ // For each types (most of the time we will find only one type if only one feature matching the
+ // reference name has been found), we check if this type is a super type of the current proposal type.
+ Optional<EClassifier> optionalEClassifier = Optional.of(next).filter(EClass.class::isInstance).filter(eClass -> {
+ for (EClass superType : superTypes) {
+ if (superType.isSuperTypeOf((EClass) eClass)) {
+ return true;
+ }
+ }
+ return false;
+ });
+
+ // If the type is not a super type of the current proposal type, we remove it from the proposal list.
+ if (!optionalEClassifier.isPresent()) {
+ iterator.remove();
+ }
+ }
+ }
+ final IContentProposal[] result = new IContentProposal[proposals.size()];
+ for (int i = 0; i < proposals.size(); i++) {
+ final IContentProposal newProposal = new TypeContentProposal(proposals.get(i), incompleteText);
+ result[i] = newProposal;
+ }
+ return result;
+ }
+
+ private IInterpreterContext createInterpretedContext() {
+ Object selectedElement = getSelectedElement();
+ EStructuralFeature f = ToolPackage.eINSTANCE.getCreateInstance_ReferenceName();
+ return SiriusInterpreterContextFactory.createInterpreterContext((EObject) selectedElement, f);
+ }
+
+ private Collection<EClass> getPotentialSuperTypes(IInterpreterContext interpreterContext) {
+ final String referenceName = ((CreateInstance) interpreterContext.getElement()).getReferenceName();
+ if (!StringUtil.isEmpty(referenceName)) {
+ return interpreterContext.getTargetType().getPossibleTypes().stream().flatMap(type -> type.search(interpreterContext.getAvailableEPackages()).stream()).filter(EClass.class::isInstance)
+ .flatMap(eClass -> ((EClass) eClass).getEStructuralFeatures().stream()).filter(eStructuralFeature -> {
+ return eStructuralFeature.getName().equals(referenceName) && eStructuralFeature.getEType() instanceof EClass;
+ }).map(eStructuralFeature -> (EClass) eStructuralFeature.getEType()).collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/SiriusFeatureContentProposalProvider.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/SiriusFeatureContentProposalProvider.java
index 3c5fe42d4b..6c68a0beba 100644
--- a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/SiriusFeatureContentProposalProvider.java
+++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/SiriusFeatureContentProposalProvider.java
@@ -37,10 +37,19 @@ public class SiriusFeatureContentProposalProvider extends TextContentProposalPro
final ContentContext context = getContentContext(contents, position);
String proposalStart = new ContentContextHelper(contents, position, prefix).getProposalStart();
List<ContentProposal> proposals = new ArrayList<ContentProposal>();
- proposals.addAll(new FeatureProposalProvider().getProposals(null, context));
+ proposals.addAll(createFeatureProposalProvider().getProposals(null, context));
ContentProposalConverter contentProposalConverter = new ContentProposalConverter(proposalStart);
return contentProposalConverter.convertToJFaceContentProposals(proposals);
}
+ /**
+ * Creates the {@link FeatureProposalProvider}.
+ *
+ * @return the new created {@link FeatureProposalProvider}.
+ */
+ protected FeatureProposalProvider createFeatureProposalProvider() {
+ return new FeatureProposalProvider();
+ }
+
}
diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/invalidTypeVSM.odesign b/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/invalidTypeVSM.odesign
new file mode 100644
index 0000000000..547e205459
--- /dev/null
+++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/invalidTypeVSM.odesign
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<description:Group xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/diagram/description/1.1.0" xmlns:style="http://www.eclipse.org/sirius/diagram/description/style/1.1.0" xmlns:tool="http://www.eclipse.org/sirius/diagram/description/tool/1.1.0" xmlns:tool_1="http://www.eclipse.org/sirius/description/tool/1.1.0" name="invalidTypeVSM" version="12.0.0.2017041100">
+ <ownedViewpoints name="MyViewpoint" modelFileExtension="ecore">
+ <ownedRepresentations xsi:type="description_1:DiagramDescription" name="invalidDiag" initialisation="true" domainClass="ecore.EPackage" preconditionExpression="aql:self.eContainer() = null">
+ <metamodel href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+ <defaultLayer name="Default">
+ <nodeMappings name="Class" semanticCandidatesExpression="[eClassifiers/]" domainClass="ecore::EClass">
+ <style xsi:type="style:SquareDescription" labelPosition="node" resizeKind="NSEW">
+ <borderColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+ <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+ <color xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='gray']"/>
+ </style>
+ </nodeMappings>
+ <toolSections name="create">
+ <ownedTools xsi:type="tool:NodeCreationDescription" name="Create EClass" nodeMappings="//@ownedViewpoints[name='MyViewpoint']/@ownedRepresentations[name='invalidDiag']/@defaultLayer/@nodeMappings[name='Class']">
+ <variable name="container"/>
+ <viewVariable name="containerView"/>
+ <initialOperation>
+ <firstModelOperations xsi:type="tool_1:CreateInstance" typeName="ecore::EPackage" referenceName="eClassifiers"/>
+ </initialOperation>
+ </ownedTools>
+ <ownedTools xsi:type="tool:NodeCreationDescription" name="Create EClass2" nodeMappings="//@ownedViewpoints[name='MyViewpoint']/@ownedRepresentations[name='invalidDiag']/@defaultLayer/@nodeMappings[name='Class']">
+ <variable name="container"/>
+ <viewVariable name="containerView"/>
+ <initialOperation>
+ <firstModelOperations xsi:type="tool_1:CreateInstance" typeName="ecore::EClass" referenceName="eSubpackages"/>
+ </initialOperation>
+ </ownedTools>
+ <ownedTools xsi:type="tool:NodeCreationDescription" name="Create EClass3" nodeMappings="//@ownedViewpoints[name='MyViewpoint']/@ownedRepresentations[name='invalidDiag']/@defaultLayer/@nodeMappings[name='Class']">
+ <variable name="container"/>
+ <viewVariable name="containerView"/>
+ <initialOperation>
+ <firstModelOperations xsi:type="tool_1:CreateInstance" typeName="ecore::EPackage" referenceName="eSubpackages"/>
+ </initialOperation>
+ </ownedTools>
+ </toolSections>
+ </defaultLayer>
+ </ownedRepresentations>
+ </ownedViewpoints>
+</description:Group>
diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java
index b8d3ab38d9..5ac2f7fbb4 100644
--- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java
+++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/diagram/vsm/VSMValidationTest.java
@@ -62,6 +62,8 @@ public class VSMValidationTest extends SiriusDiagramTestCase {
private Group modelerForVariableNameValidation;
private Group modelerForInvalidVariableNameValidation;
+
+ private Group modelerForInvalidTypeValidation;
private Group modelerForImagePathValidation;
@@ -85,6 +87,7 @@ public class VSMValidationTest extends SiriusDiagramTestCase {
modelerForDomainClassValidation = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/valideDomainClassVSM.odesign", true), set);
modelerForVariableNameValidation = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/valideVariableNameVSM.odesign", true), set);
modelerForInvalidVariableNameValidation = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/invalidVariableNameVSM.odesign", true), set);
+ modelerForInvalidTypeValidation = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/invalidTypeVSM.odesign", true), set);
modelerForImagePathValidation = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/validateImagePathVSM.odesign", true), set);
modelerForDefaultLayerValidation = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/validateDefaultLayerVSM.odesign", true), set);
modelerWithAllKindOfError = (Group) ModelUtils.load(URI.createPlatformPluginURI("/org.eclipse.sirius.tests.junit/data/unit/vsm/validateVSMProblemSeverity.odesign", true), set);
@@ -285,6 +288,16 @@ public class VSMValidationTest extends SiriusDiagramTestCase {
assertEquals("The VSM is not valid, it should have popup error message", Diagnostic.ERROR, diagnostic.getSeverity());
assertEquals("Validation should have found 2 invalid variable names", 2, diagnostic.getChildren().size());
}
+
+ /**
+ * Ensure that VSM validation detects inconsistent referenceName type.
+ */
+ public void testTypeValidation() {
+ Diagnostician diagnostician = new Diagnostician();
+ Diagnostic diagnostic = diagnostician.validate(modelerForInvalidTypeValidation);
+ assertEquals("The VSM is not valid, it should have popup error message", Diagnostic.ERROR, diagnostic.getSeverity());
+ assertEquals("Validation should have found 2 invalid referenceName type", 2, diagnostic.getChildren().size());
+ }
/**
* Test VSM validation with diferent paths for images (there are valid and
diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/editor/vsm/FeatureAssistTest.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/editor/vsm/FeatureAssistTest.java
index e4d622efee..68d52af4f4 100644
--- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/editor/vsm/FeatureAssistTest.java
+++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/editor/vsm/FeatureAssistTest.java
@@ -73,7 +73,7 @@ public class FeatureAssistTest extends AbstractContentAssistTest {
*
*/
public void testFeatureCompletionForSetValueFeatureName() {
- testFeatureCompletion("Set stub", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
+ testFeatureCompletion("Set stub", "stubLooseFocusChange", "eAnnotations", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
}
/**
@@ -81,7 +81,7 @@ public class FeatureAssistTest extends AbstractContentAssistTest {
*
*/
public void testFeatureCompletionForUnsetFeatureName() {
- testFeatureCompletion("Unset stub", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
+ testFeatureCompletion("Unset stub", "stubLooseFocusChange", "eAnnotations", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
}
/**
@@ -89,7 +89,7 @@ public class FeatureAssistTest extends AbstractContentAssistTest {
*
*/
public void testFeatureCompletionForMoveElementFeatureName() {
- testFeatureCompletion("Move stub", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
+ testFeatureCompletion("Move stub", "stubLooseFocusChange", "eAnnotations", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
}
/**
@@ -97,7 +97,7 @@ public class FeatureAssistTest extends AbstractContentAssistTest {
*
*/
public void testFeatureCompletionForCreateInstanceFeatureName() {
- testFeatureCompletion("Create Instance ecore::EPackage", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
+ testFeatureCompletion("Create Instance ecore::EPackage", "stubLooseFocusChange", "ePackage", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE);
}
/**
@@ -105,17 +105,17 @@ public class FeatureAssistTest extends AbstractContentAssistTest {
*
*/
public void testFeatureCompletionForFeatureColumnMappingFeatureName() {
- testFeatureCompletion(COLUMN_MAPPING_NODE, "stubLooseFocusChange", TABLE_REPRESENTATION_NAME);
+ testFeatureCompletion(COLUMN_MAPPING_NODE, "stubLooseFocusChange", "eAnnotations", TABLE_REPRESENTATION_NAME);
}
/**
* Test feature completion for FeatureChangeListenerFeatureName.
*/
public void testFeatureCompletionForFeatureChangeListenerFeatureName() {
- testFeatureCompletion("Feature Change Listener stub", "ecore::EPackage", TREE_REPRESENTATION_NAME, "Drop Tool", "Filter");
+ testFeatureCompletion("Feature Change Listener stub", "ecore::EPackage", "eAnnotations", TREE_REPRESENTATION_NAME, "Drop Tool", "Filter");
}
- private void testFeatureCompletion(String operationToSelect, String firstTextToSet, String... nodesToExpend) {
+ private void testFeatureCompletion(String operationToSelect, String firstTextToSet, String expectedResult, String... nodesToExpend) {
// Open odesign file
SWTBotView projectExplorer = bot.viewById(IModelExplorerView.ID);
projectExplorer.setFocus();
@@ -153,7 +153,7 @@ public class FeatureAssistTest extends AbstractContentAssistTest {
// Use of content assist
selectContentAssistProposal(semanticCandidateExpressionText, 0, 0);
- assertEquals("The content of Semantic Candidate Expression after content assist use is not as expected", "eAnnotations", semanticCandidateExpressionText.getText());
+ assertEquals("The content of Semantic Candidate Expression after content assist use is not as expected", expectedResult, semanticCandidateExpressionText.getText());
} finally {
activeEditor.close();
}
diff --git a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/api/assist/TextContentProposalProvider.java b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/api/assist/TextContentProposalProvider.java
index f254e20890..582e372263 100644
--- a/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/api/assist/TextContentProposalProvider.java
+++ b/plugins/org.eclipse.sirius.ui/src/org/eclipse/sirius/ui/tools/api/assist/TextContentProposalProvider.java
@@ -110,7 +110,12 @@ public class TextContentProposalProvider implements IAssistContentProvider {
}
- private Object getSelectedElement() {
+ /**
+ * Provides the selectedElement.
+ *
+ * @return the selected elements.
+ */
+ protected Object getSelectedElement() {
if (element == null && view != null && view.getSelection() instanceof IStructuredSelection) {
return ((IStructuredSelection) view.getSelection()).getFirstElement();
} else {
diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidFeatureNameConstraint.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidFeatureNameConstraint.java
index 92df53b879..62800d22c2 100644
--- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidFeatureNameConstraint.java
+++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidFeatureNameConstraint.java
@@ -10,24 +10,31 @@
*******************************************************************************/
package org.eclipse.sirius.tools.internal.validation.description.constraints;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.Iterator;
import java.util.Optional;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.validation.IValidationContext;
import org.eclipse.emf.validation.model.ConstraintStatus;
+import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
+import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterStatus;
import org.eclipse.sirius.common.tools.api.interpreter.TypeName;
import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
import org.eclipse.sirius.tools.internal.validation.AbstractConstraint;
import org.eclipse.sirius.viewpoint.description.DescriptionPackage;
+import org.eclipse.sirius.viewpoint.description.tool.impl.CreateInstanceImpl;
+import com.google.common.collect.Iterables;
import com.google.common.collect.Sets;
/**
@@ -77,6 +84,10 @@ public class ValidFeatureNameConstraint extends AbstractConstraint {
.map(EClass.class::cast).flatMap(eClass -> eClass.getEAllStructuralFeatures().stream()).filter(f -> f.getName().equals(expression)).findFirst();
if (!optional.isPresent()) {
returnStatus = ctx.createFailureStatus(expression, variableType);
+ } else if (target instanceof CreateInstanceImpl) {
+ EClassifier eType = optional.get().getEType();
+ VariableType refType = VariableType.fromEClassifiers(Sets.newLinkedHashSet(Arrays.asList(eType)));
+ returnStatus = checkFeatureWithType(ctx, target, feature, refType);
}
}
@@ -86,6 +97,42 @@ public class ValidFeatureNameConstraint extends AbstractConstraint {
return returnStatus;
}
+ /**
+ * Check if referenceName type is consistent with type name.
+ *
+ * @param ctx
+ * context used to display status error
+ * @param target
+ * object to validate
+ * @param feature
+ * referenceName feature
+ * @return error status if referenceName type is not consistent with typeName, ok status otherwise.
+ */
+ private IStatus checkFeatureWithType(IValidationContext ctx, EObject target, EStructuralFeature feature, VariableType variableType) {
+ IInterpreterContext context = SiriusInterpreterContextFactory.createInterpreterContext(target, feature);
+ for (EAttribute feat : Iterables.filter(target.eClass().getEAllStructuralFeatures(), EAttribute.class)) {
+ if (DescriptionPackage.Literals.TYPE_NAME == feat.getEType()) {
+ Object value = target.eGet(feat);
+ if (value instanceof String) {
+ TypeName className = TypeName.fromString((String) value);
+ if (className.getPackagePrefix().some()) {
+ String expression = (String) target.eGet(feature);
+ context.getVariables().put("toCheck", variableType); //$NON-NLS-1$
+ Iterator<IInterpreterStatus> errors = MultiLanguagesValidator.getInstance().validateExpression(context, "aql:toCheck.oclIsKindOf(" + className.getCompleteName("::") + ")") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ .getStatuses().iterator();
+ while (errors.hasNext()) {
+ IInterpreterStatus s = errors.next();
+ if (s.getMessage().contains("Always false")) { //$NON-NLS-1$
+ return ctx.createFailureStatus(expression, className.getCompleteName("::")); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ }
+ return ctx.createSuccessStatus();
+ }
+
private boolean isTypeIdentified(VariableType variableType) {
return variableType.hasDefinition() && variableType.getPossibleTypes().stream().anyMatch(tn -> !TypeName.EOBJECT_TYPENAME.equals(tn));
}

Back to the top