umltransformationm2mpapyrusqvt

Using an UML profile in QVTo transformation?


I have defined an UML profile using the Papyrus tool and saved the file as "my_profile.di". How do I use this profile inside a QVTo transformation?

Is it possible to do something like this (I'm not sure how the path to the file should be specified though)?

modeltype UMLProfile uses 'platform:/resource/QVT_project_test/my_profile.di';

I'm sorry if this is a stupid question but I'm completely new to QVT. I hope somebody out there could enlighten me, thanks in advance!


Solution

  • Using UML Profile with QVTo (or any EMF based tranformation language) is a little bit tricky. Short answer, you have to deal with the UML metamodel only, but following the situation, the way to deal with the profile is a little bit different. Basically, there is two scenarios:

    1. you want to use a source UML model which uses a Profile/Stereotypes,
    2. you want to create a new UML model from another one (or modify an existing one) and apply a Profile/Stereotype on it.

    First Scenario

    You only have to register the UML metamodel and you need to use the operations provided by UML (getAppliedStereotypes(),...). Actually, elements on which a stereotype is applied is not recognized as instance of the stereotype. For example, assuming you have a Property prop with a stereotype EAttribute, QVTo will see prop as a Property instance with extra-information you can recover instead of a EAttribute instance.

    Here is a little example considering a kind of ecore Profile. I considered an inout transformation, which means that the model defined as inout will be modified.

    modeltype UML "strict" uses uml('http://www.eclipse.org/uml2/5.0.0/UML');
    
    transformation testProfile(inout model : UML);
    
    main() {
      model.objects()[Property]->map copyme();
    }
    
    mapping Property::copyme() : Property
    when {
      -- You need to use the fully qualified name
      not self.getAppliedStereotype('ecore::EAttribute').oclIsUndefined()
    }
    {
      -- repr() is used at the end to get a String value from the tagged value
      name := self.name + self.getValue(self.getApplicableStereotype('ecore::EAttribute'), 'attributeName').repr(); -- toString() also works
    }
    

    And a small request to list all the elements stereotyped by a specific stereotype:

    model.objects()[Element]->select(e | not e.getAppliedStereotype('ecore::EAttribute').oclIsUndefined());
    

    Also, stereotypedBy(...) operation seems nice, but it is not yet implemented (on my QVTo version).

    Second Scenario

    This time, you will need to pass the profile as new parameter of your transformation (if your profile is defined in another file). Your profile is a UML model as well, your transformation signature becomes:

    transformation testProfile(inout model : UML, in profile : UML);
    

    First you need to apply your profile to your model:

    model.objects()[Model].applyProfile(profile.objects()![Profile]);
    

    and when you want to apply a Stereotype to an element:

    -- in context of an element
    self.applyStereotype(profile.objects()[Stereotype]![name = 'EAttribute']);
    

    If the double filter does not works (I think it will be removed in future QVTo versions), just use a select:

    self.applyStereotype(profile.objects()[Stereotype]->selectOne(name = 'EAttribute'));
    

    Also take a look at the setValue() operation ;).

    Final Note

    As you saw, it can be a little bit cumbersome to deal with profile all along your transformation. A smart move could be to derive a metamodel from your profile et code a first transformation that takes your profiled model and translate it as a instance of your derived metamodel. This way, you will be able to deal with metamodel instance instead of "UML instances with extra-information".

    EDIT>

    In order to ease the stereotype handling, you can also define global properties with your most use stereotype:

    property mystereotype : Stereotype =  profile.objects()[Stereotype]![name = 'EAttribute'];