Groovy and Object Orientation
Can we make a Groovy object and access it with Java, as in Figure 4?

Figure 4. Referencing a Groovy class directly |
How cool would that be? The first step would be to make an interface to which the Groovy code must conform:
public interface GroovyNodeIterator
{
public Object process( DOMNodeGroovyObject doc );
}
Our simple interface has one method, which takes a DOM wrapper object and returns some sort of object. With this in hand, we can make some final changes to the Java code:
import groovy.lang.GroovyClassLoader ;
...
public static Map calculateAmounts( Document doc ) throws Exception
{
// Create a class loader
GroovyClassLoader groovyLoader =
new GroovyClassLoader();
// Create the shell
GroovyShell shell =
new GroovyShell( groovyLoader, new Binding() );
We need to build a GroovyClassLoader, because we will be asking it for one of our Groovy classes. We pass this new class loader to the shell.
// Load the AmountAdder Groovy class
Class adderClass =
groovyLoader.loadClass( "AmountAdder" );
We then ask the class loader to load up our AmountAdder class.
// Create an instance of it
GroovyNodeIterator obj =
(GroovyNodeIterator)adderClass.newInstance();
And we create an instance of that class. No kidding. Seriously. We are creating an object that looks and feels just like a Java object, but it's really been written in Groovy.
// Run the process method
return (Map)obj.process( new DOMNodeGroovyObject( doc ) );
}
We then call the process method and get the return value. We can call this Groovy object just as we would any Java object.
The Groovy code for the AmountAdder class is shown below:
class AmountAdder implements GroovyNodeIterator
{
public Object process( DOMNodeGroovyObject doc )
{
accountValues = [:];
for( accountNode in doc.xpath( "/transactions/account" ) )
{
accountValues[ accountNode.id ] = 0;
for( transNode in accountNode.xpath( "transaction" ) )
{
accountValues[ accountNode.id ] +=
Integer.valueOf( transNode.amount );
}
}
return accountValues;
}
}
The process method has to be defined exactly as it would be in Java; otherwise, we will get an AbstractMethod exception, because the class will not have implemented everything in the interface.
Inside of the method, we have simplified the algorithm as much as we can. It's down to six lines, two of which are the algorithm. That's 33 percent, which is really good. Certainly, the logic of the algorithm is now more visible than it was before.
But the most important thing we have learned is that Groovy is really cool. It can extend interfaces and creates byte code that can be executed by Java directly. Which means that you can have a reference to a Groovy object that looks and works exactly like a Java object.
Conclusions
XML is pretty cool stuff, and the more we use it, the more we need to think about how to make it easier to use. We need to think about ways to reduce the XML infrastructure work for ourselves and our customers.
Now, I don't seriously think that people will start replacing XSLT with Groovy code. But I do think that this article should spur your imagination with ideas about how you can use a flexible scripting language like Groovy to simplify your application and to make it more extensible. When integrating Groovy into your application is as simple as creating an interpreter and asking the class loader for a class, you have to think about all of the things you can do in the script layer as part of rapid prototyping, things that can then be brought back into the Java layer for efficiency.
Adding dynamic scripting-language support to your application is at your fingertips. Give it a go!
Resources
Jack Herrington is a software engineer with over twenty years of experience on numerous platforms and languages.