Jet : define recursive fonction. [message #15903] |
Fri, 11 May 2007 09:39  |
Eclipse User |
|
|
|
Originally posted by: fifre.news.free.fr
Hello,
I'm trying to use Jet to transform an instance of an ecore-based model in
a dot file (in order to represent my instances in a more friendly way).
My models use the "composite" pattern, so i must define a recursive
function to browse all my composite elements.
I didn't find in the documentation how to define a function in a Jet file,
so i don't know how can i process elements recursively.
thanks for reading,
regards,
Bastien Amar
|
|
|
Re: define recursive fonction. [message #16881 is a reply to message #15903] |
Thu, 17 May 2007 10:02  |
Eclipse User |
|
|
|
Bastien:
Recursion is a bit of pain in JET. There are two possibilities: flattening
and recursive templates. Let's assume you have an input model that describes
Java classes:
<project name="foo">
<package name="a.b.c">
<class name="Foo">
<class name="NestedInFoo"/>
</class>
<class name="Bar"/>
</package>
</project>
1) flattening. The XPath implementation lets you write expressions like:
$package//class, which, assuming $package references a package element, will
return all the class elements directly or indirectly contained under
$package. You could then write a simple <c:iterate> to process each element.
There are, however, times when this probably won't do.
2) recursive templates. A template my invoke another template via
<c:include>. Although the tag is called 'include', the template is in fact
invoked, like a method; as such, you can do recursion. The biggest pain is
passing values to the invoked template. JET only has global variables (I'd
like to fix that one day...), but c:include has a passVariables attribute
which lets you pretend that variables are scoped to the template invocation.
An example:
Assume you have a template that generates a class from a 'class' element,
and that $class is the current class instance. main.jet might look like:
<c:iterate select="/project/package/class" var="class">
<ws:file template="templates/class/genClass.jet" path="..."/>
</c:iterate>
The genClass.jet template needs to include itself recursively...
class <c:get select="$class/@name"/> {
<c:iterate select="$class/class" var="class">
<c:include template="genClass.jet" />
</c:iterate>
}
This works, because <c:iterate> carefully saves the current value of $class
before setting it during the loop. But, you could also write:
class <c:get select="$class/@name"/> {
<c:iterate select="$class/class" var="class">
<c:include template="genClass.jet" passVariables="class" />
</c:iterate>
}
The differences between the two is that with passVariables, the template
only receives that variables, and any variables set during the template's
execution are removed when it exits.
Finally, as with any recursion, infinite loops, manifesting themselves by
long pauses and then stack overflows are possible.
Hope this helps.
Paul
|
|
|
Powered by
FUDForum. Page generated in 0.27790 seconds