next up previous contents
Next: B. Usage of the Up: Diploma Thesis: Utility Support Previous: 7. Outlook   Contents

Subsections


A. Maintance of the OCL Compiler

This chapter describes all major changes to Frank Fingers OCL compiler. This includes bugfixes too, if they caused changes of internal or external interfaces. It it some kind of update for [FF00], listing everything changed since.

A.1 Reflection Facade and OCL Library

Many changes occurred both in the reflection model facade and in the OCL library. This section groups these changes.

A.1.1 Polymorphism of Operation Parameters

Both ReflectionFacade.navigateParameterized and OclAnyImpl.getFeature lacked polymorphism of operation parameters. This means, that a method is found only if actual parameter types match formal parameter types exactly. The correct behavior is, that actual parameter types may also be subtypes of formal parameter types. For a detailed description see [RW00] section 3.1.5.

The new implementation made ReflectionAdapter.getClassForType superfluous, so it was removed from the interface.

A.1.2 Mandatory Name Adapters

Previous versions of the OCL library provided a default functionality, if no name adapter had been set explicitly.

Now it is mandatory to set a name adapter. Otherwise a NullPointerException is thrown. The default functionality has been moved into a separate name adapter (SimpleNameAdapter) which is used in the reflection facade as well. The name adapter may also be set by the java property tudresden.ocl.lib.nameadapter.

ArgoNameAdapter has been generalized into PrefixNameAdapter, which takes an arbitrary name prefix (``my'' for Argo/UML) as a constructor parameter. Using this adapter with ``lnk'' and ``the'' should work for Together/J and Rational Rose.

A.1.3 Qualified Associations

The OCL support was enhanced by adding a simplified form of qualified associations to the reflection facade and the OCL library. ``Simplified'' means, that there may be only one qualifier attribute.

Qualified associations are represented in java with java.util.Map by default, but this may be changed by implementing ReflectionAdapter.isMap(Class).

A.1.4 Type Mapping from OCL to Java.

The mapping between OCL types and java types now supports the collections API introduced in JDK version 1.2. The changes concern DefaultOclFactory.getOclRepresentationFor(Object) and DefaultReflectionAdapter.getClassForType.

A special handling of java.util.Vector supports code generated by Argo/UML. The static configuration variable Ocl.TAKE_VECTORS_AS_SET causes vectors to be mapped to sets, instead of sequences.

The new mapping is listed below.



Java (java.util) take vectors as set OCL
List - Sequence
Vector false Sequence
  true Set
Set - Set
Map - Set (qualified)


Furthermore, arrays are now supported. They are mapped into sequences of the appropriate element type.

A.2 OCL Library

Some modifications occurred in the OCL library only.

A.2.1 Undefined Values

Previous versions of the OCL library implemented undefined values as singletons for each type.

This was given up. Now undefined values carry the reason for their creation with them. When the undefined value is tried to be evaluated, this reason is added to the exception message.

This made Ocl.STRICT_CHECKING superfluous, so it was removed. Wherever this property was used, the library now produces an undefined value, parameterized with the message of the exception formerly thrown.

Undefined values were introduced at some other operations of OCL objects:

  1. Method OclCollection.setToRange now creates an undefined collection (instead of throwing an exception), if lower bound is greater than upper bound.
  2. The methods Ocl.to<OclType>(OclRoot) now return an undefined value of the appropriate type, if argument is undefined.

A.2.2 Java Null Values

Previous versions handled a special null value for OCL strings. This null value behaved like an empty string for most cases (e.g. concatenation). However a null string and an empty string were not equal. This was removed. Now a null string does exactly behave like an empty string.

Previous versions returned an undefined OCL collection, if the java collection field was null. Now, null collections are treated exactly like empty collections.

This behavior is encapsulated into a new method getOclRepresentationForNull(Class) in OclFactory. This method is called in OclAnyImpl.getFeature.

A.3 Type Checker

Previous versions of the type checker missed support for classifier OclAny in class DefaultTypeFactory.

Method getClassifier in class TypeFactory has been removed and replaced by TypeFactory.get.


A.4 Java Code Generator

A.4.1 Code Fragments for @pre

Meaning of code fragments created for @pre expressions (TRANSFER, PREPARATION, POST) has been changed. The new behavior is easier and more flexible for different code instrumentation tools. For a description of the new behavior see section [*].

For the old behavior compare to [FF00] section 7.1.2. Below, there is a detailed comparison on the example used there.

The OCL expression is

context Person::getIncomeAfterTax(tax:Real):Real post:
  age = age@pre
The TRANSFER fragment generated is still the same:
OclInteger tudOclNode2;
However, the PREPARATION fragment has changed. Below, there is the old version. The new version just lacks the parts set in italics.
final OclAnyImpl tudOclNode0=Ocl.toOclAnyImpl(Ocl.getFor(this));

final OclReal tudOclOpPar0=Ocl.toOclReal(Ocl.getFor(tax));

final OclReal tudOclResult0=OclReal.UNDEFINED;

final OclInteger tudOclNode1=Ocl.toOclInteger(

    tudOclNode0.getFeature("age"));

final OclInteger tudOclNode2=Ocl.toOclInteger(

    tudOclNode0.getFeature("age"));

final OclBoolean tudOclNode3=tudOclNode1.isEqualTo(tudOclNode2);

this.tudOclNode2=tudOclNode2;

The POST fragment changed as well. Again, this is the old version, with the new version lacking the first line put in italics.
final OclInteger tudOclNode2=this.tudOclNode2;

final OclAnyImpl tudOclNode0=Ocl.toOclAnyImpl(Ocl.getFor(this));

final OclReal tudOclOpPar0=Ocl.toOclReal(Ocl.getFor(tax));

final OclReal tudOclResult0=Ocl.toOclReal(Ocl.getFor(result));

final OclInteger tudOclNode1=Ocl.toOclInteger(

    tudOclNode0.getFeature("age"));

final OclBoolean tudOclNode3=tudOclNode1.isEqualTo(tudOclNode2);

The old code fragments were intended to be inserted into the user code as follows:
public class Person 

{

  // TRANSFER FRAGMENT

 

  public double getIncomeAfterTax(double tax) 

  {

    getIncomeAfterTaxPRE(tax);

    // USER CODE

    getIncomeAfterTaxPOST(tax, result);

    return result;

  }

 

  private void getIncomeAfterTaxPRE(double tax)

  {

    // PREPARATION FRAGMENT

  }

 

  private void getIncomeAfterTaxPOST(double tax, double result)

  {

    // POST FRAGMENT

  }

}

With the new fragments, this still works. However, it's also possible to insert the TRANSFER fragment into the method, thus making it a local variable:
public class Person 

{

 

  public double getIncomeAfterTax(double tax) 

  {

    // TRANSFER FRAGEMENT

    {

      // PREPARATION FRAGMENT

    }

    // USER CODE

    {

      // POST FRAGEMENT

    }

    return result;

  }

}

The code instrumentation developed with this paper uses the second insertion scheme only.

A.4.2 Explicit Package Qualifiers.

The java code generator now optionally prepends the explicit package qualifier tudresden.ocl.lib. to OCL library classes. This makes an import statement superfluous, and therefore fulfills the corresponding requirement in section [*].


next up previous contents
Next: B. Usage of the Up: Diploma Thesis: Utility Support Previous: 7. Outlook   Contents
Ralf Wiebicke 2005-11-25