As mentioned in the previous page, our model instantiation checking tool translates UML models into the executable specification language AsmL, which is based on abstract state machines. This translation is done at the specification diagram and the instance diagram levels.
A specification diagram usually consists of a class diagram, whether it is a class diagram representing the UML metamodel or a UML profile (at the M2 level), or a user-defined class diagram (at the M1 level). Class diagrams are relatively easy to translate into AsmL because AsmL is object- oriented.
public class MyClass extends libOcl.OclAnyImplwhere
libOcl.OclAnyImpl
is a class defined in the OCL library within
the libOcl
namespace. This class will be described in the page
on the Object Constraint Language (OCL).public var at_name as libOcl.OclString public var op_calcSalary() as libOcl.OClIntegerwhere
OclString
and OclInteger
are classes declared in
the OCL library defining the OCL basic data types String
and
Integer
. Each attribute and operation has a prefix attached to its
name so that it can be easily identified as either an attribute or an operation
within methods in the OCL library that return type information of the classes.public var ae_order as libOcl.OclSet of Orderwhere
libOcl.OclSet
is the OCL library class encapsulating the
Set
collection type in OCL. There is no similar member variable for
the Order class because the association is unidirectional. We use a set
even when the multiplicity of the association end is exactly one because an
incorrect object diagram can have an object that is connected by multiple links
instantiating the association to objects at that association end.
public class Customer extends PersonHowever, AsmL does not support multiple inheritance. The original workaround was to have the class with multiple parents inherit from an arbitrary parent (for example, the first parent) and then copy the features and associations of the other parents into the declaration of the class itself while resolving any name conflicts arbitrarily. Unfortunately this workaround would not work in cases when the concepts of inheritance and polymorphism are utilized because the translated class now has only one parent from the viewpoint of the AsmL compiler. If we are to continue using AsmL we will have to find a good solution to this problem.
public class Entity extends Classand any tagged definitions for the stereotype would be translated into attributes of this class.
Instance diagrams are translated into objects of classes defined at the specification diagram no matter what metamodeling level the instance diagram is at because the elements in the instance diagram will always be instances of the corresponding classes at the specification diagram. For example,
public var John as Person = new Person() public var A as Refine_Class = new Refine_Class()
shows the instantiation of two instances. The first statement creates an object called John (in an object diagram) as an instance of the user- defined class called Person. The second statement creates an object called A, which is an instance of a stereotype of the meta-class Class called Refine_Class that is defined in a UML profile not shown here. In the second example, A is a class in a user-defined class diagram that is tagged with the <<Refine_Class>> stereotype. Each object in the instance diagram is declared consecutively.
Following the object declarations are slot value assignments for each object. This is done in one step (sub-state) of the ASM. For example, we can initialize the name and SSN slots of the object John with the following AsmL block:
step John.at_name.setVal ("John") John.at_SSN.setVal (123456789)
We note that AsmL uses indentation to identify blocks, so all indentation is
important. We also note that primitive types are encapsulated by classes in the
OCL library module; hence the setVal methods used in the example to set values
for primitive OCL types. Back to the above block, we can see that both slot
values are initialized at the same time within one step of the ASM for the
Main()
function of the generated AsmL specification.
Associations are initialized the same way because they are translated into member variables that are sets or sequences of objects of the opposite association end type. The only difference with slot initialization is that a single statement may assign an entire set or sequence of objects of the opposite association end. For example, if the object John had a set of Bank objects connected by links instantiating an association between the user-defined classes Person and Bank, we could have a statement like the following:
step John.ae_bank.addItems({ BankOne, NatCityBank, BankOfUSA })
AsmL has support for set, bag, and sequence collection types, so the above block would add the set of three bank objects into the set representing the association between Person and Bank on the object John. Likewise, if the association end is ordered, a sequence notation would be used instead of a set.
After the statements initializing the objects in the instance diagram, the
tool appends additional AsmL code to initialize the set of all the instances for
each class in the class diagram. These sets are used in OCL’s allInstances()
operation, which evaluates to the set of all instances of a given class in the
UML model. Finally, the tool adds AsmL statements that will loop through each
object in the object diagram and call its verify()
method. The body
of this method for each class in the specification class diagram contains the
translated OCL constraints for the corresponding class and is generated by the
OCL parser module. In effect, the AsmL code, when compiled and executed, will
check the OCL constraints for each object and will report any OCL constraint
violations to the user. Graphical constraints will be validated by the tool
itself before the UML model is translated into AsmL.