Skip to main content



      Home
Home » Modeling » M2T (model-to-text transformation) » [Xpand] Guards in templates (Feature request)([Xpand] Guards in templates (Feature request))
[Xpand] Guards in templates (Feature request) [message #525964] Thu, 08 April 2010 08:22 Go to next message
Eclipse UserFriend
I'd like to propose an enhancement to xpand that makes writing modular and extensible templates a lot easier: By introducing guards for templates different output can be generated for model elements depending on their context.

Feature description:

DEFINE statements are enhanced by an optional "WHEN" clause:

«DEFINE templateName FOR element WHEN condition»
...
«ENDDEFINE»

When a template is invoked, only methods with their guard condition evaluating to true are considered. The polymorphic template evaluation remains as is.

Motivation:

Consider this template definition to generate a Java method for an UML operation:

«DEFINE operation(boolean markAsAbstract) FOR uml::Operation»
«EXPAND operationSimpleHead»
«EXPAND operationSignature(markAsAbstract)»
«IF !markAsAbstract»
«EXPAND operationBodyStart»
«EXPAND operationBody»
«ENDIF»
«EXPAND operationBodyEnd(markAsAbstract)»
«ENDDEFINE»

«DEFINE operationBody FOR uml::Operation»
«getReturnValue(getReturnResult())»
«ENDDEFINE»

...

Now imagine, that we want to define a different template "operationBody" for certain operations. If these special operations are marked with an own stereotype, we are lucky and just define a new template using polymorphism:

«DEFINE operationBody FOR myProfile::MyOperation»
...
«ENDDEFINE»

But what if the condition for using this special template is different? For example, we might want to use the special template when the operation has certain properties or the containing class has a certain stereotype. Using a guard, we can stick to the same solution pattern and define a specialised template:

«DEFINE operationBody FOR uml::Operation WHEN myProfile::MyStereotype.isInstance(this.owner)»
...
«ENDDEFINE»

Here "WHEN ..." acts as a guard and only those templates are considered for invocation for which the condition is true.
Without such a guard, the only solution I know is to alter the original template like this:

«DEFINE operationBody FOR uml::Operation»
«IF myProfile::MyStereotype.isInstance(this.owner)»
...
«ELSE»
«getReturnValue(getReturnResult())»
«ENDIF»
«ENDDEFINE»

However, this solution has serious drawbacks:
1) 3rd party templates, defined in .jar files can not be extended this way, because the original template has to be altered
2) It is not possible to define reusable "core" templates and extend these templates differently in different project contexts
3) Too many "if" statements in the template bodies make the templates hard to read

Thus, with the existing functionality, it is not possible to write extensible templates for the situations described above. However, in our project context, this is quite often the case: First, we use existing 3rd party templates (e.g. Fornax Hibernate Cartridge) we want to customize. Second, we provide our templates to other projects that themselves might want to customize them.
Providing the "guard" feature would help a lot in extending templates and in my opinion is a mandatory feature for effectivly reusing existing templates in own projects.

Best regards,

Ingo
Re: [Xpand] Guards in templates (Feature request) [message #525968 is a reply to message #525964] Thu, 08 April 2010 08:30 Go to previous messageGo to next message
Eclipse UserFriend
It is something that already exists, but you need to use Xtend and FOREACH.
Using your example
Quote:
«DEFINE templateName FOR element WHEN condition»
...
«ENDDEFINE»


So you define in Xtend a function that returns all element where condition is true. Let us call that function elements_when.

Your Xpand template would look like
Quote:
«DEFINE templateName FOREACH elements_when()»
...
«ENDDEFINE»

(you need to import the Xtend file using EXTENSION first)

[Updated on: Thu, 08 April 2010 08:31] by Moderator

Re: [Xpand] Guards in templates (Feature request) [message #525974 is a reply to message #525964] Thu, 08 April 2010 09:01 Go to previous messageGo to next message
Eclipse UserFriend
Frst of all:
Hello Ingo. Welcome to the forum.

A nice idea,
but what if you define different DEFINEs with guards for an type,
and more then one guard is true?

Which one should Xpand choose?

Regards
Darius
Re: [Xpand] Guards in templates (Feature request) [message #525978 is a reply to message #525964] Thu, 08 April 2010 09:07 Go to previous messageGo to next message
Eclipse UserFriend
Hi Ingo!

Thanks for your detailed explanation. However, posting feature requests on the forum is not the right way. The proper way would be opening a bugzilla entry with severity 'enhancement'.

The Xpand language is designed to have only orthogonal concepts and a minimum of keywords. I do not consider this concept as orthogonal to existing features, since the problem you have to solve is a typical usecase for Xtend functions. The 'guard' condition is usually a select on a couple of elements and used when invoking a definition with
«EXPAND someDefinition FOREACH elementsMatchingSomeCondition()»
just like Maxime mentions.

So please explain why your situation is not solvable this way or too inconvenient.

Kind regards,
~Karsten
Re: [Xpand] Guards in templates (Feature request) [message #526006 is a reply to message #525964] Thu, 08 April 2010 10:14 Go to previous messageGo to next message
Eclipse UserFriend

Hi,

thanks to all for the fast responses! The key to my problem is extensibility and reuse: When somebody provides a template, he does not know about future needs to cutomize it in other projects. Let's have a look at the example again (BTW it's from the Fornax Java Basic Cartridge):

«DEFINE operation(boolean markAsAbstract) FOR uml::Operation»
«EXPAND operationSimpleHead»
«EXPAND operationSignature(markAsAbstract)»
«IF !markAsAbstract»
«EXPAND operationBodyStart»
«EXPAND operationBody»
«ENDIF»
«EXPAND operationBodyEnd(markAsAbstract)»
«ENDDEFINE»

«DEFINE operationBody FOR uml::Operation»
«getReturnValue(getReturnResult())»
«ENDDEFINE»

When I write this template, how can I make it customizable for project specific needs, without forcing the using project to alter it? With customization I mean changing a small part of its output while reusing the rest. There are some pretty good templates libraries available for XPand (e.g. the Fornax Hibernate Cartridge), but I always came to the point where I found no way to customize them without changing the original code.
The only chance I see for customization is to overwrite templates using polymorphism. However, as I explained in my original post, this is not always possible, because the condition when to use the other template may be different than selecting the template by the type of its parameters.

I know that a language like XPand must be carefully maintained to keep it simple and concise. However, I am really seeking for a solution to make existing templates better reusable (either this way or another). With the proposed enhancement, I see a good way to achieve this. Perhaps, the first goal should be to get a common understanding of the current limitations in writing reusable templates. If it is still unclear to you, where the core of my problem is, please let me know and I try to make another example.

@Marius: Yes, during runtime there might be an unambiguity which template to call. The behaviour here has to be carefully chosen. Maybe it is sufficient to require that only one guard may be true at any time and to throw an error, if this is not the case. In XSLT, which has a similar mechanism, a template can have a priority and the highest priorized applicable template is chosen.

Ingo





Re: [Xpand] Guards in templates (Feature request) [message #526008 is a reply to message #526006] Thu, 08 April 2010 10:24 Go to previous messageGo to next message
Eclipse UserFriend
Hello Ingo,

did you have a look on xpands aspect oriented programming support? If you want to change the behaviour of a certain define this may useful for you.
Re: [Xpand] Guards in templates (Feature request) [message #526179 is a reply to message #526008] Fri, 09 April 2010 03:14 Go to previous messageGo to next message
Eclipse UserFriend

Hi Christian,

yes, with AOP I can do some customization, but this has some limitations.
The customization from my original posting could be realized with AOP like this:

«AROUND operationBody() FOR uml::Operation»
«IF myProfile::MyStereotype.isInstance(this.owner)»
...
«ELSE»
«targetDef.proceed()»
«ENDIF»
«ENDAROUND»

However, this definition can itself not be overwritten. Let's assume we have a template library T, defining basic templates for java fragments, such as classes, methods etc., including my example templates "operation" and "operationBody". Now imagine two other libraries E1 and E2, reusing the templates of T, but wanting to alter "operationBody" when the containing class has a certain stereotype. With my proposed enhancement, this would look like this:

Template in E1:

«DEFINE operationBody FOR uml::Operation WHEN E1::E1Stereotype.isInstance(this.owner)»
...
«ENDDEFINE»

Template in E2:

«DEFINE operationBody FOR uml::Operation WHEN E2::E2Stereotype.isInstance(this.owner)»
...
«ENDDEFINE»

With AOP this is not possible. The same is true, when E1 extends T and then E1 itself is reused and extended by E2 (this is the case in my project).

Even if AOP is applicable, I think specialising a template with a WHEN-clause is simpler to use than AOP. For example, for using AOP the generation workflow has to be altered. Also, the WHEN-clause clearly defines when to apply the template, while using AOP you have to use an IF clause in the template body (or even an IF cascade if you have multiple cases).

Best regards,

Ingo


Re: [Xpand] Guards in templates (Feature request) [message #526213 is a reply to message #525964] Fri, 09 April 2010 05:15 Go to previous message
Eclipse UserFriend

Hi,

I just realized that my proposed enhancement is not working as expected because of a false assumption: I thought that the polymorphic template invocation works across multiple template files. However, it seems that each template file has its own namespace, so it is impossible to write a specialised version of a template in another template file. This makes it impossible to customize a template library without AOP. Bad luck for me, because as i pointed out earlier, I think AOP has some disadvantages and I would like to find a more elegant solution.

Ingo
Previous Topic:Two models in a transformation
Next Topic:[Xtend/Xpand] Posted 2 Bugs I found while working with Stereotyped Elements
Goto Forum:
  


Current Time: Thu Jul 17 21:59:09 EDT 2025

Powered by FUDForum. Page generated in 0.03088 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top