Watching a new world…

February 27th, 2007

Marshalling mit smooks - Erweiterung der javabeans-Cartridge

Für mein aktuellen JBoss-ESB-Projekt habe ich mir in den Kopf gesetzt eine eingehende XML-Datei in Entity-Beans zu transformieren. JBoss-ESB bietet das von Hause aus über die Integration des Smooks-Frameworks.

Kurz zur Erklärung: Smooks ist ein Framework zur generischen Verarbeitung von XML-Dateien, bzw. XML-Fragmenten. Die Verarbeitung ist einfach: In einer Mapping-datei wird für jeden XML-Pfad ein Handler definiert, der über das Visitor-Pattern irgendetwas ausführt. So kann für ein Element (oder einen Teilbaum) z.B. ein XSLT ausgeführt werden oder auch völlig individueller Java-Codeausgeführt werden.

Hier ein Beispiel aus der Mapping-Datei (smooks-res.xml):

<smooks-resource selector="ORDER"
useragent="from-type:text/xml:fullfillorder and
from:dvdstore:orderdispatchservice"
path="org.milyn.javabean.ProcessingPhaseBeanPopulator" >
<param name="beanId">ORDER</param>
<param name="beanClass">org.jboss.soa.esb.dvdstore.Order</param>
<param name="addToList">true</param>
</smooks-resource>
<smooks-resource selector="ORDER"
useragent="from-type:text/xml:fullfillorder and
from:dvdstore:orderdispatchservice"
path="org.milyn.javabean.ProcessingPhaseBeanPopulator" >
<param name="beanId">order</param>
<param name="attributeName">orderId</param>
</smooks-resource>
<!-- ... repeat for each attribute ... -->

In diesem Beispiel wird für jedes Element “ORDER” der ProcessingPhaseBeanPopulator “besucht”. Der ProcessingPhaseBeanPopulator wird vom smooks-Framework über eine sog. Cartridge mitgeliefert. Er hat die Aufgabe, aus dem element “ORDER” ein POJO, also eine Java-Klasse zu generieren. Attribute können zu Java-Properties gemappt werden und für Unterelemente können ebenfalls Visitors definiert werden, die beispielsweise wiederum Properties setzen. Sowie sogut. Das Problem ist bloss, dass bei “echten” Business-Daten die Datenstrukturen nicht so trivial sind, wie in dem vom ESB mitgelieferten Sample “quickstarts/transformXML2POJO“. Habe ich ein ORDER-Element mit 30 oder mehr Unterelementen, die die Properties der ORDER definieren, wird mein smooks-mappingfile recht umfangreich und vor allem sehr wartungsfeindlich.

Schön wäre eine Smooks-Cartridge, die die Unterlemente eines XML-Elements automatisch auf die Properties (genaugesagt auf die Setter) meines POJO Mappt. So kann mit minimaler Konfiguration eine ganze Reihe von umfangreichen XML-Strukturen auf POJOs transformiert werden, ohne tonnenweise quasi-redundanten Konfigurationscode zu erzeugen.

Hierzu habe ich die von smooks mitgelieferte javabeans-cartridge etwas modifiziert, so dass folgende Konfiguration möglich ist:

<smooks-resource selector="ORDER"
useragent="from-type:text/xml:fullfillorder and
from:dvdstore:orderdispatchservice"
path="org.milyn.javabean.MyProcessingPhaseBeanPopulator" >
<param name="beanId">order</param>
<param name="beanClass">org.jboss.soa.esb.dvdstore.Order</param>
<param name=”attributesFromChildren”>true</param>
</smooks-resource>

Damit das funktioniert, habe ich in der Klasse ProcessingPhaseBeanPopulator etwas Code ergänzt.

Zunächst das Einlesen der Konfiguration, die nun den Parameter “attributesFromChildren” unterstützen soll:

public void setConfiguration(SmooksResourceConfiguration config) {
// ... existing code
// START Added by om, form4
attributesFromChildren =
config.getBoolParameter("attributesFromChildren", false);
// END Added by om, form4
}

Und das Processing im eigentlichen Visitor:

public void visit(Element element, ContainerRequest request) {
Object bean = getBean(request);
// START Added by om, form4
if (attributesFromChildren) {
NodeList children = element.getElementsByTagName("*");
for (int i = 0; i < bean.getClass().getMethods().length; i++) {
Method method = bean.getClass().getMethods()[i];
if (method.getName().startsWith(”set”)) {
String attr = method.getName().replaceAll(”^set”, “”).toLowerCase();
for (int j = 0; j < children.getLength(); j++) {
Element child = (Element) children.item(j);
if (attr.equalsIgnoreCase(child.getNodeName())) {
try {
String val = DomUtils.getAllText(child, false);
method.invoke(bean, new Object[] { val });
} catch (Exception e) {
logger.error(e); // etwas ignorant…
}
break;
}
}
}
}
}
// END Added by om, form4
// … go on with original code …
}

2 Responses to “Marshalling mit smooks - Erweiterung der javabeans-Cartridge”

Tom Fennelly said:

Hi there.

I came across your post here. I’m the developer behind Smooks.

You might find the newer version of the Javabean Cartridge (v0.3-SNAPSHOT) a lot easier to use. It’s been enhanced to support:
1. Binding specification for a whole bean class through a single resource configuration - verses a requiring 1 config per bean property.
2. More complex types. Everything was a String prior to v0.3.
3. Creation of proper Object Graphs. Pre v0.3 didn’t support this at all.

See the tutorials at http://milyn.codehaus.org/Tutorials. Of particular interest might be the “javabean-populator”, and “edi-to-java” examples.

I think this makes this cartridge a lot more useful now. I also plan adding a JPA option on this stuff - to support persisting of the beans to a DB via something like Hibernate.

Regards,

Tom.

May 31st, 2007 at 01:34

Tom Fennelly said:

Sorry, I noticed that the blog software screwed up that link - it included the full-stop. Tutorials at http://milyn.codehaus.org/Tutorials

May 31st, 2007 at 01:36

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

klipal online pharmacy buy online cialis viagra online xanax cream for women order zyban online oxazepam buy alternative erection lorazepam cheap drugs 2003 tramadol tramadol market sales tramadol rx pills diazepam discount retail alternative to valium at gnc online drugstore tenuate order order levitra discount cialis buy the cheapest propecia online cheapest generic viagra online drugstore order cialis soft tabs over internet need no doctor cheapest levitra prices woman viagra soft tabs natural substitutes for viagra soft tabs online viagra natural levitra substitutes female cialis alternative