:: 1) the decoupling of AndroMDA from any particular scripting
:: engine (i.e.
:: Velocity)
:: 2) the addition of FreeMarker as a supported scripting
:: engine alternative
::
:: So here is my opinion on the topic. Point (1) just seems
:: like a good thing to do from an architectural point of view.
:: I cannot see any strong reasons for why we'd want AndroMDA
:: to continue to be so tightly coupled to Velocity. Just
:: because we decouple AndroMDA from Velocity does not mean we
:: must provide an alternative scripting engine. It just means
:: that we can.
::
:: Point (2) is not so clear to me. I believe Jonathan has
:: stated the case very clearly. Would AndroMDA be served well
:: by the "friendly fascism" of not providing alternative
:: scripting engines? Or would AndroMDA be better served by
:: providing alternatives? Jonathan thinks yes. I honestly do
:: not know, but I don't think more choices is clearly better.
:: I actually see it as a really hard call to know what is the
:: right thing to do. Honestly I would be ok with it going either way.
i'm the www.beanshell.org supporting guy who popped in the middle of the
discussion with my first post.
i've got a point to support choice... if you look at the way andromda
can be used by _developers_ you realize that it's never going to be that
simple as drawing uml and typing ant. you always need to change things
here and there, understand the way andromda works, or even more create
your own cartridge for a single project. so having choice helps here.
and on the other hand if we have choice then we will have cartridges
written in various script languages that hurts uniformity, etc... but
it's not a problem for those drawing kind of users, who will only type
ant and don't know what's happening inside. and if the cartridge
architecture is flexible enough then we could have 3 ejb cartridge and
let the insiders choose. if you document only one, set the default
configuration to use the velocity based one, then who's not digging deep
will not see anything about the "mess".
and as of beanshell, i think it's great to use the same language on the
macro level as on the execution level. if you can use java to generate
java you can have a lot of fun, with multi level macros, etc... it's
power (, that must not be abused of course).
and as of quote, back quote context switches... imho it's much cleaner
to have a switching syntax other then # on each line. and with a proper
syntax highlighting it's much easier to read.
example with beanshell: generate a method for each entry in methods
array, and as their body call each other method. (syntax is just a quick
idea)
see also attached file without wrapped.
// start in execution context
for(int i = 0; i < methods.size(); ++i)
{
// no cast needed here, beanshell typesystem can be relaxed
(most probably)
Method thisMethod = methods.get(i);
// switch to quoted context
<+
public void ${thisMethod}(String calledBy) // assumes
thisMethod.toString() returns it's name (it goes into the generated
file)
{
${
// go back here to beanshell execution context
// log we were called and call all other methods
generateLog(thisMethod, calledBy); // put logging
here with a "macro call"
for (int j = 0; j < methods.size(); ++j)
{
Method otherMethod = methods.get(j);
if (thisMethod != otherMethod) // skip
ourselves to avoid infinite reqursion
{
<+
// calling method ${otherMethod} from
${thisMethod}
${otherMethod}("${thisMethod}");
+>
}
}
}
}
+>
}
// this is effectively a macro
void generateLog(String thisMethod, String calledBy)
{
<+
log.info("method ${thisMethod} called by ${calledBy}");
+>
}
(this example is probably buggy as writing stuff at the macro level
requres heavy testing :)
by a preparser written by us, it would be turned into a beanshell script
with full of stream.write's (similar to how JSP's work). there's a
possibility of easily supporting multiple output streams from one
template for example by giving the stream id after '<+', sometimes it
can be a big help!
anyways i think choice is better, and can be controlled with
documentation and defaults. and if there were a clean interface in
andromda i would implement the above.
what do you think?
yours,
- 101
// start in execution context
for(int i = 0; i < methods.size(); ++i)
{
// no cast needed here, beanshell typesystem can be relaxed (most probably)
Method thisMethod = methods.get(i);
// switch to quoted context
<+
public void ${thisMethod}(String calledBy) // assumes thisMethod.toString()
returns it's name (it goes into the generated file)
{
${
// go back here to beanshell execution context
// log we were called and call all other methods
generateLog(thisMethod, calledBy); // put logging here with a
"macro call"
for (int j = 0; j < methods.size(); ++j)
{
Method otherMethod = methods.get(j);
if (thisMethod != otherMethod) // skip ourselves to avoid
infinite reqursion
{
<+
// calling method ${otherMethod} from ${thisMethod}
${otherMethod}("${thisMethod}");
+>
}
}
}
}
+>
}
// this is effectively a macro
void generateLog(String thisMethod, String calledBy)
{
<+
log.info("method ${thisMethod} called by ${calledBy}");
+>
}