introduction
"Lendvai Attila" <[email protected]>
| Newsgroups | gmane.comp.java.beanshell.devel |
|---|---|
| Message-ID | <E12F73E3BF124B45A118F3323DEB49553227FA@netvisorpdc.intranet.netvisor.hu> |
hi Pat and BeanShell dev list,
i've just subscribed to the list because i'm thinking of integrating
beanshell into andromda (sourceforge).
andromda is a java project that can read in XMI (UML saved in XML) and
with various cartridges generate files for you. it's using velocity as a
scripring engine, but i would like to have beanshell in it as an option.
but, i would also like to extend either beanshell or preprocess my
templates so that it's much better for templates. i would like to have a
funtionality similar to JSP's, where you can switch between execution
context and static text context.
here's a silly example template, it gets an array of methods, walks
trough them, and generates an output file. it would contain a method for
each entry in the array, of which implementation calls all other
methods. possible output:
array is {foo1, foo2, foo3}
file is
foo1()
{
foo2();
foo3();
}
foo2()
{
foo1();
foo3();
}
foo3()
{
foo1();
foo2();
}
this file is also attached to avoid wrapping...
// 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 but in fact it's a beanshell function
void generateLog(String thisMethod, String calledBy)
{
<+
log.info("method ${thisMethod} called by ${calledBy}");
+>
}
note that the syntax is completly ad-hoc.
i would also like to have some support for
- indenting that makes the template indentation independent from the
output indentation
- multiple output stream support where you can define to which scream
the <+ +> blocks should go
- etc?
so there's two possible way to solve this:
A: create a preprocessor that turns the <+ +> blocks into
stream.write()'s and call untouched beanshell
B: put together a correct requirement and design, and implement it as an
optional beanshell language extension. (after posting to andromda i got
mails that people would like to have it independently from andromda,
too)
i would also like to have a question:
is it simple to call java objects from beanshell? (i guess it is)
because after the XMI is read in it's turned into a navigable object
graph, that is the primary information provider for the generator
cartridges. so painless accessing of these objects is vital for andromda
itegration.
what do you think?
happy coding,
- 101
example.txt
(text/plain, 1 KB)
// 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}");
+>
}