diff options
| author | Florian Barbin | 2017-09-12 09:51:59 +0000 |
|---|---|---|
| committer | Florian Barbin | 2017-09-15 10:02:52 +0000 |
| commit | 3d40d8a67cd9fda2c99f8f90d21fec2d92c6cddb (patch) | |
| tree | 3fe880ff32b9f2a6347e5c63ba1c20c0af2d47be | |
| parent | 2eb4fd7a04475038868466eb923e38f0ac49379f (diff) | |
| download | org.eclipse.sirius-3d40d8a67cd9fda2c99f8f90d21fec2d92c6cddb.tar.gz org.eclipse.sirius-3d40d8a67cd9fda2c99f8f90d21fec2d92c6cddb.tar.xz org.eclipse.sirius-3d40d8a67cd9fda2c99f8f90d21fec2d92c6cddb.zip | |
[521294] Fixes NPE when missing model operation at runtime.
* If the corresponding modelOperation task cannot be created, we return
an unexecutableOperationTask and log a warning to inform the end user.
Bug: 521294
Change-Id: Ic3df36f5e59931a9346551d546551b319a1263e9
Signed-off-by: Florian Barbin <florian.barbin@obeo.fr>
7 files changed, 112 insertions, 3 deletions
diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.html b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.html index 2cc0e9b98c..598893fc06 100644 --- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.html +++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.html @@ -300,6 +300,14 @@ <em>Create if not existent</em> flag is not set. </p> <h2 id="dialogandwizard">Dialog & Wizard</h2> + <p> + <strong>Warning:</strong> The model operations below are provided by the Sirius properties view plugins. To make sure those operations will be available to the end user, you should add the following plugins in your modeler dependencies: + </p> + <ul> + <li>org.eclipse.sirius.properties</li> + <li>org.eclipse.sirius.ui.properties</li> + </ul> + <p>If those plugins are missing at runtime, Open Dialog and Open Wizard operations will not be executable.</p> <h3 id="dialog">Open Dialog</h3> <p>The <em>Open Dialog</em> model operation is used in order to open a new dialog where the end user will be able to see and manipulate some pieces of information. You can change the title of the dialog with the diff --git a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.textile b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.textile index b4a9b1116c..b7737ce8b8 100644 --- a/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.textile +++ b/plugins/org.eclipse.sirius.doc/doc/specifier/general/Model_Operations.textile @@ -112,6 +112,12 @@ The operation does nothing if the current element is not compatible with the spe h2(#dialogandwizard). Dialog & Wizard +*Warning:* The model operations below are provided by the Sirius properties view plugins. To make sure those operations will be available to the end user, you should add the following plugins in your modeler dependencies: +* org.eclipse.sirius.properties +* org.eclipse.sirius.ui.properties +If those plugins are missing at runtime, Open Dialog and Open Wizard operations will not be executable. + + h3(#dialog). Open Dialog The _Open Dialog_ model operation is used in order to open a new dialog where the end user will be able to see and manipulate some pieces of information. You can change the title of the dialog with the _Title expression_. This expression must return a string. You can specify one _Page_ with various _Groups_ to specify the content of the dialog. You can leverage existing _Pages_ and _Groups_ from existing definition of your _Properties View_. diff --git a/plugins/org.eclipse.sirius.tests.junit/data/unit/tool/1907/ecore.odesign b/plugins/org.eclipse.sirius.tests.junit/data/unit/tool/1907/ecore.odesign index dc33b6877c..fdd5cac1a0 100644 --- a/plugins/org.eclipse.sirius.tests.junit/data/unit/tool/1907/ecore.odesign +++ b/plugins/org.eclipse.sirius.tests.junit/data/unit/tool/1907/ecore.odesign @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="ASCII"?> -<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:description_2="http://www.eclipse.org/sirius/table/description/1.1.0" xmlns:filter="http://www.eclipse.org/sirius/diagram/description/filter/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" xmlns:validation="http://www.eclipse.org/sirius/description/validation/1.1.0" name="Ecore Editing Workbench V4.6" version="10.1.0.201507271600"> +<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:description_2="http://www.eclipse.org/sirius/table/description/1.1.0" xmlns:filter="http://www.eclipse.org/sirius/diagram/description/filter/1.1.0" xmlns:properties="http://www.eclipse.org/sirius/properties/1.0.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" xmlns:validation="http://www.eclipse.org/sirius/description/validation/1.1.0" name="Ecore Editing Workbench V4.6" version="12.0.0.2017041100"> <ownedViewpoints name="Design" modelFileExtension="ecore"> <ownedRepresentations xsi:type="description_1:DiagramDescription" dropDescriptions="//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@toolSections.0/@ownedTools[name='External%20EClass%20from%20treeview']" name="Entities" titleExpression="aql:self.name + ' package entities'" domainClass="EPackage" enablePopupBars="true"> <filters xsi:type="filter:CompositeFilterDescription" name="Hide class content"> @@ -183,6 +183,24 @@ </firstModelOperations> </initialOperation> </tools> + <tools xsi:type="tool_1:NodeCreationDescription" name="unexecutableTool" nodeMappings="//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@nodeMappings[name='EC%20EClass']"> + <variable name="container"/> + <viewVariable name="containerView"/> + <initialOperation> + <firstModelOperations xsi:type="tool:CreateInstance" typeName="ecore::EClass" referenceName="eClassifiers"> + <subModelOperations xsi:type="properties:DialogModelOperation" titleExpression="New Dialog"> + <buttons labelExpression="Cancel" closeDialogOnClick="true" rollbackChangesOnClose="true"> + <initialOperation/> + </buttons> + <buttons labelExpression="OK" default="true" closeDialogOnClick="true"> + <initialOperation/> + </buttons> + <page name="Default Page" labelExpression="Page" semanticCandidateExpression="var:self" groups="//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@toolSections.0/@ownedTools[name='Classifier']/@tools.5/@initialOperation/@firstModelOperations/@subModelOperations.0/@groups.0"/> + <groups name="Default Group" labelExpression="Group" semanticCandidateExpression="var:self"/> + </subModelOperations> + </firstModelOperations> + </initialOperation> + </tools> </ownedTools> <ownedTools xsi:type="tool_1:ContainerCreationDescription" name="Datatype" containerMappings="//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EDataType']"> <variable name="container"/> @@ -1146,6 +1164,8 @@ <ownedColumnMappings name="Available Tags" headerLabelExpression="aql:if self->oclIsKindOf(ecore::EStructuralFeature) and self.derived then '/' else '' endif + self.key" domainClass="EStringToStringMapEntry" semanticCandidatesExpression="aql:self.eResource().getContent()->first().eAnnotations->select( e | e.source='Tags').details"/> <intersection name="Elements to Tags" semanticElements="var:self" lineMapping="//@ownedViewpoints[name='Review']/@ownedRepresentations[name='Tags']/@ownedLineMappings[name='Tags%20EClassifiers'] //@ownedViewpoints[name='Review']/@ownedRepresentations[name='Tags']/@ownedLineMappings[name='Tags%20EClassifiers']/@ownedSubLines[name='Tag%20EStructural%20Features']" columnMapping="//@ownedViewpoints[name='Review']/@ownedRepresentations[name='Tags']/@ownedColumnMappings.0" labelExpression="XXXXXX" useDomainClass="true" columnFinderExpression="aql:self.references" lineFinderExpression="feature:eContainer" semanticCandidatesExpression="aql:self.eAllContents(EAnnotation)->select( e | e.source='TagValues')" domainClass="EAnnotation"> <directEdit> + <variables name="table" documentation="The current DTable."/> + <variables name="line" documentation="The DLine of the current DCell."/> <variables name="element" documentation="The currently edited element."/> <variables name="lineSemantic" documentation="The semantic element corresponding to the line."/> <variables name="columnSemantic" documentation="The semantic element corresponding to the column (only available for Intersection Mapping)."/> @@ -1206,6 +1226,8 @@ <ownedColumnMappings name="Doc Root" headerLabelExpression="Domain Documentation" domainClass="EPackage" semanticCandidatesExpression="aql:self.eResource().getContents()->at(1)"/> <intersection name="EModelElements to Doc Annotation" semanticElements="var:self" lineMapping="//@ownedViewpoints[name='Review']/@ownedRepresentations[name='Documentation']/@ownedLineMappings[name='Doc%20EClassifiers'] //@ownedViewpoints[name='Review']/@ownedRepresentations[name='Documentation']/@ownedLineMappings[name='Doc%20EClassifiers']/@ownedSubLines[name='Doc%20EStructural%20Features']" columnMapping="//@ownedViewpoints[name='Review']/@ownedRepresentations[name='Documentation']/@ownedColumnMappings.0" labelExpression="aql:self.value" useDomainClass="true" columnFinderExpression="aql:self.eResource().getContents()->first()" lineFinderExpression="aql:self.eContainerOrSelf(ecore::EAnnotation).eContainer()" semanticCandidatesExpression="aql:self.eAllContents(ecore::EAnnotation)->select( e | e.source='http://www.eclipse.org/emf/2002/GenModel').details->select(d | d.key='documentation')" domainClass="EStringToStringMapEntry"> <directEdit> + <variables name="table" documentation="The current DTable."/> + <variables name="line" documentation="The DLine of the current DCell."/> <variables name="element" documentation="The currently edited element."/> <variables name="lineSemantic" documentation="The semantic element corresponding to the line."/> <variables name="columnSemantic" documentation="The semantic element corresponding to the column (only available for Intersection Mapping)."/> diff --git a/plugins/org.eclipse.sirius/plugin.properties b/plugins/org.eclipse.sirius/plugin.properties index 15180057f4..377a647d30 100644 --- a/plugins/org.eclipse.sirius/plugin.properties +++ b/plugins/org.eclipse.sirius/plugin.properties @@ -202,6 +202,7 @@ ModelingProject_getMainRepFileURIMsg = Get main representations resource URI ModelingProjectQuery_severalRepresentationsFiles = Found {0} main representations files (that means not referenced by another) in "{1}": {2}. A modeling project must contain only one. ModelingProjectQuery_mustContainOneRepFileMsg = Zero representations file found in "{0}". A modeling project must contain one. ModelingProjectQuery_and = and +ModelOperationToTask_cannotCreateTaskWarningMsg = Impossible to create the task corresponding to the "{0}" model operation. The plugin contributing this model operation could be missing. MoveElementInListAction_notAMemberErrorMsg = 'element' parameter is not a member of the designated list. MoveElementInListAction_predecessorParameterErrorMsg = 'predecessor' parameter is not a member of the designated list. MoveElementInListAction_elementAndPredecessorShouldBeDiffErrorMsg = 'element' and 'predecessor' must be different. diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/ModelOperationToTask.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/ModelOperationToTask.java index 6d8d9a4bef..8b2623ac0b 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/ModelOperationToTask.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/ModelOperationToTask.java @@ -10,9 +10,12 @@ *******************************************************************************/ package org.eclipse.sirius.business.internal.helper.task; +import java.text.MessageFormat; import java.util.Iterator; import java.util.Optional; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; import org.eclipse.emf.ecore.EObject; import org.eclipse.sirius.business.api.dialect.DialectManager; import org.eclipse.sirius.business.api.helper.task.AbstractCommandTask; @@ -30,12 +33,15 @@ import org.eclipse.sirius.business.internal.helper.task.operations.MoveElementTa import org.eclipse.sirius.business.internal.helper.task.operations.RemoveElementTask; import org.eclipse.sirius.business.internal.helper.task.operations.SetValueTask; import org.eclipse.sirius.business.internal.helper.task.operations.SwitchTask; +import org.eclipse.sirius.business.internal.helper.task.operations.UnexecutableOperationTask; import org.eclipse.sirius.business.internal.helper.task.operations.UnsetTask; import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter; import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor; import org.eclipse.sirius.ext.base.Option; import org.eclipse.sirius.tools.api.command.CommandContext; import org.eclipse.sirius.tools.api.command.ui.UICallBack; +import org.eclipse.sirius.viewpoint.Messages; +import org.eclipse.sirius.viewpoint.SiriusPlugin; import org.eclipse.sirius.viewpoint.description.tool.AbstractToolDescription; import org.eclipse.sirius.viewpoint.description.tool.ChangeContext; import org.eclipse.sirius.viewpoint.description.tool.ContainerModelOperation; @@ -159,8 +165,11 @@ public class ModelOperationToTask implements Function<ModelOperation, ICommandTa ModelOperationManagerDescriptor descriptor = iterator.next(); optionalTask = descriptor.getModelOperationManager().createTask(op, extPackage, uiCallback, session, interpreter, context); } - - if (optionalTask.isPresent() && optionalTask.get() instanceof AbstractOperationTask) { + if (!optionalTask.isPresent()) { + task = UnexecutableOperationTask.getInstance(); + SiriusPlugin.getDefault().getLog() + .log(new Status(IStatus.WARNING, SiriusPlugin.ID, MessageFormat.format(Messages.ModelOperationToTask_cannotCreateTaskWarningMsg, op.eClass().getName()))); + } else if (optionalTask.isPresent() && optionalTask.get() instanceof AbstractOperationTask) { task = (AbstractOperationTask) optionalTask.get(); } } diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/operations/UnexecutableOperationTask.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/operations/UnexecutableOperationTask.java new file mode 100644 index 0000000000..c1b2f83750 --- /dev/null +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/business/internal/helper/task/operations/UnexecutableOperationTask.java @@ -0,0 +1,60 @@ +/******************************************************************************* + * 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.business.internal.helper.task.operations; + +import org.eclipse.sirius.common.tools.api.interpreter.IInterpreter; +import org.eclipse.sirius.ecore.extender.business.api.accessor.ModelAccessor; +import org.eclipse.sirius.ecore.extender.business.api.accessor.exception.FeatureNotFoundException; +import org.eclipse.sirius.ecore.extender.business.api.accessor.exception.MetaClassNotFoundException; +import org.eclipse.sirius.tools.api.command.CommandContext; +import org.eclipse.sirius.viewpoint.Messages; + +/** + * An unexecutable AbstractOperationTask. + * + * @author fbarbin + * + */ +public final class UnexecutableOperationTask extends AbstractOperationTask { + + private static UnexecutableOperationTask instance; + + private UnexecutableOperationTask(CommandContext context, ModelAccessor extPackage, IInterpreter interpreter) { + super(context, extPackage, interpreter); + } + + /** + * Provides the UnexecutableOperationTask unique instance. + * + * @return the UnexecutableOperationTask instance. + */ + public static UnexecutableOperationTask getInstance() { + if (instance == null) { + instance = new UnexecutableOperationTask(null, null, null); + } + return instance; + } + + @Override + public String getLabel() { + return Messages.UnexecutableTask_label; + } + + @Override + public void execute() throws MetaClassNotFoundException, FeatureNotFoundException { + } + + @Override + public boolean canExecute() { + return false; + } + +} diff --git a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java index f66f5d0cc9..582c5d42f6 100644 --- a/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java +++ b/plugins/org.eclipse.sirius/src/org/eclipse/sirius/viewpoint/Messages.java @@ -400,6 +400,9 @@ public final class Messages { public static String ModelingProjectQuery_and; @TranslatableMessage + public static String ModelOperationToTask_cannotCreateTaskWarningMsg; + + @TranslatableMessage public static String MoveElementInListAction_notAMemberErrorMsg; @TranslatableMessage |
