Thursday, December 24, 2009

Mavenizing your XMLBeans Code Generation

Automating your Code Generation


XMLBeans provides a nifty code generator (scomp) that creates Java POJOs to represent XML Schema Types from XSD documents. You can run scomp from the command line, an ant build file, but if you work within the context of Maven projects, I recommend taking advantage of the XMLBeans mojo

As with most things maven, if you follow the standard conventions, things just work. The trick to setting up your pom.xml to execute your code generation is to fit into the convention, and in this case it is not that difficult.

Keeping the source around

I happen to like having the generated source code in the context of my projects, and scomp lets you specify where you want it to place the source it generates. Maven has conventions around the directory structure for your source code, so we need to ensure our source goes to the right place - in this case it would be
src/generated/java
Generated code should be "throwaway", in other words we should be able to safely delete it, and run the code generator again. We can specify in our pom.xml that we would like to have the generated sources removed as part of the clean process. We do this by configuring the maven-clean-plugin.
<plugin>
 <groupid>org.apache.maven.plugins</groupid>
  <artifactid>maven-clean-plugin</artifactid>
  <configuration>
   <filesets>
     <fileset>
      <directory>src/generated/java</directory>
     </fileset>
    </filesets>
  </configuration>
</plugin>
Now the sources will be cleaned out prior to any code generation.

Generating the Java Source

Now we can configure the XMLBeans plugin to do our bidding. First we tell Maven we want it to run at all - the plugin "plugs" itself into the proper lifecycle events in Maven so you don't have to worry about that. Then it's a matter of providing scomp with the appropriate options. Here again there are conventions that are good to follow, for example you may note the schema directory location and the .xsdconfig file location.

<plugin> 
 <groupid>org.codehaus.mojo</groupid> 
 <artifactid>xmlbeans-maven-plugin</artifactid> 
 <version>2.3.3</version> 
 <executions> 
  <execution> 
   <goals> 
    <goal>xmlbeans</goal> 
   </goals> 
  </execution> 
 </executions> 
 <inherited>true</inherited> 
 <configuration> 
  <schemadirectory>src/main/xsd/MyServiceTypes</schemadirectory> 
  <sourceschemas> 
   <sourceschema>MyType.xsd</sourceschema> 
  </sourceschemas> 
  <xmlconfigs> 
   <xmlconfig implementation="java.io.File">src/main/xsd/xmlbeans.xsdconfig</xmlconfig> 
  </xmlconfigs> 
  <sourcegenerationdirectory>src/generated/java</sourcegenerationdirectory>
  <classgenerationdirectory>${project.build.directory}/generated-classes</classgenerationdirectory> 
  <javasource>1.5</javasource> 
  <nojavac>true</nojavac> 
 </configuration> 
</plugin>

Overriding the Package Names

By default, XMLBeans uses the schema namespace as inspiration for creating your Java package names. In some cases this works well, but a schema designer may not take Java developer usability into account when creating XSD documents. For example, you may not appreciate a package name of "com.mylongcompanyname.services.public.purchaseorders.v356", and would prefer something like "com.mylongcompanyname.po". Happily, scomp will grant your wish by honouring any overrides you have defined in an xsdconfig file. In this case, we would create a file (xmlbeans.xsdconfig) with the following content:

<xb:config xb="http://www.bea.com/2002/09/xbean/config">      

 <xb:namespace uri="http://services.mylongcompanyname.com/public/purchaseorders/v356">         
  <xb:package>com.mylongcompanyname.po</xb:package>     
 </xb:namespace>  
</xb:config>

Gratification

Now you can run "mvn clean install" on your pom and marvel at the automation you just implemented.

2 comments:

  1. Tim,

    Post some photo tips and techniques.

    Srikanth
    (www.srikanthmadduri.com)

    ReplyDelete
  2. Juicy! Content dense and direct.

    Unfortunately there's so much stuff here I don't understand that I don't know what questions to ask. Still, if you post more I might be able to absorb some of it.

    -h

    ReplyDelete