As well as 65+ bug fixes, Smooks v1.3 includes the following new features:
- Greatly improved XPath support in selectors. This allows you to write more complex selectors with XPath syntax. See here. See JIRA.
- Support for Fixed Length Field (FLF) messages. See JIRA.
- Java Binding:
- String manipulation functions for tweaking CSV and FLF fields before forwarding to Smooks components. See JIRA.
- Support premature filter termination. See JIRA.
- Simple fragment splitter. See JIRA.
- CSV Header Validation. See JIRA.
There is one (known) backward compatibility issue in Smooks v1.3 with respect to resolution of EDI <import> resource URL. See JIRA.
The easiest way to get started with Smooks is to download and try out some of the examples. The examples are the perfect base upon which to integrate Smooks into your application.
See the FAQ
For details on how to integrate Smooks into your project via Maven, see the Maven & Ant Guide.
For details on how to integrate Smooks into your project via Ant, see the Maven & Ant Guide.
The most commonly accepted definition of Smooks would be that it is a "Transformation Engine". However, at it's core, Smooks makes no mention of "data transformation". The smooks-core codebase is designed simply to support hooking of custom "Visitor" logic into an Event Stream produced by a data Source of some kind (XML, CSV, EDI, Java etc). As such, smooks-core is simply a "Structured Data Event Stream Processor".
Of course, the most common application of this will be in the creation of Transformation solutions i.e. implementing Visitor logic that uses the Event Stream produced from a Source message to produce a Result of some other kind. The capabilities in smooks-core enable more than this however. We have implemented a range of other solutions based on this processing model:
- Java Binding: Population of a Java Object Model from the Source message.
- Message Splitting & Routing: The ability to perform complex splitting and routing operations on the Source message, including routing to multiple destinations concurrently, as well as routing different data formats concurrently (XML, EDI, CSV, Java etc).
- Huge Message Processing: The ability to declaratively consume (transform, or split and route) huge message without writing lots of high maintenance code.
Basic Processing Model
As stated above, the basic principal of Smooks is to take a data Source of some kind (e.g. XML) and from it generate an Event Stream, to which you apply Visitor logic to produce a Result of some other kind (e.g. EDI).
Many different data Source and Result types are supported, meaning many different transformation types are supported, including (but not limited to):
- XML to XML
- XML to Java
- Java to XML
- Java to Java
- EDI to XML
- EDI to Java
- Java to EDI
- CSV to XML
- CSV to ...
- etc etc
In terms of the Event Model used to map between the Source and Result, Smooks currently supports DOM and SAX Event Models. We will concentrate on the SAX event model here. If you want low level details on either models, please consult the Smooks Developer Guide. The SAX event model is based on the hierarchical SAX events generated from an XML Source (startElement, endElement etc). However, this event model can be just as easily applied to other structured/hierarchical data Sources (EDI, CSV, Java etc).
The most important events (typically) are the visitBefore and visitAfter events. The following illustration tries to convey the hierarchical nature of these events.
In order to consume the SAX Event Stream produced from the Source message, you need to implement one or more of the SAXVisitor interfaces (depending on which events you need to consume).
The following is a very simple example of how you implement Visitor logic and target that logic at the visitBefore and visitAfter events for a specific element in the Event Stream. In this case we target the Visitor logic at the <xxx> element events.
As you can see, the Visitor implementation is very simple; one method implementation per event. To target this implementation at the <xxx> element visitBefore and visitAfter events, we need to create a Smook configuration as shown (more on "Resource Configurations" in the following sections).
The Smooks code to execute this is very simple:
Smooks smooks = new Smooks("/smooks/echo-example.xml");
Note that in this case we don't produce a Result. Also note that we don't interact with the "execution" of the filtering process in any way, since we don't explicitly create an ExecutionContext and supply it to the Smooks.filterSource method call.
This example illustrated the lower level mechanics of the Smooks Programming Model. In reality however, users are not going to want to solve their problems by implementing lots Java code themselves from scratch. For this reason, Smooks is shipped with quite a lot of pre-built functionality i.e. ready to use Visitor logic. We bundle this Visitor logic based on functionality and we call the bundles "Cartridges".
Smooks Resources (Visitors etc)
Smooks executes by taking a data stream of one form or another (XML, EDI, Java, JSON, CSV etc) and from it, it generates an event stream, which it uses to fire different types of "Visitor logic" (Java, Groovy, FreeMarker, XSLT etc). The result of this process can be to produce a new data stream in a different format (i.e. a traditional "transformation"), bind data from the source message data stream to java objects to produce a populated Java object graph (i.e. a "Java binding"), produce many smaller messages (message splitting) etc.
At a core level (inside Smooks), it just sees all of the "Visitor logic" etc as "Smooks Resources" (SmooksResourceConfiguration) that are configured to be applied based on an event selector (i.e. event from the source data event stream). This is a very generic processing model and makes a lot of sense from the point of view of Smooks Core and it's architecture (maintainance etc). However, it can be a little too generic from a usability perspective because everything looks very similar in the configuration. To help with this, Smooks v1.1 introduced an "Extensible Configuration Model" feature. This allows specific resource types (Javabean binding configs, FreeMarker template configs etc) to be specified in the configuration using dedicated XSD namespaces of their own.
Example (Java Binding Resource):
<jb:bean beanId="lineOrder" class="example.trgmodel.LineOrder" createOnElement="example.srcmodel.Order">
<jb:wiring property="lineItems" beanIdRef="lineItems" />
<jb:value property="customerId" data="header/customerNumber" />
<jb:value property="customerName" data="header/customerName" />
Example (FreeMarker Template Resource):
When comparing the above examples to the pre Smooks v1.1 equivalents you can see that:
- The user now has a more strongly typed configuration that is domain specific in each case (and so easier to read).
- Because the v1.1+ configurations are XSD based, the user also gets autocompletion support from their IDE.
- No longer any need to define the actual handler for the given resource type e.g. the BeanPopulator for java bindings.
Smooks Resource "selectors" are a very important part of Smooks and how it works. They instruct Smooks as to which message fragments to apply configured Visitor logic to, as well working as a simple opaque lookup value for non Visitor logic.
When the resource is a Visitor implementation (e.g. <jb:bean>, <ftl:freemarker> etc), Smooks will interpret the selector as an XPath (like) selector. There are a number of things to be aware of:
- The order in which the XPath expression is applied is the reverse of normal order e.g. as applied by an XSLT. Smooks works backwards from the targeted fragment element, as opposed to forwards from the message root element.
- Not all of the XPath specification is supported. S