Jelly Overview
Jelly is an XML based scripting engine. The basic idea is that XML
elements can be bound to a Java Tag which is a Java bean that performs
some function. Here's an example action
public class FooTag extends TagSupport {
private int count;
public void setCount(int count) {
this.count = count;
}
public void doTag(XMLOutput output) throws Exception {
for ( int i = 0; i < count; i++ ) {
// evaluate body
getBody().run( context, output );
}
}
}
Then in a Jelly script this tag could be used as follows:-
<f:foo count="123">
something...
</f:foo>
Jelly is totally extendable
via custom actions (in a similar way to JSP custom tags) as well as cleanly integrating with scripting
languages such as Jexl, Velocity, pnuts, beanshell and via BSF (Bean Scripting Framework)
languages like JavaScript & JPython
Also notice that Jelly uses an XMLOutput class which extends SAX ContentHandler
to output XML events.
This makes Jelly ideal for XML content generation, SOAP scripting or dynamic web site generation.
A single Jelly tag can produce, consume, filter or transform XML events. This leads to a powerful
XML pipeline engine similar in some ways to Cocoon.
Background
It seems quite common these days to define custom XML languages to perform
some kind of processing. Here are a few examples
- Ant
- XSLT
- XML Pipeline language
- JSTL and JSP custom tags
- Latka, AntEater & other similar XML based unit testing frameworks
- commons-workflow
So the motivation behind Jelly was to create a simple XML based processing
engine that could be extended to support various custom actions. A fully
qualified XML element name can be mapped to a Java Bean (or DynaBean), the
attributes map to bean properties, once the bean is constructed and the
properties set it is executed via the Tag interfaces doTag() method. So custom
actions can perform all kinds of processing from lower level looping,
conditional logic and expression evaluations to higher level actions like post
processing their bodies, making
a HTTP, SOAP or JMS call, querying SQL databases etc.
Comparisons
To try give you a better feel for what Jelly is, we'll compare and contrast
Jelly with other scripting engines and templating technologies.
Jelly versus JSP
Similarities
- Jelly uses the concept of custom tag libraries from JSP and follows many
of the lessons learnt from the JSTL (JSP Standard Tag Library). Indeed JSTL
could be implemented in Jelly.
Differences
- Jelly has no dependency on Servlets or JSP so Jelly can be run from the
command line, inside Ant, inside an applet or anywhere that Java code can be
ran.
- Jelly tags are much simpler to write and use than JSP tags. Because JSP
must support scriptlets due to backwards compatibility issues, they are
implemented 'inside out' with 3 different interfaces (Tag, BodyTag,
IterationTag) to implement based on the kind of tag you are writing, together
with a fairly complex set of event-based methods that are called by the page
container. Jelly tags are very easy - just derive from TagSupport and
implement the doTag() method. Really simple!
- Jelly is XML native both as the format of the scripts and the output
format, so its ideal for work with XML and XML based applications and web
services
- Jelly tags can parse and compile their bodies for more optimal performance
and easier validation. So a tag can ignore whitespace, iterate over its body,
transform its body at compile time etc. So a Jelly tag can be a simple macro, preprocessing
its body at compile time, such as to build smart HTML forms or to make SOAP
macros etc.
Jelly versus Velocity
Velocity could actually be used inside Jelly via custom tags which support
Velocity expressions, directives and scripts. However here's a head to head
comparison anyways.
Similarities
- Jelly allows Java objects to be manipulated in a Java-like manner just
like Velocity.
- Jelly could have a surface syntax that looks similar to Velocity.
i.e. someone could make a parser of Jelly that had a look-and-feel of Velocity
for common directives and expressions.
Differences
- Jelly provides an extensible tag mechanism to provide more powerful
scripting such as by supporting JSTL, XML, XPath, XSLT, SQL or SOAP service
scripting. In essence, Jelly uses XML tags to denote 'directives'.
- Jelly has integrated support for other scripting languages such as
JavaScript, NetRexx, Jython etc.
Jelly versus Ant
Ant is a truly awesome build system which has always resisted 'scripting'.
Jelly has never tried to be a build system but instead has just focussed on 'scripting'.
However Jelly is a lot like Ant in many ways.
The two can work hand in hand together very nicely.
Jelly could be thought of as a scripting plugin for Ant.
Jelly can be called from inside Ant as an Ant Task, then the Jelly script can script other Ant tasks,
access Ant properties and use all other Jelly tags such as for logic, looping, working with beans, XPath, SQL etc.
Similarities
- Both use an XML format for the script with an expression language like ${foo.bar}
- XML elements are mapped to a Java object, so its easy to extend both Ant and Jelly with simple Java code.
Differences
- Jelly has full support for pluggable expression languages. The default expression language is a superset of the one
used in JSP, JSTL and JSF which supports conditional expressions, navigating bean properties,
and working with Maps, Collections, Lists, arrays etc.
Jexl is the current implementation which adds some Velocity-like enhancements like method calls on beans etc.
Jelly supports other expression and scripting languages like Velocity, beanshell, JavaScript, Jython, pnuts, BSF etc in separate tag libraries
- Jelly has native XML support. Jelly can parse XML and process it using XPath expressions (via the JSTL tags).
Also Jelly supports a declarative model of processing XML (via the JSL tags) which is similar to XSLT
but can use Jelly tags, beans and Ant tasks inside the XML template in a similar way to DVSL.
-
Jelly has a much more powerful collaboration mechanism for passing information between tags/tasks.
In Jelly variables can be any object plus variable scopes can be nested to allow nested scripts to work together neatly.
A tag/task can be customized with beans as well as being able to consume, emit, filter and transform XML.
So Jelly tags can be configured from and can collaborate with beans and XML.
- Jelly supports dynamic tags. Tags can be defined in Jelly script to avoid repetitive typing
such as to wrap up most of the complexity of making a SOAP call. So Jelly has an integrated tag based macro facility.
-
Jelly uses XML namespaces to allow lots of different tag libraries to work together seamlessly in the same
XML document. This means you can mix and match Ant tasks with JSTL and Jelly tag libraries.
All can use their own expression languages, so one script could mix and match the expression languages
from Ant and JSTL as well as XPath and Jython.
- There is a clear difference of emphasis. Ant is a build system, Jelly is a scripting engine.
Possible uses for Jelly
Jelly has various possible uses. Here's a few to think about
- An additional tool for Ant users to provide more flexible Ant scripting.
Indeed Jelly is already used in Maven to provide a more flexible build system
while still preserving existing investment in Ant tasks.
- HTTP, JMS, SOAP, XML and SQL based unit testing framework similar to Latka and AntEater
- SOAP scripting or XML processing engine
- XML or page templating system, possibly a Generator for Cocoon
- Alternative (very lightweight) implementation of JSTL that can be run from
Ant to generate static content
- A workflow, EAI or integration, maybe integrated into commons-workflow
- Code generation system, maybe an enhanced scripting engine for XDoclet