JSTL, EL, and DBXML

I changed my DBXML taglib last night so it will work with JSTL tags.  I left out EL support because I didn't need it yet.

As to the kind of changes needed for a taglib to be integrated with JSTL, classes need to support the JavaBeans method naming design pattern and implement common interfaces like Iterator or Collection.  For example JSTL Core forEach tag requires a variable set with an array of primitive data types or an object or its member implementing Iterator or Collection interface.

Unfortunately, DBXML's Java binding classes looks like they were written by a C programmer with little understanding common Java practices nor common performance pitfalls.  XmlResults class, for example, doesn't follow the JavaBeans method naming design pattern and doesn't provide an Iterator interface.  Not surprising since it doesn't even override the toString method.  It also instantiates a new XmlValue for each result item.

To get around these problems, I made these changes to DBXML Java binding:

  1. added XmlValue.setCPtr method so XmlValue can be reused.
  2. added XmlValue.nextValue method with an XmlValue out parameter.
  3. added XmlValue.toString()
  4. added getXXX versions of asXXX methods.
  5. added XmlResults.getItems() that resets and returns an Iterator implementation.

With above changes, I was able to use my DBXML taglib with JSTL tags like this:

<%@ taglib prefix="dbxml"
uri="/WEB-INF/dbxml.tld" %>
<%@ taglib prefix="c"
uri="http://java.sun.com/jstl/core" %>
<html><head><title>DBXML Test</title></head><body>
<h2>My Posts about Flash</h2>
<dbxml:setDataSource dataSource="dbxml/blog"/>
<dbxml:query var="titles"
  xpath=
"/donpark/post/item/title[contains(.,'Flash')]/text()"
  resultType="values" />
<c:forEach var="item" items="${titles.items}">
  <h4><c:out value="${item.string}"/></h4>
</c:forEach>

</body></html>

Which returns:

<h4>Funniest Comment about Flash Mobs</h4>
<h4>Flash Mob Discount?</h4>
<h4>Flash Mobs in the Bay Area?</h4>
<h4>Flashing XML</h4>

Note that EL expression ${titles.items} invokes XmlResults.getItems method and ${item.string} invokes XmlResults.getString method according to JavaBeans design pattern.  Adding EL support to a taglib involves passing attribute values and body content through the EL parser so users can use EL expressions when using your tags.

Tomcat Inner City

I spent a couple of hours this morning to write a JNDI ObjectFactory for DBXML so access to XML databases can be located and shared across web applications via JNDI similar to the way JDBC DataSources are handled automatically by Tomcat.  Unfortunately, ObjectFactory doesn't handle object lifecycle meaning it just ships objects out the door and not worry about them afterward.

To close down those databases gracefully, I need to receive notification of the container shutting down.  Tomcat provides varioius kinds of Listener support but there are two problems:

  1. Tomcat-specific interfaces must be used.
  2. Listeners are specified by class name.

I think a JCA (J2EE Connector Architecture) connector version would be more portable but I am not sure if Tomcat supports this.  Looks like I'll have to wander around the inner city a little longer.

After dinner, I am going to tinker with DBXML TagLib to make it look more like JSTL's SQL tags and support EL as well.  I don't usually get to play around at this level, so it's fun in a way.

DBXML TagLib

Not much to blog about except I now have a simple taglib for DBXML.  It has only two tags for now, <dbxml:query> for querying DBXML with XPath and <dbxml:value> for retrieving query result value.  Writing taglib is rather tedious so I might just build some more blog, wiki, and RSS related taglibs while I am at it.

DBXML Weekend

I am dedicating this weekend to DBXML.  Early this morning, I saved all of my Radio blog posts (630) into a single RSS file and imported them into a DBXML database using the StAX-based RSS parser I started writing yesterday.  The parser is not ready for public consumption yet, but it's useful enough for me to extract <item> elements and serialize them back into strings so they can be inserted into DBXML.  Boy, it is fast!

A couple of hours later, I am having a blast querying my 'blog database' using XPath.  For example, "/item/title/text()" is all I need to list titles of my blog posts.  Neato.  On my to do lists are writing DBXML taglib for rendering the results from JSP, experimenting with indexes and Berkeley DB triggers to drive cascading network of XML documents stored in DBXML.  And then maybe throw in some recursive dependencies to watch DBXML thrash violently in pain.  Muhahaha!  Definitely a fun weekend.

You think maybe I should take up golf again?

StAX Fun

Last night I played with StAX, the new streaming XML parser API.  I am impressed with the performance and ease of use.  There are some weirdness in the API though.  For example, check out these overloaded methods:

 writeStartElement(String name);
writeStartElement(String ns, String name)
writeStartElement(String prefix, String name, String ns)

writeEmptyElement() is similarly overloaded , but writeAttribute() is not.

 writeAttribute(String name, String value)
 writeAttribute(String ns, String name, String value)
 writeAttribute(String prefix, String ns, String name, String value)

All I can say is this parameter order scrambling doesn't make sense to me.

BTW, I am building up a set of useful StAX functions and hope to share it with others soon.  For example, skipElement and exitElement are pretty handy for skipping over an element or exiting from within an element.