| author | ghillairet | 2012-01-06 10:44:00 (EST) |
|---|---|---|
| committer | mgolubev | 2012-01-06 10:44:00 (EST) |
| commit | 313db87de8afb59eef7b3d751638cb305b0d4f89 (patch) (side-by-side diff) | |
| tree | 99fd18f21b70ed4e676ef66655be53d69a7dbdbe | |
| parent | 2b248320688ef3fd8aa1a0ba7a4328bc95665100 (diff) | |
| download | org.eclipse.gmf-tooling-313db87de8afb59eef7b3d751638cb305b0d4f89.zip org.eclipse.gmf-tooling-313db87de8afb59eef7b3d751638cb305b0d4f89.tar.gz org.eclipse.gmf-tooling-313db87de8afb59eef7b3d751638cb305b0d4f89.tar.bz2 | |
updated qvto bridge - rewrite generation of
visualIDs - support for recursive node mapping - fix
GenCompartment mapping - extend audit mapping - fix
expression provider mapping - fix LabelMapping - fix
LabelModelFacet - fix Viewmap attributes - add support
for ModeledViewmap add qvto library Map2GenUtil containing
queries for main transformation
3 files changed, 732 insertions, 351 deletions
diff --git a/plugins/org.eclipse.gmf.bridge/transforms/Identity.qvto b/plugins/org.eclipse.gmf.bridge/transforms/Identity.qvto index b3eff21..6d8acef 100644 --- a/plugins/org.eclipse.gmf.bridge/transforms/Identity.qvto +++ b/plugins/org.eclipse.gmf.bridge/transforms/Identity.qvto @@ -16,41 +16,40 @@ modeltype ECORE uses ecore('http://www.eclipse.org/emf/2002/Ecore'); transformation Identity(in mapModel : GMFMAP, inout gmfgenModel : GMFGEN); -main() { - var mapRoot := mapModel.rootObjects()![GMFMAP::Mapping]; - var editorGen := gmfgenModel.rootObjects()![GMFGEN::GenEditorGenerator]; - visualIdentity(mapRoot, editorGen.diagram); -} +main() {} -- ************************************************************************************* -- Visual ID -- ************************************************************************************* -helper visualIdentity(in mapRoot : GMFMAP::Mapping, inout genDiagram : GMFGEN::GenDiagram) { - genDiagram.visualID := 1000; - --5.range(1, genDiagram.topLevelNodes->size())->forEach(i) { - Sequence { 1..genDiagram.topLevelNodes->size() }->forEach(i) { - var n : GenTopLevelNode := genDiagram.topLevelNodes->at(i); - n.visualID := 2000 + i; - }; - Sequence { 1..genDiagram.childNodes->size() }->forEach(i) { - var n : GenChildNode := genDiagram.childNodes->at(i); - n.visualID := 3000 + i; - }; - Sequence { 1..genDiagram.links->size() }->forEach(i) { - var l : GenLink := genDiagram.links->at(i); - l.visualID := 4000 + i; - }; - Sequence { 1..genDiagram.compartments->size() }->forEach(i) { - var c : GenCompartment := genDiagram.compartments->at(i); - c.visualID := 7000 + i; - }; - Sequence { 1..genDiagram.getAllNodes().labels->size() }->forEach(i) { - var l : GenLabel := genDiagram.getAllNodes().labels->at(i); - l.visualID := 5000 + i; - }; - Sequence { 1..genDiagram.links.labels->size() }->forEach(i) { - var l : GenLabel := genDiagram.links.labels->at(i); - l.visualID := 6000 + i; - }; +property topNodeID: Integer = 2000; +property childNodeID: Integer = 3000; +property linkNodeID: Integer = 4000; +property nodeLabelID: Integer = 5000; +property linkLabelID: Integer = 6000; +property compartmentID: Integer = 7000; + +helper topNodeID(): Integer { + topNodeID := this.topNodeID + 1; + return this.topNodeID; +} +helper childNodeID(): Integer { + childNodeID := childNodeID + 1; + return childNodeID; +} +helper nodeLabelID(): Integer { + nodeLabelID := nodeLabelID + 1; + return nodeLabelID; +} +helper linkNodeID(): Integer { + linkNodeID := linkNodeID + 1; + return linkNodeID; +} +helper compartmentID(): Integer { + compartmentID := compartmentID + 1; + return compartmentID; +} +helper linkLabelID(): Integer { + linkLabelID := linkLabelID + 1; + return linkLabelID; } diff --git a/plugins/org.eclipse.gmf.bridge/transforms/Map2Gen.qvto b/plugins/org.eclipse.gmf.bridge/transforms/Map2Gen.qvto index 9a61b37..5734c26 100644 --- a/plugins/org.eclipse.gmf.bridge/transforms/Map2Gen.qvto +++ b/plugins/org.eclipse.gmf.bridge/transforms/Map2Gen.qvto @@ -9,14 +9,8 @@ * Contributors: * Artem Tikhomirov (Borland) - initial API and implementation */ -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'); - -- import transformations. To be replaced with access keyword, once supported +import Map2GenUtil; import DiagramRunTimeModel; import PropertySheet; import PreferencePages; @@ -27,114 +21,106 @@ import RichClientPlatformApp; import Identity; -- import gmf.GenModelAccess; - import xpt.XpandFacade; +-- import gmf.IdentifierLibrary; + +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'); -- -- Next attempt to author GMFMap-to-GMFGen transformation -- transformation Map2Gen(in mapModel : GMFMAP, in domainGenModel : GENMODEL, in diagramRuntimeGenModel : GENMODEL, out gmfgenModel : GMFGEN) --- access transformation Structure(in GMFMAP, inout GMFGEN) --- access transformation DiagramRunTimeModel(in GMFMAP, inout GMFGEN) - ; +access Map2GenUtil; ---configuration property options : Dict(String, OclAny); configuration property rcp : Boolean; configuration property useMapMode : Boolean; configuration property useFullRunTime : Boolean; +configuration property useInTransformationCodeGen : Boolean; -property domainGenModel : GENMODEL::GenModel = null; +property mapRoot : GMFMAP::Mapping = mapModel.rootObjects()![GMFMAP::Mapping]; + +main() { + genModel := domainGenModel.rootObjects()![GENMODEL::GenModel]; + childReferences := mapRoot.getChildReferences(); -main() { - var mapRoot := mapModel.rootObjects()![GMFMAP::Mapping]; - this.domainGenModel := domainGenModel.rootObjects()![GENMODEL::GenModel]; - -- var genEditor := mapRoot.map structure(); - genEditor.diagram.compartments += genEditor.diagram.getAllNodes().compartments; -- DGMT#createGenCompartment + new Identity(mapModel, gmfgenModel).transform(); - --new Viewmaps(mapModel, gmfgenModel).transform(); - -- ???genEditor.diagram.palette := mapRoot.diagram.map palette(); + genEditor.diagram.palette := mapRoot.diagram.map palette(); genEditor.domainGenModel := mapRoot.diagram.domainModel.findGenPackage().genModel; - genEditor.plugin := object GenPlugin {}; + + genEditor.plugin := mapRoot.map editorPlugin(); genEditor.editor := object GenEditorView {}; + genEditor.diagramUpdater := object GenDiagramUpdater {}; genEditor.audits := mapRoot.audits.map audits(); -- these two should go before expression providers collection genEditor.metrics := mapRoot.metrics.map metrics(); + -- FIXME allInstances HACK if not GMFGEN::GenParserImplementation.allInstances()->isEmpty() then { - genEditor.labelParsers := object GenParsers { - implementations += GMFGEN::GenParserImplementation.allInstances(); - if this.designLabelParser <> null then implementations += this.designLabelParser endif; - if this.auxParser <> null then implementations += this.auxParser endif; - extensibleViaService := false; - }; - } endif; - if not GMFGEN::GenExpressionProviderBase.allInstances()->isEmpty() then { - genEditor.expressionProviders := object GMFGEN::GenExpressionProviderContainer { - providers += GMFGEN::GenExpressionProviderBase.allInstances(); - } + genEditor.labelParsers := mapRoot.map createGenParsers() } endif; + -- var xx : GENMODEL := GENMODEL::createEmptyModel().oclAsType(GENMODEL); -- var notationGenModel@xx : GENMODEL::GenModel := loadNotationGenModel(genEditor.oclAsType(ECORE::EObject)); new DiagramRunTimeModel(diagramRuntimeGenModel, gmfgenModel).transform(); + if not rcp then new Navigator(mapModel, gmfgenModel).transform() endif; + new PropertySheet(mapModel, gmfgenModel).transform(); new PreferencePages(mapModel, gmfgenModel).transform(); new Actions(mapModel, gmfgenModel).transform(); + if rcp then new RichClientPlatformApp(mapModel, gmfgenModel).transform() endif; } +-- ************************************************************************************* +-- Editor & Diagram +-- ************************************************************************************* + mapping GMFMAP::Mapping::structure() : GMFGEN::GenEditorGenerator@gmfgenModel { --- new Structure(self, result)->transform(); diagram := self.diagram.map structure(); - diagram.topLevelNodes += self.nodes.structure(); - -- FIXME allInstances is a HACK - diagram.childNodes += GMFMAP::ChildReference.allInstances().child.resolve(GMFGEN::GenChildNode); + + diagram.topLevelNodes += self.nodes->map structure()->asOrderedSet(); + childReferences->forEach(c) { diagram.childNodes += c.map structure(c.child); }; + diagram.links := self.links->map structure()->asOrderedSet(); - -- model facets - -- - -- element types - -- For now, for legacy reasons, setupElementType is invoked at the same places where DGMT used to invoke it - -- However, for real M2M, I'd prefer to have a single place for all elementTypes setting. FIXME:refactor later - --diagram.getAllNodes()->forEach(n) { setupElementType(n) }; - --diagram.links->forEach(l) { setupElementType(l) }; - -- <end of element types> - diagram.viewmap := self.diagram.diagramCanvas.map viewmap(); -} - --- 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; -} -query GENMODEL::GenClass::getOrCreateRuntimeMetamodelType() : GMFGEN::ElementType { - var mmt = self.resolveoneIn(GENMODEL::GenClass::gmfRuntimeMetamodelType, GMFGEN::MetamodelType); - if mmt.oclIsUndefined() then - return self.map gmfRuntimeMetamodelType() + self.getCompartments()->forEach(e) { diagram.compartments += e.c.map structure(e.n, e.r); }; + + diagram.getAllNodes()->forEach(n) { setupElementType(n) }; + diagram.links->forEach(l) { setupElementType(l) }; + + diagram.viewmap := self.diagram.diagramCanvas.map viewmap(); + + if self.expressionsByLanguages()->notEmpty() then + expressionProviders := self.map createProviderContainer() endif; - return object GMFGEN::SpecializationType { metamodelType := mmt } + + self.visualIdentity(); } --- XXX ElementType as return value, disjunct? -mapping GENMODEL::GenClass::gmfRuntimeMetamodelType() : GMFGEN::MetamodelType { + +query GMFMAP::Mapping::expressionsByLanguages(): Sequence(ValueExpression) { + return GMFMAP::ValueExpression.allInstances()->iterate(it; res: Sequence(ValueExpression) = Sequence{} | + if res->exists(e | e.language = it.language) then res else res->including(it) endif + ) +} +mapping GMFMAP::Mapping::createProviderContainer(): GMFGEN::GenExpressionProviderContainer { + self.expressionsByLanguages()->forEach(e) { + providers += e.map createExpressionProvider() + } } mapping GMFMAP::CanvasMapping::structure() : GMFGEN::GenDiagram { - result.domainDiagramElement := self.domainMetaElement.findGenClass(); + domainDiagramElement := self.domainMetaElement.findGenClass(); + iconProviderPriority := GMFGEN::ProviderPriority::Low; + validationProviderPriority := GMFGEN::ProviderPriority::Low; + if result.domainDiagramElement.oclIsUndefined() then result.elementType := object GMFGEN::NotationType {} else @@ -142,138 +128,214 @@ mapping GMFMAP::CanvasMapping::structure() : GMFGEN::GenDiagram { endif; } -helper GMFMAP::TopNodeReference::structure() : GMFGEN::GenTopLevelNode { - var rv = object GMFGEN::GenTopLevelNode {}; - rv.modelFacet := self.createModelFacet(); - setupElementType(rv); - self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += rv; - self.child.processAbstractNode(rv); - rv.viewmap := self.child.diagramNode.viewmap(); - return rv; +-- ************************************************************************************* +-- TopLevelNode +-- ************************************************************************************* + +mapping GMFMAP::TopNodeReference::structure() : GMFGEN::GenTopLevelNode { + modelFacet := self.createModelFacet(); + self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result; + + self.child.children->select(e | e.compartment.oclIsUndefined())->forEach(c) { + var node := c.findProcessableChildReference(); + childNodes := node.map structure(node.child); + }; + + labels += self.child.labelMappings->map createNodeLabel(self); + + viewmap := self.child.diagramNode.viewmap(); + behaviour += self.child.relatedDiagrams.handleRelatedDiagram(self.child); +} + +-- ************************************************************************************* +-- GenChildNode +-- ************************************************************************************* + +mapping GMFMAP::ChildReference::structure(node: GMFMAP::NodeMapping) : GMFGEN::GenChildNode + disjuncts + GMFMAP::ChildReference::createGenChildLabelNode, + GMFMAP::ChildReference::createGenChildSideAffixedNode, + GMFMAP::ChildReference::createGenChildNode +{} + +mapping GMFMAP::ChildReference::createGenChildLabelNode(node: GMFMAP::NodeMapping) : GMFGEN::GenChildLabelNode + when { node.isPureLabelNode() } { + + var soleLabel := node.labelMappings->first(); + labelModelFacet := soleLabel.map createLabelModelFacet(self); + labelReadOnly := soleLabel.readOnly; + labelElementIcon := soleLabel.diagramLabel.elementIcon; + viewmap := soleLabel.diagramLabel.viewmap(); + + self.child.children[ChildReference]->select(e | e.compartment.oclIsUndefined())->forEach(c) { + var node := c.findProcessableChildReference(); + childNodes := node.map structure(node.child); + }; + + modelFacet := self.createModelFacet(); + + self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result; +} +mapping GMFMAP::ChildReference::createGenChildSideAffixedNode(node: GMFMAP::NodeMapping) : GMFGEN::GenChildSideAffixedNode + when { node.diagramNode.affixedParentSide <> GMFGRAPH::Direction::NONE} { + + viewmap := node.diagramNode.viewmap(); + preferredSideName := node.diagramNode.getAffixedSideAsPositionConstantsName(); + + labels += node.labelMappings->map createNodeLabel(self); + + self.child.children[ChildReference]->select(e | e.compartment.oclIsUndefined())->forEach(c) { + var node := c.findProcessableChildReference(); + childNodes += node->map structure(node.child); + }; + + behaviour += node.relatedDiagrams.handleRelatedDiagram(node); + modelFacet := self.createModelFacet(); + self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result; +} +mapping GMFMAP::ChildReference::createGenChildNode(node: GMFMAP::NodeMapping) : GMFGEN::GenChildNode { + viewmap := node.diagramNode.viewmap(); + + labels += node.labelMappings->map createNodeLabel(self); + + self.child.children[ChildReference]->select(e | e.compartment.oclIsUndefined())->forEach(c) { + var node := c.findProcessableChildReference(); + childNodes += node->map structure(node.child); + }; + + behaviour += node.relatedDiagrams.handleRelatedDiagram(node); + modelFacet := self.createModelFacet(); + + self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result; +} + +-- ************************************************************************************* +-- Compartment +-- ************************************************************************************* + +mapping GMFMAP::CompartmentMapping::structure(_mapping: GMFMAP::NodeMapping, container: GMFMAP::NodeReference): GMFGEN::GenCompartment { + init { + result := object GMFGEN::GenCompartment { + canCollapse := self.compartment.collapsible; + needsTitle := self.compartment.needsTitle; + title := self.compartment.name; + viewmap := self.compartment.viewmap(); + }; + } + + if container.oclIsKindOf(GMFMAP::TopNodeReference) then + container.resolveone(GMFGEN::GenNode).compartments += result + else { + var node := container.oclAsType(ChildReference).findProcessableChildReference(); + if not node.oclIsUndefined() then + node.map structure(node.child).compartments += result + endif + } endif; + + allChildReferences->select(e | e.compartment = self)->forEach(c) { + if c.child.children->size() > 0 then + listLayout := false + endif; + var node := if equivalentChild->hasKey(c) then c else + equivalentChild->keys()->selectOne(e | equivalentChild->get(e) = c) endif; + childNodes += node.map structure(node.child); + } } helper GMFMAP::NodeReference::createModelFacet() : GMFGEN::TypeModelFacet { if self.child.domainMetaElement.oclIsUndefined() then return null endif; var mf := object TypeModelFacet {}; + mf.metaClass := self.child.domainMetaElement.findGenClass(); mf.containmentMetaFeature := self.containmentFeature.findGenFeature(); - if self.childrenFeature.oclIsUndefined() then mf.childMetaFeature := mf.containmentMetaFeature else mf.childMetaFeature := self.childrenFeature.findGenFeature() endif; - mf.modelElementSelector := self.child.domainSpecialization.map structure(); + + if self.childrenFeature.oclIsUndefined() then + mf.childMetaFeature := mf.containmentMetaFeature + else + mf.childMetaFeature := self.childrenFeature.findGenFeature() + endif; + + mf.modelElementSelector := self.child.domainSpecialization.map createConstraint(); mf.modelElementInitializer := self.child.domainInitializer.map structure(); return mf; } +-- ************************************************************************************* +-- Link +-- ************************************************************************************* + +mapping GMFMAP::LinkMapping::createModeFacet(): GMFGEN::LinkModelFacet + disjuncts + GMFMAP::LinkMapping::createFeatureLinkModelFacet, + GMFMAP::LinkMapping::createTypeLinkModelFacet + {} + +mapping GMFMAP::LinkMapping::createFeatureLinkModelFacet() : GMFGEN::FeatureLinkModelFacet when { + self.domainMetaElement.oclIsUndefined() and not self.linkMetaFeature.oclIsUndefined()} { + + metaFeature := self.linkMetaFeature.findGenFeature(); +} +mapping GMFMAP::LinkMapping::createTypeLinkModelFacet() : GMFGEN::TypeLinkModelFacet when { + not self.domainMetaElement.oclIsUndefined()} { + + metaClass := self.domainMetaElement.findGenClass(); + containmentMetaFeature := self.containmentFeature.findGenFeature(); + childMetaFeature := containmentMetaFeature; + sourceMetaFeature := self.sourceMetaFeature.findGenFeature(); + targetMetaFeature := self.linkMetaFeature.findGenFeature(); + modelElementSelector := self.domainSpecialization.map createConstraint(); -- ALTERNATIVE: if not self.domainSpecialization.oclIsUndefined() then modelElementSelector := self.domainSpecialization.map structure() endif; + modelElementInitializer := self.domainInitializer.map structure(); +} + mapping GMFMAP::LinkMapping::structure() : GMFGEN::GenLink { + assert(not self.diagramLink.oclIsUndefined()) with log("link diagram link cannot be null"); + if not self.domainMetaElement.oclIsUndefined() then + assert(not self.linkMetaFeature.oclIsUndefined()) with log("linkMetaFeature cannot be null") + endif; + -- model facet - if self.domainMetaElement.oclIsUndefined() then { - if self.linkMetaFeature.oclIsUndefined() then result.modelFacet := null else { - result.modelFacet := object FeatureLinkModelFacet { - metaFeature := self.linkMetaFeature.findGenFeature(); - }; - } endif - } else { - result.modelFacet := object TypeLinkModelFacet { - metaClass := self.domainMetaElement.findGenClass(); - containmentMetaFeature := self.containmentFeature.findGenFeature(); - childMetaFeature := containmentMetaFeature; - sourceMetaFeature := self.sourceMetaFeature.findGenFeature(); - targetMetaFeature := self.linkMetaFeature.findGenFeature(); - modelElementSelector := self.domainSpecialization.map structure(); -- ALTERNATIVE: if not self.domainSpecialization.oclIsUndefined() then modelElementSelector := self.domainSpecialization.map structure() endif; - modelElementInitializer := self.domainInitializer.map structure(); - } - } endif; + if not (self.domainMetaElement.oclIsUndefined() and self.linkMetaFeature.oclIsUndefined()) then + modelFacet := self.map createModeFacet() + endif; + -- labels - self.labelMappings->forEach(lm) { - var gl := object GMFGEN::GenLinkLabel {}; - result.labels += gl; - gl.readOnly := lm.readOnly; - gl.elementIcon := lm.diagramLabel.elementIcon; - gl.modelFacet := lm.map createLabelModelFacet(); - gl.viewmap := lm.diagramLabel.viewmap(); - }; + labels += self.labelMappings->map structure(self); + self.tool.map paletteEntry().oclAsType(ToolEntry).genLinks += result; - setupElementType(result); + -- setupElementType(result); result.viewmap := self.diagramLink.viewmap(); result.creationConstraints := self.creationConstraints.map structure(); } -query EClass::findGenClass() : GENMODEL::GenClass { - return self.ePackage.findGenPackage().genClassifiers[GenClass]->select(gc | gc.ecoreClass.name = self.name)->first(); -} -query EPackage::findGenPackage() : GENMODEL::GenPackage { - -- XXX GenModel.findGenPackage does more than this (staticGenPackage and nestedGenPackages). FIXME - -- ->union(genModel.staticGenPackages) - return this.domainGenModel.genPackages->union(this.domainGenModel.usedGenPackages)->select(gp | gp.ecorePackage.nsURI = self.nsURI)->asSequence()->first(); -} -query EStructuralFeature::findGenFeature() : GENMODEL::GenFeature { - return self.eContainingClass.findGenClass().genFeatures->select(f | f.ecoreFeature = self)->first(); -} -helper GMFMAP::NodeMapping::processAbstractNode(inout genNode : GMFGEN::GenNode) { - genNode.compartments += self.compartments.map structure(); - self.children->forEach(ch) { - var genChildContainer : GMFGEN::GenChildContainer = genNode; - if not ch.compartment.oclIsUndefined() then genChildContainer := ch.compartment.resolveone(GMFGEN::GenCompartment) endif; - var childGenNode : GMFGEN::GenChildNode; - if ch.child.resolve(GMFGEN::GenChildNode)->isEmpty() then childGenNode := ch.createGenChildNode() else { - childGenNode := ch.child.resolve(GMFGEN::GenChildNode)->selectOne(matchChildReferenceFeatures(ch)); - if childGenNode.oclIsUndefined() then childGenNode := ch.createGenChildNode() endif; - } endif; - if (genChildContainer.oclIsKindOf(GMFGEN::GenCompartment) and ch.child.children->size() > 0) then { - genChildContainer.oclAsType(GMFGEN::GenCompartment).listLayout := false +mapping LabelMapping::structure(link: GMFMAP::LinkMapping): GenLinkLabel { + readOnly := self.readOnly; + elementIcon := self.diagramLabel.elementIcon; + modelFacet := self.map createLabelModelFacet(link); + 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; + viewmap := self.diagramLabel.viewmap(); + viewmap.attributes += object LabelOffsetAttributes { + var offsetFacet := self.diagramLabel.findOffsetFacet(); + if not offsetFacet.oclIsUndefined() then { + x := offsetFacet.x; + y := offsetFacet.y; + } else { + y := (link.labelMappings->indexOf(self) + 1) * 20; } endif; - genChildContainer.childNodes += childGenNode; - }; - genNode.labels += self.labelMappings.map createNodeLabel(genNode); - genNode.behaviour += self.relatedDiagrams.handleRelatedDiagram(self); - return null; + } } -query GMFGEN::GenChildNode::matchChildReferenceFeatures(childNodeRef : GMFMAP::ChildReference) : Boolean { - var containmentFeatureMatch : Boolean; - var childrenFeatureMatch : Boolean; - if self.modelFacet.containmentMetaFeature.oclIsUndefined() then - containmentFeatureMatch := childNodeRef.containmentFeature = null - else - containmentFeatureMatch := childNodeRef.containmentFeature = self.modelFacet.containmentMetaFeature.ecoreFeature - endif; - if self.modelFacet.childMetaFeature.oclIsUndefined() then - childrenFeatureMatch := childNodeRef.childrenFeature = null - else - if childNodeRef.childrenFeature = null then - childrenFeatureMatch := self.modelFacet.childMetaFeature = self.modelFacet.containmentMetaFeature - else - childrenFeatureMatch := self.modelFacet.childMetaFeature.ecoreFeature = childNodeRef.childrenFeature - endif - endif; - return containmentFeatureMatch and childrenFeatureMatch; -} -mapping GMFMAP::NodeMapping::structure() : GMFGEN::GenChildNode - disjuncts GMFMAP::NodeMapping::createGenChildLabelNode, GMFMAP::NodeMapping::createGenChildSideAffixedNode, GMFMAP::NodeMapping::createGenChildNode -{} - -mapping GMFMAP::NodeMapping::createGenChildLabelNode() : GMFGEN::GenChildLabelNode when { self.isPureLabelNode() } { - var soleLabel := self.labelMappings->first(); - labelModelFacet := soleLabel.map createLabelModelFacet(); - labelReadOnly := soleLabel.readOnly; - labelElementIcon := soleLabel.diagramLabel.elementIcon; - viewmap := soleLabel.diagramLabel.viewmap(); - -- needCompartmentChildrenLabelProcessing = false, no need to processAbstractNode -} -mapping GMFMAP::NodeMapping::createGenChildSideAffixedNode() : GMFGEN::GenChildSideAffixedNode when { self.diagramNode.affixedParentSide <> GMFGRAPH::Direction::NONE} { - viewmap := self.diagramNode.viewmap(); - preferredSideName := self.diagramNode.getAffixedSideAsPositionConstantsName(); - self.processAbstractNode(result); -} -mapping GMFMAP::NodeMapping::createGenChildNode() : GMFGEN::GenChildNode { - viewmap := self.diagramNode.viewmap(); - self.processAbstractNode(result); -- needCompartmentChildrenLabelProcessing = true -} -helper GMFMAP::ChildReference::createGenChildNode() : GMFGEN::GenChildNode { - -- XXX perhaps, no need to keep this helper, move the code into corresponding mapping operations? - var rv : GMFGEN::GenChildNode = self.child.map structure(); - self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += rv; - rv.modelFacet := self.createModelFacet(); - setupElementType(rv); - return rv; +query DiagramElement::findOffsetFacet(): LabelOffsetFacet { + return self.facets->selectOne(e | e.oclIsKindOf(LabelOffsetFacet)).oclAsType(LabelOffsetFacet) +} +query DiagramElement::findAlignmentFacet(): AlignmentFacet { + return self.facets->selectOne(e | e.oclIsKindOf(AlignmentFacet)).oclAsType(AlignmentFacet) } query GMFMAP::NodeMapping::isPureLabelNode() : Boolean { return self.labelMappings->size() = 1 and self.children->isEmpty() and self.labelMappings->first().diagramLabel = self.diagramNode; @@ -301,15 +363,11 @@ helper GMFMAP::CanvasMapping::handleRelatedDiagram(in mapElement : GMFMAP::Mappi return rv; } -mapping GMFMAP::CompartmentMapping::structure() : GMFGEN::GenCompartment { - -- visualID, viewmap and diagramRTclass should get assigned universally - result.canCollapse := self.compartment.collapsible; - result.needsTitle := self.compartment.needsTitle; - result.title := self.compartment.name; - result.viewmap := self.compartment.viewmap(); -} +-- ************************************************************************************* +-- NodeLabel +-- ************************************************************************************* -mapping GMFMAP::LabelMapping::createNodeLabel(in genNode : GMFGEN::GenNode) : GMFGEN::GenNodeLabel { +mapping GMFMAP::LabelMapping::createNodeLabel(node: NodeReference) : GMFGEN::GenNodeLabel { init { if self.diagramLabel.external then result := object GenExternalNodeLabel {} @@ -317,8 +375,8 @@ mapping GMFMAP::LabelMapping::createNodeLabel(in genNode : GMFGEN::GenNode) : GM result := object GenNodeLabel {} endif } - -- visualID, diagramRTclass and viewmap should get assigned universally - result.modelFacet := self.map createLabelModelFacet(); + + result.modelFacet := self.map createLabelModelFacet(node); result.readOnly := self.readOnly; result.elementIcon := self.diagramLabel.elementIcon; result.viewmap := self.diagramLabel.viewmap(); @@ -328,30 +386,110 @@ mapping GMFMAP::LabelMapping::createNodeLabel(in genNode : GMFGEN::GenNode) : GM -- neccessary, the problem is finding a proper WTF (labelMapping knows it's MappingEntry, but latter doesn't keep track of CanvasMapping or similar) property designLabelParser : GMFGEN::ExternalParser = null; property auxParser : GMFGEN::ExternalParser = null; - + -- DGMT#createLabelModelFacet -mapping GMFMAP::LabelMapping::createLabelModelFacet() : GMFGEN::LabelModelFacet { - if this.auxParser = null then this.auxParser := object GMFGEN::ExternalParser {} endif; +mapping GMFMAP::LabelMapping::createLabelModelFacet(node: NeedsContainment) : GMFGEN::LabelModelFacet + disjuncts + GMFMAP::LabelMapping::createDefaultLabelModelFacet, + GMFMAP::FeatureLabelMapping::createFeatureLabelModelFacet, + GMFMAP::DesignLabelMapping::createDesignLabelModelFacet, + GMFMAP::ExpressionLabelMapping::createExpressionLabelModelFacet + {} +mapping GMFMAP::LabelMapping::createDefaultLabelModelFacet(node: NeedsContainment) : GMFGEN::LabelModelFacet + when {self.oclIsTypeOf(LabelMapping)} { + init { + if this.auxParser = null then + this.auxParser := object GMFGEN::ExternalParser {} + endif; + } parser := this.auxParser; } --- FIXME use disjuncts instead -mapping GMFMAP::FeatureLabelMapping::createLabelModelFacet() : GMFGEN::LabelModelFacet { - init { - var r := object GMFGEN::FeatureLabelModelFacet {}; - r.metaFeatures += self.features.findGenFeature(); - r.editableMetaFeatures += self.editableFeatures.findGenFeature(); - r.viewPattern := self.viewPattern; - r.editPattern := self.editPattern; - r.editorPattern := self.editorPattern; - r.viewMethod := self.viewMethod.convertLabelTextAccessMethod(); - r.editMethod := self.editMethod.convertLabelTextAccessMethod(); +mapping GMFMAP::FeatureLabelMapping::createFeatureLabelModelFacet(node: NeedsContainment) : GMFGEN::FeatureLabelModelFacet { +-- init { +-- result := object FeatureLabelModelFacet { + metaFeatures += self.features.findGenFeature(); + editableMetaFeatures += self.editableFeatures.findGenFeature(); + viewPattern := self.viewPattern; + editPattern := self.editPattern; + editorPattern := self.editorPattern; + viewMethod := self.viewMethod.convertLabelTextAccessMethod(); + editMethod := self.editMethod.convertLabelTextAccessMethod(); +-- } +-- } +-- var r := object GMFGEN::FeatureLabelModelFacet {}; -- if exists then select else -- FIXME allInstances == hack - var p = GMFGEN::PredefinedParser.allInstances()->any(pp | pp.viewMethod = r.viewMethod and pp.editMethod = r.editMethod); - if p.oclIsUndefined() then p := object PredefinedParser {viewMethod := r.viewMethod; editMethod := r.editMethod; } endif; - r.parser := p; - result := r; + var p = GMFGEN::PredefinedParser.allInstances()->any(pp | + pp.viewMethod = result.oclAsType(FeatureLabelModelFacet).viewMethod and + pp.editMethod = result.oclAsType(FeatureLabelModelFacet).editMethod); + + if p.oclIsUndefined() then p := object PredefinedParser { + viewMethod := result.oclAsType(FeatureLabelModelFacet).viewMethod; + editMethod := result.oclAsType(FeatureLabelModelFacet).editMethod; + } endif; + parser := p; +-- return r; +} +mapping GMFMAP::DesignLabelMapping::createDesignLabelModelFacet(node: NeedsContainment) : GMFGEN::DesignLabelModelFacet { +-- init { +-- result := object DesignLabelModelFacet {} +-- } + if this.designLabelParser = null then + this.designLabelParser := object GMFGEN::ExternalParser {} + endif; + parser := this.designLabelParser; + +} +mapping GMFMAP::ExpressionLabelMapping::createExpressionLabelModelFacet(node: NeedsContainment): GMFGEN::ExpressionLabelModelFacet { +-- init { +-- result := object ExpressionLabelModelFacet { + parser := object ExpressionLabelParser { + expressionContext := GENMODEL::GenClass.allInstances()->any(e | e.ecoreClass = self.mapEntry.getDomainContext()); + viewExpression := if not self.viewExpression.oclIsUndefined() then self.viewExpression.map createValueExpression() endif; + editExpression := if not self.editExpression.oclIsUndefined() then self.editExpression.map createValueExpression() endif; + validateExpression := if not self.validateExpression.oclIsUndefined() then self.validateExpression.map createConstraint() endif; + }; + + log('create expression parser', parser) when true; +-- } +-- } +} +mapping GMFMAP::ValueExpression::createValueExpression(): GMFGEN::ValueExpression + disjuncts GMFMAP::ValueExpression::createGenValueExpression, GMFMAP::Constraint::createConstraint +{} +mapping GMFMAP::ValueExpression::createGenValueExpression(): GMFGEN::ValueExpression + when {self.oclIsTypeOf(ValueExpression)}{ + body := self.body; +} +mapping GMFMAP::Constraint::createConstraint(): GMFGEN::GenConstraint { + body := self.body; +} +mapping GMFMAP::ValueExpression::createExpressionProvider(): GenExpressionProviderBase { + init { + switch { + case (self.language = Language::java) { result := object GenJavaExpressionProvider {} }; + case (self.language = Language::ocl) { result := object GenExpressionInterpreter { language := self.language() } }; + case (self.language = Language::regexp) { result := object GenExpressionInterpreter { language := self.language() } }; + case (self.language = Language::nregexp) { result := object GenExpressionInterpreter { language := self.language() } }; + case (self.language = GenLanguage::_literal) { result := object GenLiteralExpressionProvider {} }; + else { result := object GenExpressionInterpreter {}; } + }; } + + expressions += ValueExpression.allInstances()->select(e | e.language = self.language)->map createValueExpression(); +} +helper GMFMAP::ValueExpression::language(): GenLanguage { + return switch { + case (self.language = Language::java) GenLanguage::java; + case (self.language = Language::ocl) GenLanguage::ocl; + case (self.language = Language::regexp) GenLanguage::regexp; + case (self.language = Language::nregexp) GenLanguage::nregexp; + case (self.language = Language::_literal) return GenLanguage::_literal; + else GenLanguage::ocl; + } +} +query GMFMAP::ValueExpression::selectProvider(): GenExpressionProviderBase { + return this.mapRoot->resolveone(GMFGEN::GenExpressionProviderContainer).providers->any(e | e.getLanguage() = self.language) } query GMFMAP::LabelTextAccessMethod::convertLabelTextAccessMethod() : GMFGEN::LabelTextAccessMethod { switch { @@ -362,66 +500,62 @@ query GMFMAP::LabelTextAccessMethod::convertLabelTextAccessMethod() : GMFGEN::La }; return GMFGEN::LabelTextAccessMethod::MESSAGE_FORMAT; } -mapping GMFMAP::DesignLabelMapping::createLabelModelFacet() : GMFGEN::LabelModelFacet { - init { - result := object GMFGEN::DesignLabelModelFacet {}; - } - if this.designLabelParser = null then this.designLabelParser := object GMFGEN::ExternalParser {} endif; - parser := this.designLabelParser; -} - -- ************************************************************************************* -- Constraints and initializers -- ************************************************************************************* mapping GMFMAP::LinkConstraints::structure() : GMFGEN::GenLinkConstraints { - sourceEnd := self.sourceEnd.map structure(); - targetEnd := self.targetEnd.map structure(); + sourceEnd := self.sourceEnd.map createConstraint(); + targetEnd := self.targetEnd.map createConstraint(); } -- note, Constraints may be reused through reuse of NodeMappings, hence need to keep track of the relation -mapping GMFMAP::Constraint::structure() : GMFGEN::GenConstraint { - result._body := self._body; - result.bindToProvider(self); -} -mapping GMFMAP::ValueExpression::structure_ve() : GMFGEN::ValueExpression { --XXX think about naming, how to avoid conflict with GenConstraint::structure - disjuncts? - result._body := self._body; - result.bindToProvider(self); -} -helper GMFGEN::ValueExpression::bindToProvider(in expression : GMFMAP::ValueExpression) { - if expression.language.detectGenLanguage().oclIsUndefined() then return endif; -- XXX perhaps, don't need this line, if .map would give OclInvalid - expression.language.detectGenLanguage().map expressionProvider().expressions += self; - return; -} +--mapping GMFMAP::Constraint::structure() : GMFGEN::GenConstraint { +-- result._body := self._body; +-- result.bindToProvider(self); +--} +--mapping GMFMAP::ValueExpression::structure_ve() : GMFGEN::ValueExpression { --XXX think about naming, how to avoid conflict with GenConstraint::structure - disjuncts? +-- result._body := self._body; +-- result.bindToProvider(self); +--} +--helper GMFGEN::ValueExpression::bindToProvider(in expression : GMFMAP::ValueExpression) { +-- if expression.language.detectGenLanguage().oclIsUndefined() then return endif; -- XXX perhaps, don't need this line, if .map would give OclInvalid +-- expression.language.detectGenLanguage().map expressionProvider().expressions += self; +-- return; +--} -- XXX actually, looks like I don't need GenLanguage - I can make most decisions based on -query GMFMAP::Language::detectGenLanguage() : GMFGEN::GenLanguage { - switch { - case (self = GMFMAP::Language::ocl) return GMFGEN::GenLanguage::ocl; - case (self = GMFMAP::Language::java) return GMFGEN::GenLanguage::java; - case (self = GMFMAP::Language::regexp) return GMFGEN::GenLanguage::regexp; - case (self = GMFMAP::Language::nregexp) return GMFGEN::GenLanguage::nregexp; - case (self = GMFMAP::Language::_literal) return GMFGEN::GenLanguage::_literal; - else { assert (false) with log ('Unknown expression language literal', self); } - }; - return GMFGEN::GenLanguage::ocl; -} -mapping GMFGEN::GenLanguage::expressionProvider() : GMFGEN::GenExpressionProviderBase { - init { - switch { - case (self = GMFGEN::GenLanguage::ocl) result := object GMFGEN::GenExpressionInterpreter { language := self }; - case (self = GMFGEN::GenLanguage::java) result := object GMFGEN::GenJavaExpressionProvider {}; - case (self = GMFGEN::GenLanguage::regexp) result := object GMFGEN::GenExpressionInterpreter { language := self }; - case (self = GMFGEN::GenLanguage::nregexp) result := object GMFGEN::GenExpressionInterpreter { language := self }; - case (self = GMFGEN::GenLanguage::_literal) result := object GMFGEN::GenLiteralExpressionProvider {}; - else { - assert (false) with log ('Unknown expression language literal', self); - -- fake provider with no language set to fail validation (XXX perhaps, makes sense to add 'unrecognized' language?) - result := object GMFGEN::GenExpressionInterpreter {}; - } - } - } -} +--query GMFMAP::Language::detectGenLanguage() : GMFGEN::GenLanguage { +-- switch { +-- case (self = GMFMAP::Language::ocl) return GMFGEN::GenLanguage::ocl; +-- case (self = GMFMAP::Language::java) return GMFGEN::GenLanguage::java; +-- case (self = GMFMAP::Language::regexp) return GMFGEN::GenLanguage::regexp; +-- case (self = GMFMAP::Language::nregexp) return GMFGEN::GenLanguage::nregexp; +-- case (self = GMFMAP::Language::_literal) return GMFGEN::GenLanguage::_literal; +-- else { assert (false) with log ('Unknown expression language literal', self); } +-- }; +-- return GMFGEN::GenLanguage::ocl; +--} +--mapping GMFGEN::GenLanguage::expressionProvider() : GMFGEN::GenExpressionProviderBase { +-- init { +-- switch { +-- case (self = GMFGEN::GenLanguage::ocl) result := object GMFGEN::GenExpressionInterpreter { language := self }; +-- case (self = GMFGEN::GenLanguage::java) result := object GMFGEN::GenJavaExpressionProvider {}; +-- case (self = GMFGEN::GenLanguage::regexp) result := object GMFGEN::GenExpressionInterpreter { language := self }; +-- case (self = GMFGEN::GenLanguage::nregexp) result := object GMFGEN::GenExpressionInterpreter { language := self }; +-- case (self = GMFGEN::GenLanguage::_literal) result := object GMFGEN::GenLiteralExpressionProvider {}; +-- else { +-- assert (false) with log ('Unknown expression language literal', self); +-- -- fake provider with no language set to fail validation (XXX perhaps, makes sense to add 'unrecognized' language?) +-- result := object GMFGEN::GenExpressionInterpreter {}; +-- } +-- } +-- } +--} + +-- ************************************************************************************* +-- ElementInitializer +-- ************************************************************************************* mapping GMFMAP::ElementInitializer::structure() : GMFGEN::GenElementInitializer { init { @@ -433,10 +567,17 @@ mapping GMFMAP::FeatureSeqInitializer::structure() : GMFGEN::GenElementInitializ init { result := object GenFeatureSeqInitializer { initializers += self.initializers.map structure(); - elementClass := self.elementClass.findGenClass(); + if not self.elementClass.oclIsUndefined() then + elementClass := self.elementClass.findGenClass() + endif; } } } + +-- ************************************************************************************* +-- GenFeatureInitializer +-- ************************************************************************************* + mapping GMFMAP::FeatureInitializer::structure() : GMFGEN::GenFeatureInitializer { init { assert (false) with log ('No idea how to process FeatureInitializer', self); @@ -447,7 +588,7 @@ mapping GMFMAP::FeatureValueSpec::structure() : GMFGEN::GenFeatureInitializer { init { result := object GenFeatureValueSpec { feature := self.feature.findGenFeature(); - value := self.value.map structure_ve(); + value := self.value.map createValueExpression(); } } } @@ -470,16 +611,17 @@ mapping GMFMAP::CanvasMapping::palette() : GMFGEN::Palette when { not self.palette.oclIsUndefined(); } { --if self.palette.oclIsUndefined() return OclInvalid; var paletteItems : Sequence(GMFGEN::ToolGroupItem) := self.palette.tools.map paletteEntry(); - var topLevelTools := paletteItems->asOrderedSet() - paletteItems[GMFGEN::ToolGroup]->asOrderedSet(); + var topLevelTools := paletteItems->reject(e | e.oclIsKindOf(GMFGEN::ToolGroup)); if topLevelTools->notEmpty() then { var defaultGroup := object GMFGEN::ToolGroup { title := 'Default'; description := 'Holds top-level non-container tools'; collapse := false; - entries += topLevelTools; + entries += topLevelTools; }; result.groups := result.groups->prepend(defaultGroup); } endif; + result.groups += paletteItems[GMFGEN::ToolGroup]; result.flyout := true; if (self.palette._default <> null) then { @@ -556,11 +698,18 @@ helper setupCommonToolEntry(in tool : GMFTOOL::AbstractTool, inout genTool : GMF -- FIXME process path (makeRelative/makeAbsolute) as in original java code query GMFTOOL::BundleImage::constructIconPath() : String { - if self.path = null or self.path.size() = 0 then return null endif; - if self.bundle = null then return self.path endif; - return self.bundle + '/' + self.path; + if self.path.oclIsUndefined() or self.path.trim().size() = 0 then return null endif; + if self.bundle.oclIsUndefined() or self.bundle.trim().size() = 0 then + return self.path.makeRelative() + endif; + return self.bundle.makeAbsolute() + self.path; +} +query String::makeRelative(): String { + return self; +} +query String::makeAbsolute(): String { + return if self.startsWith('/') or self->exists(e | e = ':') then self + '/' else '/' + self + '/' endif; } - -- ************************************************************************************* -- Audits @@ -568,6 +717,7 @@ query GMFTOOL::BundleImage::constructIconPath() : String { mapping GMFMAP::AuditContainer::audits() : GMFGEN::GenAuditRoot { result.categories += self.allContainers().map category(); result.rules += self.allContainers().audits.map rule(); + var allRulesWithContext := result.rules->select(not target.oclIsUndefined()); var rulesWithDiagramElementTarget := allRulesWithContext->select(target.oclIsTypeOf(GMFGEN::GenDiagramElementTarget)); rulesWithDiagramElementTarget.target[GMFGEN::GenDiagramElementTarget]->forEach(t) { @@ -583,8 +733,9 @@ mapping GMFMAP::AuditContainer::audits() : GMFGEN::GenAuditRoot { ctx := result.clientContexts->selectOne(cc | cc.ruleTargets[GMFGEN::GenDiagramElementTarget]->exists(element = t.element)); -- there might be already a context to pick same elements this target has if ctx.oclIsUndefined() then { - ctx := object GMFGEN::GenAuditContext {}; - ctx.id := t.element.visualID.repr()->asList()->joinfields('_','Ctx',''); + ctx := object GMFGEN::GenAuditContext { + id := t.element.visualID.repr()->asList()->joinfields('_','Ctx_','') + }; result.clientContexts += ctx; } endif; t.contextSelector := ctx; @@ -595,7 +746,7 @@ mapping GMFMAP::AuditContainer::audits() : GMFGEN::GenAuditRoot { } query GMFMAP::AuditContainer::allContainers() : Sequence(GMFMAP::AuditContainer) { - var nested := self.childContainers.allContainers(); --hope, there's implicit flatten + var nested := self.childContainers.allContainers()->flatten(); return nested->prepend(self); } mapping GMFMAP::AuditContainer::category() : GMFGEN::GenAuditContainer { @@ -614,7 +765,7 @@ mapping GMFMAP::AuditRule::rule() : GMFGEN::GenAuditRule { description := self.description; useInLiveMode := self.useInLiveMode; target := self.target.map auditTarget(); - rule := self.rule.map structure(); + rule := self.rule.map createConstraint(); severity := self.severity.severity(); category := self.container.map category(); } @@ -630,10 +781,21 @@ mapping GMFMAP::NotationElementTarget::ruleTarget() : GMFGEN::GenNotationElement } mapping GMFMAP::DiagramElementTarget::ruleTarget() : GMFGEN::GenDiagramElementTarget { -- alternatives: + if self.element.oclIsKindOf(LinkMapping) then { + element += self.element.oclAsType(LinkMapping).map structure(); + } else if self.element.oclIsKindOf(NodeMapping) then { + var el := self.element.container(); + if el.oclIsKindOf(TopNodeReference) then + element += el.oclAsType(TopNodeReference).map structure() + else + element += el.oclAsType(ChildReference).map structure(self.element.oclAsType(NodeMapping)) + endif + } endif + endif; -- element += self.element.resolveIn(GMFMAP::NodeMapping::structure, GMFGEN::GenCommonBase); -- element += self.element.resolveIn(GMFMAP::LinkMapping::structure, GMFGEN::GenCommonBase); -- element += self.element.resolveIn(GMFMAP::TopNodeReference::structure, GMFGEN::GenCommonBase); - element += self.element.resolve(GMFGEN::GenCommonBase); +-- element += self.element.resolve(GMFGEN::GenCommonBase); } mapping GMFMAP::AuditedMetricTarget::ruleTarget() : GMFGEN::GenAuditedMetricTarget { result.metric := self.metric.map rule(); @@ -662,22 +824,18 @@ query GMFMAP::Severity::severity() : GMFGEN::GenSeverity { mapping GMFMAP::MetricContainer::metrics() : GMFGEN::GenMetricContainer { metrics += self.metrics.map rule(); } - mapping GMFMAP::MetricRule::rule() : GMFGEN::GenMetricRule { key := self.key; name := self.name; description := self.description; lowLimit := self.lowLimit; highLimit := self.highLimit; - rule := self.rule.map structure_ve(); + rule := self.rule.map createValueExpression(); target := self.target.map metricTarget(); - } mapping GMFMAP::Measurable::metricTarget() : GMFGEN::GenMeasurable disjuncts GMFMAP::DomainElementTarget::ruleTarget, GMFMAP::NotationElementTarget::ruleTarget, GMFMAP::DiagramElementTarget::ruleTarget {} --assert (false) with log ('Unknown rule target', self); - - -- ************************************************************************************* -- Viewmaps @@ -693,49 +851,139 @@ mapping GMFGRAPH::Canvas::viewmap() : GMFGEN::Viewmap { } } helper GMFGRAPH::Node::viewmap() : GMFGEN::Viewmap { - --result := object ModeledViewmap { figureModel := self.oclAsType(ECORE::EObject); }; - var rv := self.figure.viewmap(); - if self.figure.actualFigure.layout.oclIsKindOf(GMFGRAPH::FlowLayout) then { - var fl := self.figure.actualFigure.layout.oclAsType(GMFGRAPH::FlowLayout); - if fl.forceSingleLine then rv.layoutType := GMFGEN::ViewmapLayoutType::TOOLBAR_LAYOUT else rv.layoutType := GMFGEN::ViewmapLayoutType::FLOW_LAYOUT endif; - } else - if self.figure.actualFigure.layout.oclIsKindOf(GMFGRAPH::XYLayout) then rv.layoutType := GMFGEN::ViewmapLayoutType::XY_LAYOUT endif - endif; + var rv : GMFGEN::Viewmap; + + if useInTransformationCodeGen then { + rv := self.figure.viewmap(); + rv.layoutType := self.getLayoutType(); + rv.attributes += if self.hasResizeConstraints() then self.map resizeConstraints() endif; + rv.attributes += if self.hasDefaultSize() then self.map defaultSize() endif; + } else { + rv := object GMFGEN::ModeledViewmap { + figureModel := self.oclAsType(EObject); + } + } endif; + return rv; } +query GMFGRAPH::Node::hasResizeConstraints(): Boolean { + return not (self.resizeConstraint.oclIsUndefined() or (self.resizeConstraint = Direction::NSEW)) +} +query GMFGRAPH::Node::hasDefaultSize(): Boolean { + var facet : DefaultSizeFacet := self.facets[DefaultSizeFacet]->first(); + var defaultSize := if facet.oclIsUndefined() then self.figure.actualFigure.preferredSize else facet.defaultSize endif; + + return not defaultSize.oclIsUndefined() +} +mapping GMFGRAPH::Node::resizeConstraints(): GMFGEN::ResizeConstraints { + resizeHandles := self.resizeConstraint.repr().toInteger(); +} +mapping GMFGRAPH::Node::defaultSize(): GMFGEN::DefaultSizeAttributes { + var facet : DefaultSizeFacet := self.facets[DefaultSizeFacet]->first(); + var defaultSize := if facet.oclIsUndefined() then self.figure.actualFigure.preferredSize else facet.defaultSize endif; + + if not defaultSize.oclIsUndefined() then { + height := defaultSize.dy; + width := defaultSize.dx; + } endif; +} +query GMFGRAPH::Node::getLayoutType(): GMFGEN::ViewmapLayoutType { + var layout = ViewmapLayoutType::UNKNOWN; + if (self.figure.actualFigure.layout.oclIsUndefined()) then { + layout := GMFGEN::ViewmapLayoutType::UNKNOWN; + } else { + if self.figure.actualFigure.layout.oclIsKindOf(GMFGRAPH::FlowLayout) then { + var fl := self.figure.actualFigure.layout.oclAsType(GMFGRAPH::FlowLayout); + if fl.forceSingleLine then + layout := GMFGEN::ViewmapLayoutType::TOOLBAR_LAYOUT + else + layout := GMFGEN::ViewmapLayoutType::FLOW_LAYOUT + endif; + } else + if self.figure.actualFigure.layout.oclIsKindOf(GMFGRAPH::XYLayout) then + layout := GMFGEN::ViewmapLayoutType::XY_LAYOUT + endif + endif; + } endif; + return layout; +} helper GMFGRAPH::Compartment::viewmap() : GMFGEN::Viewmap { + if self.figure.oclIsUndefined() then + return object GMFGEN::FigureViewmap {} + endif; -- FIXME check self.accessor, see InnerClassViewapProducer - if self.accessor.oclIsUndefined() then return self.figure.viewmap() endif; + if self.accessor.oclIsUndefined() then + return self.figure.viewmap() + endif; return self.figure.viewmap(self.accessor); } helper GMFGRAPH::Connection::viewmap() : GMFGEN::Viewmap { + if self.figure.oclIsUndefined() then + return object GMFGEN::FigureViewmap { + figureQualifiedClassName := "org.eclipse.gmf.runtime.draw2d.ui.figures.PolylineConnectionEx"; + } + endif; return self.figure.viewmap(); } helper GMFGRAPH::DiagramLabel::viewmap() : GMFGEN::Viewmap { - --object ModeledViewmap { figureModel := self.oclAsType(ECORE::EObject); }; - if self.accessor.oclIsUndefined() then return self.figure.viewmap() endif; + if self.figure.oclIsUndefined() then + return object GMFGEN::FigureViewmap { + figureQualifiedClassName := "org.eclipse.draw2d.Label" + } + endif; + + if self.accessor.oclIsUndefined() then + return self.figure.viewmap() + endif; + -- for GenLinkLabel, need to specify alignment based on AlignmentFacet -- besides, need to create LabelOffsetAttributes and optionally populate it from LabelOffsetFacet return self.figure.viewmap(self.accessor); } helper GMFGRAPH::FigureDescriptor::viewmap() : GMFGEN::Viewmap { - if self.actualFigure.isBareInstance() then - return object GMFGEN::FigureViewmap { + var rs: GMFGEN::Viewmap := null; + + if self.actualFigure.isBareInstance() then { + rs := object GMFGEN::FigureViewmap { figureQualifiedClassName := self.actualFigure.xpand('Runtime::fqn', templateRoots); } - endif; - return object GMFGEN::InnerClassViewmap { - classBody := self.xpand('top::Descriptor::Inner', templateRoots); - className := self.name.firstToUpper(); -- FIXME InnerClassViewmapProducer has validJavaIdentifier(capName()) - }; + } else { + rs := object GMFGEN::InnerClassViewmap { + classBody := self.xpand('top::Descriptor::Inner', templateRoots); + className := self.name.firstToUpper(); -- FIXME InnerClassViewmapProducer has validJavaIdentifier(capName()) + }; + } endif; + + rs.attributes := self.actualFigure.createStyleAttributes(); + + return rs; } + +helper GMFGRAPH::Figure::createStyleAttributes() : GMFGEN::StyleAttributes { + var attributes: GMFGEN::StyleAttributes; + if not (self.font.oclIsUndefined() and self.foregroundColor.oclIsUndefined() and + self.backgroundColor.oclIsUndefined()) then { + attributes := object GMFGEN::StyleAttributes { + fixedFont := if (self.font.oclIsUndefined()) then false else true endif; + fixedForeground := if (self.foregroundColor.oclIsUndefined()) then false else true endif; + fixedBackground := if (self.backgroundColor.oclIsUndefined()) then false else true endif; + }; + } endif; + return attributes; +} + helper GMFGRAPH::FigureDescriptor::viewmap(childAccess : GMFGRAPH::ChildAccess) : GMFGEN::Viewmap { - return object GMFGEN::ParentAssignedViewmap { - getterName := childAccess.accessor; - figureQualifiedClassName := childAccess.figure.xpand('Runtime::fqn', templateRoots); - --FIXME setupStyleAttributes - }; + return + if useInTransformationCodeGen then + object GMFGEN::ParentAssignedViewmap { + getterName := childAccess.accessor; + figureQualifiedClassName := childAccess.figure.xpand('Runtime::fqn', templateRoots); + attributes := childAccess.figure.createStyleAttributes(); + } + else object GMFGEN::ModeledViewmap { + figureModel := self.oclAsType(EObject); + } endif; } query GMFGRAPH::Figure::isBareInstance() : Boolean { return false; } query GMFGRAPH::RealFigure::isBareInstance() : Boolean { @@ -749,6 +997,7 @@ query GMFGRAPH::RealFigure::isBareInstance() : Boolean { if sh.lineKind <> LineKind::LINE_SOLID then return false endif; if not sh.outline or not sh.fill or sh.xorFill or sh.xorOutline then return false endif; } endif; + if self.border <> null then return false endif; if self.font <> null then return false endif; if self.foregroundColor <> null then return false endif; @@ -759,5 +1008,126 @@ query GMFGRAPH::RealFigure::isBareInstance() : Boolean { if self.insets <> null then return false endif; if self.location <> null then return false endif; if self.size <> null then return false endif; + + if self.oclIsKindOf(GMFGRAPH::PolylineConnection) then { + if self.oclAsType(GMFGRAPH::PolylineConnection).sourceDecoration <> null then return false endif; + if self.oclAsType(GMFGRAPH::PolylineConnection).targetDecoration <> null then return false endif; + } endif; + + if self.oclIsKindOf(GMFGRAPH::SVGFigure) then { + if self.oclAsType(GMFGRAPH::SVGFigure).documentURI <> null then return false endif; + } endif; return true; -}
\ No newline at end of file +} + +-- ************************************************************************************* +-- Parsers +-- ************************************************************************************* + +mapping GMFMAP::Mapping::createGenParsers(): GenParsers { +-- object GenParsers { + implementations += GMFGEN::GenParserImplementation.allInstances(); + if this.designLabelParser <> null then implementations += this.designLabelParser endif; + if this.auxParser <> null then implementations += this.auxParser endif; + extensibleViaService := true; +-- }; +} + +-- ************************************************************************************* +-- Editor Plugin +-- ************************************************************************************* + +mapping GMFMAP::Mapping::editorPlugin() : GMFGEN::GenPlugin { + requiredPlugins := Set{'org.eclipse.draw2d'}; + + if self.links->notEmpty() or GMFMAP::LabelMapping.allInstances()->notEmpty() then + requiredPlugins += 'org.eclipse.gmf.runtime.draw2d.ui' + endif; + + self.diagram.diagramCanvas.figures->forEach(fg) { + if not fg.implementationBundle.oclIsUndefined() then { + result.requiredPlugins += fg.implementationBundle + } endif; + } +} + +-- ************************************************************************************* +-- Visual Identity +-- ************************************************************************************* + +property labelNodes: Sequence(LabelMapping) = Sequence{}; + +helper GMFMAP::Mapping::visualIdentity() { + self.diagram.resolveone(GenDiagram).visualID := 1000; + + self.nodes->collect(e | + if e.resolveone(GenTopLevelNode).visualID = 0 then { + e.resolveone(GenTopLevelNode).visualID := topNodeID(); + e.child.children->collect(visualIdentity()); + e.child.labelMappings->collect(visualIdentity(e)); + } endif + ); + + self.links->collect(visualIdentity()); + + self.getCompartments()->collect(e | e.c.visualIdentity(e.n, e.r)); + + return null; +} + +helper GMFMAP::ChildReference::visualIdentity() { + var node := self.findProcessableChildReference(); + if not node.oclIsUndefined() then + if node.map structure(node.child).visualID = 0 then { + if not node.referencedChild.oclIsUndefined() then + node.map structure(node.child).visualID := childNodeID() + else { + node.map structure(node.child).visualID := childNodeID(); + node.child.children->collect(e | + if e.needVisualID() then e.visualIdentity() endif + ); + } endif; + node.map structure(node.child).labels->collect(e | visualIdentity(e)); + -- node.child.labelMappings->collect(visualIdentity(node)); + } endif + endif +} + +query ChildReference::needVisualID(): Boolean { + var node := self.findProcessableChildReference(); + return + if node.oclIsUndefined() then false else + node.map structure(node.child).visualID = 0 + endif +} + +helper visualIdentity(inout genNode: GMFGEN::GenNodeLabel) { + if genNode.visualID = 0 then + genNode.visualID := nodeLabelID() + endif; +} + +helper GMFMAP::LabelMapping::visualIdentity(node: GMFMAP::NodeReference) { + if self.map createNodeLabel(node).visualID = 0 then + self.map createNodeLabel(node).visualID := nodeLabelID() + endif; +} + +helper visualIdentity(inout label: GenLinkLabel) { + if label.visualID = 0 then + label.visualID := linkLabelID() + endif; +} + +helper GMFMAP::LinkMapping::visualIdentity() { + if self.map structure().visualID = 0 then { + self.map structure().visualID := linkNodeID(); + self.map structure().labels->collect(e | visualIdentity(e)) + } endif; +} + +helper GMFMAP::CompartmentMapping::visualIdentity(_mapping: NodeMapping, node: NodeReference) { + if self.map structure(_mapping, node).visualID = 0 then + self.map structure(_mapping, node).visualID := compartmentID() + endif +} diff --git a/plugins/org.eclipse.gmf.bridge/transforms/Navigator.qvto b/plugins/org.eclipse.gmf.bridge/transforms/Navigator.qvto index 913fe45..04f1b66 100644 --- a/plugins/org.eclipse.gmf.bridge/transforms/Navigator.qvto +++ b/plugins/org.eclipse.gmf.bridge/transforms/Navigator.qvto @@ -9,10 +9,15 @@ * Contributors: * Artem Tikhomirov (Borland) - initial API and implementation */ +import Map2GenUtil; + modeltype GMFMAP uses mappings('http://www.eclipse.org/gmf/2006/mappings'); modeltype GMFGEN uses gmfgen('http://www.eclipse.org/gmf/2009/GenModel'); +modeltype ECORE uses ecore('http://www.eclipse.org/emf/2002/Ecore'); +modeltype GENMODEL uses genmodel('http://www.eclipse.org/emf/2002/GenModel'); -transformation Navigator(in mapModel : GMFMAP, inout gmfgenModel : GMFGEN); +transformation Navigator(in mapModel : GMFMAP, inout gmfgenModel : GMFGEN) +access Map2GenUtil; -- FIXME result is not completely correct now main() { @@ -23,10 +28,10 @@ main() { mapping GMFMAP::CanvasMapping::navigator(genDiagram : GMFGEN::GenDiagram) : GMFGEN::GenNavigator { childReferences += genDiagram.map navigator(); - childReferences += genDiagram.topLevelNodes.map navigator(); childReferences += genDiagram.childNodes->collect(n | n.containers.getNode().map navigator(n)); + childReferences += genDiagram.topLevelNodes.map navigator(); childReferences += genDiagram.links.map navigator(); - childReferences += genDiagram.links->collect(l | l.getTargetGenNodes().showLinkTargets(l)); + childReferences += genDiagram.links->collect(l | l.getTargetGenNodes()->asSet().showLinkTargets(l)); childReferences += genDiagram.links->collect(l | l.getSourceGenNodes().showLinkSources(l)); -- Instead, may use GenLinkEnd.genOutgoingLinks/genIncomingLinks, but they seem to be less effective as they -- go through GenLink.sources/targets anyway @@ -38,12 +43,15 @@ mapping GMFGEN::GenDiagram::navigator() : GMFGEN::GenNavigatorChildReference { GMFGEN::GenNavigatorReferenceType::children.populate(result, self, null); } mapping GMFGEN::GenTopLevelNode::navigator() : GMFGEN::GenNavigatorChildReference { - GMFGEN::GenNavigatorReferenceType::children.populate(result, self, self.diagram); + parent := self.diagram; + child := self; + referenceType := GenNavigatorReferenceType::children; } mapping GMFGEN::GenNode::navigator(childNode : GMFGEN::GenChildNode) : GMFGEN::GenNavigatorChildReference { - GMFGEN::GenNavigatorReferenceType::children.populate(result, childNode, self); + parent := self; + child := childNode; + referenceType := GenNavigatorReferenceType::children; } - mapping GMFGEN::GenLink::navigator() : GMFGEN::GenNavigatorChildReference { GMFGEN::GenNavigatorReferenceType::children.populate(result, self, self.diagram); groupName := 'links'; @@ -69,7 +77,7 @@ helper GMFGEN::GenLinkEnd::showIncomingLinks(link : GMFGEN::GenLink) : GMFGEN::G var rv := object GMFGEN::GenNavigatorChildReference {}; GMFGEN::GenNavigatorReferenceType::in_source.populate(rv, link, self); rv.groupName := 'incoming links'; - rv.groupIcon := 'icons/linkTargetNavigatorGroup.gif'; + rv.groupIcon := 'icons/incomingLinksNavigatorGroup.gif'; return rv; } helper GMFGEN::GenLinkEnd::showLinkSources(link : GMFGEN::GenLink) : GMFGEN::GenNavigatorChildReference { @@ -96,15 +104,19 @@ query GMFGEN::GenLink::getSourceGenNodes() : OrderedSet(GMFGEN::GenLinkEnd) { return self.sources; } query GMFGEN::GenLink::getTargetGenNodes() : OrderedSet(GMFGEN::GenLinkEnd) { - if self.modelFacet.oclIsUndefined() then return self.diagram.getAllPossibleLinkEnds() endif; + if self.modelFacet.oclIsUndefined() then { + return self.diagram.getAllPossibleLinkEnds() + } endif; + log ("target", Sequence{self.targets->size(), self.visualID}) when true; return self.targets; } + query GMFGEN::GenDiagram::getAllPossibleLinkEnds() : OrderedSet(GMFGEN::GenLinkEnd) { -- XXX original DGMT's NavigatorHandler used getAllNodes here, which is not completely correct: -- first, links can go to links, second, links can't go to GenChildLabelNode - var rv : OrderedSet(GMFGEN::GenLinkEnd) := OrderedSet {}; - rv += self.topLevelNodes; - rv += self.childNodes - self.childNodes[GMFGEN::GenChildLabelNode]; -- child nodes, excluding labels - rv += self.links; - return rv; -}
\ No newline at end of file + var rs : OrderedSet(GenLinkEnd) = OrderedSet{}; + rs += self.topLevelNodes; + rs += self.childNodes->reject(oclIsKindOf(GMFGEN::GenChildLabelNode)); -- child nodes, excluding labels + rs += self.links; + return rs; +} |

