Carleton University, TR SCE-06-08
March 2006
A Metamodeling Approach to Pattern Specification and Detection Maged Elaasar1, 2, Lionel C. Briand1, 3, and Yvan Labiche1 1 Software Quality Engineering Laboratory (SQUALL) Department of Systems and Computer Engineering, Carleton University 1125 Colonel By Drive, Ottawa, ON K1S5B6, Canada {briand|labiche}@sce.carleton.ca 2 IBM Canada Ltd, Rational Software, Ottawa Lab 770 Palladium Dr., Kanata, ON. K2K 2E4, Canada
[email protected] 3 Simula Research Laboratory, Department of Software Engineering Martin Linges v 17, Fornebu, P.O.Box 134, 1325 Lysaker, Norway
Abstract. This report presents the Pattern Modeling Framework (PMF), a new metamodeling approach to pattern specification and detection for MOFcompliant modeling frameworks and languages. Patterns need to be precisely specified before a tool can manipulate them, and though several approaches to pattern specification have been proposed, they do not provide the scalability and flexibility required in practice. PMF provides a pattern specification language called Epattern, which is capable of precisely specifying patterns in MOF-compliant metamodels. The language is defined as an extension to MOF by adding semantics inspired from the UML composite structure diagram. The language also comes with a graphical notation and a recommended iterative specification process. It also contains features to manage the complexity of specifying patterns and simplify their application and detection in user models. Most importantly, the language is implemented using state-of-the-art technologies that are heavily used by major modeling tool vendors, thus facilitating its adoption. The report also presents a systematic way to derive a pattern detection algorithm from an Epattern specification. The algorithm can be configured by special semantics in the specification without compromising the structural definition of the pattern. This allows pattern authors to leverage their knowledge of the pattern’s target language to create more efficient detection algorithms.
1
Introduction
Model driven architecture (MDA) [1] is an approach to system development advocated by the Object Management Group (OMG). The approach starts by describing the system's specifications using a platform independent model (PIM). A PIM is usually specified in a language that is based on the Meta Object Facility (MOF), a standard by the OMG for describing modeling languages. A prominent example of such languages is the Unified Modeling Language (UML), which is well adopted by the software engineering community. Alternatives to UML also exist and are collectively
1
Carleton University, TR SCE-06-08
March 2006
referred to as Domain Specific Modeling Languages (DSML) [6], as they are more specialized and target certain modeling domains. Once a system has been specified using a PIM, a platform is then chosen to enable the realization of the system using specific implementation technologies, producing what is referred to as a platform specific model (PSM). In spite of the potential benefits of MDA including reduced development time for new applications, improved application quality, quicker adoption of new technologies into existing application and increased return on technology investment, the adoption of MDA has not picked up to its full potential yet. One reason for this is the complexity problems inherent in today's MDA tools. These tools usually appeal to the MDA savvy but fail short of meeting the expectations of the mainstream practitioners who are competent with their technologies but not necessarily with MDA. Another reason is the limited support available to the user beyond authoring their models. For instance, features that help the user inspect the quality of their models are lacking in many major MDA tools. As system models get larger and more complex, the task of inspecting their quality becomes much harder. It is now well understood that a problem detected early on in the system development life cycle is much cheaper to tackle than one discovered later on. Hence, technologies that facilitate inspecting models for quality purposes can certainly play a big role in enhancing the value of MDA. Examples of these technologies include architectural discovery [2], anti-pattern detection [10] and consistency analysis [17]. Equally important are those technologies that assure the quality of the process of going from PIM to PSM. Examples here include impact analysis [18]. One way to analyze the quality of user models is to look for instances of predefined patterns. Patterns are recurring modeling structures that are either desirable [7] or undesirable [10]. Desirable patterns represent elements of reuse at a higher level of abstraction. Therefore, trying to understand a model by its usage of patterns helps by raising the level of abstraction. Conformance to desirable patterns is expected to boost the quality of models by expediting modeling of maintainable and robust designs. On the other hand, the early identification of undesired patterns, or anti-patterns, protects against making common and expensive design mistakes. It is also a first step towards the mitigation of existing design problems. Support for patterns has started to show up in some major modeling tools like RSA [3]. One common requirement is the definition of a formalism that is used to specify patterns for tool consumption. The state of the art in this area is far yet from converging on a standard for pattern specification. In addition, there is no unanimous approach to automating pattern detection, which is another focus for this report. Pattern detection is about mining models for instances of pre-defined patterns. This report presents a new approach to precise pattern specification within a Pattern Modeling Framework (PMF). PMF uses a declarative and graphical approach to pattern specification, which is based on existing metamodeling technologies. The specification language, called Epattern, allows for the specification of patterns in MOF-compliant modeling languages using an iterative, graphical process. Epattern has inherent capabilities to manage the specification of complex patterns. It also allows for the generation of detection algorithms from the specifications. Those algorithms can be customized by pattern authors by specifying certain semantics in those specifications. PMF is
2
Carleton University, TR SCE-06-08
March 2006
implemented as a set of plug-ins to the Eclipse platform and leverages several Eclipsebased open source projects like the Eclipse Modeling Framework (EMF) [4]. The rest of this report is structured as follows. An overview of the PMF is presented in Section 2. Section 3 presents the Epattern specification language and process. An approach to generating a detection algorithm from a specification is presented in section 4. Section 5 briefly describes the tool architecture and implementation. Related works are discussed and compared to the proposed approach in Section 6. Finally, Section 7 concludes the report and discusses some of the future research directions.
2
Overview of Pattern Modeling Framework
The Pattern Modeling Framework (PMF) offers a new approach to pattern specification and detection. The framework is adopting an architecture (Figure 1) that is compatible with the OMG's 4-layer metamodeling architecture [21]. In the meta-modeling architecture, the Meta Object Facility (MOF) (M3) is used to define metamodels for various modeling languages (M2). Instance models (M1) that conform to those languages can then be defined. When these user models are deployed, user objects instantiating them are created (M0). Along the same lines, PMF defines its pattern specification language as an extension to MOF (M3). The new language is used to specify patterns in any MOF-compliant modeling language (M2). Pattern instances conforming to those patterns are hence defined in terms of instance models (M1). This conformance in architecture gives PMF the advantage of being able to specify patterns on any MOF-compliant modeling language (i.e., not only UML) and even patterns that involve multiple modeling languages and viewpoints at the same time (like patterns specified in terms of both the UML class and interaction diagrams at the same time). The pattern specification language provided by PMF is called Epattern and is defined as an extension to the MOF 2.0 specification [9]. The EMF [4] provides a platform specific realization of a subset of MOF called EMOF, whose semantics resemble those of simple UML class diagrams. This realization is called Ecore and is integrated with the Eclipse platform. Ecore is widely used today to specify various language metamodels including that of UML 2.0, which is available as an open source project [8] and used by modern UML tools like RSA [3] and EclipseUML [20]. EMF provides tooling for specifying Ecore metamodels and generating corresponding java APIs for them. The Epattern language is realized as an extension to Ecore, which gives PMF two advantages: the ability to reuse a lot of the tools provided by EMF and the ability to provide pattern specification capabilities in modern modeling tools. The Epattern language contains semantics/constructs that are inspired from similar ones in UML 2.0 composite structure diagrams (CSD) [5] and that are used in Epattern to specify patterns. CSDs were recently added to UML to depict the internal structure of a classifier (such as a class, a component, or a collaboration), including the interaction points of the classifier to other parts of the system. While class diagrams model a static view of class structures, including their attributes and operations, CSDs model specific usages of these structures. For instance, classes are viewed as
3
Carleton University, TR SCE-06-08
March 2006
parts fulfilling some roles, and roles are interconnected to represent relationships that might or might not be reflected by static diagrams. One use of CSDs, discussed in [4], is to describe patterns in UML instance models (M1). However, as CSDs are part of the UML 2.0 metamodel (M2), they cannot be used to specify general pattern structures involving elements of that same metamodel, or any other M2 metamodel. To specify such patterns you need similar capabilities at level M3. To address this problem the Epattern language, purportedly defined at the M3 level, reuses some of the CSD semantics and apply them to specify patterns in language metamodels. Once patterns are specified in Epattern, their specifications can be used to derive various types of algorithms for the purpose of pattern application and detection. The language contains some semantics that can be used by pattern authors to fine tune the generation of these algorithms without affecting the structural definition of patterns. This allows pattern authors to leverage their knowledge of the pattern’s target language to make the algorithms more efficient. One type of algorithms, which is of interest in this report, is a pattern detection algorithm. This algorithm is used to inspect user models for instances of pre-defined patterns. Furthermore, PMF includes a graphical, stepwise, and iterative process to guide the user for specifying patterns and alleviate their complexity. Other features of the framework, which are outside the scope of this report due to space limitations, include the ability to generate a detection algorithm for each specification and use it to detect and visualize pattern instances in user models.
Figure 1 Pattern specification using OMG’s metamodeling architecture
3
Epattern Specification Language
The Epattern language can be used to formally specify patterns on MOF-compliant modeling languages. As described in Section 2, Epattern is designed as an extension to MOF and realized as an extension to Ecore, which includes the concepts necessary to specify metamodels of MOF-compliant languages including UML 2.0. In the remainder of the report, we refer to concepts defined by Ecore rather than MOF as a simplification because the terminology used there is closer to the one for Epattern.
4
Carleton University, TR SCE-06-08
March 2006
A simplified metamodel of Ecore is shown in Figure 2. All classes in the ECore metamodel are subclasses of EModelElement (not shown on the diagram to avoid cluttering). A concept in a modeling language is specified using an EClassifier, which is a named element that has two subclasses: an EClass representing a complex type (e.g. ‘Property’ in UML) and an EDatatype representing a simple type (e.g., ‘AggregationKind’ in UML). EClassifiers are physically arranged in hierarchical namespaces represented by EPackages. EClasses can either represent classes (including abstract ones) or interfaces and may be organized into inheritance hierarchies. The structure of an EClass is specified with a set of EStructuralFeatures, representing the properties of a class, while its behavior is specified with a set of EOperations, representing the operations of a class. An EStructuralFeature is a named and typed element that has two subclasses: an EAttribute, typed with an EDataType (e.g. ‘Property.aggregation’ in UML), and an EReference, typed with an EClass (e.g. ‘Property.type’ in UML). An EReference can represent either a containment reference, i.e., its value is owned by the class, or a non-containment reference, i.e., its value is referenced by the class. An EReference may also point to an opposite EReference if it represents one end of a bidirectional association between two classes. An EOperation is a named element that has an EClassifier return type. It also has a list of EParameters that are named and typed with EClassifiers.
Figure 2 A simplified Ecore metamodel The Epattern language defines semantics for pattern specification that extend off those of Ecore. The remainder of this section uses a working example (Section 3.1) to explain these semantics (Section 3.2), illustrate their graphical notation (Section 3.3), and describes a recommended process for using them to specify patterns (Section 3.4). 3.1 Working Example The example is a simple variant of the well-known Gang of Four (GoF) composite pattern [7], shown in Figure 3. The pattern’s M2 target language is UML 2.0. It is classified as a structural pattern and is used to allow a client to treat both single components and collections of components identically. The pattern highlights several roles: a ‘component’ role representing an instance of UML Interface, a ‘leaf’ role
5
Carleton University, TR SCE-06-08
March 2006
representing an instance of UML Class that implements the ‘component’ interface, a ‘composite’ role representing an instance of UML Class that implements the ‘component’ interface and also composes instances of the same interface, and finally a ‘compose’ role representing an instance of UML Operation defined by the ‘composite’ class and used to compose ‘component’ instances.
Figure 3 A simplified GoF composite pattern
3.2 Semantics The metamodel of Epattern, shown in Figure 4, contains new metaclasses that subclass others in the Ecore metamodel. The following items describe the semantics of these new metaclasses (a feature level description can be found in appendix [24]A): EPattern: subclasses EClass and represents a pattern’s context. A pattern is represented as an instance of EPattern (M3) and therefore an metaclass (M2) at the same level as the target metamodel. Representing a pattern as a metaclass has big advantages including the ability to build pattern inheritance hierarchies with varying levels of abstraction, the ability to define complex patterns by composing simpler ones, the ability to use namespaces to create pattern families, the ability to be a context for pattern constraints, and the ability to represent pattern instances as objects of the pattern metaclass. In the example, the composite pattern is represented by an EPattern instance. ERole: subclasses EReference and represents a pattern role. Representing a role as a reference helps characterize (using name, type and multiplicity features) M1 instances that play that role in a pattern instance. A role can be typed (through eReferenceType that is inherited by ERole from EReference: Figure 2) with an instance of EClass (M2) capturing elements in the pattern’s target metamodel. To implement pattern composition, a role can simply be typed with an instance of EPattern (which subclasses EClass) to represent a composed pattern. Additionally, the multiplicity feature of a role allows the support of some common role semantics, namely the ability to define optional roles (e.g. leaf) and collection roles, which can be bound to more than one instance from the user model (e.g. leaf too). A role with multiplicity lower bounds of 0 and 1 are considered optional and required, respectively. Also, a multiplicity upper bound of * defines a collection role, whereas a value of 1 defines a singular role. Yet another major advantage of this role representation is simplifying the process of role binding down to the simple process of as-
6
Carleton University, TR SCE-06-08
March 2006
signing a value to a feature in a pattern metaclass instance. One more advantage is the ability to reference roles in a pattern’s constraint just as regular features of the constraint’s context (which is a pattern instance at level M1). Moreover, roles are connectable, i.e., a role can be connected to other related roles in the pattern to formalize their relationship, as described in the next paragraph. In the example, the main identified roles (component, composite, leaf and compose) are all represented by instances of ERole. EConnector: subclasses EModelElement and represents a connector between two pattern roles. A connector characterizes (through its type) a relationship between M1 model elements bound to its two roles in a pattern instance. The relationship characterized by a connector’s type is nothing but an EReference instance from the pattern target metamodel. This instance represents a directed relationship between two EClass instances from the metamodel. Since it is directed, a connector specifies which of its ends represents the source and which represents the target of the reference through its eSourceRole and eTargetRole features. If one or both roles happen to represent a composed pattern (i.e. typed with EPattern), the connector also specifies which port (refer to the EPort metaclass being defined next) instance belonging to the composed pattern it is connecting to through the eSourcePort and eTargetPort features. In the example, various connectors are represented by instances of EConnector: one from composite to component representing an implementation, one from leaf to component representing an implementation, one from composite to component representing a composition, and one from composite to compose representing an owned operation. EPort: subclasses EReference and represents a connection point on the pattern’s boundary that is used in pattern composition. When patterns compose each other, roles in the composing pattern are connected to ones in the composed pattern. However, this connection cannot be direct as roles are encapsulated within their defining pattern. To expose these roles and make them available for connection to roles in the composing pattern, ports are specified for them in the pattern. Note that not all roles need to have ports; rather only those that are considered public by the pattern author. An instance of EPort connects (though the eDelegatingRole feature) to an instance of ERole in the pattern. If that role represents a composed pattern, the port needs to also specify which port (through the eDelegatingPort feature) on the composed pattern it is connecting to in turn. An EPort is represented as a reference since it characterizes (through its name and type) the role it is connecting to. A port’s type has to match that of the role it is connecting to although this restriction may be removed in the future1. In the example, two roles are anticipated to be connected to if this pattern is composed; these are the composite and component roles. Therefore, an instance of EPort is specified for each one of them. EConstraint: subclasses EOperation and represents a well-formedness constraint (a semantic rule) for a pattern. A constraint has a boolean expression that is specified in a constraint language like EMOF OCL [19]. The context of the constraint is 1
A port in CSD may have a different type if connected to its role with a typed connector [5].
7
Carleton University, TR SCE-06-08
March 2006
nothing but an instance of a pattern, which makes pattern roles accessible in the expression as regular features of the context. This has the added advantage of being able to specify constraints between one or more pattern roles. For better formalization, an instance of EConstraint references the instances of ERole that it is constraining. In the example, two constraints can be specified with instances of EConstraint: the first one is asserting that the association between the composite and the component roles is really a ‘composition’ and that it has a ‘many’ multiplicity; the second constraint is asserting that an operation bound to the compose role has exactly one parameter whose type matches the interface of the component role. EAssociation: subclasses EClass and represents a new derived relationship between two EClass instances from the pattern’s target metamodel. The main rationale for defining EAssociations is to simplify pattern specification by introducing high level relationships that can be specified between pattern roles. Without this concept, only low level relationships represented by EReferences from the metamodel can be used between roles. A problem usually occurs when no direct EReferences exist between EClass instances in the metamodel that are types of related roles. In this case, a pattern author would need to work around that by introducing a set of intermediary roles increasing the complexity of the specification. An EAssociation is basically a namespace that defines two association ends (refer to EAssociationEnd metaclass being defined next). These ends characterize a new relationship between two EClass instances from the target metamodel. An EAssociation is the container of EReferences and hence has to subclass EClass (Ecore restriction) [4]. In the example, two instances of EAssociation are specified as they represent high level relationships that are used by the composite pattern but do not map to direct EReferences in the Ecore UML metamodel. The first one is the ‘Implementation’ relationship between the composite/leaf and component roles, and the second is the ‘Composition’ relationship between the composite and component roles. EAssociationEnd: subclasses EReference and represents one end in an EAssociation. Representing an end as a reference makes it straightforward to use as a type for EConnectors in pattern specifications. An EAssociationEnd is typed with an EClass instance from the target metamodel, representing one end of the new relationship, and is given a name and a multiplicity. If an end’s EAssociation represents a bidirectional relationship, its opposite EReference is set to the other EAssociationEnd in the same association. One main difference between EReference and EAssociationEnd is that the former is owned by an EClass representing one end of a relationship and typed with the other, while the latter is always owned by an EAssociation and the two associtated EClasses are derived from the types of both ends of the association. Moreover, an end represents a derived reference, and hence has a derivation expression specified in a language like EMOF OCL [19]. The type of the expression is the same as that of the end and the context of the expression is an instance of the type of the opposite end. In the example, the ‘Implementation’ association has two EAssociationEnd instances typed with ‘BehavioredClassifier’ and ‘Interface’ from the UML metamodel. Also, the ‘Composition’ association has two EAssociationEnd instances typed with ‘StructuredClassifier’ and ‘Type’ from the UML metamodel.
8
Carleton University, TR SCE-06-08
March 2006
Figure 4 The Epattern metamodel
3.3
Notation
The notation for Epattern is based on the notation of the class and composite structure diagrams of UML 2.0. This makes it easier to leverage already existing UML tools in pattern specification. Table 1 below illustrates this notation. Table 1 Epattern notation EPattern: a frame with a name compartment and a structure compartment showing the pattern's structure. Other optional compartments could be shown for the pattern's super types, roles, ports, connectors and constraints. ERole: a box containing a compartment that shows the role’s name, type and multiplicity (lowerBound…upperBound if different from 1…1). The box is solid if the role represents a pattern composition and dashed otherwise. Also, the box has a structure compartment if it represents a pattern composition. EPort: a small filled box on the frame of the structure compartment. The box has a floating name label that shows the name and type of the port. The box is either connected directly to a delegating role (left port in figure) or to a delegating role’s port if the role represents a composed pattern (right port in figure). EConstraint: a sticky note with a name compartment and an expression compartment. The note is connected to the constrained roles with dotted lines.
name:eReferenceType
name: eReferenceType
b
a name
expression
9
Carleton University, TR SCE-06-08 EConnector: a directed arrow that goes from the pattern’s source role to its target roles. If a connector has a source/target port, the line connects that port on the corresponding role. The connector has floating labels showing the connector’s type reference (eType) and its opposite (if any). It also has a little box with a number at each end indicating the order of the connector in the attached role’s eConnectors collection. EAssociation: a line connecting two EClass instances from the pattern target language metamodel. The line has a floating name label, two floating end name labels, and two floating end multiplicity labels. The line can be shown as an arrow if the association is directed.
March 2006
a: A
1
3
eType
A
*
name
end1.name
b: B
eType.eOpposite
*
B
end2.name
3.4 Specification Process We propose a recommended iterative specification process for using the Epattern language. The outcome of this process is a formal pattern specification. The process is depicted in Figure 5 and explained in the following suggested order of steps. In practice, a pattern author may move from any step to any other step in an iterative fashion. The composite pattern example is used to illustrate the process and the notation provided above.
Figure 5 The Epattern specification process 3.4.1 Understand Pattern Structure Before a pattern is specified with Epattern, there has to be a good understanding of its structure. A pattern's structure is a set of roles, typed with M2 metaclasses from a target metamodel and related to each other through metareferences. In our example, the target metamodel is UML 2.0, simplified in Figure 6 for the purpose of our example. The class diagram in Figure 3 reveals the following roles: component of type ‘Interface’, composite and leaf of type ‘Class’ and compose of type ‘Operation’. The relationships between these roles include an ‘implementation’ between leaf/composite and component, which is realized by an element of type ‘InterfaceRealization’ (metaclass in Figure 6). The element is related to the interface by the metareference ‘InterfaceRealization.contract’ and to the class by the metareference ‘BehavioredClassifier.interfaceRealization’. Our syntax for metareference 'X.Y' refers to an EReference named Y in an EClass named X. Another relationship is ‘composition’ between composite and component, which is realized by an element of type ‘Property’. The element is related to the class by the metareference ‘StructuredClassifier.ownedAttribute’ and to the interface by the metareference ‘Property.type’. Finally, composite is related to compose directly by metareference ‘Class.ownedOperation’.
10
Carleton University, TR SCE-06-08
March 2006
Figure 6 A partial, simplified UML 2.0 metamodel 3.4.2 Create EPattern Once there is a good understanding of the pattern’s structure, the pattern can be specified using the Epattern metamodel (M3). The first step is to create an instance of EPattern in an EPackage that belongs to a pattern model. The instance is given a name representing the pattern. In our example, an instance is created and named ‘CompositePattern’. A complete specification of this pattern is shown in Figure 7 and described below. 3.4.3 Add ERoles Once an Epattern is created, every pattern roles identified in step 1 is modeled by an instance of ERole in the pattern’s eRoles collection. Each ERole instance is given the name of the role, and typed, through its eReferenceType feature, with an EClass instance representing the type of the role in the target metamodel. If the role represents a composed pattern, it is typed with an EPattern instance instead, and its containment feature is set to true. In addition to the main roles identified in step 1, some intermediary roles might be initially needed to allow the main roles to be connected by connectors typed only with EReferences from the metamodel. In our example, ERole instances for the main roles (component, composite, leaf and compose) identified in step 1 are created. In addition, based on the metamodel in Figure 6, instances for intermediary roles are needed to connect the main roles. Two such instances typed with ‘InterfaceRealization’ are needed to represent the implementation relationship between the composite/leaf and component roles: the former role is a Class, the latter role is an Interface and those two metaclasses are related through InterfaceRealization in Figure 6. The ERole instances are named ‘realization1’ and ‘realization2’. For similar reasons, another ERole instance typed with ‘Property’, and named ‘children’, is needed to represent the composition relationship between the composite and component roles. All our role instances have their multiplicity set to ‘1…1’ except for the leaf role, where it is set to ‘*’, indicating that the role is optional and represents a collection. 3.4.4 Add EConnectors The next step after creating roles is connecting them by EConnector instances. An instance is created in the pattern’s eConnectors collection to specify every identified relationship in step 1 (and in previous specification phases) between pattern roles. Instances of source and target roles are assigned to the connector’s eSourceRole and
11
Carleton University, TR SCE-06-08
March 2006
eTargetRole features. If one or both roles represent composed patterns, i.e., typed with EPattern, the connector’s eSourcePort and/or eTargetPort features are also set to instances of EPort owned by the composed EPattern. The connector’s type is set to an EReference from the target metamodel representing a directed relationship between the EClass instances typing the connector’s source and target roles (or ports if specified). In the example, several connectors are specified using metareferences in Figure 6: 1) two connectors typed with ‘InterfaceRealization.contract’ from ‘realization1’/’realization2’ to ‘component’; 2) two connectors typed with ‘BehavioredClassifier.interfaceRealization’ from ‘leaf’/‘composite’ to ‘realization1’/‘realization2’; 3) a connector typed with ‘StructuredClassifier.ownedAttribute’ from ‘composite’ to ‘children’; 4) a connector typed with ‘Property.type’ from ‘children’ to ‘component’; and 5) a connector typed with ‘Class.ownedOperation’ from ‘composite’ to ‘compose’. 3.4.5 Add EPorts Once pattern roles have been specified, ports are added to expose some roles that are considered public. For each such port, an instance of EPort is added to the pattern’s ePorts collection. The instance is connected to a role through its eDelegatingRole feature. If the role represents a composed pattern, i.e., typed with EPattern, the instance’s eDelegatingPort feature is also set to an EPort instance owned by the composed pattern. Then the port is given a name that correlates to its connected role and is typed with the same type of that role (or port if specified). In our example, two ports are specified: ‘componentPort’ connected to ‘component’ and typed with ‘Interface’ and ‘compositePort’ connected to ‘composite’ and typed with ‘Class’. 3.4.6 Add EConstraints After the basic pattern structure is specified, well-formedness constraints are added. Each constraint is represented by an instance of EConstraint in the pattern’s eConstraints collection. A constraint is given a name and a boolean expression in a constraint language. The constraint’s eConstrainedRoles feature is then set to the ERole instances constrained by the constraint. In our example, two constraints are specified. The first is named ‘composition’ and connected to the ‘children’ role, and is specified in OCL as follows: ‘children.aggregation=AggregationKind.Composite and children.upperBound=-1’ (the second conjunct specifies a ‘many’ multiplicity). The second is named ‘parameter’ and connected to both ‘component’ and ‘compose’ roles: 'compose.ownedParameter->size()=1 and compose.ownedParameter->at(1).oclIsKindOf(component)'. Their meaning was already provided above (Section 3.2). 3.4.7 Reduce Pattern Complexity Pattern specifications can get large and complex. Various features are provided in Epattern to manage this complexity including specifying patterns by inheritance and composition, refactoring common constraint logic in operations and eliminating intermediary roles through derived associations. This last feature can be achieved by the specification of EAssociations. An instance of EAssociation is created in an EPackage that belongs to a pattern model and given a name corresponding to the represented
12
Carleton University, TR SCE-06-08
March 2006
relationship. After that, two instances of EAssociationEnd are created in the association’s eAssociationEnd collection. Every such instance is typed with an EClass from the target metamodel and given a name that corresponds to the role played by that end of the association. The end’s multiplicity is then specified along with its navigable feature. Every navigable end represents a derived reference from the end’s EClass type to the other end’s EClass type. In this case, an end gets a derivation expression in a language like OCL to derive M1 instances conforming to the end’s type from the context of an instance conforming to the other ends’s type. If both ends are navigable, they reference each other through their eOpposite feature. Once ends are specified, complex pattern specifications can be refactored to use EAssociationEnd rather than EReferences instances to type connectors. In our example, two instances of EAssociation are specified: the first is ‘Implementation’ between ‘BehavioredClassifier’ and ‘Interface’ and is used to type a connector directly from ‘compose’/‘leaf’ to ‘component’, whereas the second is ‘Composition’ between ‘StructuredClassifier’ and ‘Type’ and is used to type a connector from ‘composite’ to ‘component’. The simplified pattern specification is shown in Figure 8. The figure also shows (bottom) the specification of the two derived associations.
Figure 7 Epattern specification for composite pattern
13
Carleton University, TR SCE-06-08
March 2006
Figure 8 Simplified Epattern specification for composite pattern
4
Epattern Detection Algorithm
A pattern specification, which is an instance of the Epattern metamodel, is defined at the M2 level of the metamodeling architecture. Therefore, an instance of a pattern, where the pattern roles are bound to specific elements from the user model, is defined at the M1 level of the same architecture. Instances are created by instantiating classes representing their types. Thus, to create a pattern instance, there has to be a class representing the pattern type to instantiate. The EMF framework provides facilities to generate java classes that correspond to types at the M2 level. The generation is done by mapping instances of the Ecore metamodel to equivalent java language constructs. The PMF framework extends this mapping to the Epattern metamodel to generate java classes that represent user-specified patterns. Instances of these pattern classes can then be used by algorithms derived from the same pattern specifications. For example, a pattern application algorithm takes a pattern instance, where role bindings are specified, and performs changes to the user model to make these roles conform to the pattern’s structure. On the other hand, a pattern detection algorithm performs the reverse operation. It takes a user model, tries to detect structures of elements inside it that match the pattern’s structure, and uses them to create pattern instances and specify their role bindings. Section 4.1 discusses the extended mapping by PMF used to generate java classes corresponding to pattern specifications (M2 level). Section 4.2 elaborates on a new
14
Carleton University, TR SCE-06-08
March 2006
mapping by PMF used to generate a query class implementing a detection algorithm from a pattern specification. Both of these sections use the composite pattern example introduced in section 3.1 to illustrate the ideas. Finally, section 4.3 walks through an example of detecting pattern instances in a user model using the generated query class. 4.1 Epattern Instance Classes The EMF framework provides a mapping from Ecore to java, which is used to generate java code for the EClass instances defined in Ecore models. Since a pattern is specified as an EPattern, which is defined as an extension of EClass, it enjoys all the code generation facilities provided by EMF for EClasses. However, as EPattern has more semantics, PMF extends the code generation mapping to handle those extra semantics. The following items defines the mapping from Epattern to java using the composite pattern specification in Figure 8 as an example (the resulting java classes and interfaces are shown in Figure 9 but the interface method implementations are not shown for brevity):
EPattern maps to a java interface with the same name and an implementation class that implements that interface. In the example, it maps to ‘CompositePattern’ interface and ‘CompositePatternImpl’ class. ERole maps to an attribute in the pattern class with the same name. If the role has multiplicity ‘many’, the type of the attribute would be a java List, otherwise the type matches that of the role. Corresponding getter and setter methods are added to the pattern interface/class. If the role’s multiplicity is ‘many’, only a getter is added since the List API can be used to modify the values. In the example, all four roles (component, composite, leaf and compose) map to attributes in the class and getter and setter methods in both the class/interface. Notice that the ‘leaf’ role gets only a getter since it has a ‘many’ multiplicity. EPort maps to a getter method in the pattern interface and class. An EPort is defined as a “derived” and “un-settable” EReference, which means it does not get its own attribute in the class, it does not get a setter method, and the implementation is user defined. In this case, the implementation delegates to that of its delegating role/port. In the example, two getter methods are defined in the interface/class corresponding to the two ports ‘componentPort’ and ‘compositePort’. The implementation of the ‘getComponentPort’, for instance, calls the‘getComponent()’ method. EConstraint maps to a boolean method with the same name prefixed by ‘check’ in the pattern interface/class. The implementation is based on the constraint’s language and the expression. If the language is OCL for example, the expression is sent to the EMOF OCL [19] interpreter provided by EMF [4] for execution and the result is returned. In the example, the ‘checkParameter’ method is generated for the ‘parameter’ constraint.
15
Carleton University, TR SCE-06-08
March 2006
EAssociation maps to a java interface with the same name and a corresponding implementation class. In the example, the two associations map to the interfaces ‘Implementation’ and ‘Composition’ and the classes ‘ImplementationImpl’ and ‘CompositionImpl’. EAssociationEnd (when navigable) maps to a getter method with the same name in the association interface/class. The method is typed with an interface corresponding to the type of the end. It also takes a parameter that is typed with an interface corresponding to the type of the other association end. The implementation of the method is based on the end’s derivation language and expression. If OCL is used, the expression is sent to the OCL interpreter to execute. In the example, all ends (‘implementingClassifier’, ‘implementedInterface’, ‘composingClassifier’, and ‘composedType’) are navigable and thus we get a getter method for each end in its corresponding interface/class.
Figure 9 The composite pattern classes and interfaces
4.2 Epattern Query Class The PMF framework allows for the generation of a detection algorithm that corresponds to each pattern specification. The algorithm’s goal is to detect structures of elements in user models (level M1) that conform to the structure depicted by a pattern specification (M2). The algorithm takes as input an iterator over user model elements and returns as output a collection of zero or more pattern instances. To accomplish that, the algorithm navigates through the user model (a graph) guided by the structure of a pattern (another graph), making the algorithm similar in essence to graph matching algorithms [22]. The control flow graph (CFG) of a given pattern’s detection algorithm is determined by certain semantics in its specification. More specifically, the algorithm uses a depth first strategy to traverse the pattern specification starting from a given port. Thus the chosen port in addition to the order of constraints and connectors at each role affects the CFG of the algorithm. These semantics do not affect the es-
16
Carleton University, TR SCE-06-08
March 2006
sence of the specification but help pattern authors control the derived algorithms, which is an advantage of this approach. A high level activity diagram for the detection algorithm is shown in Figure 10. The algorithm is generated by PMF for each pattern specification in the form of a java ‘query’ class. Every step of the algorithm corresponds to a method on the query class. The implementation of every such method is derived from the semantics of the corresponding element in the pattern’s specification. The mapping from the semantics of an Epattern specification to the corresponding query class is explained in the following subsections (along with the numbered steps from the activity diagram) using the example pattern specification in Figure 8. In that example, a class named ‘CompositePatternQuery’ is generated as shown in Figure 11. 4.2.1 EPort Execute Method The detection algorithm starts execution at a given input port, whose EPort maps to an ‘execute’ method (step 1), named after the port, on the query class. An input port is one from which all roles are reachable through traversable connectors. The method takes an iterator on model elements as input and returns a collection of pattern instances as output. Its implementation consists of several steps. First (step 1.1), it prepares the candidate elements, which depends on whether the port’s delegating role represents a composed pattern or not. If it does, it calls the corresponding query’s ‘execute’ method and uses its result as candidates; otherwise the passed model elements are considered as candidates. Second (step 1.2), the method creates a new instance of its pattern’s java class. Finally (step 1.3), the method passes both the instance and the target elements to the ‘bind’ method (defined next) of its delegating role. The collection of pattern instances returned from this ‘bind’ method call is the one that is returned back to the caller of the query’s ‘execute’ method. In the example, two methods corresponding to the two ports (componentPort and compositePort) are generated: ‘executeFromComponentPort’ and ‘executeFromCompositePort’. 4.2.2 ERole Bind Method An ERole maps to a ‘bind’ method (step 2), named after the role, on the query class. The method takes an iterator on model elements and a pattern instance as input and returns a collection of pattern instances as output. The implementation of the method consists of several steps. First (step 2.1), it iterates over the model elements, checking their conformance to the role’s type and ignoring those that do not conform. Second (step 2.2), the method checks if the passed pattern instance already has bindings to this role. If it does, the method then checks if the bound elements are a subset of the conforming objects and returns a collection containing only the passed instance if they are; otherwise, an empty collection is returned. On the other hand, if the role is not bound, the method then binds the conforming elements to the role. If the role represents a collection, all the conforming elements are bound together in the passed pattern instance. Otherwise (the role is singular), the method duplicates the passed pattern instance and binds one conforming element to each duplicate. Third (step 2.3), the method takes each resulting pattern instance and calls with it the ‘verify’ method (defined next) of the role’s constraints in sequence. Any instance failing a constraint is
17
Carleton University, TR SCE-06-08
March 2006
ignored right away. Finally (step 2.4), the method takes the verified instances and calls with each the ‘traverse’ method (defined later) of the role’s traversable connectors in sequence. Every call to a ‘traverse’ method returns a collection of instances, which are used to call the next connector in a nested fashion. The final collection of instances is returned from the method. However, if the collection is empty and the role is optional, a collection containing a single instance with the role unbound is returned. In the example, four methods are generated for the four roles: ‘bindComponent’, ‘bindComposite’, ‘bindLeaf’, and ‘bindCompose’. 4.2.3 EConstraint Verify Method An EConstraint maps to a ‘verify’ method (step 3), named after the constraint, on the query class. The method takes a pattern instance as input and returns a boolean as output. The implementation of the method first (step 3.1) verifies that all the constraint’s (non-optional) roles are bound and returns true if not. Otherwise (step 3.2), the method checks the constraint by calling its corresponding ‘check’ method on the pattern class and returns the result. In the example, the ‘verifyParameter’ method is generated for the ‘parameter’ constraint. 4.2.4 EConnector Connect Method An EConnector maps to one or two ‘connect’ methods (step 4), named after the connector’s start and end roles, on the query class. The number of methods depends on whether the connector is traversable in one or two directions. A connector is traversable in a given direction if there is a way to derive candidate elements to its ending role from an element bound to its starting role. Three traversing cases are supported: 1) a connector traversed from its source to its target using its type reference, 2) a connector traversed form its target to its source using its type reference’s non-derived opposite reference, and 3) a connector traversed from its target to its source using its non-derived type reference by looking up in a reverse reference map maintained by EMF for each such reference (the map contains all the referencing elements to a given element using a specific reference). Additional traversing requirements include that the starting role of a connector has to have an upper bound of 1 (i.e. not a collection) and that a connector’s ending port (if any) is an input port. A ‘traverse’ method takes a pattern instance as input and returns a collection of instances as output. The implementation of the method consists of several steps. First (step 4.1), the method reads the element bound to the starting role. If the connector has a starting port, i.e. the role represents a composed pattern, the method reads the element form that port. Second (step 4.2), the method derives the elements at the opposite end using one the traversing approaches mentioned above. Third (4.3), the connector prepares the candidate elements, which depends on whether the connector’s ending role represents a composed pattern or not. If it does, it calls the corresponding query’s ‘execute’ method and uses its result as candidates; otherwise the derived model elements are considered as candidates. Finally (step 4.4), the method passes an iterator to the candidate elements along with the passed pattern instance to the ‘bind’ method of the ending role and returns the (pattern instances) result back.
18
Carleton University, TR SCE-06-08
March 2006
In the example, several methods are generated: 1) two representing the implementation connector between the ‘composite’ and ‘component’ roles, 2) one representing the connector from the ‘leaf’ to ‘component’ roles (as the other direction is not traversable due to the ‘leaf’ role being a collection), 3) two representing the composition connector between the ‘composite’ and ‘component’ roles and 4) two representing the connector between the ‘composite’ and ‘compose’ roles.
Figure 10 A high level activity diagram of the detection algorithm
Figure 11 The composite pattern query class 4.3 Epattern Detection Example An example of a composite pattern instance is shown in Figure 12. The instance represents an application of the composite pattern to commands in a UML user model. In
19
Carleton University, TR SCE-06-08
March 2006
this example, the following elements are identified: the ‘Command’ UML interface playing the ‘component’ role, the ‘CompositeCommand’ UML class playing the ‘composite’ role, the ‘UndoCommand’ and ‘RedoCommand’ UML classes playing the ‘leaf’ role and finally the ‘addCommand’ UML operation playing the ‘compose’ role. When the CompositePatternQuery class is run against a user model containing these elements, we get the composite pattern instance in Figure 13. If the ‘leaf’ role has a multiplicity upper bound of 1 (vs. *), we get the pattern instances in Figure 14 instead.
Figure 12 The composite command class diagram
Figure 13 A composite pattern instance when leaf is a collection role
Figure 14 Two composite pattern instances when leaf is an individual role
5
Tool Architecture and Implementation
The PMF framework is implemented as a set of java plug-ins to the Eclipse platform as shown in Figure 15. It uses two Eclipse-based open source frameworks, namely the Eclipse Modeling Framework (EMF) [4] and the Graphical Editing Framework (GEF) [23]. It uses the former framework to create the Epattern metamodel, generate corresponding java model APIs and generate basic user interface (UI) components to edit the Epattern instances like a tree viewer and a property sheet page, as shown in Figure 16. It uses the latter framework to create a much elaborate diagram editor for the instances, as shown in Figure 17.
20
Carleton University, TR SCE-06-08
March 2006
Figure 15 PMF and its implementation dependencies The EMF framework provides facilities to specify metamodels using Ecore. PMF uses these facilities to specify the Epattern metamodel, which means that Epattern is both specified using Ecore and as an extension to Ecore (refer to section 3). Once specified, EMF provides code generation for metamodels. Several kinds of Eclipse plug-ins can be generated: a model plug-in containing java interfaces that correspond to the metamodel EClasses along with their implementation classes that also allow for model serialization in the XMI [24] format, an edit plug-in containing basic UI support for editing metamodel instances, and an editor plug-in containing a simple treebased editor for these instances. PMF generates these three types of plug-ins for the Epattern metamodel.
Figure 16 Epattern tree viewer and property sheet
21
Carleton University, TR SCE-06-08
March 2006
Figure 17 Epattern specification editor However, as the editor generated by EMF is not suitable for Epattern’s graphical notation, another framework called GEF is used to enhance the editor. GEF allows for building rich diagram editors for arbitrary models using a model-view-controller architecture. It provides class hierarchies that can be further extended to fully define the view and controller parts of the architecture, whereas it leaves the model part undefined. PMF defines the model part to be the java model interfaces generated for Epattern by the EMF framework. It also creates specializations of viewers and controllers for all the Epattern concepts. This results in the diagram editor shown in Figure 17. Users of PMF are expected to use the Epattern graphical editor to specify their patterns and serialize them to pattern repositories in XMI format. As Epattern is an extension of Ecore, its instances (the patterns) are defined at the metamodel level (M2). This allows PMF to reuse EMF’s code generation capabilities on Epattern instances, but with extended code generation templates to handle Epattern’s added semantics (refer to section 3.2). This gives PMF users the ability to generate java interfaces and classes that correspond to their pattern specifications as explained in section 4.1. Additionally, another code generation template is provided by PMF for generating a query class that implements a detection algorithm, as explained in section 4.2.
6
Related Works
Pattern specification is a common denominator to most work in applied pattern research. Various approaches have been proposed for pattern specification [15]. One category of approaches, that our work also belongs to, uses metamodeling techniques. The work presented in [12][11] proposes specifying a pattern as a UML 1.5 metacollaboration with pattern roles typed with M1 classes stereotyped and named after metaclasses. This obviously prevents writing constraints for such roles as
22
Carleton University, TR SCE-06-08
March 2006
their type information is not available at level M1. Also a new dependency is introduced to describe role bindings as roles are not typed with real metaclasses. The work in [13] introduces the RBML language, which suggests specifying UML patterns as specialized metamodels that characterize M1 models. Pattern roles get their base types by subclassing metaclasses from the UML metamodel. One problem with specifying a pattern as a metamodel is a lack a context to the specification. This deprives the specification from OO complexity management features like inheritance and composition. It also forces role binding to be done through mapping, which is not as convenient as our solution. Another proposal is found in [14], where the DPML language is used to visually specify patterns as a collection of participants, dimensions (multiplicities), relationships and constraints. One draw back is the non-standard notation adopted by the language. Another problem is the restriction of the participants and relationships to predefined types from the UML domain, which limits the scope of the patterns definable by the language. Also, there is no mention of complexity management features. Another approach [16] provides a metamodel to specify patterns. This metamodel is first specialized with pattern related concepts before being instantiated to produce an abstract model (pattern specification) which is either instantiated to create a concrete model (pattern instance) or parameterized to use in pattern detection. One major problem with this approach is using non-standard metamodels. Concepts from a target language like UML are added to the pattern metamodel and defined to subclass pattern related metaclasses which implement functionality needed for pattern application and detection. Enough concepts to specify the Gof patterns are defined. To summarize the key differences with our PMF, most of the above approaches lack the ability to specify patterns for languages other than UML or viewpoints other than the class diagram. They also lack features that help alleviate the complexity of pattern specification and typically do not follow properly the recommended strategy of OMG for separating properly the meta levels, thus leading to unnecessary assumptions and loss of flexibility in expression the patterns. Another problem is the inability of theses approaches to give pattern authors the tools to refine patterns in a stepwise manner and explicitly model relationships among patterns (e.g., though inheritance and composition).
7
Conclusions and Future Works
Detecting (un)desirable patterns is an important component of model analysis. But patterns need to be formally specified before they can be manipulated by tools. The specification approach should ideally support patterns of any MOF-compliant language and be able to scale to patterns of different complexities. In this report, we present the PMF framework and its Epattern specification language that specifically targets such properties. In the context of the OMG's 4-layer metamodeling architecture, Epattern has M3 semantics used to specify patterns at the M2 level. A pattern is basically specified as a metaclass. This gives it the ability to be instantiated, inherited and composed. We are currently trying to specify all the GoF patterns with Epattern.
23
Carleton University, TR SCE-06-08
March 2006
Some of these patterns need more than one viewpoint (e.g. class and sequence diagrams) to be formally specified, which should test Epattern’s ability to cross the viewpoint boundaries. Also, we anticipate that more semantics may be added to the language to facilitate the specifications of more complex patterns. Beside inheritance and composition, we are experimenting with genericity (pattern templates) and refinement (redefining inherited structures from super patterns). We also demonstrate in the report a strategy to generate a pattern detection algorithm from a specification, thus automating the detection of pattern instances in user models. The strategy handles the current semantics of the language. However, as more semantics get added, it would need to evolve to incorporate the effect of these semantics on the detection algorithm. Another usability feature we are investigating is the ability to pre-bind some roles to speed up the detection algorithm. This feature will help users focus their attention to parts of their model (vs. the whole model) by prebinding some roles with particular elements and only look for the rest of the role bindings. Another possibility of further research is the ability to designate several patterns as variants of a common pattern and leverage this knowledge in designing an amalgamated detection algorithm for that family of patterns. We expect to use pattern inheritance and refinement in the specification of such families of patterns. Furthermore, a full analysis of the detection algorithm in terms of its complexity and scalability with the pattern and user model sizes is something for us to work on going forward. We have also presented in the report a tool that integrates with the RSA tool to allow pattern authors to graphically specify their patterns, generate detection algorithms for them and run them against user models created with RSA. We are currently working on a new UML profile for Epattern to allow pattern authors to use their favorite UML2-aware [8] modeling tool to specify Epatterns using CSDs and then import them into our tool. We also plan to provide tooling for visualizing the detected pattern instances using their native notations (e.g. class diagrams and sequence diagrams).
References [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
24
J. Miller and J. Mukerji. MDA Guide Version 1.0.1. OMG, Massachusetts, June 2003. G. Booch. Handbook of Software Architecture. http://www.booch.com/architecture/ IBM Rational Software Architect. http://www-128.ibm.com/developerworks/rational/ products/rsa/ F. Budinsky, D. Steinberg, T. Grose, S. Brodsky and E. Merks. Eclipse Modeling Framework. Pearson Education. August 2003. OMG. UML 2.0 Suprestructure Specifications. OMG Document formal/05-07-04 E. Magyari et.al. UDM: An Infrastructure for Implementing Domain-Specific Modeling Languages. The 3rd OOPSLA Workshop on Domain-Specific Modeling, OOPSLA '03. E. Gamma, R. Helm, R. Johnson and J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley, 1995. UML2: EMF-based UML 2.0 Metamodel Implementation. http://www.eclipse.org/uml2 OMG. MOF Core Specification v2.0. OMG Document formal/06-01-01 W. Brown, H. McCormick, T. Mowbray and RC Malveau. Antipatterns: Refactoring Software, Architectures, and Projects in Crisis. John Wiley & Sons, 1998.
Carleton University, TR SCE-06-08 [11] [12] [13] [14] [15] [16]
[17] [18] [19] [20] [21] [22] [23]
[24]
A
March 2006
J. Mak., C. Choy and D. Lun. Precise Modeling of Design Patterns in UML. In Proceedings of the 26th International Conference on Software Engineering, 2004. A. Guennec, G. Sunye and J.M. Jezequel. Precise Modeling of Design Patterns. Proceedings of UML 2000, volume 1939 of LNCS, pages 482-496. Springer Verlag, 2000. D. Kim, R. France, S. Ghosh, and E. Song. A UML-Based Metamodeling Language to Specify Design Patterns. In Proceedings of WiSME, UML Conference, Oct. 2003. D. Maplesden, J.G. Hosking and J.C. Grundy. Design Pattern Modelling and Instantiation using DPML. In Proceedings of Tools Pacific 2002, Sydney, p. 18-21, Feb. 2002. A. Baroni, Y.G. Gueheneuc and H. Albin-Amiot. Design Patterns Formalization. Ecole Notionale Superieure des Techniques Industrielles. Research Report 03/3/INFO, 2003. H. Albin-Amiot and Y.G. Guéhéneuc. Metamodeling Design Patterns: Application to Pattern Detection and Code Synthesis. In Proceedings of the ECOOP 2001 Workshop on Adaptative Object-Models and MetaModeling Techniques, 2001. G. Engels, J.M. Kuster and L. Groenewegen. Consistent Interaction of Software Components. In Proceedings of Integrated Design and Process Technology, 2002. L. Briand. Y. Labiche, L. O'Sullivan, M. Sowka. Automated Impact Analysis of UML Models. Journal of Systems and Software, vol. 79, no. 3, pp 339-352, March 2006. OMG. OCL for EMOF Specification v2.0. OMG Document ptc/05-06-13 Omodo. EclipseUML for MDA. http://www.omondo.com OMG. UML 2.0 Infrastructure Specifications. OMG Document formal/05-07-05 G. Valiente. Algorithms on Trees and Graphs. Springer, October 2002. B. More et. al. Eclipse Development Using the Graphical Editing Framework and the Eclipse Modeling Framework. IBM Redbooks. http://www.redbooks.ibm.com/rebooks/ pdfs/sg246302.pdf. OMG. XMI Mapping Specification v2.0. OMG Document formal/05-09-01.
Appendix: Epattern Metamodel Description
The following is a description of the new concepts in the Epattern metamodel. It includes description of new features (marked with ‘*’) and inherited ones (from Ecore): 1.
EPattern EClass It represents a pattern
name: String It specifies a name for the pattern. abstract: boolean It specifies whether the pattern is abstract or concrete. *eSuperPattern: EPattern (non-containment, ⊆ eSuperTypes) A reference to the pattern’s super pattern *eRoles: ERole (non-containment, ⊆ eReferences) A collection of references to the pattern’s roles *ePorts: EPort (non-containment, ⊆ eReferences) A collection of references to the pattern’s ports *eConstraints: EConstraint (non-containment, ⊆ eOperations) A collection of references to the pattern’s constraints *eConnectors: EConnector (containment)
25
Carleton University, TR SCE-06-08
March 2006
A collection of references to the pattern’s connectors 2.
ERole EReference It represents a pattern role
name: String It specifies a name for the pattern role. lowerBound: int It specifies a lower bound on the role's multiplicity. A value of 0 or 1 indicates whether the role is optional or required respectively upperBound: int It specifies an upper bound on the role's multiplicity. A value of * or 1 indicates whether the role is collection or singular respectively. eReferenceType: EClass (non-containment) A reference to the role’s type, which can either be an EClass from the pattern’s target metamodel or an EPattern representing a composed pattern containment: boolean It specifies whether the role represents a composed pattern or not. *eConstraints: EConstraint (non-containment) An ‘ordered’ collection of reference to the role’s constraints *eConnectors: EConnector (non-containment) An ‘ordered’ collection of reference to the role’s connectors
3.
EConnector EModelElement It represents a connector between two pattern roles
*eSourceRole: ERole (non-containment) A reference to the connector’s source role *eTargetRole: ERole (non-containment) A reference to the connector’s target role *eSourcePort: EPort (non-containment) A reference to the connector’s source port if the source role represents a composed pattern *eTargetPort: EPort (non-containment) A reference to the connector’s target port if the target role represents a composed pattern *eType: EReference (non-containment) A reference to the connector’s type, which can either be an EReference from the pattern’s target metamodel or an EAssociationEnd of a derived association
4.
EPort EReference It represents a port on the boundary of a pattern that connects to a pattern role
name: String It specifies a name for the pattern port. *eDelegatingRole: ERole (non-containment)
26
Carleton University, TR SCE-06-08
March 2006
A reference to a role connected to the port *eDelegatingPort: EPort (non-containment) A reference to a port on another pattern if the delegating role represents a composition of that pattern eReferenceType: EClass (non-containment) A reference to the port’s type, which is an EClass from the pattern’s target metamodel (the type has to match that of the delegating port if specified; otherwise that of the delegating role)
5.
EConstraint EOperation It represents a constraint on one or more pattern roles
name: String It specifies a name for the pattern constraint. *expression: String It specifies a boolean-typed expression in the context of an instance of the pattern *language: String It specifies a constraint language (e.g. EMOF OCL) used for the expression *eConstrainedRoles: ERole (non-containment) A collection of references to the constrained pattern roles
6.
EAssociation EClass It represents a new derived association between two EClasses from the pattern’s target metamodel
name: String It specifies a name for the association *eAssociationEnds: EAssociationEnd (containment) A collection of references to the two association ends
7.
EAssociationEnd EReference It represents an end in a derived association
name: String It specifies a name for the association end lowerBound: int It specifies a lower bound on the association end's multiplicity. upperBound: int It specifies an upper bound on the association end's multiplicity. eReferenceType: EClass (non-containment) A reference to the association end’s type, which is an EClass from the pattern’s target metamodel *navigable: boolean It specifies whether instances of this association end’s type can be derived from an instance of the opposite association end’s type *eOppositeEnd: EAssociationEnd (non-containment, ⊆ eOpposite)
27
Carleton University, TR SCE-06-08
March 2006
A reference to the opposite association end if both ends are navigable *expression: String It specifies an expression in the context of an instance of the opposite association end’s type used to derive instances of this association end’s type *language: String It specifies a language (e.g. EMOF OCL) used for the derivation expression
28