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}");
+>
}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.