Bug 528773: [Papyrus][SysML1.4] SysML 1.4 should provide its own ViewProvider
-create a ViewProvider supporting semanticHint==null to create a view. It fixes troubles with ShowHideContentAction as described in the bug.
Change-Id: I9292ae6538f7bf019f88c88f897b8dec8600cf3f
Signed-off-by: Vincent Lorenzo <vincent.lorenzo@cea.fr>
diff --git a/diagram/org.eclipse.papyrus.sysml14.diagram.common/META-INF/MANIFEST.MF b/diagram/org.eclipse.papyrus.sysml14.diagram.common/META-INF/MANIFEST.MF
index e027fbb..322b494 100644
--- a/diagram/org.eclipse.papyrus.sysml14.diagram.common/META-INF/MANIFEST.MF
+++ b/diagram/org.eclipse.papyrus.sysml14.diagram.common/META-INF/MANIFEST.MF
@@ -17,6 +17,7 @@
org.eclipse.papyrus.infra.gmfdiag.css;bundle-version="[2.0.0,3.0.0)",
org.eclipse.papyrus.infra.gmfdiag.preferences;bundle-version="[3.0.0,4.0.0)",
org.eclipse.papyrus.infra.gmfdiag.common;bundle-version="[3.0.0,4.0.0)",
+ org.eclipse.papyrus.infra.gmfdiag.expansion;bundle-version="[2.0.0,3.0.0)",
org.eclipse.papyrus.infra.services.edit;bundle-version="[3.0.0,4.0.0)",
org.eclipse.papyrus.infra.tools;bundle-version="[3.0.0,4.0.0)",
org.eclipse.papyrus.uml.diagram.clazz;bundle-version="[3.0.0,4.0.0)",
@@ -58,6 +59,7 @@
org.eclipse.papyrus.sysml14.diagram.internalblock,
org.eclipse.papyrus.sysml14.diagram.parametric,
org.eclipse.papyrus.sysml14.diagram.requirement",
+ org.eclipse.papyrus.sysml14.diagram.common.internal.provider;x-internal:=true,
org.eclipse.papyrus.sysml14.diagram.common.provider,
org.eclipse.papyrus.sysml14.diagram.common.util
Bundle-ActivationPolicy: lazy
diff --git a/diagram/org.eclipse.papyrus.sysml14.diagram.common/plugin.xml b/diagram/org.eclipse.papyrus.sysml14.diagram.common/plugin.xml
index be7ccca..5f6c904 100644
--- a/diagram/org.eclipse.papyrus.sysml14.diagram.common/plugin.xml
+++ b/diagram/org.eclipse.papyrus.sysml14.diagram.common/plugin.xml
@@ -48,5 +48,15 @@
path="pathmap://SysML14_OMG/omg.sysml.uml">
</library>
</extension>
+
+ <extension
+ point="org.eclipse.gmf.runtime.diagram.core.viewProviders">
+ <viewProvider
+ class="org.eclipse.papyrus.sysml14.diagram.common.internal.provider.SysML14ExpandViewProvider">
+ <Priority
+ name="Low">
+ </Priority>
+ </viewProvider>
+ </extension>
</plugin>
diff --git a/diagram/org.eclipse.papyrus.sysml14.diagram.common/src/org/eclipse/papyrus/sysml14/diagram/common/internal/provider/SysML14ExpandViewProvider.java b/diagram/org.eclipse.papyrus.sysml14.diagram.common/src/org/eclipse/papyrus/sysml14/diagram/common/internal/provider/SysML14ExpandViewProvider.java
new file mode 100755
index 0000000..d770d5a
--- /dev/null
+++ b/diagram/org.eclipse.papyrus.sysml14.diagram.common/src/org/eclipse/papyrus/sysml14/diagram/common/internal/provider/SysML14ExpandViewProvider.java
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ * Copyright (c) 2017 CEA LIST and others.
+ *
+ * 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:
+ * Vincent Lorenzo (CEA LIST) - vincent.lorenzo@cea.fr - Initial API and implementation
+ *
+ *****************************************************************************/
+
+package org.eclipse.papyrus.sysml14.diagram.common.internal.provider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.gmf.runtime.diagram.core.services.view.CreateChildViewOperation;
+import org.eclipse.gmf.runtime.diagram.ui.requests.CreateViewRequest.ViewDescriptor;
+import org.eclipse.gmf.runtime.notation.Diagram;
+import org.eclipse.gmf.runtime.notation.View;
+import org.eclipse.papyrus.infra.architecture.representation.PapyrusRepresentationKind;
+import org.eclipse.papyrus.infra.core.architecture.ArchitectureDescriptionLanguage;
+import org.eclipse.papyrus.infra.gmfdiag.expansion.expansionmodel.AbstractRepresentation;
+import org.eclipse.papyrus.infra.gmfdiag.expansion.expansionmodel.Representation;
+import org.eclipse.papyrus.infra.gmfdiag.expansion.expansionmodel.providers.ExpandViewProvider;
+import org.eclipse.papyrus.infra.gmfdiag.expansion.expansionmodel.rendering.ChildrenListRepresentation;
+import org.eclipse.papyrus.infra.types.ElementTypeConfiguration;
+import org.eclipse.papyrus.infra.types.MetamodelTypeConfiguration;
+import org.eclipse.papyrus.infra.types.SpecializationTypeConfiguration;
+import org.eclipse.papyrus.infra.viewpoints.policy.ViewPrototype;
+import org.eclipse.papyrus.uml.diagram.common.actions.ShowHideContentsAction;
+
+/**
+ * Class created for bug 528773. This ViewProvider works only on diagrams described in the sysml14.architecture file
+ * (see method {@link #isAllowedLanguage(CreateChildViewOperation)}) .
+ *
+ * This View Provider has been defined to find the view to create by the {@link ShowHideContentsAction}.
+ * This action has a generic behavior, creating {@link ViewDescriptor} with a semanticHint=null. Its work fine with generated diagram,
+ * but not compartment defined by the expansion model.
+ *
+ * So This ViewProvider cross the expansion model to be able to find the semanticHint of the view to create according to the compartment, when the semanticHint exists.
+ */
+public class SysML14ExpandViewProvider extends ExpandViewProvider {
+
+ /**
+ * The name of the language on which works this ViewProvider
+ */
+ private static final String SYSML_14 = "SysML 1.4"; //$NON-NLS-1$
+
+ /**
+ *
+ * @param operation
+ * a create child view operation
+ * @return
+ * <code>true</code> if the current diagram comes from the description language dedicated to SysML 1.4
+ */
+ private boolean isAllowedLanguage(final CreateChildViewOperation operation) {
+ final View currentView = operation.getContainerView();
+ if (null != currentView) {
+ final Diagram diagram = currentView.getDiagram();
+ final ViewPrototype viewPrototype = org.eclipse.papyrus.infra.gmfdiag.common.utils.DiagramUtils.getPrototype(diagram);
+ if (null != viewPrototype) {
+ final PapyrusRepresentationKind kind = viewPrototype.getRepresentationKind();
+ if (null != kind && null != kind.getLanguage()) {
+ final ArchitectureDescriptionLanguage language = kind.getLanguage();
+ return isAllowedLanguage(language.getName());
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ *
+ * @param language
+ * a language
+ * @return
+ * <code>true</code> if the current language is allowed
+ */
+ protected boolean isAllowedLanguage(final String language) {
+ return SYSML_14.equals(language);
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.expansion.expansionmodel.providers.ExpandViewProvider#getNodeGraphicalType(org.eclipse.core.runtime.IAdaptable, org.eclipse.gmf.runtime.notation.View, java.lang.String)
+ *
+ * @param semanticAdapter
+ * @param containerView
+ * @param semanticHint
+ * @return
+ */
+ @Override
+ protected String getNodeGraphicalType(final IAdaptable semanticAdapter, final View containerView, final String semanticHint) {
+ if (null == semanticHint) {
+ final String currentDiagramType = getDiagramType(containerView);
+ final String containerType = containerView.getType();
+ final List<String> possibleChildrenIDs = this.diagramExpansionRegistry.mapChildreen.get(currentDiagramType).parentChildrenRelation.get(containerType);
+
+ final List<String> supportedChildrenIDs = new ArrayList<String>();
+ for (final String currentChildId : possibleChildrenIDs) {
+ final ChildrenListRepresentation childrenListRepresentation = this.diagramExpansionRegistry.mapChildreen.get(currentDiagramType);
+ final AbstractRepresentation answer = childrenListRepresentation.IDMap.get(currentChildId);
+ if (answer instanceof Representation) {
+ ElementTypeConfiguration elementTypeConfiguration = ((Representation) answer).getGraphicalElementTypeRef();
+ List<MetamodelTypeConfiguration> res = getSupportedMetamodelTypeConfiguration(semanticAdapter, elementTypeConfiguration);
+ if (res.size() > 0) {
+ supportedChildrenIDs.add(currentChildId);
+ }
+ }
+ }
+
+ if (supportedChildrenIDs.size() == 1) {// other case not yet supported, we are waiting concrete case to continue implementationS
+ return supportedChildrenIDs.get(0);
+ }
+ }
+ return null;// not super because the super return a value !=null even when the element is not supported for the compartment
+ }
+
+ /**
+ *
+ * @param semanticAdapter
+ * the semantic adapter for the element we would like to be able to create in a compartment
+ * @param elementTypeConfiguration
+ * an element type configuration
+ * @return
+ * <code>true</code> if the elementTypeConfiguration is defined on a type (or a subtype) of the current element we are trying to create.
+ */
+ private List<MetamodelTypeConfiguration> getSupportedMetamodelTypeConfiguration(final IAdaptable semanticAdapter, final ElementTypeConfiguration elementTypeConfiguration) {
+ final List<MetamodelTypeConfiguration> metamodelTypeConfiguration = new ArrayList<MetamodelTypeConfiguration>();
+ if (elementTypeConfiguration instanceof MetamodelTypeConfiguration) {
+ final MetamodelTypeConfiguration mtc = (MetamodelTypeConfiguration) elementTypeConfiguration;
+ final EClass metamodelEClass = mtc.getEClass();
+ if (null != metamodelEClass) {
+ final EObject currentEObject = semanticAdapter.getAdapter(EObject.class);
+ if (metamodelEClass.isInstance(currentEObject)) {
+ metamodelTypeConfiguration.add((MetamodelTypeConfiguration) elementTypeConfiguration);
+ }
+ }
+ } else if (elementTypeConfiguration instanceof SpecializationTypeConfiguration) {
+ final SpecializationTypeConfiguration stc = (SpecializationTypeConfiguration) elementTypeConfiguration;
+ final List<ElementTypeConfiguration> specialiedTypes = stc.getSpecializedTypes();
+ for (final ElementTypeConfiguration current : specialiedTypes) {
+ final List<MetamodelTypeConfiguration> result = getSupportedMetamodelTypeConfiguration(semanticAdapter, current);
+ metamodelTypeConfiguration.addAll(result);
+ }
+ }
+ return metamodelTypeConfiguration;
+ }
+
+ /**
+ * @see org.eclipse.papyrus.infra.gmfdiag.expansion.expansionmodel.providers.ExpandViewProvider#providesFromExpansionModel(org.eclipse.gmf.runtime.diagram.core.services.view.CreateChildViewOperation)
+ *
+ * @param operation
+ * @return
+ */
+ @Override
+ protected boolean providesFromExpansionModel(final CreateChildViewOperation operation) {
+ boolean result = false;
+ final String semanticHint = operation.getSemanticHint();
+ if (isAllowedLanguage(operation) && (null == semanticHint || semanticHint.isEmpty())) {
+ result = null != getNodeGraphicalType(operation.getSemanticAdapter(), operation.getContainerView(), semanticHint);
+ }
+ return result;
+ }
+
+
+}