blob: 313e1897b87fc3222cebd6a7163fa15cde5cdda2 [file] [log] [blame]
/**
* Copyright (c) 2009, 2011, 2012 Borland Software Corporation & 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:
* Artem Tikhomirov (Borland) - initial API and implementation
* Guillaume Hillairet (Montages A.G.)
*/
library Mappings;
import Utils;
import ModelFacets;
import Palette;
import Viewmaps;
import ModeledViewmaps;
import Identity;
import Behaviours;
modeltype GMFMAP uses mappings('http://www.eclipse.org/gmf/2006/mappings');
modeltype GMFTOOL uses tooldef('http://www.eclipse.org/gmf/2005/ToolDefinition');
modeltype GMFGEN uses gmfgen('http://www.eclipse.org/gmf/2009/GenModel');
modeltype GMFGRAPH uses gmfgraph('http://www.eclipse.org/gmf/2006/GraphicalDefinition');
modeltype ECORE uses ecore('http://www.eclipse.org/emf/2002/Ecore');
modeltype GENMODEL uses genmodel('http://www.eclipse.org/emf/2002/GenModel');
--
-- Mapping
--
property genEditorGenerator : GMFGEN::GenEditorGenerator = null;
mapping GMFMAP::Mapping::structure() : GMFGEN::GenEditorGenerator {
init {
result := object GMFGEN::GenEditorGenerator {
diagram := self.diagram.map structure();
}
}
genEditorGenerator := result;
childReferences := self.getChildReferences();
self.nodes->map structure();
diagram.links := self.links->map structure();
diagram.getAllNodes()->forEach(n) { setupElementType(n) };
diagram.links->forEach(l) { setupElementType(l) };
if self.expressionsByLanguages()->notEmpty() then
expressionProviders := self.map createProviderContainer()
endif;
}
mapping GMFMAP::Mapping::createProviderContainer(): GMFGEN::GenExpressionProviderContainer {
self.expressionsByLanguages()->forEach(e) {
providers += e.map createExpressionProvider()
}
}
mapping GMFMAP::CanvasMapping::structure() : GMFGEN::GenDiagram {
init {
result := object GenDiagram {
viewmap := self.viewmap();
domainDiagramElement := self.domainMetaElement.findGenClass();
iconProviderPriority := GMFGEN::ProviderPriority::Low;
validationProviderPriority := GMFGEN::ProviderPriority::Low;
}
}
result.visualID := result.visualID();
if result.domainDiagramElement.oclIsUndefined() then
result.elementType := object GMFGEN::NotationType {}
else
result.elementType := result.domainDiagramElement.getOrCreateRuntimeMetamodelType()
endif;
}
--
-- TopLevelNode
--
mapping GMFMAP::TopNodeReference::structure() : GMFGEN::GenTopLevelNode {
init {
result := object GenTopLevelNode {
modelFacet := self.createModelFacet();
viewmap := self.viewmap();
}
}
genEditorGenerator.diagram.topLevelNodes += result;
result.visualID := result.visualID();
self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result;
self.child.map abstractStructure(result);
labels += self.child.labelMappings->map createNodeLabel(self, result);
behaviour += self.child.relatedDiagrams.handleRelatedDiagram(self.child);
behaviour += self.child.visualEffects->map createVisualEffects(result, self.child.diagramNode);
}
--
--
--
mapping GMFMAP::NodeMapping::abstractStructure(inout genNode: GMFGEN::GenNode) {
var mapOfCompartments : Dict(CompartmentMapping, GenCompartment) = Dict{};
self.compartments->forEach(c) {
var childCompartment := object GMFGEN::GenCompartment {
title := c.compartment.name;
canCollapse := c.compartment.collapsible;
needsTitle := c.compartment.needsTitle;
viewmap := c.viewmap();
};
mapOfCompartments->put(c, childCompartment);
genEditorGenerator.diagram.compartments += childCompartment;
genNode.compartments += childCompartment;
childCompartment.node := genNode;
childCompartment.visualID := childCompartment.visualID();
};
self.children->forEach(childNodeRef) {
var compartmentMapping := childNodeRef.compartment;
var genChildContainer : GenChildContainer = null;
if not compartmentMapping.oclIsUndefined() and not mapOfCompartments->get(compartmentMapping).oclIsUndefined() then
genChildContainer := mapOfCompartments->get(compartmentMapping)
else
genChildContainer := genNode
endif;
var childNodeMapping := childNodeRef.child;
var node := childNodeRef.findProcessableChildReference();
var childNode := node.map structure(childNodeMapping);
if genChildContainer.oclIsKindOf(GenCompartment) and childNodeMapping.children->size() > 0 then
genChildContainer.oclAsType(GenCompartment).listLayout := false
endif;
genChildContainer.childNodes += childNode;
};
}
--
-- GenChildNode
--
abstract mapping GMFMAP::ChildReference::abstractStructure(nodeMapping: GMFMAP::NodeMapping): GMFGEN::GenChildNode {
modelFacet := self.createModelFacet();
viewmap := self.viewmap(nodeMapping);
self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result;
}
mapping GMFMAP::ChildReference::structure(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildNode
disjuncts
GMFMAP::ChildReference::createGenChildLabelNode,
GMFMAP::ChildReference::createGenChildSideAffixedNode,
GMFMAP::ChildReference::createGenChildNode
{}
mapping GMFMAP::ChildReference::createGenChildLabelNode(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildLabelNode
inherits GMFMAP::ChildReference::abstractStructure
when {
nodeMapping.isPureLabelNode()
}
{
init {
result := object GMFGEN::GenChildLabelNode {}
}
genEditorGenerator.diagram.childNodes += result;
result.visualID := result.visualID();
var soleLabel := nodeMapping.labelMappings->first();
labelModelFacet := soleLabel.map createLabelModelFacet(self);
labelReadOnly := soleLabel.readOnly;
labelElementIcon := soleLabel.diagramLabel.elementIcon;
}
mapping GMFMAP::ChildReference::createGenChildSideAffixedNode(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildSideAffixedNode
inherits GMFMAP::ChildReference::abstractStructure
when {
nodeMapping.diagramNode.affixedParentSide <> GMFGRAPH::Direction::NONE
}
{
init {
result := object GMFGEN::GenChildSideAffixedNode {}
}
genEditorGenerator.diagram.childNodes += result;
result.visualID := result.visualID();
self.child.map abstractStructure(result);
preferredSideName := nodeMapping.diagramNode.getAffixedSideAsPositionConstantsName();
labels += nodeMapping.labelMappings->map createNodeLabel(self, result);
behaviour += nodeMapping.relatedDiagrams.handleRelatedDiagram(nodeMapping);
behaviour += nodeMapping.visualEffects->map createVisualEffects(result, nodeMapping.diagramNode);
}
mapping GMFMAP::ChildReference::createGenChildNode(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildNode
inherits GMFMAP::ChildReference::abstractStructure
{
init {
result := object GMFGEN::GenChildNode {}
}
genEditorGenerator.diagram.childNodes += result;
result.visualID := result.visualID();
self.child.map abstractStructure(result);
nodeMapping.labelMappings->map createNodeLabel(self, result);
behaviour += nodeMapping.relatedDiagrams.handleRelatedDiagram(nodeMapping);
behaviour += nodeMapping.visualEffects->map createVisualEffects(result, nodeMapping.diagramNode);
}
--
-- NodeLabel
--
mapping GMFMAP::LabelMapping::createNodeLabel(node: NodeReference, inout genNode: GMFGEN::GenNode) : GMFGEN::GenNodeLabel {
init {
if self.diagramLabel.external then
result := object GenExternalNodeLabel {}
else
result := object GenNodeLabel {}
endif
}
result.viewmap := self.viewmap();
result.modelFacet := self.map createLabelModelFacet(node);
result.readOnly := self.readOnly;
result.elementIcon := self.diagramLabel.elementIcon;
genNode.labels += result;
result.visualID := result.visualID();
}
--
-- GenLink
--
mapping GMFMAP::LinkMapping::structure() : GMFGEN::GenLink
when {
not self.diagramLink.oclIsUndefined() and
not self.linkMetaFeature.oclIsUndefined()
}{
init {
result := object GMFGEN::GenLink {
-- model facet
if not (self.domainMetaElement.oclIsUndefined() and self.linkMetaFeature.oclIsUndefined()) then
modelFacet := self.map createModelFacet()
endif;
viewmap := self.viewmap();
}
}
genEditorGenerator.diagram.links += result;
result.visualID := result.visualID();
-- labels
self.labelMappings->map structure(self, result);
self.tool.map paletteEntry().oclAsType(ToolEntry).genLinks += result;
result.creationConstraints := self.creationConstraints.map structure();
behaviour += self.visualEffects->map createVisualEffects(result, self.diagramLink);
}
mapping LabelMapping::structure(link: GMFMAP::LinkMapping, inout genLink: GMFGEN::GenLink): GenLinkLabel {
init {
result := object GMFGEN::GenLinkLabel {
readOnly := self.readOnly;
elementIcon := self.diagramLabel.elementIcon;
modelFacet := self.map createLabelModelFacet(link);
viewmap := self.viewmap();
var alignmentFacet := self.diagramLabel.findAlignmentFacet();
if not alignmentFacet.oclIsUndefined() then
alignment := switch {
case (alignmentFacet.alignment = GMFGRAPH::Alignment::BEGINNING) LinkLabelAlignment::SOURCE;
case (alignmentFacet.alignment = GMFGRAPH::Alignment::CENTER) LinkLabelAlignment::MIDDLE;
case (alignmentFacet.alignment = GMFGRAPH::Alignment::END) LinkLabelAlignment::TARGET;
else LinkLabelAlignment::MIDDLE;
}
endif;
}
}
genLink.labels += result;
result.visualID := result.visualID()
}
-- XXX ElementType as return value, disjunct?
mapping GENMODEL::GenClass::gmfRuntimeMetamodelType() : GMFGEN::MetamodelType {}
--
-- Helpers
--
query GENMODEL::GenClass::getOrCreateRuntimeMetamodelType() : GMFGEN::ElementType {
var mmt = self.resolveoneIn(GENMODEL::GenClass::gmfRuntimeMetamodelType, GMFGEN::MetamodelType);
if mmt.oclIsUndefined() then
return self.map gmfRuntimeMetamodelType()
endif;
return object GMFGEN::SpecializationType { metamodelType := mmt }
}
-- XXX review - Specialization type is created again and again - why not reuse it?
-- static, for some reasons, helpers couldn't specify 'inout' for context element
-- XXX, actually, don't need GenNode here, GenClass should be sufficient
helper setupElementType(inout genNode : GMFGEN::GenNode) {
if genNode.modelFacet.oclIsUndefined() then genNode.elementType := object GMFGEN::NotationType {}
else genNode.elementType := genNode.modelFacet.metaClass.getOrCreateRuntimeMetamodelType() endif;
return;
}
helper setupElementType(inout genLink : GMFGEN::GenLink) {
if genLink.modelFacet.oclIsUndefined() then
genLink.elementType := object GMFGEN::NotationType {}
else
if genLink.modelFacet.oclIsKindOf(GMFGEN::TypeModelFacet) then
genLink.elementType := genLink.modelFacet.oclAsType(GMFGEN::TypeModelFacet).metaClass.getOrCreateRuntimeMetamodelType()
else { -- ref-based link; specialize null
genLink.elementType := object GMFGEN::SpecializationType {};
-- genLink.elementType.displayName := genLink.modelFacet.oclAsType(FeatureLinkModelFacet).metaFeature.ecoreFeature.name.firstToUpper();
} endif
endif;
return;
}
helper GMFMAP::CanvasMapping::viewmap(): Viewmap =
if useModeledViewmaps then
object ModeledViewmap {
figureModel := self.diagramCanvas.oclAsType(EObject);
}
else
self.diagramCanvas.map Viewmaps::viewmap()
endif;
helper GMFMAP::TopNodeReference::viewmap(): Viewmap =
if useModeledViewmaps then
self.child.diagramNode.ModeledViewmaps::viewmap()
else
self.child.diagramNode.Viewmaps::viewmap()
endif;
helper GMFMAP::ChildReference::viewmap(_mapping: NodeMapping): Viewmap =
if useModeledViewmaps then
self.child.diagramNode.ModeledViewmaps::viewmap()
else
self.Viewmaps::viewmap(_mapping)
endif;
helper GMFMAP::LinkMapping::viewmap(): Viewmap =
if useModeledViewmaps then
self.diagramLink.ModeledViewmaps::viewmap()
else
self.diagramLink.Viewmaps::viewmap()
endif;
helper GMFMAP::LabelMapping::viewmap(): Viewmap =
if useModeledViewmaps then
self.diagramLabel.ModeledViewmaps::viewmap()
else
self.diagramLabel.Viewmaps::viewmap()
endif;
helper GMFMAP::CompartmentMapping::viewmap(): Viewmap =
if useModeledViewmaps then
self.compartment.ModeledViewmaps::viewmap()
else
self.compartment.Viewmaps::viewmap()
endif;
--
-- Queries
--
query GMFMAP::Mapping::expressionsByLanguages(): Sequence(ValueExpression) =
GMFMAP::ValueExpression.allInstances()->iterate(it; res: Sequence(ValueExpression) = Sequence{} |
if res->exists(e | e.language = it.language) then res else res->including(it) endif
);
query GMFGRAPH::Node::getAffixedSideAsPositionConstantsName() : String =
switch {
case (self.affixedParentSide = GMFGRAPH::Direction::NONE) assert (false) with log('DiagramNode is not side-affixed', self);
case (self.affixedParentSide = GMFGRAPH::Direction::EAST) return 'EAST';
case (self.affixedParentSide = GMFGRAPH::Direction::WEST) return 'WEST';
case (self.affixedParentSide = GMFGRAPH::Direction::NORTH) return 'NORTH';
case (self.affixedParentSide = GMFGRAPH::Direction::SOUTH) return 'SOUTH';
case (self.affixedParentSide = GMFGRAPH::Direction::NSEW) return 'NONE'; -- any side
else return 'NONE'; -- any side
};
query DiagramElement::findAlignmentFacet(): AlignmentFacet =
self.facets->selectOne(e | e.oclIsKindOf(AlignmentFacet)).oclAsType(AlignmentFacet);