-- @atlcompiler atl2006 -- $Id: UML2Accessors.atl 7380 2007-11-08 09:49:02Z dwagelaa $ -- 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; uses UML2Copy; uses Strings; uses UML2; uses Mappings; -- ====================================================================== -- model-specific helpers begin -- ====================================================================== 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::UML2Accessors_Package" using { myProperties : Set(UML2!"uml::Property") = s.allContainment ->select(o|o.oclIsKindOf(UML2!"uml::UML2Accessors_PublicProperty")); } to t : UML2!"uml::Package" mapsTo s ( 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::UML2Accessors_Class" using { myProperties : Set(UML2!"uml::Property") = s.attribute ->select(p|p.oclIsKindOf(UML2!"uml::UML2Accessors_PublicProperty")); } to t : UML2!"uml::Class" mapsTo s ( 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::UML2Accessors_Property" to t : UML2!"uml::Property" mapsTo s ( 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, templateBinding <- s.templateBinding, ownedTemplateSignature <- s.ownedTemplateSignature, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue, templateParameter <- s.templateParameter, end <- s.end, deployment <- s.deployment, redefinedProperty <- s.redefinedProperty, subsettedProperty <- s.subsettedProperty, association <- s.association, defaultValue <- s.defaultValue, qualifier <- s.qualifier) } rule PublicPropertySingle { from s : UML2!"uml::UML2Accessors_PublicPropertySingle" using { baseNameS : String = s.accessorBaseNameS; } to t : UML2!"uml::Property" mapsTo s ( name <- s.name, 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, templateBinding <- s.templateBinding, ownedTemplateSignature <- s.ownedTemplateSignature, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue, templateParameter <- s.templateParameter, end <- s.end, 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' + baseNameS, class <- s.class, visibility <- s.visibility, isStatic <- s.isStatic, isAbstract <- false, ownedParameter <- Sequence{getPar}, concurrency <- #sequential), getPar : UML2!"uml::Parameter" ( name <- 'return', type <- s.type, effect <- #read, direction <- #return), getBehavior : UML2!"uml::OpaqueBehavior" ( specification <- getOp, name <- 'get' + baseNameS + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.getter()}), getDep : UML2!"uml::Dependency" ( name <- 'accessor get' + baseNameS + '()', client <- getOp, supplier <- s), -- Set -- setOp : UML2!"uml::Operation" ( name <- 'set' + baseNameS, 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, name <- 'set' + baseNameS + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.setter()}), setDep : UML2!"uml::Dependency" ( name <- 'accessor set' + baseNameS + '()', client <- setOp, supplier <- s) } rule PublicPropertyCollection { from s : UML2!"uml::UML2Accessors_PublicPropertyCollection" using { baseNameS : String = s.accessorBaseNameS; baseName : String = s.accessorBaseName; } to t : UML2!"uml::Property" mapsTo s ( name <- s.name, 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, templateBinding <- s.templateBinding, ownedTemplateSignature <- s.ownedTemplateSignature, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue, templateParameter <- s.templateParameter, end <- s.end, 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' + baseNameS, 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 <- 'get' + baseNameS + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.getter()}), getDep : UML2!"uml::Dependency" ( name <- 'accessor get' + baseNameS + '()', client <- getOp, supplier <- s), -- Add -- addOp : UML2!"uml::Operation" ( name <- 'add' + baseName, 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 <- 'add' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.adder()}), addDep : UML2!"uml::Dependency" ( name <- 'accessor add' + baseName + '()', client <- addOp, supplier <- s), -- Remove -- removeOp : UML2!"uml::Operation" ( name <- 'remove' + baseName, 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 <- 'remove' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.remover()}), removeDep : UML2!"uml::Dependency" ( name <- 'accessor remove' + baseName + '()', client <- removeOp, supplier <- s) } rule PublicPropertySequence { from s : UML2!"uml::UML2Accessors_PublicPropertySequence" using { baseNameS : String = s.accessorBaseNameS; baseName : String = s.accessorBaseName; } to t : UML2!"uml::Property" mapsTo s ( name <- s.name, 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, templateBinding <- s.templateBinding, ownedTemplateSignature <- s.ownedTemplateSignature, clientDependency <- s.clientDependency, nameExpression <- s.nameExpression, type <- s.type, upperValue <- s.upperValue, lowerValue <- s.lowerValue, templateParameter <- s.templateParameter, end <- s.end, 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' + baseNameS, 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 <- 'get' + baseNameS + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.getter()}), getDep : UML2!"uml::Dependency" ( name <- 'accessor get' + baseNameS + '()', client <- getOp, supplier <- s), -- Add -- addOp : UML2!"uml::Operation" ( name <- 'add' + baseName, 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 <- 'add' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.adder()}), addDep : UML2!"uml::Dependency" ( name <- 'accessor add' + baseName + '()', client <- addOp, supplier <- s), -- Remove -- removeOp : UML2!"uml::Operation" ( name <- 'remove' + baseName, 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 <- 'remove' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.remover()}), removeDep : UML2!"uml::Dependency" ( name <- 'accessor remove' + baseName + '()', client <- removeOp, supplier <- s), -- GetAt -- getAtOp : UML2!"uml::Operation" ( name <- 'get' + baseName + '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 <- 'get' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.getAt()}), getAtDep : UML2!"uml::Dependency" ( name <- 'accessor get' + baseName + 'At()', client <- getAtOp, supplier <- s), -- IndexOf -- indexOfOp : UML2!"uml::Operation" ( name <- 'getIndexOf' + baseName, 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 <- 'getIndexOf' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.name.indexOfBody()}), indexOfDep : UML2!"uml::Dependency" ( name <- 'accessor getIndexOf' + baseName + '()', client <- indexOfOp, supplier <- s), -- Insert -- insertOp : UML2!"uml::Operation" ( name <- 'insert' + baseName, 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 <- 'insert' + baseName + 'Behavior', language <- Sequence{thisModule.language}, body <- Sequence{s.insert()}), insertDep : UML2!"uml::Dependency" ( name <- 'accessor insert' + baseName + '()', client <- insertOp, supplier <- s) } -- ====================================================================== -- transformation rules end -- ======================================================================