blob: 4b39759e767f95f829740db703b74864dfa8bf84 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2015 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.diagram.business.internal.dialect.description;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.EStructuralFeature.Setting;
import org.eclipse.emf.ecore.util.ECrossReferenceAdapter;
import org.eclipse.sirius.business.api.dialect.description.AbstractInterpretedExpressionQuery;
import org.eclipse.sirius.business.api.dialect.description.DefaultInterpretedExpressionTargetSwitch;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionQuery;
import org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionTargetSwitch;
import org.eclipse.sirius.business.api.dialect.description.MultiLanguagesValidator;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterContext;
import org.eclipse.sirius.common.tools.api.interpreter.IInterpreterSiriusVariables;
import org.eclipse.sirius.common.tools.api.interpreter.ValidationResult;
import org.eclipse.sirius.common.tools.api.interpreter.VariableType;
import org.eclipse.sirius.common.tools.api.util.StringUtil;
import org.eclipse.sirius.diagram.ContainerLayout;
import org.eclipse.sirius.diagram.DiagramPackage;
import org.eclipse.sirius.diagram.business.api.diagramtype.DiagramTypeDescriptorRegistry;
import org.eclipse.sirius.diagram.business.api.diagramtype.IDiagramTypeDescriptor;
import org.eclipse.sirius.diagram.business.api.query.EObjectQuery;
import org.eclipse.sirius.diagram.description.AbstractNodeMapping;
import org.eclipse.sirius.diagram.description.ConditionalContainerStyleDescription;
import org.eclipse.sirius.diagram.description.ConditionalEdgeStyleDescription;
import org.eclipse.sirius.diagram.description.ConditionalNodeStyleDescription;
import org.eclipse.sirius.diagram.description.ContainerMapping;
import org.eclipse.sirius.diagram.description.DescriptionPackage;
import org.eclipse.sirius.diagram.description.DiagramDescription;
import org.eclipse.sirius.diagram.description.DiagramElementMapping;
import org.eclipse.sirius.diagram.description.DiagramExtensionDescription;
import org.eclipse.sirius.diagram.description.EdgeMapping;
import org.eclipse.sirius.diagram.description.EdgeMappingImport;
import org.eclipse.sirius.diagram.description.Layer;
import org.eclipse.sirius.diagram.description.NodeMapping;
import org.eclipse.sirius.diagram.description.OrderedTreeLayout;
import org.eclipse.sirius.diagram.description.concern.ConcernPackage;
import org.eclipse.sirius.diagram.description.filter.FilterPackage;
import org.eclipse.sirius.diagram.description.style.ContainerStyleDescription;
import org.eclipse.sirius.diagram.description.style.EdgeStyleDescription;
import org.eclipse.sirius.diagram.description.style.NodeStyleDescription;
import org.eclipse.sirius.diagram.description.style.StylePackage;
import org.eclipse.sirius.diagram.description.tool.ContainerCreationDescription;
import org.eclipse.sirius.diagram.description.tool.CreateEdgeView;
import org.eclipse.sirius.diagram.description.tool.CreateView;
import org.eclipse.sirius.diagram.description.tool.DeleteElementDescription;
import org.eclipse.sirius.diagram.description.tool.DiagramNavigationDescription;
import org.eclipse.sirius.diagram.description.tool.DirectEditLabel;
import org.eclipse.sirius.diagram.description.tool.DoubleClickDescription;
import org.eclipse.sirius.diagram.description.tool.EdgeCreationDescription;
import org.eclipse.sirius.diagram.description.tool.NodeCreationDescription;
import org.eclipse.sirius.diagram.description.tool.ReconnectEdgeDescription;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.tools.api.interpreter.context.SiriusInterpreterContextFactory;
import org.eclipse.sirius.viewpoint.description.ConditionalStyleDescription;
import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
import org.eclipse.sirius.viewpoint.description.RepresentationElementMapping;
import org.eclipse.sirius.viewpoint.description.style.BasicLabelStyleDescription;
import org.eclipse.sirius.viewpoint.description.tool.EditMaskVariables;
import org.eclipse.sirius.viewpoint.description.tool.ModelOperation;
import org.eclipse.sirius.viewpoint.description.tool.OperationAction;
import org.eclipse.sirius.viewpoint.description.tool.RepresentationCreationDescription;
import org.eclipse.sirius.viewpoint.description.tool.ToolDescription;
import org.eclipse.sirius.viewpoint.description.tool.ToolPackage;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
/**
* Query allowing to get the target domain classes and available packages for a
* given Interpreted expression. This diagram query will treat all generic
* description elements and those related to the diagram concept.
*
* @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
*
*/
public class DiagramInterpretedExpressionQuery extends AbstractInterpretedExpressionQuery implements IInterpretedExpressionQuery {
private static final String DIAGRAM_D_DIAGRAM_ELEMENT_CONTAINER = "diagram.DDiagramElementContainer"; //$NON-NLS-1$
private static final String DIAGRAM_D_SEMANTIC_DIAGRAM = "diagram.DSemanticDiagram"; //$NON-NLS-1$
private static final String DIAGRAM_D_NODE = "diagram.DNode"; //$NON-NLS-1$
private static final String DIAGRAM_D_NODE_LIST = "diagram.DNodeList"; //$NON-NLS-1$
private static final String DIAGRAM_D_NODE_CONTAINER = "diagram.DNodeContainer"; //$NON-NLS-1$
private static final String DIAGRAM_D_EDGE_TYPE = "diagram.DEdge"; //$NON-NLS-1$
private static final VariableType EDGE_TARGET_POSSIBILITIES = VariableType.fromStrings(Sets.newHashSet(DIAGRAM_D_EDGE_TYPE, DIAGRAM_D_NODE, DIAGRAM_D_DIAGRAM_ELEMENT_CONTAINER));
/**
* Default constructor.
*
* @param target
* the target containing the InterpretedExpression (NodeMapping,
* ModelOperation...)
* @param feature
* the feature corresponding to the InterpretedExpression to
* evaluate ( NodeMapping.semanticCandidatesExpression...)
*/
public DiagramInterpretedExpressionQuery(EObject target, EStructuralFeature feature) {
super(target, feature);
}
@Override
public Collection<EPackage> getPackagesToImport() {
Collection<EPackage> superResult = super.getPackagesToImport();
superResult.add(DiagramPackage.eINSTANCE);
superResult.add(DescriptionPackage.eINSTANCE);
superResult.add(StylePackage.eINSTANCE);
superResult.add(org.eclipse.sirius.diagram.description.tool.ToolPackage.eINSTANCE);
superResult.add(FilterPackage.eINSTANCE);
superResult.add(ConcernPackage.eINSTANCE);
return superResult;
}
/**
*
* {@inheritDoc}
*
* @see org.eclipse.sirius.business.api.dialect.description.AbstractInterpretedExpressionQuery#initializeTargetSwitch()
*/
@Override
protected void initializeTargetSwitch() {
targetSwitch = new DiagramGlobalInterpretedTargetSwitch();
}
/**
* {@inheritDoc}
*/
@Override
protected void appendAllLocalVariableDefinitions(Map<String, Collection<VariableType>> definitions, EObject context) {
super.appendAllLocalVariableDefinitions(definitions, context);
// Direct edit defines numbered variables based on their mask.
if (context instanceof DirectEditLabel && ((DirectEditLabel) context).getMask() != null) {
EditMaskVariables emv = ((DirectEditLabel) context).getMask();
appendEditMaskVariables(emv, definitions);
}
// Add CreateView and CreateEdgeView Variable Name to available
// variables
if (context instanceof CreateView) {
availableVariables.put(((CreateView) context).getVariableName(), VariableType.ANY_EOBJECT);
}
}
@Override
protected void collectContextualVariableForOperation(EObject current, Map<String, Collection<VariableType>> definitions, EObject leaf) {
super.collectContextualVariableForOperation(current, definitions, leaf);
if (current instanceof CreateView) {
CreateView op = (CreateView) current;
DiagramElementMapping mapping = op.getMapping();
if (mapping instanceof NodeMapping) {
changeSelfType(VariableType.fromString(DIAGRAM_D_NODE));
} else if (mapping instanceof ContainerMapping) {
if (((ContainerMapping) mapping).getChildrenPresentation() == ContainerLayout.LIST) {
changeSelfType(VariableType.fromString(DIAGRAM_D_NODE_LIST));
} else {
changeSelfType(VariableType.fromString(DIAGRAM_D_NODE_CONTAINER));
}
} else if (mapping instanceof EdgeMapping) {
changeSelfType(VariableType.fromString(DIAGRAM_D_EDGE_TYPE));
}
}
}
@Override
public Map<String, VariableType> getAvailableVariables() {
Map<String, VariableType> availableVariables = super.getAvailableVariables();
/*
* [428757] tool variables are not displayed in autocompletion. This
* patch adds hard coded variables and hence is a temporary solution.
* The good way would be to put those metadata on the
* EdgeCreationDescription EClass in the diagram.ecore metamodel and to
* complete the AbstractInterpretedExpressionQuery to make it able to
* find specific variables for concrete types.
*/
if (target instanceof EdgeCreationDescription) {
EdgeCreationDescription tool = (EdgeCreationDescription) target;
collectEdgeCreationDescriptionVariableTypes(availableVariables, tool);
} else if (target instanceof ConditionalNodeStyleDescription || target instanceof NodeStyleDescription) {
availableVariables.put(IInterpreterSiriusVariables.VIEW, VariableType.fromString(DIAGRAM_D_NODE));
} else if (target instanceof ConditionalContainerStyleDescription || target instanceof ContainerStyleDescription) {
availableVariables.put(IInterpreterSiriusVariables.VIEW, VariableType.fromString(DIAGRAM_D_NODE_CONTAINER));
} else if (target instanceof ConditionalEdgeStyleDescription || target instanceof EdgeStyleDescription || target instanceof BasicLabelStyleDescription) {
availableVariables.put(IInterpreterSiriusVariables.VIEW, VariableType.fromString(DIAGRAM_D_EDGE_TYPE));
} else if (target instanceof DiagramElementMapping) {
if (this.feature == DescriptionPackage.Literals.DIAGRAM_ELEMENT_MAPPING__PRECONDITION_EXPRESSION) {
Collection<String> possibleContainerViewTypes = Sets.newLinkedHashSet();
Collection<String> possibleContainerTypes = Sets.newLinkedHashSet();
collectPotentialContainerTypes(possibleContainerTypes, possibleContainerViewTypes, ImmutableList.of((DiagramElementMapping) this.target));
availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleContainerTypes));
availableVariables.put(IInterpreterSiriusVariables.CONTAINER_VIEW, VariableType.fromStrings(possibleContainerViewTypes));
}
}
if (target instanceof EdgeMapping && this.feature == DescriptionPackage.Literals.DIAGRAM_ELEMENT_MAPPING__PRECONDITION_EXPRESSION) {
EdgeMapping edge = (EdgeMapping) target;
Set<String> sourceSemanticType = Sets.newLinkedHashSet();
Set<String> sourceViewType = Sets.newLinkedHashSet();
for (DiagramElementMapping m : edge.getSourceMapping()) {
collectTypes(sourceSemanticType, sourceViewType, m);
}
availableVariables.put(IInterpreterSiriusVariables.SOURCE, VariableType.fromStrings(sourceSemanticType));
availableVariables.put(IInterpreterSiriusVariables.SOURCE_VIEW, VariableType.fromStrings(sourceViewType));
Set<String> targetSemanticType = Sets.newLinkedHashSet();
Set<String> targetViewType = Sets.newLinkedHashSet();
for (DiagramElementMapping m : edge.getTargetMapping()) {
collectTypes(targetSemanticType, targetViewType, m);
}
availableVariables.put(IInterpreterSiriusVariables.TARGET, VariableType.fromStrings(targetSemanticType));
availableVariables.put(IInterpreterSiriusVariables.TARGET_VIEW, VariableType.fromStrings(targetViewType));
}
if (target instanceof ConditionalStyleDescription && this.feature == org.eclipse.sirius.viewpoint.description.DescriptionPackage.Literals.CONDITIONAL_STYLE_DESCRIPTION__PREDICATE_EXPRESSION) {
/*
* We don't use the Ecore annotation to define the 'diagram'
* variable as it is only available for subclasses of
* ConditionalStyleDescription which are defined in the
* diagram.description EPackage.
*/
availableVariables.put(IInterpreterSiriusVariables.DIAGRAM, VariableType.fromString(DIAGRAM_D_SEMANTIC_DIAGRAM));
}
if ((target instanceof NodeCreationDescription || target instanceof ContainerCreationDescription) && this.feature == ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION) {
Collection<String> possibleContainerViewTypes = Sets.newLinkedHashSet();
Collection<String> possibleContainerTypes = Sets.newLinkedHashSet();
Collection<DiagramElementMapping> mappings = Sets.newLinkedHashSet();
if (target instanceof NodeCreationDescription) {
mappings.addAll(((NodeCreationDescription) target).getNodeMappings());
}
if (target instanceof ContainerCreationDescription) {
mappings.addAll(((ContainerCreationDescription) target).getContainerMappings());
}
collectPotentialContainerTypes(possibleContainerTypes, possibleContainerViewTypes, mappings);
if (target instanceof ContainerCreationDescription) {
addExtraMappings(possibleContainerTypes, ((ContainerCreationDescription) target).getExtraMappings());
}
if (target instanceof NodeCreationDescription) {
addExtraMappings(possibleContainerTypes, ((NodeCreationDescription) target).getExtraMappings());
}
availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleContainerTypes));
availableVariables.put(IInterpreterSiriusVariables.CONTAINER_VIEW, VariableType.fromStrings(possibleContainerViewTypes));
}
if (target instanceof OrderedTreeLayout && this.feature == DescriptionPackage.Literals.ORDERED_TREE_LAYOUT__CHILDREN_EXPRESSION) {
Collection<String> possibleSemanticTypes = Sets.newLinkedHashSet();
for (AbstractNodeMapping n : ((OrderedTreeLayout) target).getNodeMapping()) {
collectTypes(possibleSemanticTypes, Sets.<String> newLinkedHashSet(), n);
}
refineVariableType(availableVariables, SELF, possibleSemanticTypes);
}
if (target instanceof ReconnectEdgeDescription && this.feature == ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION) {
Collection<String> possibleContainerTypes = Sets.newLinkedHashSet();
collectPotentialContainerTypes(possibleContainerTypes, Sets.<String> newLinkedHashSet(), ((ReconnectEdgeDescription) target).getMappings());
availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleContainerTypes));
}
if (target instanceof RepresentationCreationDescription) {
typeVariablesForDiagramCreationRepresentation((RepresentationCreationDescription) target, availableVariables);
}
return availableVariables;
}
private void addExtraMappings(Collection<String> possibleContainerTypes, Collection<AbstractNodeMapping> extra) {
for (AbstractNodeMapping np : extra) {
String domainClass = np.getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleContainerTypes.add(domainClass);
}
}
}
private void typeVariablesForDiagramCreationRepresentation(RepresentationCreationDescription desc, Map<String, VariableType> availableVariables) {
Collection<String> possibleSemanticTypes = Sets.newLinkedHashSet();
Collection<String> possibleViewTypes = Sets.newLinkedHashSet();
Collection<String> possibleContainerViewTypes = Sets.newLinkedHashSet();
Collection<String> possibleContainerTypes = Sets.newLinkedHashSet();
for (DiagramElementMapping n : Iterables.filter(desc.getMappings(), DiagramElementMapping.class)) {
collectTypes(possibleSemanticTypes, possibleViewTypes, n);
collectPotentialContainerTypes(possibleContainerTypes, possibleContainerViewTypes, n);
}
refineVariableType(availableVariables, SELF, possibleSemanticTypes);
if (this.feature == ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION) {
/*
* then we are validating the attribute expressions of the tool.
*/
availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleContainerTypes));
availableVariables.put(IInterpreterSiriusVariables.CONTAINER_VIEW, VariableType.fromStrings(possibleContainerViewTypes));
} else if (this.feature != ToolPackage.Literals.REPRESENTATION_CREATION_DESCRIPTION__BROWSE_EXPRESSION) {
/*
* we are in the model operations
*/
availableVariables.put(IInterpreterSiriusVariables.CONTAINER_VIEW, VariableType.fromStrings(possibleContainerViewTypes));
if (desc.getRepresentationNameVariable() != null && !StringUtil.isEmpty(desc.getRepresentationNameVariable().getName())) {
availableVariables.put(desc.getRepresentationNameVariable().getName(), VariableType.fromJavaClass(java.lang.String.class)); // $NON-NLS-1$
}
}
}
private void collectEdgeCreationDescriptionVariableTypes(Map<String, VariableType> availableVariables, EdgeCreationDescription tool) {
Collection<String> possibleSemanticSources = Sets.newLinkedHashSet();
Collection<String> possibleViewSources = Sets.newLinkedHashSet();
Collection<String> possibleSemanticTargets = Sets.newLinkedHashSet();
Collection<String> possibleViewTargets = Sets.newLinkedHashSet();
Collection<String> possibleContainerTypes = Sets.newLinkedHashSet();
collectPotentialContainerTypes(possibleContainerTypes, Sets.<String> newLinkedHashSet(), tool.getEdgeMappings());
for (EdgeMapping eMapping : tool.getEdgeMappings()) {
for (DiagramElementMapping endMapping : eMapping.getSourceMapping()) {
collectTypes(possibleSemanticSources, possibleViewSources, endMapping);
}
for (DiagramElementMapping endMapping : eMapping.getTargetMapping()) {
collectTypes(possibleSemanticTargets, possibleViewTargets, endMapping);
}
}
for (DiagramElementMapping extraSource : tool.getExtraSourceMappings()) {
collectTypes(possibleSemanticSources, possibleViewSources, extraSource);
}
for (DiagramElementMapping extraTarget : tool.getExtraTargetMappings()) {
collectTypes(possibleSemanticTargets, possibleViewTargets, extraTarget);
}
if (ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION.equals(feature)) {
availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleContainerTypes));
availableVariables.put(IInterpreterSiriusVariables.DIAGRAM, VariableType.fromString(DIAGRAM_D_SEMANTIC_DIAGRAM));
availableVariables.put(IInterpreterSiriusVariables.SOURCE_PRE, VariableType.fromStrings(possibleSemanticSources));
availableVariables.put(IInterpreterSiriusVariables.SOURCE_VIEW_PRE, VariableType.fromStrings(possibleViewSources));
availableVariables.put(IInterpreterSiriusVariables.TARGET_PRE, VariableType.fromStrings(possibleSemanticTargets));
availableVariables.put(IInterpreterSiriusVariables.TARGET_VIEW_PRE, VariableType.fromStrings(possibleViewTargets));
}
if (this.feature == org.eclipse.sirius.diagram.description.tool.ToolPackage.Literals.EDGE_CREATION_DESCRIPTION__CONNECTION_START_PRECONDITION) {
availableVariables.put(IInterpreterSiriusVariables.CONTAINER, VariableType.fromStrings(possibleContainerTypes));
availableVariables.put(IInterpreterSiriusVariables.DIAGRAM, VariableType.fromString(DIAGRAM_D_SEMANTIC_DIAGRAM));
availableVariables.put(IInterpreterSiriusVariables.SOURCE_PRE, VariableType.fromStrings(possibleSemanticSources));
availableVariables.put(IInterpreterSiriusVariables.SOURCE_VIEW_PRE, VariableType.fromStrings(possibleViewSources));
}
}
@Override
protected void addVariableFromCreateOperation(ModelOperation modelOperation) {
super.addVariableFromCreateOperation(modelOperation);
if (modelOperation instanceof CreateEdgeView) {
availableVariables.put(((CreateEdgeView) modelOperation).getVariableName(), VariableType.fromString("diagram.DEdge")); //$NON-NLS-1$
} else if (modelOperation instanceof CreateView) {
availableVariables.put(((CreateView) modelOperation).getVariableName(), VariableType.fromString("viewpoint.DView")); //$NON-NLS-1$
}
}
@Override
protected void addVariablesFromToolContext(EObject toolContext) {
if (toolContext != null) {
addVariablesForCreationTools(toolContext);
if (toolContext instanceof DeleteElementDescription) {
DeleteElementDescription tool = (DeleteElementDescription) toolContext;
Collection<String> possibleSemanticTypes = Sets.newLinkedHashSet();
Collection<String> possibleViewTypes = Sets.newLinkedHashSet();
Collection<String> possibleContainerViewTypes = Sets.newLinkedHashSet();
for (DiagramElementMapping mapping : tool.getMappings()) {
collectTypes(possibleSemanticTypes, possibleViewTypes, mapping);
collectPotentialContainerTypes(Sets.<String> newLinkedHashSet(), possibleContainerViewTypes, mapping);
}
refineVariableType(availableVariables, IInterpreterSiriusVariables.ELEMENT, possibleSemanticTypes);
refineVariableType(availableVariables, "elementView", possibleViewTypes); //$NON-NLS-1$
refineVariableType(availableVariables, "containerView", possibleContainerViewTypes); //$NON-NLS-1$
}
if (toolContext instanceof OperationAction) {
OperationAction tool = (OperationAction) toolContext;
if (new EObjectQuery(tool).getFirstAncestorOfType(DescriptionPackage.Literals.DIAGRAM_DESCRIPTION).some()) {
availableVariables.put(IInterpreterSiriusVariables.DIAGRAM, VariableType.fromString(DIAGRAM_D_SEMANTIC_DIAGRAM));
}
availableVariables.put("views", VariableType.fromString("viewpoint.DSemanticDecorator")); //$NON-NLS-1$ //$NON-NLS-2$
}
if (toolContext instanceof ToolDescription) {
ToolDescription tool = (ToolDescription) toolContext;
if (!StringUtil.isEmpty(tool.getPrecondition())) {
IInterpreterContext iContext = SiriusInterpreterContextFactory.createInterpreterContext(tool, ToolPackage.Literals.ABSTRACT_TOOL_DESCRIPTION__PRECONDITION);
ValidationResult res = MultiLanguagesValidator.getInstance().validateExpression(iContext, tool.getPrecondition());
Map<String, VariableType> inferedTypes = res.getInferredVariableTypes(Boolean.TRUE);
for (Entry<String, VariableType> infered : inferedTypes.entrySet()) {
if (SELF.equals(infered.getKey())) {
changeSelfType(infered.getValue());
} else if (infered.getValue().getPossibleTypes().size() > 0) {
availableVariables.put(infered.getKey(), infered.getValue());
}
}
availableVariables.put(IInterpreterSiriusVariables.DIAGRAM, VariableType.fromString(DIAGRAM_D_SEMANTIC_DIAGRAM));
}
}
if (toolContext instanceof DiagramNavigationDescription) {
DiagramNavigationDescription tool = (DiagramNavigationDescription) toolContext;
Collection<String> possibleContainerSemanticTypes = Sets.newLinkedHashSet();
Collection<String> possibleContainerViewTypes = Sets.newLinkedHashSet();
collectPotentialContainerTypes(possibleContainerSemanticTypes, possibleContainerViewTypes, Lists.newArrayList(Iterables.filter(tool.getMappings(), DiagramElementMapping.class)));
refineVariableType(availableVariables, tool.getContainerVariable().getName(), possibleContainerSemanticTypes);
refineVariableType(availableVariables, tool.getContainerViewVariable().getName(), possibleContainerViewTypes);
}
if (toolContext instanceof DoubleClickDescription) {
DoubleClickDescription tool = (DoubleClickDescription) toolContext;
Collection<String> possibleSemanticTypes = Sets.newLinkedHashSet();
Collection<String> possibleViewTypes = Sets.newLinkedHashSet();
for (DiagramElementMapping m : tool.getMappings()) {
collectTypes(possibleSemanticTypes, possibleViewTypes, m);
}
refineVariableType(availableVariables, tool.getElement().getName(), possibleSemanticTypes);
refineVariableType(availableVariables, tool.getElementView().getName(), possibleViewTypes);
}
if (toolContext instanceof RepresentationCreationDescription) {
typeVariablesForDiagramCreationRepresentation((RepresentationCreationDescription) toolContext, availableVariables);
}
}
}
private void addVariablesForCreationTools(EObject toolContext) {
if (toolContext instanceof EdgeCreationDescription) {
EdgeCreationDescription tool = (EdgeCreationDescription) toolContext;
declareEdgeSourceTargets(availableVariables, tool.getEdgeMappings(), tool.getExtraSourceMappings(), tool.getExtraTargetMappings());
}
if (toolContext instanceof ReconnectEdgeDescription) {
ReconnectEdgeDescription tool = (ReconnectEdgeDescription) toolContext;
declareEdgeSourceTargets(availableVariables, tool.getMappings(), Collections.<DiagramElementMapping> emptyList(), Collections.<DiagramElementMapping> emptyList());
availableVariables.put("otherEnd", EDGE_TARGET_POSSIBILITIES); //$NON-NLS-1$
availableVariables.put("edgeView", VariableType.fromString(DIAGRAM_D_EDGE_TYPE)); //$NON-NLS-1$
Collection<String> possibleSources = Lists.newArrayList();
for (EdgeMapping eMapping : tool.getMappings()) {
collectSemanticElementType(possibleSources, eMapping);
}
refineVariableType(availableVariables, IInterpreterSiriusVariables.ELEMENT, possibleSources);
}
if (toolContext instanceof NodeCreationDescription) {
NodeCreationDescription tool = (NodeCreationDescription) toolContext;
Collection<String> possibleSemanticTypes = Sets.newLinkedHashSet();
/*
* gather types for the "container" variable.
*/
for (AbstractNodeMapping np : tool.getExtraMappings()) {
String domainClass = np.getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
}
Collection<String> possibleViewTypes = Sets.newLinkedHashSet();
collectPotentialContainerTypes(possibleSemanticTypes, possibleViewTypes, tool.getNodeMappings());
refineVariableType(availableVariables, IInterpreterSiriusVariables.CONTAINER, possibleSemanticTypes);
refineVariableType(availableVariables, IInterpreterSiriusVariables.CONTAINER_VIEW, possibleViewTypes);
}
if (toolContext instanceof ContainerCreationDescription) {
ContainerCreationDescription tool = (ContainerCreationDescription) toolContext;
Collection<String> possibleTypes = Sets.newLinkedHashSet();
/*
* gather types for the "container" variable.
*/
for (AbstractNodeMapping np : tool.getExtraMappings()) {
String domainClass = np.getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleTypes.add(domainClass);
}
}
Collection<String> possibleViewTypes = Sets.newLinkedHashSet();
collectPotentialContainerTypes(possibleTypes, possibleViewTypes, tool.getContainerMappings());
refineVariableType(availableVariables, IInterpreterSiriusVariables.CONTAINER_VIEW, possibleViewTypes);
refineVariableType(availableVariables, IInterpreterSiriusVariables.CONTAINER, possibleTypes);
}
}
private void refineVariableType(Map<String, VariableType> availableVariables, String variableName, Collection<String> foundTypes) {
if (foundTypes.size() > 0) {
availableVariables.put(variableName, VariableType.fromStrings(foundTypes));
}
}
private void collectPotentialContainerTypes(Collection<String> possibleSemanticTypes, Collection<String> possibleViewTypes, Collection<? extends DiagramElementMapping> toolMappings) {
for (DiagramElementMapping anyMapping : toolMappings) {
collectPotentialContainerTypes(possibleSemanticTypes, possibleViewTypes, anyMapping);
}
}
private void collectPotentialContainerTypes(Collection<String> possibleSemanticTypes, Collection<String> possibleViewTypes, DiagramElementMapping mapping) {
/*
* A mapping is "used" by its container.
*/
EObject container = mapping.eContainer();
if (container instanceof Layer) {
/*
* Layer is a no-op from a type perspective.
*/
container = container.eContainer();
}
if (container instanceof AbstractNodeMapping) {
String domainClass = ((AbstractNodeMapping) container).getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
collectViewTypes(possibleViewTypes, (AbstractNodeMapping) container);
} else if (container instanceof DiagramDescription) {
String domainClass = ((DiagramDescription) container).getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
possibleViewTypes.add(DIAGRAM_D_SEMANTIC_DIAGRAM);
}
/*
* besides the container a mapping can be re-used by another one or by a
* diagram description.
*/
ECrossReferenceAdapter crossReferencer = ECrossReferenceAdapter.getCrossReferenceAdapter(mapping);
if (crossReferencer != null) {
for (Setting xRef : crossReferencer.getInverseReferences(mapping)) {
EStructuralFeature eStructuralFeature = xRef.getEStructuralFeature();
EObject referencingObject = xRef.getEObject();
if (eStructuralFeature == DescriptionPackage.Literals.DIAGRAM_DESCRIPTION__REUSED_MAPPINGS && referencingObject instanceof DiagramDescription) {
String domainClass = ((DiagramDescription) referencingObject).getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
} else if (eStructuralFeature == DescriptionPackage.Literals.ABSTRACT_NODE_MAPPING__REUSED_BORDERED_NODE_MAPPINGS && referencingObject instanceof AbstractNodeMapping) {
String domainClass = ((AbstractNodeMapping) referencingObject).getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
} else if ((eStructuralFeature == DescriptionPackage.Literals.CONTAINER_MAPPING__REUSED_CONTAINER_MAPPINGS
|| eStructuralFeature == DescriptionPackage.Literals.CONTAINER_MAPPING__REUSED_NODE_MAPPINGS) && referencingObject instanceof ContainerMapping) {
String domainClass = ((ContainerMapping) referencingObject).getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
}
}
}
}
private void declareEdgeSourceTargets(Map<String, VariableType> availableVariables, Collection<EdgeMapping> eMappings, Collection<DiagramElementMapping> extraSourceMappings,
Collection<DiagramElementMapping> extraTargetMappings) {
Collection<String> possibleSemanticSources = Sets.newLinkedHashSet();
Collection<String> possibleViewSources = Sets.newLinkedHashSet();
Collection<String> possibleSemanticTargets = Sets.newLinkedHashSet();
Collection<String> possibleViewTargets = Sets.newLinkedHashSet();
for (EdgeMapping eMapping : eMappings) {
for (DiagramElementMapping endMapping : eMapping.getSourceMapping()) {
collectTypes(possibleSemanticSources, possibleViewSources, endMapping);
}
for (DiagramElementMapping endMapping : eMapping.getTargetMapping()) {
collectTypes(possibleSemanticTargets, possibleViewTargets, endMapping);
}
}
for (DiagramElementMapping extraSource : extraSourceMappings) {
collectTypes(possibleSemanticSources, possibleViewSources, extraSource);
}
for (DiagramElementMapping extraTarget : extraTargetMappings) {
collectTypes(possibleSemanticTargets, possibleViewTargets, extraTarget);
}
refineVariableType(availableVariables, IInterpreterSiriusVariables.SOURCE_VIEW, possibleViewSources);
refineVariableType(availableVariables, IInterpreterSiriusVariables.SOURCE_VIEW_PRE, possibleViewSources);
refineVariableType(availableVariables, IInterpreterSiriusVariables.TARGET_VIEW, possibleViewTargets);
refineVariableType(availableVariables, IInterpreterSiriusVariables.SOURCE_PRE, possibleSemanticSources);
refineVariableType(availableVariables, IInterpreterSiriusVariables.SOURCE, possibleSemanticSources);
if (feature != org.eclipse.sirius.diagram.description.tool.ToolPackage.Literals.EDGE_CREATION_DESCRIPTION__CONNECTION_START_PRECONDITION) {
refineVariableType(availableVariables, IInterpreterSiriusVariables.TARGET_PRE, possibleSemanticTargets);
refineVariableType(availableVariables, IInterpreterSiriusVariables.TARGET, possibleSemanticTargets);
refineVariableType(availableVariables, IInterpreterSiriusVariables.TARGET_VIEW_PRE, possibleViewTargets);
}
}
private void collectTypes(Collection<String> possibleSemanticTypes, Collection<String> possibleViewTypes, DiagramElementMapping endMapping) {
collectViewTypes(possibleViewTypes, endMapping);
if (endMapping instanceof AbstractNodeMapping) {
String domainClass = ((AbstractNodeMapping) endMapping).getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSemanticTypes.add(domainClass);
}
} else if (endMapping instanceof EdgeMapping) {
EdgeMapping edgeMapping = (EdgeMapping) endMapping;
collectSemanticElementType(possibleSemanticTypes, edgeMapping);
}
}
private void collectViewTypes(Collection<String> possibleViewTypes, DiagramElementMapping endMapping) {
if (endMapping instanceof ContainerMapping) {
if (((ContainerMapping) endMapping).getChildrenPresentation() == ContainerLayout.LIST) {
possibleViewTypes.add(DIAGRAM_D_NODE_LIST);
} else {
possibleViewTypes.add(DIAGRAM_D_NODE_CONTAINER);
}
} else if (endMapping instanceof NodeMapping) {
possibleViewTypes.add(DIAGRAM_D_NODE);
} else if (endMapping instanceof EdgeMapping) {
possibleViewTypes.add(DIAGRAM_D_EDGE_TYPE);
}
}
private void collectSemanticElementType(Collection<String> possibleSources, EdgeMapping edgeMapping) {
if (edgeMapping.isUseDomainElement()) {
String domainClass = edgeMapping.getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSources.add(domainClass);
}
} else {
for (AbstractNodeMapping nMapping : Iterables.filter(edgeMapping.getSourceMapping(), AbstractNodeMapping.class)) {
String domainClass = nMapping.getDomainClass();
if (!StringUtil.isEmpty(domainClass)) {
possibleSources.add(domainClass);
}
}
}
}
/**
* An {@link IInterpretedExpressionTargetSwitch} that delegates to the
* defaultSwitch or the diagram specific switch, according to the package of
* the considered element.
*
* @author <a href="mailto:alex.lagarde@obeo.fr">Alex Lagarde</a>
*
*/
private class DiagramGlobalInterpretedTargetSwitch implements IInterpretedExpressionTargetSwitch {
private DefaultInterpretedExpressionTargetSwitch defaultSwitch = new DefaultInterpretedExpressionTargetSwitch(feature, this) {
@Override
public EObject getFirstRelevantContainer(EObject obj) {
return DiagramGlobalInterpretedTargetSwitch.this.getFirstRelevantContainer(obj);
}
};
private DiagramInterpretedExpressionTargetSwitch diagramDescriptionSwitch = new DiagramInterpretedExpressionTargetSwitch(feature, this);
private DiagramStyleInterpretedExpressionTargetSwitch diagramStyleSwitch = new DiagramStyleInterpretedExpressionTargetSwitch(feature, this);
private DiagramToolInterpretedExpressionTargetSwitch diagramToolSwitch = new DiagramToolInterpretedExpressionTargetSwitch(feature, this);
private FilterInterpretedExpressionTargetSwitch diagramFilterSwitch = new FilterInterpretedExpressionTargetSwitch(feature, this);
/**
*
* {@inheritDoc}
*
* @see org.eclipse.sirius.business.api.dialect.description.IInterpretedExpressionTargetSwitch#doSwitch(org.eclipse.emf.ecore.EObject)
*/
@Override
public Option<Collection<String>> doSwitch(EObject target, boolean considerFeature) {
Collection<String> targetTypes = Sets.newLinkedHashSet();
Option<Collection<String>> expressionTarget = Options.newSome(targetTypes);
if (target != null) {
// Step 1: trying to apply any contributed switch that matches
// the given target's EPackage
for (final IDiagramTypeDescriptor diagramTypeDescriptor : DiagramTypeDescriptorRegistry.getInstance().getAllDiagramTypeDescriptors()) {
if (diagramTypeDescriptor.getDiagramDescriptionProvider().handles(target.eClass().getEPackage())) {
IInterpretedExpressionTargetSwitch contributedSwitch = diagramTypeDescriptor.getDiagramDescriptionProvider().createInterpretedExpressionSwitch(feature, this);
if (contributedSwitch != null) {
expressionTarget = contributedSwitch.doSwitch(target, considerFeature);
}
}
}
// If no result has been found
if (expressionTarget.some() && expressionTarget.get().isEmpty()) {
// Step 2: apply the Diagram description specific switch
diagramDescriptionSwitch.setConsiderFeature(considerFeature);
expressionTarget = diagramDescriptionSwitch.doSwitch(target);
}
// If no result has been found
if (expressionTarget.some() && expressionTarget.get().isEmpty()) {
// Step 3: apply the Diagram style specific switch
diagramStyleSwitch.setConsiderFeature(considerFeature);
expressionTarget = diagramStyleSwitch.doSwitch(target);
}
// If no result has been found
if (expressionTarget.some() && expressionTarget.get().isEmpty()) {
// Step 4: apply the Diagram tool specific switch
diagramToolSwitch.setConsiderFeature(considerFeature);
expressionTarget = diagramToolSwitch.doSwitch(target);
}
// If no result has been found
if (expressionTarget.some() && expressionTarget.get().isEmpty()) {
// Step 5: apply the Diagram filter specific switch
diagramFilterSwitch.setConsiderFeature(considerFeature);
expressionTarget = diagramFilterSwitch.doSwitch(target);
}
// If no result has been found
if (expressionTarget.some() && expressionTarget.get().isEmpty()) {
// Step 7 : we use the default switch
expressionTarget = defaultSwitch.doSwitch(target, considerFeature);
}
}
return expressionTarget;
}
@Override
public EObject getFirstRelevantContainer(EObject obj) {
if (obj != null) {
EObject container = obj.eContainer();
while (container != null && !isRelevant(container)) {
container = container.eContainer();
}
return container;
} else {
return null;
}
}
private boolean isRelevant(EObject container) {
return container instanceof RepresentationDescription || container instanceof RepresentationElementMapping || container instanceof EdgeMappingImport
|| container instanceof DiagramExtensionDescription;
}
}
}