Binding XML to Maps and Beans
May 17th, 2007With Stencil, you start with the output XHTML page.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns:s="flag://stencil.agtrz.com/snippits"
xmlns:var="flag://stencil.agtrz.com/attributes" s:snippit="hello"
xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Hello, World!</title>
</head>
<body>
<form>
First Name: <input name="firstName" value="Fred" var:firstName="value"/><br/>
Last Name: <input name="lastName" value="Flintstone" var:lastName="value"/>
Hometown: <input name="lastName" value="Bedrock" var:address.city="value"/>
</form>
<s:switch>
<s:if test="neighbors">
<table>
<tr>
<td>First Name</td>
<td>Last Name</td>
</tr>
<s:each name="neighbors">
<tr>
<td><s:var name="firstName">Barney</s:var></td>
<td><s:var name="lastName">Rubble</s:var></td>
</tr>
</s:each>
</table>
</s:if>
<s:default>
<p>No neighbors.</p>
</s:default>
</s:switch>
</body>
</html>
<!-- vim: set ts=2 sw=2 et: -->
You will note that this XHTML will not look right in a browser. You have to strip all things in the flag://stencil.agtrz.com/snippits namespace before it looks like XHTML. Stripping the Stencil elements is easy to do though. XSLT anyone?
It is easier to preview the output through an XSLT transform, or through a servlet that strips the Stencil elements, then depend on mockups of business logic.
Binding
public interface Person {
public String getFirstName();
public String getLastName();
public Iterator getNeighbors();
}
It all comes down to strings. Back in the days of Perl, HTML was string, SQL was a string, and CGI was a string. String processing made life easy.
We don’t want to extract structure out of the Java, we want to extract strings. The structure is dictated by the Stencil. You compose an object graph that matches the Stencil, creating facade objects where necessary.
How do we get the strings out of Java? How do we bind Java and XML?
There are three ways to bind XML to Java. One it to go the JSP route, and write Java code into the template language. Another is to go the XStream or Castor route, and express the structure of a Java object graph in XML. The other is to go an OGNL route, create a path language, that will evaluate a little bit or a lot of Java, to get string values and put them in a structure.
I’m going to go with a minimal path language. Bare minimum. No swapping. No choosing your own path language.
Dirt Simple Path Language
Dirt Simple Path Language (DSPL) is a dot separated path to a final object that will be evaluated to a String using that objects toString method.
For any Java object, you will get the class name in DSLP using:
class.name
This is for the case of obvious nested objects like:
employee.address.zip
That would save the hassle of writing a bean wrapper to get the ZIP.
There are no accomodations for indexes or map keys. No conditionals. No operators. You should feel lucky to have this much.
Variable Elements and Attributes
There is always a context object. That object is either an object or else it is a map. In the case of an Object the object is treated as a JavaBean and the variable names are bean properties. In the case of a Map the names are interpreted as hash keys.
Variable Elements
Variables are indicated with the var element. The var element is replaced by calling the the toString method of the object returned by evaluating the property. If the value is null, then the element is simply deleted.
Question Do I accommodate null values? It could be done by adding a null attribute.
Variable Attributes
Variable attributes are indicated using the namespace
flag://stencil.agtrz.com/attributes
An attribute in that namespace is interpreted in the following fashion.
The local name is the DSPL to apply to the context object
The attribute value is the qualified name of the new attribute to add to the element, the attribute local name is the DSPL to apply to the context object to obtain the value of the new attribute.
If the attribute already exists in the template, it is removed.
If the value evaluates to null, the attribute is not added.
This backwards naming convention is simple to implement. Added bonus of allowing a placeholder value for static editing.
Question Do I accommodate null values? It could be done by adding the null value replacement after a comma. Is there a common case where one attribute is added in lieu of another for a specific condition? What about zebra striping, how do I know which row is even or odd? Do I use ListIterator?
No Expressions
While there is logic above, there are no expressions. Truth in Stencil is somewhat like truth in Perl. In addition to boolean false, null is false, as is an empty iterator.
When an iterator is used as a condition, it is cached, so that it can be later used for iterator. Quite naturally, after an iterator is used for iteration, it will always return false.
Control Structures
There are no expressions, only control structures that take a truth value returned from the underlying object model. Those control structures are as follows.
if- The content of theifelement are evaluated if the property named by thetestattribute is true.unless- The content of theunlesselement are evaluated if the property named by thetestattribute is false.each- For each object in theIteratororCollectionreturned by the property named by thenameattribute, the context switches to the object, and the contents of theeachelement are evaluated.with- The context switches to the object return by the property named by thenameelement, and the contents of thewithelement are evaluated.switch- Theswitchelement can contain any of the above elements, the first to be evaluated will replace theswitchelement. Theifandunlessare evaluated conditionally, whileeachandwithwill always evaluate and terminate theswitch.default- For use in aswitchstatement, the default condition that will always execute and terminate theswitch.
Then there are two more to consider, invoke or include. It is intended that Stencil will allow creation of pages through composition, reuse of Stencils through object orientation.
comments
Stencil by Convention
May 7th, 2007When toying with Stencil at the outset, I dipped into the JavaBeans API. It seemed like the easiest way to get started on a dirt simple path language to extract string values from Java objects. I’d replace it when a better idea came to me.
Still waiting.
I created a an interface. Given an object and a property name, an implementation would extract the property form the object. There were two distinct implementations of name and value pairing that were apparent at the outset. JavaBeans, which are ObjectS whose properties are obtained though the JavaBeans API, and MapS. Certainly, there would be more.
There weren’t.
The API programmer was burdened with choices. Not only did you have to provide an object model for a Stencil, you needed provide a was to interpret that object model? Flexible? Sure. As flexible as 0 and 1.
This calls for a convention.
An object returned from a property is either an Object, Map, array, Collection, Iterator, or a ListIterator.
ObjectS, through JavaBeans, and MapS are interpreted as name value pairs. They give named values for a dirt simple path language.
Colletion and Iterator are used by the each keyword. A Java array or ListIterator expose an index property to the each keyword.
The Liberty of Convention
Amusing to think of how it hit struck me though. That word; convention. It freed me from sifting though design patterns, thinking up ever more convoluted means of delgation, dispatch, configuration, and construction.
One mental block was an avoidance of the instanceof keyword, which always feels like your cheating. However, this time around, I realized that I was already employing reflection, and that binding begs reflection or similar.
Once I’d decided that instanceof was the way to go, then it became a matter of deciding, instanceof what?
Enter Stencil
May 4th, 2007Two weeks back, I began work on an XML template engine. The name came to me shortly after. I’d call it Stencil. I like the name. I’m surprised that it does not already describe a template engine of sorts.
Today, I found another reason to like the name. It is easy to find pictures to accompany posts.
Motivations
When last I approached web applications programming, I was using XSLT and developing an XML pipeline engine called Relay. This engine is still about. I’m a fan of Saxon and XSLT.
XSLT, The T is for Transform
The problem with XSLT is that it is sight too complicated for XML generation. XSLT is a transform language. In order to generate a document from XSLT you need to feed it a bogus document. Then you match the root of the document, but copy none of it. Instead, you write out your new document.
Using this method, dynamic content must be passed in as parameters. A complicated document, with a lot of different dynamic sections, would require a lot of parameters passed to the Template. The invocation of the template looks and feels messy.
Feeding XSLT, With XML Serialization
There are ways to generate a document to get the ball rolling, like using XStream to serialize an object graph, which work rather well. Building map with the objects in them, and then serializing them gave a nice big XML document to roll from.
However, it does not always work, of course. Your object graph has to contain the data. You’ll have a JDBC cursor, for example, that you need to convert into an List, before you can put it in a Map that would also include the user login information.
The output can be very complicated, include a lot of extra data that is undesired, and is not terribly semantic.
There major drawback is that, if all I was doing was laying out a simple signup form, I couldn’t do that layout separately from the development of the form. I needed to start with the object model, serialize it, develop a transform. I’d have to create a pipeline to see what was going on at all.
A lot of complexity for something that once upon a time, was very simple.
JSP, Perpetual Context Switching
JSP hurts my eyes and my brain. I don’t like to see wayward Java injected into that twisty, angle-bracket maze. I don’t like it because it’s not valid XML. I don’t like it because logic has bled into the presentation.
On the client side, I manipulate the DOM with JavaScript, rather than place JavaScript directly in the document. Certainly, in client side JavaScript, there is no concept of a while loop that emits XML. (Okay, there is, but didn’t you get the memo? You’re not supposed to use document.write anymore.)
Two worlds collide.
Display Only XHTML
My ideal template engine would allow me to work on the XHTML separately. Creating the page in XHTML, then adding variable placeholders, and even then, using a utility that would strip the placeholders, view the static XHTML without having to yet implement the object model or controller.
I’d like to get back to the whipitupitude of the HTML and Perl days of yore.
Binding XML
April 24th, 2007The problem with templating languages it binding. Perl would treat markup as a string. That is an honest interpretation of markup.
Ruby wants to turn markup into objects. PHP wants to turn markup into logic.
Java straddles objects and logic. There are two ways to embed. Path languages or embedded logic.
Attempt to make something that is delcaritive?
Can you represent all of the iterative constructs with a declaration? Or a call to an implementation in Java? That is a worthy goal. Let’s see if it works. Novel an interesting enough to put out there for people’s consideration.





