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....
3 comments:
Hi, could you help me with an update to this article and the new repository and plugins addresses? That would be nice, thanks!
What exactly are you missing?
The maven-jaxb2-plugin (lastest is 0.7.5) is available from Maven Central, and the property-listener-injector is still at http://download.java.net/maven/2/
HTH,
Harald
thanks for the reply! Got it working! A tiny problem though, the generated code is firing the changes before the change actually happens:
firePropertyChange(...)
this.name = name;
This is not the correct behavior for property changes to be fired, this is actually for vetoablepropertychange, where the new value is validated and if it passed, then the value is assigned. In my case, property changes and event is fired.
Right? Solutions? Thanks again!
Post a Comment