XVisitor is a plugin for the xjc code generator to enrich the JAXB model
generated from an XML schema so that users can work with the Visitor
pattern on this model.
Showing posts with label JAXB. Show all posts
Showing posts with label JAXB. Show all posts
02 December 2011
29 August 2011
Eclipse Maven Integration Extensions
For me, the most important new feature in Eclipse 3.7.0 (Indigo) is the improved Maven Integration, formerly developed by Sonatype under the name of m2eclipse, now an official Eclipse subproject under the name of m2e.
m2eclipse and Eclipse sometimes used to have different opinions on what was going on in the workspace, and so we had to go through series of refresh/update dependencies/update configuration/rebuild voodoo (or "m2eclipse dance" as some called it) to get projects in a good state. (Quote from the m2e Wiki).
m2e has a different approach. First of all, it complains when detecting a Maven plugin in one of your POMs that it cannot handle out of the box. m2e flags your POM with an error marker that will not go away until you tell m2e what do to about the unknown plugin. The easy way out is a Quick Fix to ignore the plugin, which means you'll have to run the corresponding Maven goal manually when you need it.
However, when the Maven plugin in question generates source code or post-processes byte code, this is usually not sufficient - ideally, Eclipse and m2e should pick up the required build steps from your POM automatically.
This issue is addressed by m2e extensions, which provide the missing link between Eclipse project builders and Maven plugins. An m2e extension for a given Maven plugin not only invokes the required mojos but also informs Eclipse about new source or binary folders created by the mojos, so that Eclipse and Maven can stay in sync.
My projects use a number of Maven plugins that are not supported by m2e out of the box, e.g. for JAXB and OpenJPA, so I started creating some custom extensions for these plugins, based on a GitHub fork of the official m2e extensions from Sonatype.
See the wiki page at GitHub for more details. The GitHub project also contains an Eclipse update site (aka p2 repository) for installing the plugins. Time permitting, I'll try to make these extensions available via the Eclipse marketplace.
For any fixes, additions or new extensions, feel free to send my pull requests.
m2eclipse and Eclipse sometimes used to have different opinions on what was going on in the workspace, and so we had to go through series of refresh/update dependencies/update configuration/rebuild voodoo (or "m2eclipse dance" as some called it) to get projects in a good state. (Quote from the m2e Wiki).
m2e has a different approach. First of all, it complains when detecting a Maven plugin in one of your POMs that it cannot handle out of the box. m2e flags your POM with an error marker that will not go away until you tell m2e what do to about the unknown plugin. The easy way out is a Quick Fix to ignore the plugin, which means you'll have to run the corresponding Maven goal manually when you need it.
However, when the Maven plugin in question generates source code or post-processes byte code, this is usually not sufficient - ideally, Eclipse and m2e should pick up the required build steps from your POM automatically.
This issue is addressed by m2e extensions, which provide the missing link between Eclipse project builders and Maven plugins. An m2e extension for a given Maven plugin not only invokes the required mojos but also informs Eclipse about new source or binary folders created by the mojos, so that Eclipse and Maven can stay in sync.
My projects use a number of Maven plugins that are not supported by m2e out of the box, e.g. for JAXB and OpenJPA, so I started creating some custom extensions for these plugins, based on a GitHub fork of the official m2e extensions from Sonatype.
See the wiki page at GitHub for more details. The GitHub project also contains an Eclipse update site (aka p2 repository) for installing the plugins. Time permitting, I'll try to make these extensions available via the Eclipse marketplace.
For any fixes, additions or new extensions, feel free to send my pull requests.
20 March 2011
JAXB Marshalling with Custom Namespace Prefixes
The Problem
- You have an XML schema with multiple XML namespaces.
- You generate a JAXB model with xjc.
- You build a JAXB document model and use the JAXB Marshaller to create XML from the model.
- You want to override the default namespace prefixes
ns1, ns2, ...created by the Marshaller.
14 May 2010
Java XML Binding with Property Change Support
In an earlier post, I was talking about generating Java classes with xjc with property change support which is not enabled by default. This post explains the details, an in fact the Maven build explained below is a lot a easier than my original approch with Ant which required some downloads to set things up.
The general idea is same as described by Kohsuke Kawaguchi in a post of 2007, but his POM is broken with the current stage of the Maven repositories. In addition, there is a tweak with the PropertyListener customization.
So here is a little example schema:
We use the following file bindings.xjb to customize the Java classes generated by xjc. We make all classes serializable and include support for PropertyChangeListeners.
The following POM takes care of the code generation:
You do need to use the 1.1-SNAPSHOT version of the property-listener-injector, as the 1.0 release only supports VetoableChangeListeners and not the PropertyChangeListeners we want to use. The <li:listener> element in the bindings file is used to define the listener class.
It is important to exclude the jaxb-xjc dependency from the property-listener-injector, or else it will try to download an non-existing snapshot version. Looks like something is broken in the java.net repository, but then again, working with snapshot releases is always dangerous....
The general idea is same as described by Kohsuke Kawaguchi in a post of 2007, but his POM is broken with the current stage of the Maven repositories. In addition, there is a tweak with the PropertyListener customization.
So here is a little example schema:
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://www.example.org/person/" targetNamespace="http://www.example.org/person/">
<complexType name="Person">
<sequence>
<element name="firstName" type="string"></element>
<element name="lastName" type="string"></element>
<element name="address" type="tns:Address"></element>
</sequence>
</complexType>
<complexType name="Address">
<sequence>
<element name="street" type="string"></element>
<element name="houseNumber" type="string"></element>
<element name="city" type="string"></element>
<element name="postalCode" type="string"></element>
<element name="country" type="string"></element>
</sequence>
</complexType>
</schema>
We use the following file bindings.xjb to customize the Java classes generated by xjc. We make all classes serializable and include support for PropertyChangeListeners.
<?xml version="1.0" encoding ="UTF-8"?>
<jaxb:bindings
schemaLocation="person.xsd"
version="2.1"
xmlns:li="http://jaxb.dev.java.net/plugin/listener-injector"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:bindings node="/xs:schema">
<jaxb:globalBindings>
<jaxb:serializable uid="1" />
</jaxb:globalBindings>
<li:listener>java.beans.PropertyChangeListener</li:listener>
</jaxb:bindings>
</jaxb:bindings>
The following POM takes care of the code generation:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>jaxb-properties</groupId>
<artifactId>jaxb-properties</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>JAXB PropertyListener Demo</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.7.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<extension>true</extension>
<generatePackage>com.example.jaxb</generatePackage>
<schemaIncludes>
<schemaInclude>person.xsd</schemaInclude>
</schemaIncludes>
<bindingIncludes>
<bindingInclude>bindings.xjb</bindingInclude>
</bindingIncludes>
<args>
<arg>-Xinject-listener-code</arg>
</args>
</configuration>
<dependencies>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
<version>2.1.13</version>
</dependency>
<dependency>
<groupId>org.jvnet.jaxb2-commons</groupId>
<artifactId>property-listener-injector</artifactId>
<version>1.1-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-xjc</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
You do need to use the 1.1-SNAPSHOT version of the property-listener-injector, as the 1.0 release only supports VetoableChangeListeners and not the PropertyChangeListeners we want to use. The <li:listener> element in the bindings file is used to define the listener class.
It is important to exclude the jaxb-xjc dependency from the property-listener-injector, or else it will try to download an non-existing snapshot version. Looks like something is broken in the java.net repository, but then again, working with snapshot releases is always dangerous....
Subscribe to:
Posts (Atom)