--- Transformation developed with Eclipse INDIGO --- We have enabled "Inter-model References" in this transformations, since our --- behavior models reference to GCS and ECORE module WeaveMetaModels; -- Module Template create OUTMM : WeaveMM, OUTGCS : WeaveGCS from INDSLMM : DSLMM, INDSLGCS : DSLGCS, INObsMM : ObsMM, INObsGCS : ObsGCS, INCorresp : CorrespMM ; -- OUTMM : WeaveMM --> Metamodel resulting of the weave between INDSLMM:DSLMM and INObsMM:ObsMM. It conforms to Ecore -- The Ecore metamodel is taken from the EMF registry and the resulting model is stored in WeaveModels/WeaveMetamodels/OUTWeaveMM.ecore -- OUTGCS : WeaveGCS --> Metamodel resulting of the weave between INDSLGCS:DSLGCS and INObsGCS:ObsGCS. It conforms to the GCS metamodel -- The GCS metamodel is in SLE12/Metamodels/GCS.ecore and the resulting model is stored in WeaveModels/WeaveMetamodels/OUTWeaveGCS.gcs -- INDSLMM : DSLMM --> Metamodel of the DSL. It conforms to Ecore -- The Ecore metamodel is taken from the EMF registry and the DSL metamodel is taken from PLS/Metamodel/DEVSMM.ecore -- INDSLGCS : DSLGCS --> GCS model of the DSL. It conforms to the GCS metamodel -- The GCS metamodel is in SLE12/Metamodels/GCS.ecore and the GCS model is taken from PLS/Behavior/DEVSgcs.gcs -- INObsMM : ObsMM --> Metamodel of observers. It conforms to Ecore -- The Ecore metamodel is taken from the EMF registry and the observers metamodel is taken from SLE12/Metamodels/RespTimeMM.ecore -- INObsGCS : ObsGCS --> GCS model of the observers. It conforms to the GCS metamodel -- The GCS metamodel is in SLE12/Metamodels/GCS.ecore and the observers GCS model is taken from SLE12/GCSs/RespTimeMM.gcs -- INCorresp : CorrespMM --> Model with the correspondences. It conforms to the CorrespondencesMM metamodel -- The CorrespondencesMM metamodel is at SLE12/Metamodels/CorrespondencesMM.ecore and the model is at SLE12/Models/PLSCorrespondences.xmi helper def : packageMM : WeaveMM!EPackage = OclUndefined; -- It will keep the package of the output metamodel helper def : packageGCS : WeaveGCS!PackageGD = OclUndefined; -- It will keep the package of the output GCS helper def : classes : Sequence(WeaveMM!EClass) = Sequence{}; -- It will store all the classes created in the output metamodel -----------------RULES FOR COPYING THE DSL METAMODEL-------------------------- -- Those attributes commented are non-changeable properties rule CopyPackagesMM{ from p : DSLMM!EPackage to pMM : WeaveMM!EPackage( name <- p.name, nsURI <- p.nsURI, nsPrefix <- p.nsPrefix, eSubpackages <- p.eSubpackages, eClassifiers <- p.eClassifiers, eAnnotations <- p.eAnnotations ) do{ thisModule.packageMM <- pMM; } } rule CopyClasses{ from c : DSLMM!EClass to c2 : WeaveMM!EClass( instanceClassName <- c.instanceClassName, name <- c.name, abstract <- c.abstract, interface <- c.interface, eSuperTypes <- c.eSuperTypes, eOperations <- c.eOperations, eStructuralFeatures <- c.eStructuralFeatures, eAnnotations <- c.eAnnotations --ePackage <-c.ePackage --instanceClass <- c.instanceClass, --defaultValue <- c.defaultValue, --eAllSuperTypes <- c.eAllSuperTypes, --eAllContainments <- c.eAllContainments, --eAllReferences <- c.eAllReferences, --eReferences <- c.eReferences, --eAllAttributes <- c.eAllAttributes, --eAttributes <- c.eAttributes, --eIDAttribute <- c.eIDAttribute, --eAllStructuralFeatures <- c.eAllStructuralFeatures, --eAllOperations <- c.eAllOperations ) do{ --We insert the class inside our EPackage thisModule.packageMM.eClassifiers <- thisModule.packageMM.eClassifiers -> append(c2); --We add the new class to the set of classes thisModule.classes <- thisModule.classes -> including(c2); } } rule CopyAttributes{ from a : DSLMM!EAttribute to a2 : WeaveMM!EAttribute( eType <- a.eType, name <- a.name, iD <- a.iD, changeable <- a.changeable, volatile <- a.volatile, transient <- a.transient, defaultValueLiteral <- a.defaultValueLiteral, unsettable <- a.unsettable, derived <- a.derived, ordered <- a.ordered, unique <- a.unique, lowerBound <- a.lowerBound, upperBound <- a.upperBound, eAnnotations <- a.eAnnotations --eAttributeType <- a.eAttributeType, --defaultValue <- a.defaultValue, --eContainingClass <- a.eContainingClass, --many <- a.many, --required <- a.required, ) } rule CopyReferences{ from r : DSLMM!EReference to r2 : WeaveMM!EReference( name <- r.name, containment <- r.containment, eOpposite <- r.eOpposite, changeable <- r.changeable, volatile <- r.volatile, transient <- r.transient, defaultValueLiteral <- r.defaultValueLiteral, unsettable <- r.unsettable, derived <- r.derived, ordered <- r.ordered, unique <- r.unique, lowerBound <- r.lowerBound, upperBound <- r.upperBound, eType <- r.eType, eAnnotations <- r.eAnnotations --container <- r.container, --eReferenceType <- r.eReferenceType, --defaultValue <- a.defaultValue, --eContainingClass <- a.eContainingClass, --many <- a.many, --required <- a.required, ) } rule CopyDataTypes{ from dt : DSLMM!EDataType to dt2 : WeaveMM!EDataType( serializable <- dt.serializable, instanceClassName <- dt.instanceClassName, name <- dt.name, eAnnotations <- dt.eAnnotations --instanceClass <- dt.instanceClass, --defaultValue <- dt.defaultValue, --ePackage <- dt.ePackage, ) } rule CopyParameters{ from p : DSLMM!EParameter to p2 : WeaveMM!EParameter( name <- p.name, eOperation <- p.eOperation, ordered <- p.ordered, unique <- p.unique, lowerBound <- p.lowerBound, upperBound <- p.upperBound, eType <- p.eType, eAnnotations <- p.eAnnotations ) } rule CopyOperations{ from o : DSLMM!EOperation to o2 : WeaveMM!EOperation( name <- o.name, eContainingClass <- o.eContainingClass, eParameters <- o.eParameters, eExceptions <- o.eExceptions, ordered <- o.ordered, unique <- o.unique, lowerBound <- o.lowerBound, upperBound <- o.upperBound, eType <- o.eType, eAnnotations <- o.eAnnotations ) } rule CopyEnums{ from e : DSLMM!EEnum to e2 : WeaveMM!EEnum( name <- e.name, eLiterals <- e.eLiterals, instanceClassName <- e.instanceClassName, instanceClass <- e.instanceClass, defaultValue <- e.defaultValue, eAnnotations <- e.eAnnotations ) } rule CopyEnumLiterals{ from e : DSLMM!EEnumLiteral to e2 : WeaveMM!EEnumLiteral( name <- e.name, value <- e.value, instance <- e.instance, eEnum <- e.eEnum, eAnnotations <- e.eAnnotations ) } rule CopyAnnotations{ from a : DSLMM!EAnnotation to a2 : WeaveMM!EAnnotation( source <- a.source, details <- a.details, eAnnotations <- a.eAnnotations ) } rule CopyFactories{ from f : DSLMM!EFactory to f2 : WeaveMM!EFactory( ePackage <- f.ePackage, eAnnotations <- f.eAnnotations ) } -----------------END OF RULES FOR COPYING THE DSL METAMODEL----------------------- ----------------RULES FOR COPYING THE DSL AND OBSERVER GCS----------------------- rule CopyPackagesGCS{ from p : DSLGCS!PackageGD to pGCS : WeaveGCS!PackageGD( name <- p.name, metamodelGD <- mmGCS, --classesGD <- p.classesGD, superPackageGD <- p.superPackageGD, subPackagesGD <- p.subPackagesGD, package <- p.package ), mmGCS : WeaveGCS!MetamodelGD( name <- p.metamodelGD.name ) do{ thisModule.packageGCS <- pGCS; } } rule CopyClassesGDDSL{ from c : DSLGCS!ClassGD to c2 : WeaveGCS!ClassGD( name <- c.name, figurePath <- c.figurePath, class <- c.class ) do{ --We insert the class inside our EPackage thisModule.packageGCS.classesGD <- thisModule.packageGCS.classesGD -> append(c2); } } rule CopyClassesGDObs{ from -- We want to add the ClassGD only from the observers, not from those classes -- having a correspondence (observers do not have correspondences) c : ObsGCS!ClassGD, cObs : ObsMM!EClass(cObs.name=c.name and not CorrespMM!ClassMatching.allInstances()->exists(cm|cm.obName=c.name)) to c2 : WeaveGCS!ClassGD( name <- c.name, figurePath <- c.figurePath, class <- thisModule.CreateNonFunctionalClass(cObs) ) do{ --We insert the class inside our EPackage thisModule.packageGCS.classesGD <- thisModule.packageGCS.classesGD -> append(c2); } } ----------------END OF RULES FOR COPYING THE DSL AND OBSERVER GCS----------------------- ----------------RULES FOR CREATING REFERENCES, CLASSES AND ATTRIBUTES OF NONFUNCTIONAL PROPERTIES--------------------- rule CreateObserverOnlyReference { -- This rule aims to include in the final metamodel a reference (and class) that is included in the observers -- metamodel but not in the DSL metamodel. To achieve it, the rule will look in the CorrespondenceMM -- for two classes that match. The condition to trigger the rule is also that it finds a reference departing -- from the class in the matching belonging to the observers metamodel such as there is not a matching -- between that reference and any reference in the DSL metamodel. -- The rule will create that reference departing from (the class in the WeaveMM model created from) -- the class in the DSL metamodel as well as the class at the other end of the reference. from cc : CorrespMM!ClassMatching, -- Correspondence between the observer and DSL classes cDSL : DSLMM!EClass, -- Class in the correspondence that belongs to the DSL metamodel rObs : ObsMM!EReference, -- Reference departing from a class in the observer metamodel. This reference -- does not have a match in the correspondence metamodel cEndRefObs : ObsMM!EClass, -- This is the class at the other end of the rObs reference, i.e., -- the one representing the non-functional property -- The next one is the class in the correspondence that belongs to the observer metamodel. -- We check that the rObs reference does not have a match with any reference in the DSL metamodel. --(Sometimes it gives an error in the condition of the next line. Simply comment it, save it, -- uncomment it, and execute again) cObs : ObsMM!EClass (cObs.name = cc.obName and cDSL.name = cc.DSLName and cObs.eAllReferences->includes(rObs) and rObs.eReferenceType = cEndRefObs and CorrespMM!RefMatching.allInstances() -> select(rm | rm.obClassName=cObs.name and rm.obRefName=rObs.name) -> size() = 0 ) to rDSL : WeaveMM!EReference( -- The new reference pointing the class representing the nonFunctional property name <- rObs.name, -- We create the class pointed by this reference by means of a unique lazy rule, because it can happen that two classes -- in the observer metamodel reference the same nonFunctional class. In such case, the nonFunctional -- class has to be created only once eType <- thisModule.CreateNonFunctionalClass(cEndRefObs), containment <- rObs.containment, changeable <- rObs.changeable, volatile <- rObs.volatile, transient <- rObs.transient, defaultValueLiteral <- rObs.defaultValueLiteral, unsettable <- rObs.unsettable, derived <- rObs.derived, ordered <- rObs.ordered, unique <- rObs.unique, lowerBound <- rObs.lowerBound, upperBound <- rObs.upperBound, eAnnotations <- rObs.eAnnotations ) do{ -- We have to stablish the source class for the new reference created. To do that, we cannot use the eContainingClass -- of the reference because that property is non-changeable, -- so we look in the set of classes created in order to find the one with the same name as cDSL, and -- then we use its eStructuralFeatures reference for (c in thisModule.classes){ if (c.name = cDSL.name){ c.eStructuralFeatures <- c.eStructuralFeatures -> append(rDSL); } } } } unique lazy rule CreateNonFunctionalClass{ -- This rule creates those classes representing non-functional properties. It is a unique lazy rule -- because two different classes in the obs metamodel may be referencing the same non-functional class. -- In such case, this rule will be called more than once, but only one class has to be created from cEndRefObs : ObsMM!EClass -- This is the class at the other end of the rObs reference, i.e., -- the one representing the non-functional property to cEndRefDSL : WeaveMM!EClass( -- The new class with a non-functional property to be added -- in the output metamodel instanceClassName <- cEndRefObs.instanceClassName, name <- cEndRefObs.name, abstract <- cEndRefObs.abstract, interface <- cEndRefObs.interface, eOperations <- cEndRefObs.eOperations, eStructuralFeatures <- cEndRefObs.eStructuralFeatures, -- It will look for the EAttributes -- created by the "CreateNonFuncionalAttribute" rule eAnnotations <- cEndRefObs.eAnnotations ) do{ -- We add the new created class in the package thisModule.packageMM.eClassifiers <- thisModule.packageMM.eClassifiers -> append(cEndRefDSL); --We add the new class to the set of classes thisModule.classes <- thisModule.classes -> including(cEndRefDSL); } } rule CreateNonFunctionalAttribute{ -- This rule creates the attributes for that classes representing non-functional properties. Those classes -- do not have a correspondence in the correspondence model (that is how we identify them) -- The attributes created by this rule are to be contained by the class created by the unique lazy rule -- "CreateNonFunctionalClass" (eStructuralFeatures <- cEndRefObs.eStructuralFeatures). That rule will look in -- the traceability links for those attributes belonging to the ObsMM!EClass in the LHS of the rule from a : ObsMM!EAttribute (not CorrespMM!ClassMatching.allInstances()->exists(cm|cm.obName=a.eContainingClass.name)) to a2 : WeaveMM!EAttribute( eType <- a.eType, name <- a.name, iD <- a.iD, changeable <- a.changeable, volatile <- a.volatile, transient <- a.transient, defaultValueLiteral <- a.defaultValueLiteral, unsettable <- a.unsettable, derived <- a.derived, ordered <- a.ordered, unique <- a.unique, lowerBound <- a.lowerBound, upperBound <- a.upperBound, eAnnotations <- a.eAnnotations ) } --------------------------------------------------------------------------------------------------------------