-- @atlcompiler atl2006 -- $Id$ -- Implements the Observer profile. module UML2JavaObserver; --extends UML2Copy create OUT : UML2 from IN : UML2, IMPLTYPES : UML2, UML2TYPES : UML2; uses UML2Copy; uses Strings; uses UML2; uses Mappings; -- ====================================================================== -- model-specific helpers begin -- ====================================================================== helper def : language : String = 'language'.value(); helper def : separator : String = 'separator'.value(); helper def : Observer : UML2!"uml::Interface" = 'java::util::Observer'.interface().debug('Observer'); helper def : Observable : UML2!"uml::Class" = 'java::util::Observable'.class().debug('Observable'); helper def : ObserverName : String = thisModule.Observer.qualifiedName('separator'.value()).debug('ObserverName'); helper def : oclString : UML2!"uml::PrimitiveType" = 'String'.primitiveType(); helper def : oclAny : UML2!"uml::PrimitiveType" = 'OclAny'.primitiveType(); helper def : observables : Sequence(UML2!"Observer::Observable") = UML2!"Observer::Observable".allInstances(); helper def : observers : Sequence(UML2!"Observer::Observer") = UML2!"Observer::Observer".allInstances(); helper def : subscribes : Sequence(UML2!"Observer::subscribe") = UML2!"Observer::subscribe".allInstances(); helper def : accessors : Sequence(UML2!"Accessors::accessor") = UML2!"Accessors::accessor".allInstances(); helper context UML2!"uml::Classifier" def : isObservable : Boolean = thisModule.observables->exists(o|o.base_Classifier=self); helper context UML2!"uml::Classifier" def : isObserver : Boolean = thisModule.observers->exists(o|o.base_Classifier=self); helper context UML2!"uml::Association" def : isSubscribe : Boolean = thisModule.subscribes->exists(s|s.base_Association=self); helper context UML2!"uml::Dependency" def : isAccessor : Boolean = thisModule.accessors->exists(a|a.base_Dependency=self); helper context UML2!"uml::Dependency" def : accessor : Boolean = thisModule.accessors->any(a|a.base_Dependency=self); helper context UML2!"uml::Behavior" def : isNotifyMethod : Boolean = if self.specification.isAccessor then self.owner.isObservableKind else false endif; helper context UML2!"uml::Behavior" def : isSubscribeMethod : Boolean = if self.specification.isAccessor then if self.owner.isObserverKind then self.specification.isSubscriber else false endif else false endif; helper context UML2!"uml::Operation" def : accessorFor : UML2!"uml::Property" = self.accessorDependency.supplier->any(p| p.oclIsKindOf(UML2!"uml::Property")); helper context UML2!"uml::Operation" def : accessorDependency : UML2!"uml::Dependency" = self.clientDependency->any(d|d.isAccessor); helper context UML2!"uml::Operation" def : isAccessor : Boolean = not self.accessorDependency.oclIsUndefined(); helper context UML2!"uml::Classifier" def : isObservableKind : Boolean = if self.isObservable then true else self.generalization->exists(g|g.general.isObservableKind) endif; helper context UML2!"uml::Classifier" def : isObserverKind : Boolean = if self.isObserver then true else self.generalization->exists(g|g.general.isObserverKind) endif; helper context UML2!"uml::Operation" def : isSubscriber : Boolean = if self.isAccessor then self.accessorFor.hasSubscribesAssociation else false endif; helper context UML2!"uml::Property" def : hasSubscribesAssociation : Boolean = if self.association.oclIsUndefined() then false else self.association.isSubscribe endif; helper context UML2!"uml::Operation" def : notify(body : String) : String = let acc : UML2!"Accessor::accessor" = self.accessorDependency.accessor in if acc.kind = #remove then self.accessorFor.removerNotify(body) else if acc.kind = #add or acc.kind = #insert then self.accessorFor.adderNotify(body) else if acc.kind = #set then self.accessorFor.setterNotify(body) else body endif endif endif; helper context UML2!"uml::Property" def : setterNotify(body : String) : String = self.name.setterNotifyBody( self.type.qualifiedName(thisModule.separator), body, true); helper context UML2!"uml::Property" def : adderNotify(body : String) : String = self.name.adderNotifyBody( self.type.qualifiedName(thisModule.separator), body, self.isUnique, true); helper context UML2!"uml::Property" def : removerNotify(body : String) : String = self.name.removerNotifyBody( self.type.qualifiedName(thisModule.separator), body, true); helper context UML2!"uml::Operation" def : subscribe(body : String) : String = let acc : UML2!"Accessor::accessor" = self.accessorDependency.accessor in if acc.kind = #remove then self.accessorFor.name.removerSubscribeBody(body, true) else if acc.kind = #add or acc.kind = #insert then self.accessorFor.name.adderSubscribeBody(body) else if acc.kind = #set then self.accessorFor.name.setterSubscribeBody(body, true) else body endif endif endif; -- ====================================================================== -- model-specific helpers end -- ====================================================================== -- ====================================================================== -- transformation rules begin -- ====================================================================== rule Class { from s : UML2!"uml::Class" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Class") and not s.isObservable else false endif) 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(if s.isObserver then Set{thisModule.ObserverClass(s)} else Set{} endif), classifierBehavior <- s.classifierBehavior, interfaceRealization <- s.interfaceRealization, ownedTrigger <- s.ownedTrigger, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation, ownedReception <- s.ownedReception) } rule ObservableClass { from s : UML2!"uml::Class" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::Class") and s.isObservable else false endif) to t : UML2!"uml::Class" ( __xmiID__ <- s.__xmiID__, name <- s.name.debug('ObservableClass'), 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(if s.isObserver then Set{thisModule.ObserverClass(s)} else Set{} endif), classifierBehavior <- s.classifierBehavior, interfaceRealization <- s.interfaceRealization, ownedTrigger <- s.ownedTrigger, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation, ownedReception <- s.ownedReception), -- Observable functionality -- gen : UML2!"uml::Generalization" ( general <- thisModule.Observable, specific <- s) } rule ObserverClass(s : UML2!"uml::Class") { to real : UML2!"uml::InterfaceRealization" ( contract <- thisModule.Observer, implementingClassifier <- s), -- Update -- updateOp : UML2!"uml::Operation" ( name <- 'update'.debug('ObserverClass : ' + s.name), class <- s, visibility <- #public, ownedParameter <- Sequence{updatePar1, updatePar2}, concurrency <- #sequential), updatePar1 : UML2!"uml::Parameter" ( name <- 'o', type <- thisModule.Observable, effect <- #read, direction <- #"in"), updatePar2 : UML2!"uml::Parameter" ( name <- 'arg', type <- thisModule.oclAny, effect <- #update, direction <- #"in"), updateBehavior : UML2!"uml::OpaqueBehavior" ( specification <- updateOp, name <- updateOp.name + 'Behavior', ownedParameter <- Sequence{updateBPar1, updateBPar2}, language <- Sequence{thisModule.language}, body <- Sequence{'arg'.reflectiveUpdateBody()}), updateBPar1 : UML2!"uml::Parameter" ( name <- 'o', type <- thisModule.Observable, effect <- #read, direction <- #"in"), updateBPar2 : UML2!"uml::Parameter" ( name <- 'arg', type <- thisModule.oclAny, effect <- #update, direction <- #"in") do { updateBehavior; } } rule OpaqueBehavior { from s : UML2!"uml::OpaqueBehavior" ( if thisModule.inElements->includes(s) then s.oclIsTypeOf(UML2!"uml::OpaqueBehavior") else false endif) to t : UML2!"uml::OpaqueBehavior" ( __xmiID__ <- s.__xmiID__, name <- s.name, visibility <- s.visibility, isLeaf <- s.isLeaf, isAbstract <- s.isAbstract, isActive <- s.isActive, isReentrant <- s.isReentrant, body <- if s.isNotifyMethod then if s.isSubscribeMethod then s.body->collect(b|s.specification.notify(s.specification.subscribe(b))) else s.body->collect(b|s.specification.notify(b)) endif else if s.isSubscribeMethod then s.body->collect(b|s.specification.subscribe(b)) else s.body endif endif, language <- s.language, 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, classifierBehavior <- s.classifierBehavior, interfaceRealization <- s.interfaceRealization, ownedTrigger <- s.ownedTrigger, nestedClassifier <- s.nestedClassifier, ownedOperation <- s.ownedOperation, ownedReception <- s.ownedReception, redefinedBehavior <- s.redefinedBehavior, ownedParameter <- s.ownedParameter, precondition <- s.precondition, postcondition <- s.postcondition, ownedParameterSet <- s.ownedParameterSet, specification <- s.specification) } -- ====================================================================== -- transformation rules end -- ======================================================================