10.2 The UML to EJB Mapping

This section describes the transformation definition for transforming PIMs in UML to models of EJB components. The definition is identical to the rules used in section 5.2. As explained before, we need the metamodel for both the source and the target language. The source language is UML, for which we already introduced a metamodel in Figure 10-1. The target language is the coarse grained EJB model described in section 5.2.1. The metamodel for the coarse grained EJB components used is depicted in Figure 10-3. For the sake of simplicity, the transformations and metamodel elements for enumerations and data types without operations (that is, structs) are not defined. These are used for the Style and Address classes in Rosa's model.

Figure 10-3. Simplified EJB metamodel

graphics/10fig03.gif

Note that we use some additional queries on the UML metamodel called getAllContained() and getOuterMostContainer(). These queries are defined in OCL in section 10.2.1 as additional operations on the UML metamodel.

  1. There is a transformation from each UML class to a key class in the EJB model. For each class in the UML model, a separate key class is generated. This is needed in the EJB platform. This rule formalizes rule 1 in section 5.2.2.

      Transformation  ClassToKeyClass (UML, EJB) {  source  class    : UML::Class;  target  keyClass : EJB::EJBKeyClass;      id       : EJB::EJBAttribute;  target condition  id.class = keyClass  and  id.type  = Integer;  unidirectional;   mapping  class.name + 'Key' <~> keyClass.name;     class.name + 'ID'  <~> id.name; } 
  2. This is a transformation from each UML association class to a key class in the EJB model with two attributes that identify the associated class. Note that this rule only supports association classes between ordinary (non association) classes.

      Transformation  AssociationClassToKeyClass (UML, EJB) {  source  associationClass : UML::AssociationClass  target  keyClass : EJB::EJBKeyClass;      id1      : EJB::EJBAttribute;      id2      : EJB::EJBAttribute;  target condition  id1.class = keyClass  and  id1.type  = Integer  and  id2.class = keyClass  and  id2.type  = Integer;  unidirectional;   mapping  associationClass.name                          <~> keyClass.name;      associationClass.end->first().type.name + 'ID' <~> id1.name;      associationClass.end->                          first().otherEnd.type.name.concat('ID') <~>                                                            id2.name; } 
  3. Each class that is not the part of a composite aggregation is mapped to an EJB entity component. Classes that are composite parts of other classes do not conform to this rule and are transformed by the next rule. This rule formalizes rule 2 in section 5.2.2.

      Transformation  ClassToEntityComponent (UML, EJB) {  source  class : UML::Class;  target  entityComponent  : EJB::EJBEntityComponent;        rootDataClass    : EJB::EJBDataClass;        dataSchema       : EJB::EJBDataSchema;        servingAttribute : EJB::EJBServingAttribute;  source condition   not  class.associationEnds()->exists(                                     otherEnd.composition = true);  target condition  servingAttribute.class = entityComponent  and  servingAttribute.type  = rootDataClass  and  rootDataClass.package  = dataSchema  unidirectional  ;  mapping  class.name <~> entityComponent.name;      class.name <~> rootDataClass.name;      class.name <~> servingAttribute.name;      class.name <~> dataSchema.name;      class.getAllContained(Set(UML::Class){}).operations() <~>                                             entityComponent.feature;      class.feature->select(oclKindOf(UML::Attribute)  or  oclKindOf(UML::AssociationEnd)) <~>                                             rootDataClass.feature;      class.getAllContained(Set(UML::Class){}) <~>                                           entityComponent.usedTable; } 
  4. The following transformation defines the mapping from a UML class to an EJB data class. The source condition states that this transformation can only be applied when the UML class is part of a composite aggregation. This rule formalizes a part of rule 3 in section 5.2.2.

      Transformation  ClassToDataClass (UML, EJB) {  source  class        : UML::Class;  target  nonRootClass : EJB::EJBDataClass;  source condition  class.associationEnds()->exists(otherEnd.composition = true);  unidirectional;   mapping  class.name <~> nonRootClass.name;      class.feature->select(oclKindOf(UML::Attribute)  or  oclKindOf(UML::AssociationEnd)) <~>                                       rootDataClass.feature;      class.getOuterMostContainer() <-> nonRootClass.package; } 
  5. Each association is transformed into an EJB association. This rule formalizes rule 4 in section 5.2.2.

      Transformation  AssociationToDataAssociation (UML, EJB) {  source  assoc     : UML::Association;  target  dataAssoc : EJB::EJBDataAssociation;  source condition  assoc.end->exists(composition);  unidirectional  ;  mapping  assoc.name                    <~> dataAssoc.name;      assoc.end                     <~> dataAssoc.end;      assoc.getOuterMostContainer() <~> dataAssoc.package; } 
  6. This rule formalizes a part of rule 5 in section 5.2.2.

      Transformation  AssociationClassToDataClass (UML, EJB) {  source  associationClass : UML::AssociationClass;  target  nonRootClass     : EJB::EJBDataClass;  source condition  class.feature->exists(end : AssociationEnd                                            end.otherEnd.composition);  unidirectional;   mapping  associationClass.name <~> nonRootClass.name;      associationClass.feature->select(oclKindOf(UML::Attribute)  or  oclKindOf(UML::AssociationEnd)) <~>                                                  rootDataClass.feature;      associationClass.getOuterMostContainer() <~>                                                nonRootClass.package; } 
  7. The following rule formalizes rule 6 in section 5.2.2. This is a straightforward transformation from UML attribute to EJB attribute.

      Transformation  UMLAttributeToEJBAttribute (UML, EJB) {  source  umlAttribute : UML::Attribute;  target  ejbAttribute : EJB::EJBAttribute;  unidirectional;   mapping  umlAttribute.name <~> ejbAttribute.name;      umlAttribute.type <~> ejbAttribute.type; } 
  8. This rule defines a transformation from a UML association end to an EJB association end. The condition of this rule states that it is only applicable if the transformed association end is not crossing an EJB data schema. In this case, the type of the EJB association end is an EJB data class. This rule formalizes a part of rule 4 in section 5.2.2.

      Transformation  UMLAssociationEndToEJBAssociationEnd(UML, EJB) {  source  umlAssociationEnd : UML::AssociationEnd;  target  ejbAssociationEnd : EJB::EJBAssociationEnd;  source condition  umlAssociationEnd.association.oclIsTypeOf(Association)  and  umlAssociationEnd.class.getOuterMostContainer() =                      umlAssociationEnd.type.getOuterMostContainer();  unidirectional;   mapping  umlAssociationEnd.name        <~> ejbAssociationEnd.name;      umlAssociationEnd.upper       <~> ejbAssociationEnd.upper;      umlAssociationEnd.lower       <~> ejbAssociationEnd.lower;      umlAssociationEnd.composition <~>                                       ejbAssociationEnd.composition;      umlAssociationEnd.type        <~>                 ejbAssociationEnd.type.oclAsType(EJB::EJBDataClass); } 
  9. This rule also defines a transformation from a UML association end to an EJB association end. The condition of this rule states that it is only applicable if the transformed association end is crossing an EJB data schema. In this case, the type of the EJB association end is an EJB key class. This rule formalizes a part of rule 4 in section 5.2.2.

      Transformation  UMLAssociationEndToEJBAssociationEnd(UML, EJB) {  source  umlAssociationEnd : UML::AssociationEnd;  target  ejbAssociationEnd : EJB::EJBAssociationEnd;  source condition  umlAssociationEnd.association.oclIsTypeOf(Association)  and   not  umlAssociationEnd.class.getOuterMostContainer() =                      umlAssociationEnd.type.getOuterMostContainer();  unidirectional;   mapping  umlAssociationEnd.name  <~> ejbAssociationEnd.name;      umlAssociationEnd.upper <~> ejbAssociationEnd.upper;      umlAssociationEnd.lower <~> ejbAssociationEnd.lower;      umlAssociationEnd.composition <~>                                       ejbAssociationEnd.composition;      umlAssociationEnd.type  <~>                  ejbAssociationEnd.type.oclAsType(EJB::EJBKeyClass); } 
  10. The following rule transforms association ends from an association class into associations in the EJB data schemes. This is because we need two associations per association class to implement them in the EJB model that does not support association classes in the metamodel. This rule formalizes a part of rule 5 in section 5.2.2.

      Transformation  UMLAssociationClassEndToEJBAssociation(UML, EJB) {  source  umlAssociationEnd  : UML::AssociationEnd;  target  ejbAssociation     : EJB::EJBAssociation;      ejbAssociationEnd1 : EJB::EJBAssociationEnd;      ejbAssociationEnd2 : EJB::EJBAssociationEnd;  source condition  umlAssociationEnd.upper <> 1  and  umlAssociationEnd.association.oclIsTypeOf(AssociationClass)  and  umlAssociationEnd.association.getOuterMostContainer() =                      umlAssociationEnd.type.getOuterMostContainer();  target condition  ejbAssociationEnd1.lower = 0  and  ejbAssociationEnd1.upper = *  and  ejbAssociationEnd2.lower = 1  and  ejbAssociationEnd2.upper = 1  and  ejbAssociationEnd1.composition = false  and  ejbAssociationEnd1.association = ejbAssociation  and  ejbAssociationEnd2.association = ejbAssociation;  unidirectional;   mapping  umlAssociationEnd.type.name   <~> ejbAssociationEnd2.name;      umlAssociationEnd.composition <~>                                      ejbAssociationEnd2.composition;      umlAssociationEnd.type        <~>                ejbAssociationEnd2.type.oclAsType(EJB::EJBDataClass);      umlAssociationEnd.type        <~>               ejbAssociationEnd1.class.oclAsType(EJB::EJBDataClass);      umlAssociationEnd.association.name <~>ejbAssociationEnd1.name;      umlAssociationEnd.association <~>                ejbAssociationEnd1.type.oclAsType(EJB::EJBDataClass);      umlAssociationEnd.association <~>               ejbAssociationEnd2.class.oclAsType(EJB::EJBDataClass); } 
  11. If we cross different EJB data schemes, we only need an association end pointing out of the EJB data schema to an EJB key class. This rule formalizes a part of rule 5 in section 5.2.2.

      Transformation  UMLAssociationClassEndToEJBAssociation(UML, EJB) {  source  umlAssociationEnd  : UML::AssociationEnd;  target  ejbAssociationEnd2 : EJB::EJBAssociationEnd;  source condition  umlAssociationEnd.upper <> 1  and  umlAssociationEnd.association.                                   oclIsTypeOf(UML::AssociationClass)  and   not  umlAssociationEnd.association.getOuterMostContainer() =                      umlAssociationEnd.type.getOuterMostContainer();  target condition  ejbAssociationEnd2.lower = 1  and  ejbAssociationEnd2.upper = 1;  unidirectional;   mapping  umlAssociationEnd.type.name   <~> ejbAssociationEnd2.name;      umlAssociationEnd.composition <~>                                      ejbAssociationEnd2.composition;      umlAssociationEnd.type        <~>                 ejbAssociationEnd2.type.oclAsType(EJB::EJBKeyClass);      umlAssociationEnd.association <~>               ejbAssociationEnd2.class.oclAsType(EJB::EJBDataClass); } 
  12. An Operation in UML becomes a business method in the EJB model. This rule formalizes a part of rule 7 in section 5.2.2.

      Transformation  UMLOperationToBusinessMethod(UML, EJB) {  source  umlOperation   : UML::Operation;  target  businessMethod : EJB::BusinessMethod;  unidirectional;   mapping  umlOperation.name      <~> businessMethod.name;      umlOperation.parameter <~> businessMethod.parameter; } 
  13. UML Parameters are transformed into EJB Parameters.

      Transformation  UMLParameterToEJBParameter(UML, EJB) {  source  umlParameter : UML::Parameter;  target  ejbParameter : EJB::EJBParameter;  unidirectional;   mapping  umlParameter.name <~> ejbParameter.name;      umlParameter.type <~> ejbParameter.type; } 

At the lowest level we need to transform UML datatypes to EJB datatypes. This transformation is not defined here, but there should be a number of (predefined) transformations at the lowest level of UML to EJB datatypes. The definition below simply states that there must be such a transformation from UML to EJB datatypes.

  Transformation  UMLDataTypeToEJBDataType (UML, EJB) {  source  umlDataType : UML::DataType;  target  ejbDataType : EJB::EJBDataType;  unidirectional;  } 

10.2.1 Additional Operations

The following query operations are defined on the UML metamodel, and used in the transformations above. The definition uses the OCL 2.0 functionality to define additional operations on existing classes in a model.

  1. The operation getAllContained() returns a set of all classes that are directly or indirectly composed via a composite association, including the class itself.

      context  Class  def:  getAllContained( contained : Set(Class) ) : Set(Class) =  if  contained->includes(self)  then  result = contained  else   let  allContained = contained->including(self)  in  result = self.feature->           select(end : AssociationEnd end.composition)->           collect(type)->           iterate( containedClass : Class ; acc : Set(Class) =                                                      allContained             acc->union(containedClass.getAllContained(allContained))  endif  
  2. The operation getOuterMostContainer returns the outermost class that incorporates this class through a composition association.

      context  Class  def  : getOuterMostContainer() : Class =  if  self.feature->exists(end : AssociationEnd                                            end.otherEnd.composition)  then  result = self.feature->select(end : AssociationEnd    end.otherEnd.composition)->first().type.getOuterMostContainer()  else  result = class  endif  
  3. The operation getOuterMostContainer returns the outermost class that incorporates this association through a composition association.

      context  Association  def:  getOuterMostContainer() : Class = result = self.end->select(end : AssociationEnd                                             end.otherEnd.composition)                              ->first().type.getOuterMostContainer() 
  4. The operation getOuterMostContainer returns the outermost class that incorporates this association class through a composition association.

      context  AssociationClass  def  : getOuterMostContainer() : Class =  if  self.end->size() = 1              -- is one way navigable  then  result = self.end->first().class.getOuterMostContainer()  else  result = self  endif  


MDA Explained. The Model Driven Architecture(c) Practice and Promise 2003
Project Leadership (The Project Management Essential Library)
ISBN: N/A
EAN: 2147483647
Year: 2004
Pages: 118

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net