Community
Participate
Working Groups
We have to support a incremental M2M-transformation in our company. While the transformation itself is around for quite a few years now and is written in Java against the Eclipse UML API, our generators have been developed with Xtend / Xpand & MWE. An important Stereotype of our Profile is the "Generated"-Stereotype which is used to drive the incremental transformation of the model. It extends every UML Element. To provide some input to our Generator templates we transform the stereotyped UML Elements to an more specialized Ecore-Model. We use the Xtend UML Typesystem for this - more precisely: the ProfileMetaModel. Consider the following scenario: <<Generated, ServiceClass>> <uml::Class> SomeServiceClass -> contains many -> <<Generated, ServiceOperation>> <uml::Operation> SomeServiceOperation -> has many -> <<Generated>> <uml::Parameter> SomeRequestParameter -> has Type -> <<Generated, RequestInterface>> <uml::Class> SomeRequestInterface Please note that the <<Generated>> Stereotype has been added automatically by the incremental UML M2M Transformation. To obtain the <<RequestInterface>> from the <<ServiceOperation>> in Xtend I'd use the following piece of code: MyProfile::RequestInterface request(MyProfile::ServiceOperation transformable): transformable.ownedParameters.type.typeSelect(MyProfile::RequestInterface).first(); Xtend cannot process this line successfully (EvaluationException) since it cannot find the "type"-Feature of the "<uml::Parameter>-Collection". The problem lies deep within the ProfileMetaModel: A plain UML-Element is normally asked for a list of its features - one of those resolved features of <uml::Parameter> would be "type" since it's inherited from one of the also resolved supertypes <uml::TypedElement>. A Stereotype is handled a bit differently. If an Element has a Stereotype applied, then the Stereotypes Tagged-Values are resolved as features. Additionally the typesystem resolves features from the Supertypes of the Stereotype (The Element types it may be applied to). This works fine for Stereotypes like <<MyProfile::ServiceOperation>> since it may only be applied to an <uml::Operation> - the features required for interaction with the Type get successfully resolved - but it leads to a Problem for the <<MyProfile::Generated>>-Stereotype which may be applied to ALL <uml::Elements> - only the features of <uml::Element> are resolved... which is not enough for the <uml::Parameter> from the sample. I was able to build a workaround. It includes a specialization of ProfileMetamodel that is actually aware of the ACTUAL type of a given uml::Element and a Stereotype-Representation that partially bypasses the caching-mechanisms and extends the list of supertypes to reolve the required features from based on the ACTUAL type of the stereotyped Element. Unfortunately I had to patch the Xtend Framework code (introduce a method) for this. I'll post my workaround here... Kind regards & thanks in advance
Created attachment 163143 [details] The alternative MetaModel The alternative MetaModel - had to patch the Xtend Framework code to introduce the protected getInternalProfileMetaModel() method
Created attachment 163144 [details] Delegates to the original StereotypeType Partially delegates to the originally resolved StereotypeType and adds the actual UML-Type to the Supertypes Set if required.
We experienced a similar problem, especially concerining type compatibility. Our solution was to create "artificial" StereotypeType whenever an element's type is requested as in your case above. However we just override getSuperTypes to return the "real" StereotypeType and the actual UML type. This is not the full problem, though. When it comes to static checks e.g. in the xpand editor, casts as in the case above will fail because the stereotype and the original UML type are incompatible from the viewpoint of type hierarchy. Maybe we should discuss these ProfileMetaModel issues in general?
Yes that's true. I didn't further look into the problem you mentioned before due to deadline pressure - though I ran into it a few times. Well overriding getSuperTypes() did the trick in most cases. If you have a look at the attached "DelegatingStereotype"-Class you'll notice that it also tries to bypass caching for operation & property resolution. This is necessary if you have two Element, say a Class and a Operation that both apply the same stereotype. If now a special feature of the Operation would be called after the Class has been used in another context ... the TypeSystem could not find the feature because rather the Cache would be asked for the feature - not the Operation itself - a null value would be returned in this case.
I finally managed to provide a patch that should solve this issue (without breaking API). Please have a look into this.
Created attachment 192549 [details] Adds actual type awareness for Stereotypes In some cases it is necessary for a Stereotyped object to be aware of its actual UML Type... In other words, if a Stereotype is applicable to any Element, it only offers the features of the Stereotype itself and the base class - which is Element in this example. The patch solves this problem by a) extending the list of super types by adding the actual type and b) creating an exclusive StereotypeType instance for any combination of Stereotype and actual UML type to bypass any caching limitations.
Fixed like discussed at EclipseCon.
Bug resolved before Xpand 1.2 release date => Closing