Skip to end of metadata
Go to start of metadata

Content Handlers are the cornerstone of the Smooks component model. The following Content Handler types are currently in existance:

  1. Stream Readers: Smooks supports filtering of both XML and non-XML data because it allows you to configure a "Stream Reader" for each filter process. If no reader is configured, it defaults to XML. So, the Stream Reader resource is responsible for generating a stream of SAX events from a hierarchical data stream (e.g. XML, CSV, EDI etc.). This stream of SAX events can then be processed by XML Element Visitors (via Smooks). More on this later.
  2. Element Visitors: After Smooks hooks a Stream Parser to the data Stream, it starts receiving a stream of SAX events i.e. "startElement", "endElement" etc. These events are then used by Smooks to select an "ElementVisitor" implementation, which process the event in some way. This is the primary extension point in Smooks, as well as being the mechanism though which Smooks supports a fragment based processing model. See the list of Smooks Cartridges for examples of ElementVisitor implementations already available with Smooks. More on this later.
  3. Element Serializers: DOM based processing supports implementation of DOM Element "Serialization Units", allowing you to implement custom serialization at a fragment level.

Configuration

All Content Handler types share the same configuration model. This is based on the SmooksResourceConfiguration class (see Smooks Resources). Version 1.0 of Smooks also introduces an Annotation driven approach to Content Handler configuration.

SmooksResourceConfiguration

Content Handlers can receive their configuration by implementing the setConfiguration method:

public void setConfiguration(SmooksResourceConfiguration resourceConfig) throws SmooksConfigurationException;

Annotations

Version 1.0 of Smooks introduces support for annotation driven Content Handler configuration. This means that as well as supporting the old "setConfiguration(SmooksResourceConfiguration resourceConfig)" style Content Handler configuration, Smooks v1.0 also supports configuration injection via annotations. Two annotations are supported for this purpose:

@Config for injecting the SmooksResourceConfiguration directly onto the Content Handler e.g.

public class MyVisitor implements SAXElementVisitor {
    @Config
    private SmooksResourceConfiguration config;

    ... etc...
}

@ConfigParam for injecting specific <param> values from the SmooksResourceConfiguration directly onto the Content Handler e.g.

public class MyVisitor implements SAXElementVisitor {
    
    /**
     * Inject the "encoding" <param> from the SmooksResourceConfiguration.  Do some automatic type conversion on the value (to Charset).  Also default the value to "UTF-8".
     */
    @ConfigParam(defaultVal = "UTF-8")
    private Charset encoding;

    /**
     * Inject the "action" <param> from the SmooksResourceConfiguration.  Do some defaulting and validation on the value.
     */
    @ConfigParam(defaultVal = "replace", choice = {"replace", "addto", "insertbefore", "insertafter"})
    private String action;

    ... etc...
}

Annotation based <param> injection has a number of advantages:

  1. Cleaner code.
  2. Automatic type conversion.
  3. Automatic validation.
  4. Automatic "choice" support.

Lifecycle

Content Handler lifecycle is supported through the method annotations @Initialize and @Uninitialize.

Content Handler methods annotated with @Initialize will be automatically called by Smooks after handler creation and configuration. Content Handler methods annotated with @Uninitialize will be automatically called on VM shutdown (via a shutdown hook), or after calling Smooks.close() (useful where multiple Smooks instances are running in the same VM, with container managed lifecycle).

Stream Readers

Smooks relies on a "Stream Reader" for generating a stream of SAX events from the Source message data stream. A Stream Reader is a class that implements the XMLReader interface (or the SmooksXMLReader interface).

By default, Smooks uses the default XMLReader (XMLReaderFactory.createXMLReader()), but can be easily configured to read non-XML data Sources by configuring a specialized XMLReader:

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd">

    <reader class="com.acme.ZZZZReader" />

    <!-- 
         Other Smooks resources, e.g. <jb:bindings> configs for 
         binding data from the ZZZZ data stream into Java Objects....
    -->

</smooks-resource-list>

The reader can also be configured with a set of handlers, features and parameters. Here is a full example configuration.

<reader class="com.acme.ZZZZReader">
    <handlers>
        <handler class="com.X" />
        <handler class="com.Y" />
    </handlers>
    <features>
        <setOn feature="http://a" />
        <setOn feature="http://b" />
        <setOff feature="http://c" />
        <setOff feature="http://d" />
    </features>
    <params>
        <param name="param1">val1</param>
        <param name="param2">val2</param>
    </params>
</reader>

A number of non-XML Readers are available with Smooks out of the box:

  1. CSVReader
  2. SmooksEDIReader
  3. JSONReader
  4. XStreamXMLReader


Any of the above XMLReaders can be configured as outlined above, but some of them have a specialized configuration namespaces that simplify configuration.

Example - CSVReader Configuration

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:csv="http://www.milyn.org/xsd/smooks/csv-1.1.xsd">

    <!--
    Configure the CSV  to parse the message into a stream of SAX events.
    -->
    <csv:reader fields="firstname,lastname,gender,age,country" separator="|" quote="'" skipLines="1" />

</smooks-resource-list>

Example - SmooksEDIReader Configuration

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:edi="http://www.milyn.org/xsd/smooks/edi-1.1.xsd">

    <edi:reader mappingModel="/org/milyn/smooks/edi/edi-to-xml-mapping.xml" />

</smooks-resource-list>

Example - JSONReader Configurations

<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:json="http://www.milyn.org/xsd/smooks/json-1.1.xsd">

    <!--
    Basic configuration...
    -->
    <json:reader/>

</smooks-resource-list>
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:json="http://www.milyn.org/xsd/smooks/json-1.1.xsd">

    <!--
    Key replacement...
    -->
    <json:reader>
        <json:keyMap>
            <json:key from="some key">someKey</json:key>
            <json:key from="some&amp;key" to="someAndKey" />
        </json:keyMap>
    </json:reader>

</smooks-resource-list>
<?xml version="1.0"?>
<smooks-resource-list xmlns="http://www.milyn.org/xsd/smooks-1.1.xsd" xmlns:json="http://www.milyn.org/xsd/smooks/json-1.1.xsd">

    <!--
    Other configurations...
    -->
    <json:reader keyWhitspaceReplacement="_" keyPrefixOnNumeric="n" illegalElementNameCharReplacement="." nullValueReplacement="##NULL##" />

</smooks-resource-list>

To set features on the default reader, simply omit the class name from the configuration:

<reader>
    <features>
        <setOn feature="http://a" />
        <setOn feature="http://b" />
        <setOff feature="http://c" />
        <setOff feature="http://d" />
    </features>
</reader>

DOM Element Vistors & Serializers

DOMElementVisitors and SerializationUnits are Content Handler specializations that are applied during the DOM Filtering process.

DOMElementVisitors implement a very simple 2 method interface:

public interface DOMElementVisitor extends ContentHandler {

    public abstract void visitBefore(Element element, ExecutionContext executionContext) throws SmooksException;

    public abstract void visitAfter(Element element, ExecutionContext executionContext) throws SmooksException;
}

See the DOM Filtering section for details on when the SmooksDOMFilter calls the visitiBefore and visitAfter methods.

Points to note:

Icon
  1. The best way to get a hands on feel for how to write your own DOMElementVisitor, or reuse some of the implementations already available in the Smooks Cartridges, is to check out the tutorials.
  2. It's not likely that you'll ever need to worry about SerializationUnits. For the most part, the default serialization fits the bill.

SAX Element Vistors

SAXElementVisitors are Content Handler specializations that are applied during the SAX Filtering process.

SAXElementVisitors implement a very simple 4 method interface:

public interface SAXElementVisitor extends ContentHandler {

    public abstract void visitBefore(SAXElement element, ExecutionContext executionContext) throws SmooksException, IOException;

    public abstract void onChildText(SAXElement element, SAXText childText, ExecutionContext executionContext) throws SmooksException, IOException;

    public abstract void onChildElement(SAXElement element, SAXElement childElement, ExecutionContext executionContext) throws SmooksException, IOException;

    public abstract void visitAfter(SAXElement element, ExecutionContext executionContext) throws SmooksException, IOException;
}

See the SAX Filtering section for details on when the SmooksSAXFilter calls the visitor methods.

Smooks Cartridges

The basic functionality of Smooks Core can be extended through the creation of what we call a "Smooks Cartridge". A Cartridge is simply a Java archive (jar) containing reusable Content Handlers (Visitor Logic). A Smooks Cartridge should provide "ready to use" support for a specific type of XML analysis or transformation.

Using Maven?

Name

DOM Support

SAX Support

Description

JavaBean

(tick)

(tick)

Enables population of Java Object Model from data embedded in
a data stream (XML, non XML, Java etc). See Tutorials. Download.

Templating

(tick)
 FreeMarker
(tick)
 XSL
(tick)
 StringTemplate

(tick)
 FreeMarker
(error)
 XSL
(error)
 StringTemplate

Enables fragment-level templating using different templating solutions
e.g. FreeMarker, StringTemplate and XSLT. See Tutorials. Download.

Routing

(tick)
 File
(tick)
 JMS
(tick)
 Database

(tick)
 File
(tick)
 JMS
(tick)
 Database

Enables routing of message fragments (including populated object models)
to a range of different destination types. See Tutorials. Download.

Scripting

(tick)
 Groovy

(tick)
 Groovy

Enables fragment-level Transformation/Analysis using different
scripting languages. Currenly supports Groovy. See Tutorials. Download.

EDI

(tick)

(tick)

Smooks Cartridge that converts an EDI message data stream
into a stream of SAX events. Download.

CSV

(tick)

(tick)

Smooks Cartridge that converts a Comma Separated Value (CSV)
data stream into a stream of SAX events. Download.

JSON

(tick)

(tick)

Smooks Cartridge that converts a JSON formatted
data stream into a stream of SAX events. (Since v1.1).

Misc

(tick)

(error)

Contains miscellaneous resources for performing common analysis/transformation tasks
on an XML stream e.g. rename an element, delete an element, delete and attribute etc. Download.

Servlet

(tick)

(error)

Plugs Smooks into the J2EE Servlet Container. This allows Smooks to be
used for Servlet Response Analysis and Transformation e.g. to optimse the
Servlet Response for the requesting browser make/model. See Tutorials. Download.

CSS

(tick)

(error)

Makes Cascading Style Sheet (CSS) information easily available to web content
analysis or transformation logic. Supports linked or inline CSS Download.

Calc

(tick)

(tick)

Smooks Cartridge that can do simple calculation tasks.
At the moment it only contains a Counter visitor. (Since v1.1).

  • No labels