diff options
| author | pguilet | 2017-03-24 10:12:14 +0000 |
|---|---|---|
| committer | Pierre-Charles David | 2017-05-16 15:19:30 +0000 |
| commit | 02f266cd9d0d5b83346755a8edc72f66a5ff8514 (patch) | |
| tree | b0380fdc1883187db66aa5784efc02257dab083e | |
| parent | 5df158d382bc6489ef954871c7ea4f422dfb8359 (diff) | |
| download | org.eclipse.sirius-02f266cd9d0d5b83346755a8edc72f66a5ff8514.tar.gz org.eclipse.sirius-02f266cd9d0d5b83346755a8edc72f66a5ff8514.tar.xz org.eclipse.sirius-02f266cd9d0d5b83346755a8edc72f66a5ff8514.zip | |
[479049] Add completion and validation for feature names in VSM editor
Bug: 479049
Change-Id: I4370b223907686685614cbbebe848d0b2b528ec2
Signed-off-by: pguilet <pierre.guilet@obeo.fr>
29 files changed, 927 insertions, 232 deletions
diff --git a/plugins/org.eclipse.sirius.common.ui/plugin.xml b/plugins/org.eclipse.sirius.common.ui/plugin.xml index a6f1cbcafc..8ad9bae7f8 100644 --- a/plugins/org.eclipse.sirius.common.ui/plugin.xml +++ b/plugins/org.eclipse.sirius.common.ui/plugin.xml @@ -31,7 +31,7 @@ interpreter="org.eclipse.sirius.common.variableInterpreter"> </proposalProvider> <proposalProvider - class="org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider" + class="org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureAndPseudoFeatureProposalProvider" interpreter="org.eclipse.sirius.common.featureInterpreter"> </proposalProvider> <proposalProvider diff --git a/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureAndPseudoFeatureProposalProvider.java b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureAndPseudoFeatureProposalProvider.java new file mode 100644 index 0000000000..7f230974d1 --- /dev/null +++ b/plugins/org.eclipse.sirius.common.ui/src/org/eclipse/sirius/common/ui/tools/internal/interpreter/FeatureAndPseudoFeatureProposalProvider.java @@ -0,0 +1,80 @@ +/******************************************************************************* + * 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.common.ui.tools.internal.interpreter; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.emf.ecore.EClass; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal; +import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter; + +/** + * Provides completion for the feature interpreter. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + */ +public class FeatureAndPseudoFeatureProposalProvider extends FeatureProposalProvider { + private static final String SEPARATOR_3 = "[0..*]"; //$NON-NLS-1$ + + @Override + protected List<ContentProposal> addComputedFeatures(String featureNamePrefix) { + List<ContentProposal> proposals = new ArrayList<ContentProposal>(); + String eObjectName = EObject.class.getSimpleName(); + + String eContainerFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[0]; + + if (eContainerFeatureName.startsWith(featureNamePrefix)) { + String displayedName = eContainerFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_2 + eObjectName; + proposals.add(new ContentProposal(eContainerFeatureName, displayedName, displayedName)); + } + + String eContentsFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[1]; + if (eContentsFeatureName.startsWith(featureNamePrefix)) { + String displayedName = eContentsFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2 + eObjectName; + proposals.add(new ContentProposal(eContentsFeatureName, displayedName, displayedName)); + } + + String eAllContentsFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[2]; + if (eAllContentsFeatureName.startsWith(featureNamePrefix)) { + String displayedName = eAllContentsFeatureName + SEPARATOR_1 + "TreeIterator" + SEPARATOR_2 + eObjectName; //$NON-NLS-1$ + proposals.add(new ContentProposal(eAllContentsFeatureName, displayedName, displayedName)); + } + + String eClassFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[3]; + if (eClassFeatureName.startsWith(featureNamePrefix)) { + String displayedName = eClassFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2 + EClass.class.getSimpleName(); + proposals.add(new ContentProposal(eClassFeatureName, displayedName, displayedName)); + } + String eReferencesFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[4]; + if (eReferencesFeatureName.startsWith(featureNamePrefix)) { + String displayedName = eReferencesFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2 + eObjectName; + proposals.add(new ContentProposal(eReferencesFeatureName, displayedName, displayedName)); + } + return proposals; + } + + @Override + protected String getContentWithoutPrefix(String featureNamePrefix) { + // We remove the feature: prefix + if (featureNamePrefix.length() >= FeatureInterpreter.PREFIX.length()) { + return featureNamePrefix.trim().substring(FeatureInterpreter.PREFIX.length()); + } + return null; + } + + @Override + protected boolean isPrefixUsed() { + return true; + } + +} 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 71d7f2dbe6..9bc555a3ee 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 @@ -1,12 +1,12 @@ /******************************************************************************* - * Copyright (c) 2013 THALES GLOBAL SERVICES. + * 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 + * Obeo - initial API and implementation *******************************************************************************/ package org.eclipse.sirius.common.ui.tools.internal.interpreter; @@ -16,7 +16,6 @@ import java.util.List; import java.util.Set; import org.eclipse.emf.ecore.EClass; -import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.sirius.common.tools.api.contentassist.ContentContext; import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext; @@ -33,18 +32,22 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** - * A {@link IProposalProvider} to provide completion for the feature - * interpreter. + * All instances of this abstract {@link IProposalProvider} provide feature proposals of ECLass for feature interpreter. * - * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a> + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * */ public class FeatureProposalProvider implements IProposalProvider { - private static final String SEPARATOR_1 = ":"; //$NON-NLS-1$ - - private static final String SEPARATOR_2 = " - "; //$NON-NLS-1$ + /** + * Separator used to construct proposals. + */ + protected static final String SEPARATOR_1 = ":"; //$NON-NLS-1$ - private static final String SEPARATOR_3 = "[0..*]"; //$NON-NLS-1$ + /** + * Separator used to construct proposals. + */ + protected static final String SEPARATOR_2 = " - "; //$NON-NLS-1$ @Override public ContentProposal getNewEmtpyExpression() { @@ -54,9 +57,9 @@ public class FeatureProposalProvider implements IProposalProvider { @Override public List<ContentProposal> getProposals(IInterpreter interpreter, ContentContext context) { final List<ContentProposal> proposals; - if (context == null || !(interpreter instanceof FeatureInterpreter)) { + if (context == null || (!(interpreter instanceof FeatureInterpreter)) && interpreter != null) { proposals = Collections.emptyList(); - } else if (context.getContents() == null || context.getContents().length() == 0) { + } else if ((context.getContents() == null || context.getContents().length() == 0) && isPrefixUsed()) { proposals = Collections.singletonList(getNewEmtpyExpression()); } else { Set<ContentProposal> intersectingProposals = null; @@ -81,6 +84,15 @@ public class FeatureProposalProvider implements IProposalProvider { return proposals; } + /** + * True if the provider use a prefix. False otherwise. + * + * @return True if the provider use a prefix. False otherwise. + */ + protected boolean isPrefixUsed() { + return false; + } + @Override public List<ContentProposal> getProposals(IInterpreter interpreter, ContentInstanceContext context) { final List<ContentProposal> proposals; @@ -95,14 +107,12 @@ public class FeatureProposalProvider implements IProposalProvider { } /** - * Evaluates the content proposals for a given expression and returns the - * result as a list. + * Evaluates the content proposals for a given expression and returns the result as a list. * * @param writtenExpression * The complete expression with feature: prefix. * @param cursorPosition - * The current cursor position to consider only characters before - * it. + * The current cursor position to consider only characters before it. * @param currentElementType * The current element type in the context. * @return content proposal list. @@ -111,52 +121,24 @@ public class FeatureProposalProvider implements IProposalProvider { final List<ContentProposal> proposals = new ArrayList<ContentProposal>(); // Keep only characters before cursor - String featureNamePrefix = writtenExpression.substring(0, cursorPosition); + String featureNameWithPrefix = writtenExpression.substring(0, cursorPosition); // Remove not needed space characters. - featureNamePrefix = featureNamePrefix.trim(); + featureNameWithPrefix = featureNameWithPrefix.trim(); // Remove "feature:" prefix if the cursor position is after the prefix // If the cursor position is before the prefix, there is no proposal // returned. - if (featureNamePrefix.length() >= FeatureInterpreter.PREFIX.length()) { - featureNamePrefix = featureNamePrefix.trim().substring(FeatureInterpreter.PREFIX.length()); - - String eObjectName = EObject.class.getSimpleName(); - - String eContainerFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[0]; - if (eContainerFeatureName.startsWith(featureNamePrefix)) { - String displayedName = eContainerFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_2 + eObjectName; - proposals.add(new ContentProposal(eContainerFeatureName, displayedName, displayedName)); - } - - String eContentsFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[1]; - if (eContentsFeatureName.startsWith(featureNamePrefix)) { - String displayedName = eContentsFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2 + eObjectName; - proposals.add(new ContentProposal(eContentsFeatureName, displayedName, displayedName)); - } - - String eAllContentsFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[2]; - if (eAllContentsFeatureName.startsWith(featureNamePrefix)) { - String displayedName = eAllContentsFeatureName + SEPARATOR_1 + "TreeIterator" + SEPARATOR_2 + eObjectName; //$NON-NLS-1$ - proposals.add(new ContentProposal(eAllContentsFeatureName, displayedName, displayedName)); - } - - String eClassFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[3]; - if (eClassFeatureName.startsWith(featureNamePrefix)) { - String displayedName = eClassFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2 + EClass.class.getSimpleName(); - proposals.add(new ContentProposal(eClassFeatureName, displayedName, displayedName)); - } - - String eReferencesFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[4]; - if (eReferencesFeatureName.startsWith(featureNamePrefix)) { - String displayedName = eReferencesFeatureName + SEPARATOR_1 + eObjectName + SEPARATOR_3 + SEPARATOR_2 + eObjectName; - proposals.add(new ContentProposal(eReferencesFeatureName, displayedName, displayedName)); + String userInput = getContentWithoutPrefix(featureNameWithPrefix); + if (userInput != null) { + List<ContentProposal> newComputedFeatures = addComputedFeatures(userInput); + if (newComputedFeatures != null) { + proposals.addAll(newComputedFeatures); } if (currentElementType != null) { for (EStructuralFeature eStructuralFeature : currentElementType.getEAllStructuralFeatures()) { - if (eStructuralFeature.getName().startsWith(featureNamePrefix)) { + if (eStructuralFeature.getName().startsWith(userInput)) { String displayedName = eStructuralFeature.getName() - + (eStructuralFeature.isMany() ? "[" + eStructuralFeature.getLowerBound() + ".." //$NON-NLS-1$//$NON-NLS-2$ + + (eStructuralFeature.isMany() ? "[" + eStructuralFeature.getLowerBound() + ".." //$NON-NLS-1$//$NON-NLS-2$ + (eStructuralFeature.getUpperBound() == -1 ? "*" : eStructuralFeature.getUpperBound()) + "]" : "") //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + (eStructuralFeature.getEType() != null ? SEPARATOR_1 + eStructuralFeature.getEType().getName() : "") + SEPARATOR_2 //$NON-NLS-1$ + eStructuralFeature.getEContainingClass().getName(); @@ -168,4 +150,28 @@ public class FeatureProposalProvider implements IProposalProvider { return proposals; } + /** + * Return the content of the given string without the prefix handled by this provider. + * + * @param featureNameWithPrefix + * the current user input that can contains the prefix handled by this provider. + * @return the content of the given string without the prefix handled by this provider. Null if no proposal can + */ + protected String getContentWithoutPrefix(String featureNameWithPrefix) { + // this provider is used without prefix so we return it as we got it. + return featureNameWithPrefix; + } + + /** + * Adds some additional features handled by this provider that can be different from the one retrieved by method + * org.eclipse.emf.ecore.EClass.getEAllStructuralFeatures(). + * + * @param userInput + * the user input from which some additional features can be computed and added to the proposals. + * @return some additional proposals regarding the given input. If no such element exists, return null. + */ + protected List<ContentProposal> addComputedFeatures(String userInput) { + return new ArrayList<ContentProposal>(0); + } + } diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html index 3bb32dbbe9..fc4aeaa81a 100644 --- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html +++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.html @@ -436,6 +436,12 @@ <li><span class="label label-success">Added</span> The method <code>org.eclipse.sirius.ui.business.api.dialect.DialectUIServices.refreshEditor(DialectEditor, IProgressMonitor)</code> has been added to allow specifiers to do a full refresh of its dialect editor easily. </li> + <li><span class="label label-info">Modified</span> The method + <code>org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider.getContentContext(String, int)</code> has been made protected instead of private to allow to use it for sub types. + </li> + <li><span class="label label-info">Modified</span> The method + <code>org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider.removeDuplicatedProposals(List<ContentProposal>)</code> has been made protected instead of private to allow to use it in sub types. + </li> <li><span class="label label-success">Added</span> The method <code>org.eclipse.sirius.ui.tools.api.color.VisualBindingManager.getDefaultFontWithRuntimeSizeAndFromLabelFormat(List<FontFormat>)</code> has been added to allow to retrieve a font using the given format and the default Sirius font (arial) and the runtime height. </li> @@ -1728,6 +1734,15 @@ SWTBotUtils.waitAllUiEvents(); <code>org.eclipse.sirius.editor</code>) still depends on PDE (and thus indirectly the JDT too). </li> </ul> + <h4 id="Changesinorg.eclipse.sirius.editor">Changes in + <code>org.eclipse.sirius.editor</code> + </h4> + <ul> + <li><span class="label label-success">Added</span> The method + <code>bindCompletionProcessor(AbstractPropertySection, IAssistContentProvider, Text)</code> has been added to the class + <code>org.eclipse.sirius.editor.tools.api.assist.TypeContentProposalProvider</code> to allow to bind a specific IAssistContentProvider to the text. + </li> + </ul> <h2 id="sirius3.1.0">Changes in Sirius 3.1.0</h2> <h3 id="UserVisibleChanges7">User-Visible Changes</h3> <ul> diff --git a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile index db2e5793b1..83de2e9edf 100644 --- a/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile +++ b/plugins/org.eclipse.sirius.doc/doc/Release_Notes.textile @@ -121,6 +121,8 @@ h4. Changes in @org.eclipse.sirius@ h4. Changes in @org.eclipse.sirius.ui@ * <span class="label label-success">Added</span> The method @org.eclipse.sirius.ui.business.api.dialect.DialectUIServices.refreshEditor(DialectEditor, IProgressMonitor)@ has been added to allow specifiers to do a full refresh of its dialect editor easily. +* <span class="label label-info">Modified</span> The method @org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider.getContentContext(String, int)@ has been made protected instead of private to allow to use it for sub types. +* <span class="label label-info">Modified</span> The method @org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider.removeDuplicatedProposals(List<ContentProposal>)@ has been made protected instead of private to allow to use it in sub types. * <span class="label label-success">Added</span> The method @org.eclipse.sirius.ui.tools.api.color.VisualBindingManager.getDefaultFontWithRuntimeSizeAndFromLabelFormat(List<FontFormat>)@ has been added to allow to retrieve a font using the given format and the default Sirius font (arial) and the runtime height. * <span class="label label-success">Added</span> The method @org.eclipse.sirius.ui.tools.api.color.VisualBindingManager.getFontFromNameAndLabelFormatAndWithDefaultSize(List<FontFormat>, String)@ has been added to allow to retrieve a font using the given format and the given font name and the runtime height. * <span class="label label-info">Modified</span> The method @org.eclipse.sirius.ui.tools.api.project.ModelingProjectManager.createLocalRepresentationsFile(IProject, IProgressMonitor)@ has its return type changed from @void@ to @Session@ to allow callers to have access to the newly created session directly. @@ -535,6 +537,9 @@ h4. Changes in @org.eclipse.sirius.common.xtext@ * <span class="label label-info">Modified</span> The dependency from @org.eclipse.sirius.common.xtext@ to the JDT plug-in @org.eclipse.jdt.core@ is now optional. If you need the JDT Core in your environment, you will need to add the dependency explicitly. The Sirius specification environment (@org.eclipse.sirius.editor@) still depends on PDE (and thus indirectly the JDT too). +h4. Changes in @org.eclipse.sirius.editor@ + +* <span class="label label-success">Added</span> The method @bindCompletionProcessor(AbstractPropertySection, IAssistContentProvider, Text)@ has been added to the class @org.eclipse.sirius.editor.tools.api.assist.TypeContentProposalProvider@ to allow to bind a specific IAssistContentProvider to the text. h2(#sirius3.1.0). Changes in Sirius 3.1.0 diff --git a/plugins/org.eclipse.sirius.editor.table/src-gen/org/eclipse/sirius/table/editor/properties/sections/description/featurecolumnmapping/FeatureColumnMappingFeatureNamePropertySection.java b/plugins/org.eclipse.sirius.editor.table/src-gen/org/eclipse/sirius/table/editor/properties/sections/description/featurecolumnmapping/FeatureColumnMappingFeatureNamePropertySection.java index ac796e8ca6..81ad1651a1 100644 --- a/plugins/org.eclipse.sirius.editor.table/src-gen/org/eclipse/sirius/table/editor/properties/sections/description/featurecolumnmapping/FeatureColumnMappingFeatureNamePropertySection.java +++ b/plugins/org.eclipse.sirius.editor.table/src-gen/org/eclipse/sirius/table/editor/properties/sections/description/featurecolumnmapping/FeatureColumnMappingFeatureNamePropertySection.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 @@ -14,6 +14,8 @@ package org.eclipse.sirius.table.editor.properties.sections.description.featurec 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.table.metamodel.table.description.DescriptionPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -35,6 +37,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +50,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * @see org.eclipse.sirius.table.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "FeatureName"; //$NON-NLS-1$ } @@ -54,6 +58,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * @see org.eclipse.sirius.table.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +71,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * @see org.eclipse.sirius.table.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return DescriptionPackage.eINSTANCE.getFeatureColumnMapping_FeatureName(); } @@ -73,6 +79,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * @see org.eclipse.sirius.table.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +87,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * @see org.eclipse.sirius.table.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +95,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +111,8 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +120,7 @@ public class FeatureColumnMappingFeatureNamePropertySection extends AbstractText /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "The name of the feature."; } diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/editorPlugin/SiriusEditor.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/editorPlugin/SiriusEditor.java index 71251dd597..8b74b5e94d 100644 --- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/editorPlugin/SiriusEditor.java +++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/editorPlugin/SiriusEditor.java @@ -1411,7 +1411,7 @@ public class SiriusEditor extends MultiPageEditorPart colorRegistry.put("gray", new RGB(209, 210, 208)); colorRegistry.put("light_blue", new RGB(212, 229, 247)); // Start of user code put your own colors here - + colorRegistry.put("lightgreen", new RGB(227, 249, 204)); // End of user code put your own colors here } 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 6cf60e3fb0..b00c7064ce 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 @@ -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 @@ -14,6 +14,9 @@ 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.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.ui.tools.api.assist.ContentProposalClient; import org.eclipse.sirius.viewpoint.description.tool.ToolPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -27,7 +30,7 @@ import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage; /** * A section for the referenceName property of a CreateInstance object. */ -public class CreateInstanceReferenceNamePropertySection extends AbstractTextPropertySection { +public class CreateInstanceReferenceNamePropertySection extends AbstractTextPropertySection implements ContentProposalClient { /** Help control of the section. */ protected CLabel help; @@ -35,6 +38,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +51,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "ReferenceName"; //$NON-NLS-1$ } @@ -54,6 +59,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +72,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return ToolPackage.eINSTANCE.getCreateInstance_ReferenceName(); } @@ -73,6 +80,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +88,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +96,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +112,8 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +121,7 @@ public class CreateInstanceReferenceNamePropertySection extends AbstractTextProp /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "Reference name in which the new instance will be stored. This reference should be part of the container element."; } diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/featurechangelistener/FeatureChangeListenerFeatureNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/featurechangelistener/FeatureChangeListenerFeatureNamePropertySection.java index 5a7d861954..9a654be9d8 100644 --- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/featurechangelistener/FeatureChangeListenerFeatureNamePropertySection.java +++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/featurechangelistener/FeatureChangeListenerFeatureNamePropertySection.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 @@ -14,6 +14,8 @@ package org.eclipse.sirius.editor.properties.sections.tool.featurechangelistener 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.viewpoint.description.tool.ToolPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -35,6 +37,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +50,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "FeatureName"; //$NON-NLS-1$ } @@ -54,6 +58,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +71,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return ToolPackage.eINSTANCE.getFeatureChangeListener_FeatureName(); } @@ -73,6 +79,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +87,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +95,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +111,8 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +120,7 @@ public class FeatureChangeListenerFeatureNamePropertySection extends AbstractTex /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "Feature name of the element to listen "; } diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/moveelement/MoveElementFeatureNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/moveelement/MoveElementFeatureNamePropertySection.java index fc3147e3cf..8ee7cf30c6 100644 --- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/moveelement/MoveElementFeatureNamePropertySection.java +++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/moveelement/MoveElementFeatureNamePropertySection.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 @@ -14,6 +14,8 @@ package org.eclipse.sirius.editor.properties.sections.tool.moveelement; 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.viewpoint.description.tool.ToolPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -35,6 +37,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +50,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "FeatureName"; //$NON-NLS-1$ } @@ -54,6 +58,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +71,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return ToolPackage.eINSTANCE.getMoveElement_FeatureName(); } @@ -73,6 +79,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +87,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +95,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +111,8 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +120,7 @@ public class MoveElementFeatureNamePropertySection extends AbstractTextPropertyS /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "Name of the feature on the new container used to store the element."; } diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setobject/SetObjectFeatureNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setobject/SetObjectFeatureNamePropertySection.java index 99fc2b4788..597d899c25 100644 --- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setobject/SetObjectFeatureNamePropertySection.java +++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setobject/SetObjectFeatureNamePropertySection.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 @@ -14,6 +14,8 @@ package org.eclipse.sirius.editor.properties.sections.tool.setobject; 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.viewpoint.description.tool.ToolPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -35,6 +37,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +50,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "FeatureName"; //$NON-NLS-1$ } @@ -54,6 +58,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +71,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return ToolPackage.eINSTANCE.getSetObject_FeatureName(); } @@ -73,6 +79,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +87,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +95,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +111,8 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +120,7 @@ public class SetObjectFeatureNamePropertySection extends AbstractTextPropertySec /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "Name of the feature to set."; } diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setvalue/SetValueFeatureNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setvalue/SetValueFeatureNamePropertySection.java index 4aa5ed9994..ebc696f408 100644 --- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setvalue/SetValueFeatureNamePropertySection.java +++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/setvalue/SetValueFeatureNamePropertySection.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 @@ -14,6 +14,8 @@ package org.eclipse.sirius.editor.properties.sections.tool.setvalue; 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.viewpoint.description.tool.ToolPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -35,6 +37,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +50,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "FeatureName"; //$NON-NLS-1$ } @@ -54,6 +58,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +71,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return ToolPackage.eINSTANCE.getSetValue_FeatureName(); } @@ -73,6 +79,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +87,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +95,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +111,8 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +120,7 @@ public class SetValueFeatureNamePropertySection extends AbstractTextPropertySect /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "Name of the feature to set."; } diff --git a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/unset/UnsetFeatureNamePropertySection.java b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/unset/UnsetFeatureNamePropertySection.java index de2154496e..19f2d9092d 100644 --- a/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/unset/UnsetFeatureNamePropertySection.java +++ b/plugins/org.eclipse.sirius.editor/src-gen/org/eclipse/sirius/editor/properties/sections/tool/unset/UnsetFeatureNamePropertySection.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 @@ -14,6 +14,8 @@ package org.eclipse.sirius.editor.properties.sections.tool.unset; 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.viewpoint.description.tool.ToolPackage; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; @@ -35,6 +37,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * @see org.eclipse.ui.views.properties.tabbed.view.ITabbedPropertySection#refresh() */ + @Override public void refresh() { super.refresh(); @@ -47,6 +50,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getDefaultLabelText() */ + @Override protected String getDefaultLabelText() { return "FeatureName"; //$NON-NLS-1$ } @@ -54,6 +58,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getLabelText() */ + @Override protected String getLabelText() { String labelText; labelText = super.getLabelText() + "*:"; //$NON-NLS-1$ @@ -66,6 +71,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeature() */ + @Override public EAttribute getFeature() { return ToolPackage.eINSTANCE.getUnset_FeatureName(); } @@ -73,6 +79,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#getFeatureValue(String) */ + @Override protected Object getFeatureValue(String newText) { return newText; } @@ -80,6 +87,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * @see org.eclipse.sirius.editor.properties.sections.AbstractTextPropertySection#isEqual(String) */ + @Override protected boolean isEqual(String newText) { return getFeatureAsText().equals(newText); } @@ -87,6 +95,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * {@inheritDoc} */ + @Override public void createControls(Composite parent, TabbedPropertySheetPage tabbedPropertySheetPage) { super.createControls(parent, tabbedPropertySheetPage); @@ -102,7 +111,8 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection nameLabel.setFont(SiriusEditor.getFontRegistry().get("required")); // Start of user code create controls - + text.setBackground(SiriusEditor.getColorRegistry().get("lightgreen")); + TypeContentProposalProvider.bindCompletionProcessor(this, new SiriusFeatureContentProposalProvider(), text); // End of user code create controls } @@ -110,6 +120,7 @@ public class UnsetFeatureNamePropertySection extends AbstractTextPropertySection /** * {@inheritDoc} */ + @Override protected String getPropertyDescription() { return "Name of the feature to unset."; } diff --git a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/api/assist/TypeContentProposalProvider.java b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/api/assist/TypeContentProposalProvider.java index 427c01ce1f..edf8d8616a 100644 --- a/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/api/assist/TypeContentProposalProvider.java +++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/api/assist/TypeContentProposalProvider.java @@ -11,6 +11,7 @@ package org.eclipse.sirius.editor.tools.api.assist; import java.util.List; +import java.util.Optional; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.jface.bindings.Trigger; @@ -73,9 +74,8 @@ public class TypeContentProposalProvider implements IContentProposalProvider { * Bind a completion processor to a given text element. * * @param section - * section to give, if it implements {@link ModelViewBinding} - * then the section update will be disabled during proposal - * settings. + * section to give, if it implements {@link ModelViewBinding} then the section update will be disabled + * during proposal settings. * @param text * text to bind a completion processor to. */ @@ -111,18 +111,18 @@ public class TypeContentProposalProvider implements IContentProposalProvider { } /** - * Bind the completion processors available in plugins to a given text - * element. + * Bind the completion processor computed from the given {@link IAssistContentProvider} to a given text element. * * @param section * the property section where the text element come from. + * @param assistContentProvider + * the content assist provider to use for completion. * @param text * text to bind a completion processors to. */ - public static void bindPluginsCompletionProcessors(final AbstractPropertySection section, final Text text) { - List<IAssistContentProvider> extension = EclipseUtil.getExtensionPlugins(IAssistContentProvider.class, IAssistContentProvider.ID, IAssistContentProvider.CLASS_ATTRIBUTE); - if (!(extension.size() == 0)) { - IAssistContentProvider contentProposalAdapter = extension.get(0); + public static void bindCompletionProcessor(final AbstractPropertySection section, IAssistContentProvider assistContentProvider, final Text text) { + IAssistContentProvider contentProposalAdapter = Optional.ofNullable(assistContentProvider).orElseGet(TypeContentProposalProvider::getIAssistContentProvider); + if (contentProposalAdapter != null) { contentProposalAdapter.setView(section); IBindingService bindingService = PlatformUI.getWorkbench().getService(IBindingService.class); // gives // the @@ -146,6 +146,26 @@ public class TypeContentProposalProvider implements IContentProposalProvider { } } + private static IAssistContentProvider getIAssistContentProvider() { + List<IAssistContentProvider> extension = EclipseUtil.getExtensionPlugins(IAssistContentProvider.class, IAssistContentProvider.ID, IAssistContentProvider.CLASS_ATTRIBUTE); + if (!(extension.size() == 0)) { + return extension.get(0); + } + return null; + } + + /** + * Bind the completion processors available in plugins to a given text element. + * + * @param section + * the property section where the text element come from. + * @param text + * text to bind a completion processors to. + */ + public static void bindPluginsCompletionProcessors(final AbstractPropertySection section, final Text text) { + bindCompletionProcessor(section, null, text); + } + private static KeyStroke getKeyStroke(TriggerSequence sequence) { for (Trigger trigger : sequence.getTriggers()) { if (trigger instanceof KeyStroke) { 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 new file mode 100644 index 0000000000..3c5fe42d4b --- /dev/null +++ b/plugins/org.eclipse.sirius.editor/src/org/eclipse/sirius/editor/tools/internal/assist/SiriusFeatureContentProposalProvider.java @@ -0,0 +1,46 @@ +/******************************************************************************* + * Copyright (c) 2009, 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 + * 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.ArrayList; +import java.util.List; + +import org.eclipse.jface.fieldassist.IContentProposal; +import org.eclipse.sirius.common.tools.api.contentassist.ContentContext; +import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal; +import org.eclipse.sirius.common.tools.internal.assist.ContentContextHelper; +import org.eclipse.sirius.common.ui.tools.internal.contentassist.ContentProposalConverter; +import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider; +import org.eclipse.sirius.ui.tools.api.assist.IAssistContentProvider; +import org.eclipse.sirius.ui.tools.api.assist.TextContentProposalProvider; + +/** + * Provides proposal from {@link FeatureProposalProvider} only. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ +public class SiriusFeatureContentProposalProvider extends TextContentProposalProvider implements IAssistContentProvider { + + @Override + public IContentProposal[] getProposals(String contents, int position) { + final String prefix = ""; + + 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)); + + ContentProposalConverter contentProposalConverter = new ContentProposalConverter(proposalStart); + return contentProposalConverter.convertToJFaceContentProposals(proposals); + } + +} diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/valideVSMWithDiagramExtension.odesign b/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/valideVSMWithDiagramExtension.odesign index 1d1c28efaa..a5e52b6ce9 100644 --- a/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/valideVSMWithDiagramExtension.odesign +++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/vsm/valideVSMWithDiagramExtension.odesign @@ -1,5 +1,5 @@ <?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/description/tool/1.1.0" xmlns:tool_1="http://www.eclipse.org/sirius/diagram/description/tool/1.1.0" name="VP-3834" version="11.0.0.201601261200"> +<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/description/tool/1.1.0" xmlns:tool_1="http://www.eclipse.org/sirius/diagram/description/tool/1.1.0" name="VP-3834" version="12.0.0.2017041100"> <ownedViewpoints name="VP-3834_Viewpoint" modelFileExtension="ecore"> <ownedRepresentations xsi:type="description_1:DiagramDescription" name="VP-3834_Diagram" initialisation="true" domainClass="ecore.EPackage" preconditionExpression="aql:self.eContainer() = null"> <metamodel href="http://www.eclipse.org/emf/2002/Ecore#/"/> @@ -63,8 +63,10 @@ <variable name="container"/> <viewVariable name="containerView"/> <initialOperation> - <firstModelOperations xsi:type="tool:CreateInstance" typeName="ecore.EClass" referenceName="eClassifiers"> - <subModelOperations xsi:type="tool:SetValue" featureName="name" valueExpression="eClass"/> + <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="var:container"> + <subModelOperations xsi:type="tool:CreateInstance" typeName="ecore.EClass" referenceName="eClassifiers"> + <subModelOperations xsi:type="tool:SetValue" featureName="name" valueExpression="eClass"/> + </subModelOperations> </firstModelOperations> </initialOperation> </ownedTools> diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java index 6b1be59d2c..219a835f78 100644 --- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/suite/common/AllCommonPluginTests.java @@ -86,7 +86,7 @@ import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.IInterpreter import org.eclipse.sirius.tests.unit.common.interpreter.acceleo.mtl.InterpretedExpressionTargetSwitchTest; import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureCompletionTests; import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureInterpreterTests; -import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureProposalProviderTests; +import org.eclipse.sirius.tests.unit.common.interpreter.feature.FeatureProposalProviderWithPseudoFeatureTests; import org.eclipse.sirius.tests.unit.common.interpreter.ocl.OCLCompletionTest; import org.eclipse.sirius.tests.unit.common.interpreter.service.ServiceCompletionTests; import org.eclipse.sirius.tests.unit.common.interpreter.service.ServiceInterpreterTests; @@ -299,7 +299,7 @@ public class AllCommonPluginTests extends TestCase { suite.addTestSuite(ServiceCompletionTests.class); suite.addTestSuite(VariableInterpreterTests.class); suite.addTestSuite(VariableCompletionTests.class); - suite.addTestSuite(FeatureProposalProviderTests.class); + suite.addTestSuite(FeatureProposalProviderWithPseudoFeatureTests.class); suite.addTestSuite(ServiceProposalProviderTests.class); suite.addTestSuite(VariableProposalProviderTests.class); suite.addTestSuite(InterpretedExpressionTargetSwitchTest.class); diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java index 966784d503..5874530197 100644 --- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureCompletionTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES. + * Copyright (c) 2010, 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 @@ -20,7 +20,7 @@ import org.eclipse.sirius.common.tools.api.contentassist.ContentContext; import org.eclipse.sirius.common.tools.api.contentassist.ContentInstanceContext; import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal; import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter; -import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalProvider; +import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureAndPseudoFeatureProposalProvider; import org.eclipse.sirius.diagram.DNode; import org.eclipse.sirius.diagram.DiagramFactory; import org.eclipse.sirius.diagram.DiagramPackage; @@ -40,7 +40,7 @@ public class FeatureCompletionTests extends AbstractCompletionTestCase { @Override protected void setUp() throws Exception { super.setUp(); - setInterpreterAndProposalProvider(new FeatureInterpreter(), new FeatureProposalProvider()); + setInterpreterAndProposalProvider(new FeatureInterpreter(), new FeatureAndPseudoFeatureProposalProvider()); }; /** @@ -106,6 +106,7 @@ public class FeatureCompletionTests extends AbstractCompletionTestCase { c.setName("c1"); Function<Integer, ContentContext> createEmptyExpressionContextWithCursor = new Function<Integer, ContentContext>() { + @Override public ContentContext apply(Integer input) { return createContentContext("feature:", input, "EClass"); } @@ -121,6 +122,7 @@ public class FeatureCompletionTests extends AbstractCompletionTestCase { c.setName("c1"); Function<Integer, ContentInstanceContext> createEmptyExpressionContextWithCursor = new Function<Integer, ContentInstanceContext>() { + @Override public ContentInstanceContext apply(Integer input) { return new ContentInstanceContext(c, "feature:", input); } @@ -197,6 +199,7 @@ public class FeatureCompletionTests extends AbstractCompletionTestCase { StringBuilder errorMsg = new StringBuilder(); Predicate<String> concerned = new Predicate<String>() { + @Override public boolean apply(String input) { return true; } diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderTests.java index fc79f522ea..a9986bc524 100644 --- a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderTests.java +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderTests.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2014 THALES GLOBAL SERVICES. + * Copyright (c) 2010, 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 @@ -12,8 +12,6 @@ package org.eclipse.sirius.tests.unit.common.interpreter.feature; import java.util.List; -import junit.framework.TestCase; - import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.sirius.common.tools.api.contentassist.ContentContext; import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal; @@ -25,14 +23,16 @@ import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureProposalPr import org.eclipse.sirius.diagram.description.DescriptionFactory; import org.eclipse.sirius.diagram.description.DescriptionPackage; import org.eclipse.sirius.diagram.description.DiagramDescription; +import org.eclipse.sirius.tests.unit.common.interpreter.AbstractCompletionTestCase; import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory; /** - * A Test case for the {@link FeatureProposalProvider}. + * Tests for the {@link FeatureProposalProvider} . + * + * @author mporhel * - * @author <a href="mailto:esteban.dugueperoux@obeo.fr">Esteban Dugueperoux</a> */ -public class FeatureProposalProviderTests extends TestCase { +public class FeatureProposalProviderTests extends AbstractCompletionTestCase { private IInterpreter interpreter; @@ -54,19 +54,13 @@ public class FeatureProposalProviderTests extends TestCase { public void testFeatureProposalProvider() { DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription(); diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName()); - IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, - DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION); + IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION); - ContentContext context = new ContentContext(FeatureInterpreter.PREFIX, FeatureInterpreter.PREFIX.length(), interpreterContext); + ContentContext context = new ContentContext("", 0, interpreterContext); List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context); assertNotNull("proposals should not be null", proposals); - assertEquals("There should be 13 proposals", 13, proposals.size()); - int i; - for (i = 0; i < FeatureInterpreter.DEFAULT_FEATURE_NAMES.length; i++) { - String defaultFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[i]; - ContentProposal contentProposal = proposals.get(i); - assertEquals("The proposal should be the " + defaultFeatureName, defaultFeatureName, contentProposal.getProposal()); - } + assertEquals("There should be 13 proposals", 8, proposals.size()); + int i = 0; ContentProposal contentProposal = proposals.get(i++); assertEquals("The proposal should be the " + EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS.getName() + " feature", EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS.getName(), contentProposal.getProposal()); @@ -101,11 +95,9 @@ public class FeatureProposalProviderTests extends TestCase { public void testFeatureProposalProviderWithPrefix() { DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription(); diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName()); - IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, - DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION); + IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION); - ContentContext context = new ContentContext(FeatureInterpreter.PREFIX + EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName().substring(0, 3), FeatureInterpreter.PREFIX.length() + 3, - interpreterContext); + ContentContext context = new ContentContext(EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName().substring(0, 3), 3, interpreterContext); List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context); assertNotNull("proposals should not be null", proposals); assertEquals("There should be 1 proposals", 1, proposals.size()); @@ -114,7 +106,6 @@ public class FeatureProposalProviderTests extends TestCase { contentProposal.getProposal()); } - @Override protected void tearDown() throws Exception { interpreter = null; diff --git a/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderWithPseudoFeatureTests.java b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderWithPseudoFeatureTests.java new file mode 100644 index 0000000000..e721bb5d1a --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.junit/src/org/eclipse/sirius/tests/unit/common/interpreter/feature/FeatureProposalProviderWithPseudoFeatureTests.java @@ -0,0 +1,121 @@ +/******************************************************************************* + * 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.tests.unit.common.interpreter.feature; + +import java.util.List; + +import org.eclipse.emf.ecore.EcorePackage; +import org.eclipse.sirius.common.tools.api.contentassist.ContentContext; +import org.eclipse.sirius.common.tools.api.contentassist.ContentProposal; +import org.eclipse.sirius.common.tools.api.contentassist.IProposalProvider; +import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter; +import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext; +import org.eclipse.sirius.common.tools.internal.interpreter.FeatureInterpreter; +import org.eclipse.sirius.common.ui.tools.internal.interpreter.FeatureAndPseudoFeatureProposalProvider; +import org.eclipse.sirius.diagram.description.DescriptionFactory; +import org.eclipse.sirius.diagram.description.DescriptionPackage; +import org.eclipse.sirius.diagram.description.DiagramDescription; +import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory; + +import junit.framework.TestCase; + +/** + * A Test case for the {@link FeatureAndPseudoFeatureProposalProvider}. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + */ +public class FeatureProposalProviderWithPseudoFeatureTests extends TestCase { + + private IInterpreter interpreter; + + private IProposalProvider proposalProvider; + + @Override + protected void setUp() throws Exception { + super.setUp(); + interpreter = new FeatureInterpreter(); + proposalProvider = new FeatureAndPseudoFeatureProposalProvider(); + } + + public void testFeatureProposalProviderNewEmptyExpression() { + ContentProposal contentProposal = proposalProvider.getNewEmtpyExpression(); + assertNotNull("FeatureProposalProvider.getNewEmtpyExpression() should not return null", contentProposal); + assertEquals("The proposal should be the feature interpreter prefix", FeatureInterpreter.PREFIX, contentProposal.getProposal()); + } + + public void testFeatureProposalProvider() { + DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription(); + diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName()); + IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION); + + ContentContext context = new ContentContext(FeatureInterpreter.PREFIX, FeatureInterpreter.PREFIX.length(), interpreterContext); + List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context); + assertNotNull("proposals should not be null", proposals); + assertEquals("There should be 13 proposals", 13, proposals.size()); + int i; + for (i = 0; i < FeatureInterpreter.DEFAULT_FEATURE_NAMES.length; i++) { + String defaultFeatureName = FeatureInterpreter.DEFAULT_FEATURE_NAMES[i]; + ContentProposal contentProposal = proposals.get(i); + assertEquals("The proposal should be the " + defaultFeatureName, defaultFeatureName, contentProposal.getProposal()); + } + ContentProposal contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS.getName() + " feature", EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS.getName(), + contentProposal.getProposal()); + contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName() + " feature", EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName(), + contentProposal.getProposal()); + contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.EPACKAGE__NS_URI.getName() + " feature", EcorePackage.Literals.EPACKAGE__NS_URI.getName(), contentProposal.getProposal()); + contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.EPACKAGE__NS_PREFIX.getName() + " feature", EcorePackage.Literals.EPACKAGE__NS_PREFIX.getName(), + contentProposal.getProposal()); + contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.EPACKAGE__EFACTORY_INSTANCE.getName() + " feature", EcorePackage.Literals.EPACKAGE__EFACTORY_INSTANCE.getName(), + contentProposal.getProposal()); + contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.EPACKAGE__ECLASSIFIERS.getName() + " feature", EcorePackage.Literals.EPACKAGE__ECLASSIFIERS.getName(), + contentProposal.getProposal()); + contentProposal = proposals.get(i++); + assertEquals("The proposal should be the " + EcorePackage.Literals.EPACKAGE__ESUBPACKAGES.getName() + " feature", EcorePackage.Literals.EPACKAGE__ESUBPACKAGES.getName(), + contentProposal.getProposal()); + contentProposal = proposals.get(i); + assertEquals("The proposal should be the " + EcorePackage.Literals.EPACKAGE__ESUPER_PACKAGE.getName() + " feature", EcorePackage.Literals.EPACKAGE__ESUPER_PACKAGE.getName(), + contentProposal.getProposal()); + } + + /** + * Check that if the user begins to write something (in this test, the "nam" + * characters), the proposals are filtered. In this test, only "name" + * feature (EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName()) should be + * returned. + */ + public void testFeatureProposalProviderWithPrefix() { + DiagramDescription diagramDescription = DescriptionFactory.eINSTANCE.createDiagramDescription(); + diagramDescription.setDomainClass(EcorePackage.eNAME + "." + EcorePackage.Literals.EPACKAGE.getName()); + IInterpreterContext interpreterContext = SiriusInterpreterContextFactory.createInterpreterContext(diagramDescription, DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__PRECONDITION_EXPRESSION); + + ContentContext context = new ContentContext(FeatureInterpreter.PREFIX + EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName().substring(0, 3), FeatureInterpreter.PREFIX.length() + 3, + interpreterContext); + List<ContentProposal> proposals = proposalProvider.getProposals(interpreter, context); + assertNotNull("proposals should not be null", proposals); + assertEquals("There should be 1 proposals", 1, proposals.size()); + ContentProposal contentProposal = proposals.get(0); + assertEquals("The proposal should be the " + EcorePackage.Literals.EMODEL_ELEMENT__EANNOTATIONS.getName() + " feature", EcorePackage.Literals.ENAMED_ELEMENT__NAME.getName(), + contentProposal.getProposal()); + } + + @Override + protected void tearDown() throws Exception { + interpreter = null; + proposalProvider = null; + super.tearDown(); + } +} diff --git a/plugins/org.eclipse.sirius.tests.swtbot/data/unit/contentAssist/featureTest.odesign b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/contentAssist/featureTest.odesign new file mode 100644 index 0000000000..c62d345dfa --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/data/unit/contentAssist/featureTest.odesign @@ -0,0 +1,69 @@ +<?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/table/description/1.1.0" xmlns:description_2="http://www.eclipse.org/sirius/tree/description/1.0.0" xmlns:description_3="http://www.eclipse.org/sirius/diagram/description/1.1.0" xmlns:tool="http://www.eclipse.org/sirius/description/tool/1.1.0" xmlns:tool_1="http://www.eclipse.org/sirius/diagram/description/tool/1.1.0" documentation="<html>
<head>
</head>
<body>
<h1>POUET POUET<h1/>
</body>
</html>" name="featureTest" version="11.1.1.201610211630"> + <ownedViewpoints documentation="<html>
<head>
</head>
<body>
<h1>POUET POUET<h1/>
</body>
</html>" name="featureTest" modelFileExtension="ecore"> + <ownedRepresentations xsi:type="description_1:EditionTableDescription" name="featureTestTable" domainClass="EPackage"> + <metamodel href="http://www.eclipse.org/emf/2002/Ecore#/"/> + <ownedLineMappings name="Classes" domainClass="EClass" semanticCandidatesExpression="feature:eClassifiers"/> + <ownedColumnMappings name="IsAbstractColumn" headerLabelExpression="Is Abstract?" featureName="abstract" labelExpression="feature:abstract"/> + <ownedColumnMappings name="stubLooseFocus" headerLabelExpression="Label" featureName="stub" labelExpression="aql:'D'+self.name"> + <directEdit> + <variables name="element" documentation="The semantic currently edited element."/> + <variables name="lineSemantic" documentation="The semantic element corresponding to the line."/> + <variables name="root" documentation="The semantic root element of the table."/> + <firstModelOperation xsi:type="tool:ChangeContext" browseExpression="aql:self"> + <subModelOperations xsi:type="tool:CreateInstance" typeName="ecore::EPackage" referenceName="stub" variableName="stubLooseFocus"/> + <subModelOperations xsi:type="tool:SetValue" featureName="stub" valueExpression="stubLooseFocus"/> + <subModelOperations xsi:type="tool:Unset" featureName="stub" elementExpression="stubLooseFocus"/> + <subModelOperations xsi:type="tool:MoveElement" newContainerExpression="stubLooseFocus" featureName="stub"/> + </firstModelOperation> + <mask mask="{0}"/> + </directEdit> + </ownedColumnMappings> + </ownedRepresentations> + <ownedRepresentations xsi:type="description_2:TreeDescription" name="featureTestTree" domainClass="EPackage"> + <metamodel href="http://www.eclipse.org/emf/2002/Ecore#/"/> + <subItemMappings name="eclass2" domainClass="ecore.EClass" semanticCandidatesExpression="feature:eAllContents"> + <defaultStyle> + <labelColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/> + <backgroundColor xsi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='white']"/> + </defaultStyle> + <directEdit name="directEdit" mapping="//@ownedViewpoints[name='featureTest']/@ownedRepresentations[name='featureTestTree']/@subItemMappings[name='eclass2']"> + <firstModelOperation xsi:type="tool:ChangeContext" browseExpression="var:element"> + <subModelOperations xsi:type="tool:SetValue" featureName="name" valueExpression="var:arg0"/> + </firstModelOperation> + <mask mask="{0}"/> + <element name="element"/> + <root name="root"/> + </directEdit> + </subItemMappings> + <dropTools forceRefresh="true"> + <filters> + <listeners domainClass="stubLooseFocus" featureName="stub"/> + </filters> + <firstModelOperation xsi:type="tool:ChangeContext"/> + <oldContainer name="oldContainer"/> + <newContainer name="newContainer"/> + <element name="element"/> + <newViewContainer name="newViewContainer"/> + <precedingSiblings name="precedingSiblings" documentation="The list of all the preceding siblings in a Drag and Drop operation"/> + </dropTools> + </ownedRepresentations> + <ownedRepresentations xsi:type="description_3:DiagramDescription" name="featureTestDiagram" domainClass="EPackage" enablePopupBars="true"> + <defaultLayer name="Default"> + <containerMappings name="EPackageContainer"/> + <toolSections> + <ownedTools xsi:type="tool_1:ContainerCreationDescription" containerMappings="//@ownedViewpoints[name='featureTest']/@ownedRepresentations[name='featureTestDiagram']/@defaultLayer/@containerMappings[name='EPackageContainer']"> + <variable name="container"/> + <viewVariable name="containerView"/> + <initialOperation> + <firstModelOperations xsi:type="tool:ChangeContext" browseExpression="aql:container"> + <subModelOperations xsi:type="tool:CreateInstance"/> + <subModelOperations xsi:type="tool:SetValue" valueExpression="feature:"/> + </firstModelOperations> + </initialOperation> + </ownedTools> + </toolSections> + </defaultLayer> + </ownedRepresentations> + </ownedViewpoints> +</description:Group> 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 new file mode 100644 index 0000000000..ac282763c9 --- /dev/null +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/editor/vsm/FeatureAssistTest.java @@ -0,0 +1,159 @@ +/******************************************************************************* + * 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.tests.swtbot.editor.vsm; + +import org.eclipse.sirius.tests.swtbot.Activator; +import org.eclipse.sirius.tests.swtbot.support.api.business.UIDiagramRepresentation; +import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotSiriusDiagramEditor; +import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotVSMEditor; +import org.eclipse.sirius.tests.swtbot.support.api.editor.SWTBotVSMHelper; +import org.eclipse.sirius.ui.tools.api.views.modelexplorerview.IModelExplorerView; +import org.eclipse.swtbot.eclipse.finder.widgets.SWTBotView; +import org.eclipse.swtbot.swt.finder.SWTBot; +import org.eclipse.swtbot.swt.finder.widgets.SWTBotText; + +/** + * This class verifies that feature name of various tool's operations and column mapping have completion. + * + * @author <a href="mailto:pierre.guilet@obeo.fr">Pierre Guilet</a> + * + */ +public class FeatureAssistTest extends AbstractContentAssistTest { + + /** + * + */ + private static final String CHANGE_CONTEXT_NODE = "Change Context aql:self"; + + private static final String LABEL_EDIT_NODE = "Label Edit"; + + private static final String COLUMN_MAPPING_NODE = "stubLooseFocus"; + + private static final String NODE_NAME = "EPackage"; + + private static final String GROUP_NAME = "featureTest"; + + private static final String TABLE_REPRESENTATION_NAME = "featureTestTable"; + + private static final String TREE_REPRESENTATION_NAME = "featureTestTree"; + + private static final String VIEWPOINT_NAME = "featureTest"; + + private static final String VSM_FILE = "featureTest.odesign"; + + private static final String DATA_UNIT_DIR = "data/unit/contentAssist/"; + + /** + * Current editor. + */ + protected SWTBotSiriusDiagramEditor editor; + + /** + * Current diagram. + */ + protected UIDiagramRepresentation diagram; + + /** + * {@inheritDoc} + */ + @Override + protected void onSetUpBeforeClosingWelcomePage() throws Exception { + copyFileToTestProject(Activator.PLUGIN_ID, DATA_UNIT_DIR, VSM_FILE); + + } + + /** + * Test feature completion for SetValueFeatureName. + * + */ + public void testFeatureCompletionForSetValueFeatureName() { + testFeatureCompletion("Set stub", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE); + } + + /** + * Test feature completion for UnsetFeatureName. + * + */ + public void testFeatureCompletionForUnsetFeatureName() { + testFeatureCompletion("Unset stub", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE); + } + + /** + * Test feature completion for MoveElementFeatureName. + * + */ + public void testFeatureCompletionForMoveElementFeatureName() { + testFeatureCompletion("Move stub", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE); + } + + /** + * Test feature completion for CreateInstanceReferenceName. + * + */ + public void testFeatureCompletionForCreateInstanceFeatureName() { + testFeatureCompletion("Create Instance ecore::EPackage", "stubLooseFocusChange", TABLE_REPRESENTATION_NAME, COLUMN_MAPPING_NODE, LABEL_EDIT_NODE, CHANGE_CONTEXT_NODE); + } + + /** + * Test feature completion for FeatureColumnMappingFeatureName. + * + */ + public void testFeatureCompletionForFeatureColumnMappingFeatureName() { + testFeatureCompletion(COLUMN_MAPPING_NODE, "stubLooseFocusChange", TABLE_REPRESENTATION_NAME); + } + + /** + * Test feature completion for FeatureChangeListenerFeatureName. + */ + public void testFeatureCompletionForFeatureChangeListenerFeatureName() { + testFeatureCompletion("Feature Change Listener stub", "ecore::EPackage", TREE_REPRESENTATION_NAME, "Drop Tool", "Filter"); + } + + private void testFeatureCompletion(String operationToSelect, String firstTextToSet, String... nodesToExpend) { + // Open odesign file + SWTBotView projectExplorer = bot.viewById(IModelExplorerView.ID); + projectExplorer.setFocus(); + SWTBot projectExplorerBot = projectExplorer.bot(); + projectExplorerBot.tree().expandNode(getProjectName()).expandNode(VSM_FILE).doubleClick(); + + // Select a node mapping + SWTBotVSMEditor activeEditor = SWTBotVSMHelper.getVSMEditorContainingName(VSM_FILE); + activeEditor.setFocus(); + activeEditor.bot().tree().expandNode("platform:/resource/" + getProjectName() + "/" + VSM_FILE).expandNode(GROUP_NAME).expandNode(VIEWPOINT_NAME).expandNode(nodesToExpend) + .select(operationToSelect); + + try { + // Change the semantic candidate expression + SWTBotView propertiesBot = bot.viewByTitle("Properties"); + propertiesBot.setFocus(); + final SWTBotText semanticCandidateExpressionText = propertiesBot.bot().text("stub"); + semanticCandidateExpressionText.setFocus(); + semanticCandidateExpressionText.setText(""); + + // Unfocus the semantic candidate expression and add text to another + // text area + final SWTBotText semanticElementText = propertiesBot.bot().text("stubLooseFocus"); + semanticElementText.setFocus(); + semanticElementText.setText(firstTextToSet); + + // Focus back on the semantic candidate expression and modify its + // content + semanticCandidateExpressionText.setFocus(); + semanticCandidateExpressionText.setText(""); + + // 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()); + } finally { + activeEditor.close(); + } + } +} diff --git a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java index d4f30f7c1b..6b1bb5524f 100644 --- a/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java +++ b/plugins/org.eclipse.sirius.tests.swtbot/src/org/eclipse/sirius/tests/swtbot/suite/AllTestSuite.java @@ -31,6 +31,7 @@ import org.eclipse.sirius.tests.swtbot.editor.vsm.ContainerDropPropertySectionsT import org.eclipse.sirius.tests.swtbot.editor.vsm.ContentAssistTest; import org.eclipse.sirius.tests.swtbot.editor.vsm.CreateMandatoryElementsTest; import org.eclipse.sirius.tests.swtbot.editor.vsm.CustomizationPropertySectionsTests; +import org.eclipse.sirius.tests.swtbot.editor.vsm.FeatureAssistTest; import org.eclipse.sirius.tests.swtbot.editor.vsm.MetamodelPropertyTabTests; import org.eclipse.sirius.tests.swtbot.editor.vsm.MigrationOnVsmEditorReloadTest; import org.eclipse.sirius.tests.swtbot.editor.vsm.OpeningContextTest; @@ -124,6 +125,7 @@ public class AllTestSuite extends TestCase { public static void addGerritPart1(TestSuite suite) { suite.addTest(new JUnit4TestAdapter(SWTBotBundlesReport.class)); suite.addTestSuite(ContentAssistTest.class); + suite.addTestSuite(FeatureAssistTest.class); suite.addTestSuite(ResizeKindEditorTest.class); suite.addTestSuite(CascadingSiriusURITest.class); suite.addTestSuite(AssociatedElementsOnPropertyViewTest.class); 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 8e763b2fd6..f254e20890 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2016 THALES GLOBAL SERVICES. + * Copyright (c) 2008, 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 @@ -93,7 +93,16 @@ public class TextContentProposalProvider implements IAssistContentProvider { } - private ContentContext getContentContext(final String text, final int position) { + /** + * Returns the content context from which proposal providers will make their completion proposals. + * + * @param text + * user input. + * @param position + * cursor position. + * @return the content context. + */ + protected ContentContext getContentContext(final String text, final int position) { final Object selectedElement = getSelectedElement(); final EStructuralFeature f = getEStructuralFeature(); IInterpreterContext interContext = SiriusInterpreterContextFactory.createInterpreterContext((EObject) selectedElement, f); @@ -112,11 +121,11 @@ public class TextContentProposalProvider implements IAssistContentProvider { /** * Removes the duplicated proposals. * - * @param matches + * @param contents * are the initial proposals * @return the valid proposals */ - private static List<ContentProposal> removeDuplicatedProposals(final List<ContentProposal> contents) { + protected static List<ContentProposal> removeDuplicatedProposals(final List<ContentProposal> contents) { final List<ContentProposal> resultProposals = new ArrayList<ContentProposal>(); final Iterator<ContentProposal> it = contents.iterator(); diff --git a/plugins/org.eclipse.sirius/plugin.properties b/plugins/org.eclipse.sirius/plugin.properties index b8bbf909e6..bf5984413e 100644 --- a/plugins/org.eclipse.sirius/plugin.properties +++ b/plugins/org.eclipse.sirius/plugin.properties @@ -36,6 +36,9 @@ constraint.validAttributeCustomization.name = EAttributeCustomization referenced constraint.validExpression.description = Validates that the typed Interpreter Expression is valid constraint.validExpression.message = Invalid Interpreter Expression constraint.validExpression.name = Invalid Interpreted Expression +constraint.validFeatureName.description = Validates that the Feature Name is valid +constraint.validFeatureName.message = Invalid feature ''{0}'' for the following types: {1} +constraint.validFeatureName.name = Invalid Feature Name constraint.validImagePath.description = Validates that image paths are valid constraint.validImagePath.message = {0} constraint.validImagePath.name = Invalid Image Path diff --git a/plugins/org.eclipse.sirius/plugin.xml b/plugins/org.eclipse.sirius/plugin.xml index 7028c56445..747ecd19af 100644 --- a/plugins/org.eclipse.sirius/plugin.xml +++ b/plugins/org.eclipse.sirius/plugin.xml @@ -174,6 +174,21 @@ %constraint.validExpression.description </description> </constraint> + <constraint + class="org.eclipse.sirius.tools.internal.validation.description.constraints.ValidFeatureNameConstraint" + id="org.eclipse.sirius.constraints.ValidFeatureNameConstraint" + lang="Java" + mode="Batch" + name="%constraint.validFeatureName.name" + severity="ERROR" + statusCode="1"> + <message> + %constraint.validFeatureName.message + </message> + <description> + %constraint.validFeatureName.description + </description> + </constraint> <constraint class="org.eclipse.sirius.tools.internal.validation.description.constraints.EAttributeCustomizationAttributeNameCommonToAppliedOnConstraint" id="org.eclipse.sirius.tools.internal.validation.description.constraints.EAttributeCustomizationAttributeNameCommonToAppliedOnConstraint" diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java index a004a61796..d3d25190ce 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/api/dialect/description/AbstractInterpretedExpressionQuery.java @@ -69,8 +69,7 @@ import com.google.common.collect.Maps; import com.google.common.collect.Sets; /** - * Query allowing to get the target domain classes and available packages for a - * given Interpreted expression. + * Query allowing to get the target domain classes and available packages for a given Interpreted expression. * * @since 0.9.0 * @author alagarde @@ -88,28 +87,27 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted protected static final String SELF = "self"; //$NON-NLS-1$ /** - * The source tag used in the meta-model for all EAnnotations concerning the - * variables available to interpreted expressions. + * The source tag used in the meta-model for all EAnnotations concerning the variables available to interpreted + * expressions. */ protected static final String VARIABLES_ANNOTATION_SOURCE = "http://www.eclipse.org/sirius/interpreted/expression/variables"; //$NON-NLS-1$ /** - * The character used in the documentation annotation of variables to - * separate the optional type name from the actual documentation. + * The character used in the documentation annotation of variables to separate the optional type name from the + * actual documentation. * * @see AbstractInterpretedExpressionQuery#collectLocalVariablesDefinitions() */ protected static final char TYPE_DEFINTION_SEPARATOR = '|'; /** - * The key used in {@link #VARIABLES_ANNOTATION_SOURCE} annotations of - * variable to specify the type of that variable. + * The key used in {@link #VARIABLES_ANNOTATION_SOURCE} annotations of variable to specify the type of that + * variable. */ protected static final String VARIABLE_TYPE_KEY = "type"; //$NON-NLS-1$ /** - * The target containing the InterpretedExpression (NodeMapping, - * ModelOperation...). + * The target containing the InterpretedExpression (NodeMapping, ModelOperation...). */ protected EObject target; @@ -125,20 +123,18 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted protected Option<Collection<String>> targetDomainClass; /** - * The list of EPackages to import to be able to interpret the given - * expression. + * The list of EPackages to import to be able to interpret the given expression. */ protected Collection<EPackage> packagesToImport; /** - * The list of dependencies to import to be able to interpret the given - * expression. + * The list of dependencies to import to be able to interpret the given expression. */ protected Collection<String> dependencies; /** - * A map representing all available variables. Keys of the map are the - * variable names, and values of the map their type. + * A map representing all available variables. Keys of the map are the variable names, and values of the map their + * type. */ protected Map<String, VariableType> availableVariables; @@ -148,8 +144,7 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted protected VariableType selfType; /** - * The available {@link IInterpretedExpressionTargetSwitch} that will be - * used to calculate target types. + * The available {@link IInterpretedExpressionTargetSwitch} that will be used to calculate target types. */ protected IInterpretedExpressionTargetSwitch targetSwitch; @@ -157,12 +152,10 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted * Default constructor. * * @param target - * the target containing the InterpretedExpression (NodeMapping, - * ModelOperation...) + * the target containing the InterpretedExpression (NodeMapping, ModelOperation...) * @param feature - * the feature corresponding to the InterpretedExpression to - * evaluate ( NodeMapping.semanticCandidatesExpression...), can - * be null. + * the feature corresponding to the InterpretedExpression to evaluate ( + * NodeMapping.semanticCandidatesExpression...), can be null. */ public AbstractInterpretedExpressionQuery(EObject target, EStructuralFeature feature) { this.target = target; @@ -185,10 +178,9 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted public Option<Collection<String>> getTargetDomainClasses() { if (targetDomainClass == null) { /* - * the "self" variable might be redefined by a containing - * ModelOperation (CreateInstance, ChangeContext by example). We - * have to trigger the computation of the available variables as - * this will update the "self" type computation at the same time. + * the "self" variable might be redefined by a containing ModelOperation (CreateInstance, ChangeContext by + * example). We have to trigger the computation of the available variables as this will update the "self" + * type computation at the same time. */ getAvailableVariables(); @@ -232,9 +224,8 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted // CHECKSTYLE:OFF } catch (Throwable e) { /* - * anything might happen here depending on the other - * Eclipse tools, and we've seen many time tools - * breaking all the others. + * anything might happen here depending on the other Eclipse tools, and we've seen many time + * tools breaking all the others. */ // CHECKSTYLE:ON } @@ -299,8 +290,8 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted collectContextualVariableDefinitions(operationContext, target); if (operationContext instanceof ToolDescription) { /* - * the containerView variable is accessible in any Model - * operation which is a child of the ToolDescription. + * the containerView variable is accessible in any Model operation which is a child of the + * ToolDescription. */ availableVariables.put("containerView", DSEMANTIC_DECORATOR); //$NON-NLS-1$ @@ -344,9 +335,8 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted collectLocalVariablesDefinitions(); if (this.target instanceof ToolDescription && feature == ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION) { /* - * the containerView, element and elementView variables are - * accessible in the "precondition" feature of the ToolDescription. - * See GenericToolCommandBuilder. + * the containerView, element and elementView variables are accessible in the "precondition" feature of the + * ToolDescription. See GenericToolCommandBuilder. */ availableVariables.put("containerView", DSEMANTIC_DECORATOR); //$NON-NLS-1$ availableVariables.put(((ToolDescription) this.target).getElement().getName(), VariableType.ANY_EOBJECT); @@ -427,29 +417,25 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted protected Option<EObject> getToolContext() { Option<EObject> found = Options.newNone(); /* - * ValidationFix can contains operations and is not a subclas of a tool. - * We need to return it as the "tool context" or the logic will find the - * global diagram definition instead. + * ValidationFix can contains operations and is not a subclas of a tool. We need to return it as the + * "tool context" or the logic will find the global diagram definition instead. */ found = new EObjectQuery(target).getFirstAncestorOfType(org.eclipse.sirius.viewpoint.description.validation.ValidationPackage.eINSTANCE.getValidationRule()); if (!found.some()) { if (this.target instanceof OperationAction || this.target instanceof RepresentationNavigationDescription || this.target instanceof RepresentationCreationDescription) { /* - * OperationAction and RepresentationNavigationDescription are - * representing their own context for their interpreted - * expression attributes, the variables which are child of the - * OperationAction and RepresentationNavigationDescription - * instance (like 'views', 'container') are also available in - * the precondition and elements to select expressions. + * OperationAction and RepresentationNavigationDescription are representing their own context for their + * interpreted expression attributes, the variables which are child of the OperationAction and + * RepresentationNavigationDescription instance (like 'views', 'container') are also available in the + * precondition and elements to select expressions. */ found = Options.fromNullable(this.target); } else { found = new EObjectQuery(target).getFirstAncestorOfType(ToolPackage.eINSTANCE.getAbstractToolDescription()); if (found.some() && found.get() instanceof ExternalJavaAction) { /* - * an ExternalJavaAction is a special case as it can also be - * embedded as an Operation. We need to make sure it is not - * the case. + * an ExternalJavaAction is a special case as it can also be embedded as an Operation. We need to + * make sure it is not the case. */ EObject container = found.get().eContainer(); if (container instanceof ModelOperation || container instanceof InitialOperation) { @@ -462,26 +448,21 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted } /** - * Add all the variables defined locally to the expression, as specified in - * the meta-model annotations. The type of each variable is encoded in the - * documentation string associated to each variable. + * Add all the variables defined locally to the expression, as specified in the meta-model annotations. The type of + * each variable is encoded in the documentation string associated to each variable. * <p> - * For example, on <code>BasicLabelStyleDescription.labelExpression</code>, - * an annotation using {@link #VARIABLES_ANNOTATION_SOURCE} has the - * following entry: + * For example, on <code>BasicLabelStyleDescription.labelExpression</code>, an annotation using + * {@link #VARIABLES_ANNOTATION_SOURCE} has the following entry: * <p> * <code> * diagram -> diagram.DDiagram | the current DSemanticDiagram. * </code> * <p> - * where <code>"diagram"</code> is the annotation key, representing the - * variable's name, and - * <code>"diagram.DDiagram | the current DSemanticDiagram"</code> is the - * value, indicating that the type of the variable is - * <code>diagram.DDiagram</code>. + * where <code>"diagram"</code> is the annotation key, representing the variable's name, and + * <code>"diagram.DDiagram | the current DSemanticDiagram"</code> is the value, indicating that the type of the + * variable is <code>diagram.DDiagram</code>. * <p> - * If no type is specified in the documentation, - * {@link #DEFAULT_VARIABLE_TYPE} is assumed. + * If no type is specified in the documentation, {@link #DEFAULT_VARIABLE_TYPE} is assumed. * * @see #TYPE_DEFINTION_SEPARATOR */ @@ -504,11 +485,9 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted } /** - * Collect and merge all the variables definition in the scope between - * <code>top</code> and <code>bottom</code> (<code>top</code> <em>must</em> - * be an ancestor of <code>bottom</code>) and merges them. In case of name - * shadowing, priority is given to the the value defined closest to - * <code>bottom</code> (lexical scoping). + * Collect and merge all the variables definition in the scope between <code>top</code> and <code>bottom</code> + * (<code>top</code> <em>must</em> be an ancestor of <code>bottom</code>) and merges them. In case of name + * shadowing, priority is given to the the value defined closest to <code>bottom</code> (lexical scoping). */ private void collectContextualVariableDefinitions(EObject top, EObject bottom) { // A map with multiple values is not strictly required as we only use @@ -521,9 +500,8 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted while (context != null && context != top.eContainer()) { appendAllLocalVariableDefinitions(definitions, context); /* - * Any ModelOperation which require to call IInterpreter to get more - * typing information should not create a new context at the - * ModelOperation leaf or we'll end up with an inifite loop. + * Any ModelOperation which require to call IInterpreter to get more typing information should not create a + * new context at the ModelOperation leaf or we'll end up with an inifite loop. */ collectContextualVariableForOperation(context, definitions, bottom); if (context != top) { @@ -548,11 +526,9 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted * Collect the contextual variable for a given operation. * * @param current - * the current model operation while going from the leaf to the - * top. + * the current model operation while going from the leaf to the top. * @param definitions - * the current state of variable definitions to be updated when - * needed. + * the current state of variable definitions to be updated when needed. * @param leaf * the leaf operation. */ @@ -624,25 +600,27 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted } } if (current instanceof CreateInstance) { - CreateInstance f = (CreateInstance) current; - changeSelfType(VariableType.fromString(f.getTypeName())); + // If the current context is the feature "Reference Name", the self type is not the type created by the + // CreateInstance tool. + if (feature != ToolPackage.eINSTANCE.getCreateInstance_ReferenceName()) { + CreateInstance f = (CreateInstance) current; + changeSelfType(VariableType.fromString(f.getTypeName())); + } } } /** - * Change the type of the "self" context. This method should be called while - * the model operation structure is being browsed from the leaf to the top. - * Only the most specific definition of the type of "self" will be kept, - * further assignations should not be considered. + * Change the type of the "self" context. This method should be called while the model operation structure is being + * browsed from the leaf to the top. Only the most specific definition of the type of "self" will be kept, further + * assignations should not be considered. * * @param newSelfType * the new type definition for the current "self" context. */ protected void changeSelfType(VariableType newSelfType) { /* - * We only set the self type once as we are browsing the model from most - * to less specific. The first assignation will be the most specific, - * further assignations should not be considered. + * We only set the self type once as we are browsing the model from most to less specific. The first assignation + * will be the most specific, further assignations should not be considered. */ if (selfType == null) { selfType = newSelfType; @@ -662,8 +640,7 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted int contextPositionInContainingList = childs.indexOf(context); if (contextPositionInContainingList > 0) { /* - * we have at least one sibling, we return the closest one - * to our position going upward. + * we have at least one sibling, we return the closest one to our position going upward. */ Object sibling = childs.get(contextPositionInContainingList - 1); if (sibling instanceof EObject) { @@ -676,13 +653,11 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted } /** - * Returns the name of the type of the given variable, as defined in the - * meta-model annotations. + * Returns the name of the type of the given variable, as defined in the meta-model annotations. * * @param var * the variable definition inside a VSM. - * @return the name of the type for this variables, or - * {@link #DEFAULT_VARIABLE_TYPE} if nothing more specified was + * @return the name of the type for this variables, or {@link #DEFAULT_VARIABLE_TYPE} if nothing more specified was * specified in the meta-model. */ protected VariableType getVariableTypeName(AbstractVariable var) { @@ -708,14 +683,12 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted } /** - * Append all the variable definitions defined locally by - * <code>context</code> to the specified map. Sub-classes should override - * this method (and call <code>super()</code>) to add any variable - * definitions specific to their languages/tasks/tools. + * Append all the variable definitions defined locally by <code>context</code> to the specified map. Sub-classes + * should override this method (and call <code>super()</code>) to add any variable definitions specific to their + * languages/tasks/tools. * * @param definitions - * the map in which to append all the variable definitions ( - * <code>name -> type</code>). + * the map in which to append all the variable definitions ( <code>name -> type</code>). * @param context * the element which may define new variables. */ @@ -752,11 +725,9 @@ public abstract class AbstractInterpretedExpressionQuery implements IInterpreted } /** - * Appends to the specified definition list all the implicit variables which - * will/may be defined at runtime according to the specified edit mask. For - * example, an exit mask of <code>{0}:{1}</code> implies the existence of - * two String variables at execution time, <code>arg0</code> and - * <code>arg1</code>. + * Appends to the specified definition list all the implicit variables which will/may be defined at runtime + * according to the specified edit mask. For example, an exit mask of <code>{0}:{1}</code> implies the existence of + * two String variables at execution time, <code>arg0</code> and <code>arg1</code>. * * @param mask * the edit mask which defines the format string. diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/ToolInterpretedExpressionTargetSwitch.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/ToolInterpretedExpressionTargetSwitch.java index 0e5673b970..dc7597af2a 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/ToolInterpretedExpressionTargetSwitch.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/dialect/description/ToolInterpretedExpressionTargetSwitch.java @@ -34,6 +34,7 @@ import org.eclipse.sirius.viewpoint.description.tool.CreateInstance; import org.eclipse.sirius.viewpoint.description.tool.ExternalJavaAction; import org.eclipse.sirius.viewpoint.description.tool.ExternalJavaActionCall; import org.eclipse.sirius.viewpoint.description.tool.ExternalJavaActionParameter; +import org.eclipse.sirius.viewpoint.description.tool.FeatureChangeListener; import org.eclipse.sirius.viewpoint.description.tool.For; import org.eclipse.sirius.viewpoint.description.tool.Let; import org.eclipse.sirius.viewpoint.description.tool.MappingBasedToolDescription; @@ -55,28 +56,23 @@ import org.eclipse.sirius.viewpoint.description.validation.ValidationRule; import com.google.common.collect.Sets; /** - * A switch that will return the Target Types associated to a given element - * (part of the {@link ToolPackage}) and feature corresponding to an Interpreted - * Expression. For example, for a NodeMapping : + * A switch that will return the Target Types associated to a given element (part of the {@link ToolPackage}) and + * feature corresponding to an Interpreted Expression. For example, for a NodeMapping : * <p> - * <li>if the feature is semantic candidate expression, we return the domain - * class of the first valid container (representation element mapping or - * representation description).</li> - * <li>if the feature is any other interpreted expression, we return the domain - * class associated to this mapping</li> + * <li>if the feature is semantic candidate expression, we return the domain class of the first valid container + * (representation element mapping or representation description).</li> + * <li>if the feature is any other interpreted expression, we return the domain class associated to this mapping</li> * </p> * - * Can return {@link Options#newNone()} if the given expression does not require - * any target type (for example, a Popup menu contribution only uses variables - * in its expressions). + * Can return {@link Options#newNone()} if the given expression does not require any target type (for example, a Popup + * menu contribution only uses variables in its expressions). * * @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a> */ public class ToolInterpretedExpressionTargetSwitch extends ToolSwitch<Option<Collection<String>>> { /** - * Constant used in switches on feature id to consider the case when the - * feature must not be considered. + * Constant used in switches on feature id to consider the case when the feature must not be considered. */ private static final int DO_NOT_CONSIDER_FEATURE = -1; @@ -143,9 +139,8 @@ public class ToolInterpretedExpressionTargetSwitch extends ToolSwitch<Option<Col } /** - * Changes the behavior of this switch : if true, then the feature will be - * considered to calculate target types ; if false, then the feature will be - * ignored. + * Changes the behavior of this switch : if true, then the feature will be considered to calculate target types ; if + * false, then the feature will be ignored. * * @param considerFeature * true if the feature should be considered, false otherwise @@ -163,14 +158,13 @@ public class ToolInterpretedExpressionTargetSwitch extends ToolSwitch<Option<Col } /** - * Returns the first element that changes the context of expressions. For - * example : for a given operation, will return the first ChangeContext or - * AbstractTool that contains it. + * Returns the first element that changes the context of expressions. For example : for a given operation, will + * return the first ChangeContext or AbstractTool that contains it. * * @param element * the element to get the container from - * @return the first relevant for the given EObject, i.e. the first - * container from which a domain class can be determined + * @return the first relevant for the given EObject, i.e. the first container from which a domain class can be + * determined */ protected EObject getFirstContextChangingContainer(EObject element) { EObject container = element.eContainer(); @@ -518,7 +512,21 @@ public class ToolInterpretedExpressionTargetSwitch extends ToolSwitch<Option<Col } return result; } - + + @Override + public Option<Collection<String>> caseFeatureChangeListener(FeatureChangeListener object) { + Option<Collection<String>> result = null; + switch (getFeatureId(object.eClass())) { + case DO_NOT_CONSIDER_FEATURE: + Collection<String> target = Collections.singleton(object.getDomainClass()); + result = Options.newSome(target); + break; + default: + break; + } + return result; + } + @Override public Option<Collection<String>> caseLet(Let object) { Option<Collection<String>> result = null; 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 new file mode 100644 index 0000000000..92df53b879 --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/tools/internal/validation/description/constraints/ValidFeatureNameConstraint.java @@ -0,0 +1,92 @@ +/******************************************************************************* + * 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.tools.internal.validation.description.constraints; + +import java.util.Collection; +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.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.validation.IValidationContext; +import org.eclipse.emf.validation.model.ConstraintStatus; +import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext; +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 com.google.common.collect.Sets; + +/** + * Constraint ensuring that all Feature Name of the odesign are valid. + * + * @author fbarbin + * + */ +public class ValidFeatureNameConstraint extends AbstractConstraint { + + @Override + public IStatus validate(IValidationContext ctx) { + final EObject target = ctx.getTarget(); + Collection<IStatus> statuses = Sets.newLinkedHashSet(); + + // For each structural features of the element to validate + for (EAttribute feature : target.eClass().getEAllAttributes()) { + // If this feature is a Feature Name + if (DescriptionPackage.eINSTANCE.getFeatureName().equals(feature.getEAttributeType())) { + IStatus status = checkExpression(ctx, target, feature); + if (status != null) { + statuses.add(status); + } + } + } + if (statuses.isEmpty()) { + return ctx.createSuccessStatus(); + } + + final IStatus returnStatus; + if (statuses.size() == 1) { + returnStatus = statuses.iterator().next(); + } else { + returnStatus = ConstraintStatus.createMultiStatus(ctx, statuses); + } + return returnStatus; + } + + private IStatus checkExpression(IValidationContext ctx, EObject target, EStructuralFeature feature) { + IStatus returnStatus = ctx.createSuccessStatus(); + String expression = (String) target.eGet(feature); + IInterpreterContext context = SiriusInterpreterContextFactory.createInterpreterContext(target, feature); + VariableType variableType = context.getTargetType(); + if (!StringUtil.isEmpty(expression)) { + if (isTypeIdentified(variableType)) { + Optional<EStructuralFeature> optional = variableType.getPossibleTypes().stream().flatMap(type -> type.search(context.getAvailableEPackages()).stream()).filter(EClass.class::isInstance) + .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 { + returnStatus = ctx.createFailureStatus(expression, variableType); + } + return returnStatus; + } + + private boolean isTypeIdentified(VariableType variableType) { + return variableType.hasDefinition() && variableType.getPossibleTypes().stream().anyMatch(tn -> !TypeName.EOBJECT_TYPENAME.equals(tn)); + } +} |
