Stefano Scheda wrote:
I'm trying to code some groovy string
manipulation of database-extracted
data.
I can't post the actual code but it goes along these lines:
#set ($mydb=$xwiki.sql.getDatabase("jdbc/ABC"))
#set ($SQLstring = "select mycol from fw_notifiche")
#foreach($row in $mydb.executeQuery($SQLstring))
#set ($mycol = $row.getString("mycol"))
<%
vcontext = context.get("vcontext");
mycol = vcontext.get("mycol");
newmycol = mycol.replaceAll("2", "two");
vcontext.put("newmycol", newmycol);
%>
Here is the data: $newmycol <br>
#end
The problem is that only the each loop receives the processing of the
vary
last row.
Let's say the the loop extracts three rows with values 1, 2, 3. The
previous
code results in this output:
3
3
3
(i.e. unreplaced value from the last row)
While if I switch to mycol.replaceAll("3", "three"), the output is:
three
three
three
(i.e. each loop gets the replaced value from the last row)
Seems that velocity and groovy are incorrectly linked thru the context,
or
what?
The old rendering (being replaced starting with 1.6) executes the
different interpreters in order, one after another, and not recursively.
This means that the groovy is not executed inside the foreach:
- first the velocity interpreter runs, and it sees <% groovy code as
plain text, so after velocity the document will contain three (the
number of selected rows) times the groovy block.
- After that, the groovy interpreter runs, and it sees three times the
same block. Since velocity was already interpreted, the velocity context
is not updating anymore, the last values placed in it are there for each
groovy block.
There are two solutions:
1. Use only velocity, or only groovy. The code you posted does not
justify the use of groovy, since replaceAll can be called from velocity,
too. Maybe you have a different code that does require more advanced
programming which can only be done in Groovy.
2. Put the groovy code in a different page, inside a pseudo-class,
return a new instance of that class, and then in the velocity page you
can call #set($groovyObject = $xwiki.parseGroovyFromPage("The name of
the document with Groovy code")), and then inside the loop call
$groovyObject.doSomething().
Thanks Sergiu,
I missed the ability to call replaceAll directly from velocity. That should
be enough for my current purpose.
BTW, I'm currently running on version 1.5. In case I had upgraded to 1.6
that sample code would behave as expected?