-- @atlcompiler atl2006 -- $Id$ -- Introduces accessor operations for all public properties -- -- Known issues: -- * Current UML2 standard does not allow PackageableElements -- to set their package. Only Package can set its ownedMembers. -- This issue is solved using a large query inside the Package rule. -- * Current UML2 standard does not allow Behaviors -- to set their context/owner. Only BehavioredClassifier can -- set its ownedBehavior. This issue is solved using a large -- query inside the Class rule. -- module UML2Accessors; --extends UML2Copy create OUT : UML2 from IN : UML2, ACCESSORS : UML2, UML2TYPES : UML2; uses UML2Copy; uses Strings; uses UML2; uses Mappings; -- ====================================================================== -- model-specific helpers begin -- ====================================================================== helper def : accessor : UML2!"uml::Stereotype" = 'accessor'.stereotype(); helper def : oclInteger : UML2!"uml::PrimitiveType" = 'Integer'.primitiveType(); helper def : separator : String = 'separator'.value(); helper def : language : String = 'language'.value(); helper context UML2!"uml::Property" def : setter() : String = if self.associatedProperty.oclIsUndefined() then self.name.setterBody() else self.dualSetter() endif; helper context UML2!"uml::Property" def : dualSetter() : String = if self.associatedProperty.isSingle then self.name.dualSetterBody( self.associatedProperty.name.firstToUpper) else self.name.addRemoveSetterBody( self.associatedProperty.name.firstToUpper) endif; helper context UML2!"uml::Property" def : adder() : String = if self.associatedProperty.oclIsUndefined() then self.name.adderBody(self.isUnique) else self.dualAdder() endif; helper context UML2!"uml::Property" def : dualAdder() : String = if self.associatedProperty.isSingle then self.name.setterAdderBody( self.associatedProperty.name.firstToUpper) else self.name.dualAdderBody( self.associatedProperty.name.firstToUpper) endif; helper context UML2!"uml::Property" def : insert() : String = if self.associatedProperty.oclIsUndefined() then self.name.insertBody(self.isUnique) else self.dualInsert() endif; helper context UML2!"uml::Property" def : dualInsert() : String = if self.associatedProperty.isSingle then self.name.setterInsertBody( self.associatedProperty.name.firstToUpper) else self.name.dualInsertBody( self.associatedProperty.name.firstToUpper) endif; helper context UML2!"uml::Property" def : remover() : String = if self.associatedProperty.oclIsUndefined() then self.name.removerBody() else self.dualRemover() endif; helper context UML2!"uml::Property" def : dualRemover() : String = if self.associatedProperty.isSingle then self.name.setterRemoverBody(self.associatedProperty.name.firstToUpper) else self.name.dualRemoverBody(self.associatedProperty.name.firstToUpper) endif; helper context UML2!"uml::Property" def : getter() : String = if self.isSingle then self.name.getterBody() else self.name.multiGetterBody() endif; helper context UML2!"uml::Property" def : getAt() : String = self.name.getAtBody(self.type.qualifiedName(thisModule.separator)); -- ====================================================================== -- model-specific helpers end -- ====================================================================== -- ====================================================================== -- transformation rules begin -- ====================================================================== rule Package { from s : UML2!"uml::Package" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Package") else false endif) using { myProperties : Set(UML2!"uml::Property") = UML2!"uml::Property".allInstancesFrom('IN') ->select(p|p.getNearestPackage()=s) ->select(p|p.oclIsTypeOf(UML2!"uml::Property") and (p.visibility=#public) and p.isNavigable); } to t : UML2!"uml::Package" ( __xmiID__ <- s.__xmiID__, name <- s.name.debug('Package'), visibility <- s.visibility, eAnnotations <- s.eAnnotations, ownedComment <- s.ownedComment, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, elementImport <- s.elementImport, packageImport <- s.packageImport, ownedRule <- s.ownedRule, templateParameter <- s.templateParameter, templateBinding <- s.templateBinding, ownedTemplateSignature <- s.ownedTemplateSignature, packageMerge <- s.packageMerge, packagedElement <- s.packagedElement ->union(myProperties->collect(p| thisModule.resolveTemp(p, 'getDep'))) ->union(myProperties->select(p|p.isSingle)->collect(p| thisModule.resolveTemp(p, 'setDep'))) ->union(myProperties->select(p|not p.isSingle)->collect(p| thisModule.resolveTemp(p, 'addDep'))) ->union(myProperties->select(p|not p.isSingle)->collect(p| thisModule.resolveTemp(p, 'removeDep'))) ->union(myProperties->select(p|not p.isSingle and p.isOrdered)->collect(p| thisModule.resolveTemp(p, 'getAtDep'))) ->union(myProperties->select(p|not p.isSingle and p.isOrdered)->collect(p| thisModule.resolveTemp(p, 'indexOfDep'))) ->union(myProperties->select(p|not p.isSingle and p.isOrdered)->collect(p| thisModule.resolveTemp(p, 'insertDep'))), profileApplication <- s.profileApplication) } rule Class { from s : UML2!"uml::Class" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Class") else false endif) using { myProperties : Set(UML2!"uml::Property") = s.attribute ->select(p|p.oclIsTypeOf(UML2!"uml::Property") and (p.visibility=#public) and p.isNavigable); } to t : UML2!"uml::Class" ( __xmiID__ <- s.__xmiID__, name <- s.name, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, isActive <- s.isActive, eAnnotations <- s.eAnnotations, ownedComment <- s.ownedComment, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, elementImport <- s.elementImport, packageImport <- s.packageImport, ownedRule <- s.ownedRule, templateParameter <- s.templateParameter, templateBinding <- s.templateBinding, ownedTemplateSignature <- s.ownedTemplateSignature, generalization <- s.generalization, powertypeExtent <- s.powertypeExtent, redefinedClassifier <- s.redefinedClassifier, substitution <- s.substitution, representation <- s.representation, collaborationUse <- s.collaborationUse, ownedUseCase <- s.ownedUseCase, useCase <- s.useCase, ownedAttribute <- s.ownedAttribute, ownedConnector <- s.ownedConnector, ownedBehavior <- s.ownedBehavior ->union(myProperties->collect(p| thisModule.resolveTemp(p, 'getBehavior'))) ->union(myProperties->select(p|p.isSingle)->collect(p| thisModule.resolveTemp(p, 'setBehavior'))) ->union(myProperties->select(p|not p.isSingle)->collect(p| thisModule.resolveTemp(p, 'addBehavior'))) ->union(myProperties->select(p|not p.isSingle)->collect(p| thisModule.resolveTemp(p, 'removeBehavior'))) ->union(myProperties->select(p|not p.isSingle and p.isOrdered)->collect(p| thisModule.resolveTemp(p, 'getAtBehavior'))) ->union(myProperties->select(p|not p.isSingle and p.isOrdered)->collect(p| thisModule.resolveTemp(p, 'indexOfBehavior'))) ->union(myProperties->select(p|not p.isSingle and p.isOrdered)->collect(p| thisModule.resolveTemp(p, 'insertBehavior'))), classifierBehavior <- s.classifierBehavior, interfaceRealization <- s.interfaceRealization, ownedTrigger <- s.ownedTrigger, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation, ownedReception <- s.ownedReception) } rule Property { from s : UML2!"uml::Property" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Property") and not ((s.visibility = #public) and (s.isNavigable)) else false endif) to t : UML2!"uml::Property" ( __xmiID__ <- s.__xmiID__, name <- s.name, visibility <- s.visibility, isLeaf <- s.isLeaf, isStatic <- s.isStatic, isOrdered <- s.isOrdered, isUnique <- s.isUnique, isReadOnly <- s.isReadOnly, isDerived <- s.isDerived, isDerivedUnion <- s.isDerivedUnion, aggregation <- s.aggregation, eAnnotations <- s.eAnnotations, ownedComment <- s.ownedComment, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue, templateParameter <- s.templateParameter, deployment <- s.deployment, redefinedProperty <- s.redefinedProperty, subsettedProperty <- s.subsettedProperty, association <- s.association, defaultValue <- s.defaultValue, qualifier <- s.qualifier) } abstract rule PublicProperty { from s : UML2!"uml::Property" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Property") and (s.visibility = #public) and s.isNavigable else false endif) to t : UML2!"uml::Property" ( __xmiID__ <- s.__xmiID__, name <- s.name.debug('PublicProperty'), visibility <- #private, isLeaf <- s.isLeaf, isStatic <- s.isStatic, isOrdered <- s.isOrdered, isUnique <- s.isUnique, isReadOnly <- s.isReadOnly, isDerived <- s.isDerived, isDerivedUnion <- s.isDerivedUnion, aggregation <- s.aggregation, eAnnotations <- s.eAnnotations, ownedComment <- s.ownedComment, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue, templateParameter <- s.templateParameter, deployment <- s.deployment, redefinedProperty <- s.redefinedProperty, subsettedProperty <- s.subsettedProperty, association <- s.association, defaultValue <- s.defaultValue, qualifier <- s.qualifier), -- Get -- getOp : UML2!"uml::Operation" ( name <- 'get' + s.accessorBaseNameS, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{getPar}, concurrency <- #sequential), getPar : UML2!"uml::Parameter" ( name <- 'return', lowerValue <- getParLow, upperValue <- getParUp, type <- s.type, effect <- #read, direction <- #return), getParLow : UML2!"uml::LiteralInteger" ( value <- s.lower), getParUp : UML2!"uml::LiteralUnlimitedNatural" ( value <- s.upper), getBehavior : UML2!"uml::OpaqueBehavior" ( specification <- getOp, name <- getOp.name + 'Behavior', ownedParameter <- Sequence{getBPar}, language <- Sequence{thisModule.language}, body <- Sequence{s.getter()}), getBPar : UML2!"uml::Parameter" ( name <- 'return', lowerValue <- getBParLow, upperValue <- getBParUp, type <- s.type, effect <- #read, direction <- #return), getBParLow : UML2!"uml::LiteralInteger" ( value <- s.lower), getBParUp : UML2!"uml::LiteralUnlimitedNatural" ( value <- s.upper), getDep : UML2!"uml::Dependency" ( name <- 'accessor get' + s.accessorBaseNameS + '()', client <- getOp, supplier <- s), getDepST : UML2!"Accessors::accessor" ( kind <- #get, base_Dependency <- getDep) } rule PublicPropertySingle extends PublicProperty { from s : UML2!"uml::Property" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Property") and (s.visibility = #public) and s.isNavigable and s.isSingle else false endif) to t : UML2!"uml::Property" ( name <- s.name.debug('PublicPropertySingle')), getOp : UML2!"uml::Operation", getPar : UML2!"uml::Parameter", getParLow : UML2!"uml::LiteralInteger", getParUp : UML2!"uml::LiteralUnlimitedNatural", getBehavior : UML2!"uml::OpaqueBehavior", getBPar : UML2!"uml::Parameter", getBParLow : UML2!"uml::LiteralInteger", getBParUp : UML2!"uml::LiteralUnlimitedNatural", getDep : UML2!"uml::Dependency", getDepST : UML2!"Accessors::accessor", -- Set -- setOp : UML2!"uml::Operation" ( name <- 'set' + s.accessorBaseNameS, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{setPar}, concurrency <- #sequential), setPar : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), setBehavior : UML2!"uml::OpaqueBehavior" ( specification <- setOp, ownedParameter <- Sequence{setBPar}, name <- setOp.name + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.setter()}), setBPar : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), setDep : UML2!"uml::Dependency" ( name <- 'accessor set' + s.accessorBaseNameS + '()', client <- setOp, supplier <- s), setDepST : UML2!"Accessors::accessor" ( kind <- #set, base_Dependency <- setDep) } abstract rule PublicPropertyCollection extends PublicProperty { from s : UML2!"uml::Property" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Property") and (s.visibility = #public) and s.isNavigable and not s.isSingle else false endif) to t : UML2!"uml::Property" ( name <- s.name.debug('PublicPropertyCollection')), getOp : UML2!"uml::Operation", getPar : UML2!"uml::Parameter", getParLow : UML2!"uml::LiteralInteger", getParUp : UML2!"uml::LiteralUnlimitedNatural", getBehavior : UML2!"uml::OpaqueBehavior", getBPar : UML2!"uml::Parameter", getBParLow : UML2!"uml::LiteralInteger", getBParUp : UML2!"uml::LiteralUnlimitedNatural", getDep : UML2!"uml::Dependency", getDepST : UML2!"Accessors::accessor", -- Add -- addOp : UML2!"uml::Operation" ( name <- 'add' + s.accessorBaseName, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{addPar}, concurrency <- #sequential), addPar : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), addBehavior : UML2!"uml::OpaqueBehavior" ( specification <- addOp, name <- addOp.name + 'Behavior', ownedParameter <- Sequence{addBPar}, language <- Sequence{thisModule.language}, body <- Sequence{s.adder()}), addBPar : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), addDep : UML2!"uml::Dependency" ( name <- 'accessor add' + s.accessorBaseName + '()', client <- addOp, supplier <- s), addDepST : UML2!"Accessors::accessor" ( kind <- #add, base_Dependency <- addDep), -- Remove -- removeOp : UML2!"uml::Operation" ( name <- 'remove' + s.accessorBaseName, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{removePar}, concurrency <- #sequential), removePar : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), removeBehavior : UML2!"uml::OpaqueBehavior" ( specification <- removeOp, name <- removeOp.name + 'Behavior', ownedParameter <- Sequence{removeBPar}, language <- Sequence{thisModule.language}, body <- Sequence{s.remover()}), removeBPar : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), removeDep : UML2!"uml::Dependency" ( name <- 'accessor remove' + s.accessorBaseName + '()', client <- removeOp, supplier <- s), removeDepST : UML2!"Accessors::accessor" ( kind <- #remove, base_Dependency <- removeDep) } rule PublicPropertyBag extends PublicPropertyCollection { from s : UML2!"uml::Property" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Property") and (s.visibility = #public) and s.isNavigable and not s.isSingle and not s.isOrdered else false endif) to t : UML2!"uml::Property" ( name <- s.name.debug('PublicPropertyBag')), getOp : UML2!"uml::Operation", getPar : UML2!"uml::Parameter", getParLow : UML2!"uml::LiteralInteger", getParUp : UML2!"uml::LiteralUnlimitedNatural", getBehavior : UML2!"uml::OpaqueBehavior", getBPar : UML2!"uml::Parameter", getBParLow : UML2!"uml::LiteralInteger", getBParUp : UML2!"uml::LiteralUnlimitedNatural", getDep : UML2!"uml::Dependency", getDepST : UML2!"Accessors::accessor", -- Add -- addOp : UML2!"uml::Operation", addPar : UML2!"uml::Parameter", addBehavior : UML2!"uml::OpaqueBehavior", addBPar : UML2!"uml::Parameter", addDep : UML2!"uml::Dependency", addDepST : UML2!"Accessors::accessor", -- Remove -- removeOp : UML2!"uml::Operation", removePar : UML2!"uml::Parameter", removeBehavior : UML2!"uml::OpaqueBehavior", removeBPar : UML2!"uml::Parameter", removeDep : UML2!"uml::Dependency", removeDepST : UML2!"Accessors::accessor" } rule PublicPropertySequence extends PublicPropertyCollection { from s : UML2!"uml::Property" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Property") and (s.visibility = #public) and s.isNavigable and not s.isSingle and s.isOrdered else false endif) to t : UML2!"uml::Property" ( name <- s.name.debug('PublicPropertySequence')), getOp : UML2!"uml::Operation", getPar : UML2!"uml::Parameter", getParLow : UML2!"uml::LiteralInteger", getParUp : UML2!"uml::LiteralUnlimitedNatural", getBehavior : UML2!"uml::OpaqueBehavior", getBPar : UML2!"uml::Parameter", getBParLow : UML2!"uml::LiteralInteger", getBParUp : UML2!"uml::LiteralUnlimitedNatural", getDep : UML2!"uml::Dependency", getDepST : UML2!"Accessors::accessor", -- Add -- addOp : UML2!"uml::Operation", addPar : UML2!"uml::Parameter", addBehavior : UML2!"uml::OpaqueBehavior", addBPar : UML2!"uml::Parameter", addDep : UML2!"uml::Dependency", addDepST : UML2!"Accessors::accessor", -- Remove -- removeOp : UML2!"uml::Operation", removePar : UML2!"uml::Parameter", removeBehavior : UML2!"uml::OpaqueBehavior", removeBPar : UML2!"uml::Parameter", removeDep : UML2!"uml::Dependency", removeDepST : UML2!"Accessors::accessor", -- GetAt -- getAtOp : UML2!"uml::Operation" ( name <- 'get' + s.accessorBaseName + 'At', class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{getAtPar1, getAtPar2}, concurrency <- #sequential), getAtPar1 : UML2!"uml::Parameter" ( name <- 'index', type <- thisModule.oclInteger, effect <- #read, direction <- #"in"), getAtPar2 : UML2!"uml::Parameter" ( name <- 'return', type <- s.type, effect <- #read, direction <- #"return"), getAtBehavior : UML2!"uml::OpaqueBehavior" ( specification <- getAtOp, name <- getAtOp.name + 'Behavior', ownedParameter <- Sequence{getAtBPar1, getAtBPar2}, language <- Sequence{thisModule.language}, body <- Sequence{s.getAt()}), getAtBPar1 : UML2!"uml::Parameter" ( name <- 'index', type <- thisModule.oclInteger, effect <- #read, direction <- #"in"), getAtBPar2 : UML2!"uml::Parameter" ( name <- 'return', type <- s.type, effect <- #read, direction <- #"return"), getAtDep : UML2!"uml::Dependency" ( name <- 'accessor get' + s.accessorBaseName + 'At()', client <- getAtOp, supplier <- s), getAtDepST : UML2!"Accessors::accessor" ( kind <- #getAt, base_Dependency <- getAtDep), -- IndexOf -- indexOfOp : UML2!"uml::Operation" ( name <- 'getIndexOf' + s.accessorBaseName, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{indexOfPar1, indexOfPar2}, concurrency <- #sequential), indexOfPar1 : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #read, direction <- #"in"), indexOfPar2 : UML2!"uml::Parameter" ( name <- 'return', type <- thisModule.oclInteger, effect <- #read, direction <- #"return"), indexOfBehavior : UML2!"uml::OpaqueBehavior" ( specification <- indexOfOp, name <- indexOfOp.name + 'Behavior', ownedParameter <- Sequence{indexOfBPar1, indexOfBPar2}, language <- Sequence{thisModule.language}, body <- Sequence{s.name.indexOfBody()}), indexOfBPar1 : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #read, direction <- #"in"), indexOfBPar2 : UML2!"uml::Parameter" ( name <- 'return', type <- thisModule.oclInteger, effect <- #read, direction <- #"return"), indexOfDep : UML2!"uml::Dependency" ( name <- 'accessor getIndexOf' + s.accessorBaseName + '()', client <- indexOfOp, supplier <- s), indexOfDepST : UML2!"Accessors::accessor" ( kind <- #indexOf, base_Dependency <- indexOfDep), -- Insert -- insertOp : UML2!"uml::Operation" ( name <- 'insert' + s.accessorBaseName, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{insertPar1, insertPar2}, concurrency <- #sequential), insertPar1 : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), insertPar2 : UML2!"uml::Parameter" ( name <- 'index', type <- thisModule.oclInteger, effect <- #read, direction <- #"in"), insertBehavior : UML2!"uml::OpaqueBehavior" ( specification <- insertOp, name <- insertOp.name + 'Behavior', ownedParameter <- Sequence{insertBPar1, insertBPar2}, language <- Sequence{thisModule.language}, body <- Sequence{s.insert()}), insertBPar1 : UML2!"uml::Parameter" ( name <- s.name, type <- s.type, effect <- #update, direction <- #"in"), insertBPar2 : UML2!"uml::Parameter" ( name <- 'index', type <- thisModule.oclInteger, effect <- #read, direction <- #"in"), insertDep : UML2!"uml::Dependency" ( name <- 'accessor insert' + s.accessorBaseName + '()', client <- insertOp, supplier <- s), insertDepST : UML2!"Accessors::accessor" ( kind <- #insert, base_Dependency <- insertDep) } -- ====================================================================== -- transformation rules end -- ======================================================================