Developer

Jelly offers component-rich XML scripting

Jelly is a scripting engine that turns XML into executable code. See how you can get started with this powerful tool.


Jelly is a new scripting paradigm from Jakarta that allows the developer to write scripts using XML. Mind you, this is not just another use for XML. Jelly is powerful, flexible, and easy to use—and more important, it's easy to extend.

Let’s get started using Jelly with the simple example in Listing A. You can grab the complete source code for this article here.

Jelly libraries
Jelly has quite a few built-in libraries, which are listed in Table A. In our example, we make use of three:
  • ·        Core
  • ·        Log
  • ·        Interaction

Libraries are made available by assigning them to XML namespaces. In the first tag after the XML declaration, <j:jelly>, we assign three namespaces: j, l, and i. Our first nested tag makes use of the interaction tag library. This library allows you to capture input from the user. Here, you ask for the user's name, providing a default value of anonymous. The result of the user's input is stored in the variable name. The second tag makes use of the log library. It outputs some text and uses the name variable inside of it.
Table A
Jelly Libraries

jelly:core

jelly:xml

jelly:define

jelly:sql

jelly:jsl

jelly:ant

jelly:werkz

jelly:ojb

jelly:jms

jelly:validate

jelly:http

jelly:interaction

jelly:antlr

jelly:util

jelly:html

jelly:junit

jelly:swing

jelly:quartz

jelly:betwixt

jelly:dynabean

jelly:log jelly:soap jelly:jetty jelly:beanshell jelly:jeez
jelly:email jelly:bean u u u
See Tag Reference for full details.

Jelly extensibility
One distinguishing Jelly feature is its extensibility. Any regular JavaBean can be bound to an XML tag. The JavaBean does not have to extend any special class or implement any special interface. If it supports an invokable method, such as run(), invoke(), or execute(), the method will be called after all appropriate setters are called. If you want to invoke a different method, you can declare it, as shown in Listing B.

The class in Listing B could be accessed with Jelly via the code in Listing C.

Jelly and Ant
Jelly allows full access to all of the existing Ant libraries. This makes it simple to begin writing scripts that make use of Ant’s rich set of utilities. For example, using the interaction and ant libraries from Jelly, you can easily write a directory copy script with optional backup functionality. (See dircopy.jelly.)

This Jelly script will ask you to specify a source and destination directory. It will then ask whether you want to create a backup. If you answer yes (which is the default choice), it will ask you to specify a filename. The script will copy all files from the source directory to the destination directory and if you answered yes, create a tar.gz of the specified directory.

Jelly and Maven
Although Jelly is useful as a stand-alone scripting language, it is most widely used inside of Maven, a project management and build system from Jakarta. Maven is built on the concept of plug-ins. All Maven plug-ins are written using Jelly. For instance, the default goal in Maven is java:jar, which will compile all source files for a project and create a distributable JAR file.

Working under the hood: Jelly tags
Let’s dive into the internals of Jelly and see what it takes to create a custom Jelly tag library. Our example will be a simple tag that turns our body text to lowercase or uppercase. Jelly tags are grouped in the tag libraries we saw in Table A. A tag library is registered with Jelly as a namespace.
 
<j:jelly
    xmlns="jelly:core"
    xmlns:case="jelly:com.jelly.examples.CaseTagLibrary">



This example makes available the core tag library in the default namespace and our custom library in the case namespace. CaseTagLibrary must extend the org.apache.commons.jelly.TagLibrary class and invoke the registerTag method for each available tag.
 
registerTag(“case”, CaseTag.class);
 

We now have one tag available to us, case. CaseTag must extend org.apache.commons.jelly.TagSupport. TagSupport is declared as abstract and requires us to implement the doTag(XMLOutput output). After all setters have been invoked, this method will be called. For the case tag, you will look for one attribute type. For our tag class, you will define one setter method as follows:
 
public void setType(String type) {
       this.type = type;
}



Now let’s look at the meat of the CaseTag class, the doTag method. The first thing we need to look for is whether the user supplied the required attribute, as shown in Listing D.

If type is set to lower or upper, let’s roll. The case tag is designed to take the contents of the tag and convert the text to either lowercase or uppercase. To do this, you access the text and convert it, as shown in Listing E.

Our case tag is now complete. Check out CaseTag.java (included in the download) for the complete source code. You can now use our tag like this.
 
<case:case type=”upper”>Hello World!</case:case>
 

See case.jelly (also in the download) for the complete example.

Jelly installation
After you download Jelly, you use Maven to build and install. To install on your machine, run maven dist:install. By default, it will be placed in /usr/local/jelly. To use Jelly, make sure that you set the environment variable, $JELLY_HOME, to point to where Jelly was installed. Then, add $JELLY_HOME/bin to your path. Jelly uses forehead to handle class loading. To make our CaseTagLibrary available to jelly, drop a JAR file containing the above classes into $JELLY_HOME/custom.

Final steps
Now it’s time to see the script in action. In the directory containing the sample script, run jelly case.jelly. You should be greeted with Hello World!

Wrapping up
Jelly has taken all the great ideas from many of the scripting languages that have come before and rolled them up into one. It is highly extensible, easy to use, and has a rich set of core components.

Editor's Picks

Free Newsletters, In your Inbox