Thursday, 23 February 2012

XML Schema to Java Binding - Large Enumerations

Occasionally it becomes necessary to convert XML Schema based enumeration definitions into Java objects for use in application software.

A number of different binding technologies exist to support this process, examples are JAXB (Java Architecture for XML Binding) and Castor to name but a few.

An interesting restriction in the generation of Java Enumeration objects when building source using JAXB is a size limit on the number of enumeration constants that can be declared within an enumeration declaration. An extract from the namespace definition is shown below.

<xs:attributeGroup name="typesafeEnumClassDefaults">
        <xs:attribute name="typesafeEnumMemberName"
                      default="skipGeneration" 
                      type="jaxb:typesafeEnumMemberNameType"/>
        <xs:attribute name="typesafeEnumBase" 
                      default="xs:string" 
                      type="jaxb:typesafeEnumBaseType"/>
        <xs:attribute name="typesafeEnumMaxMembers" 
                      type="xs:int" 
                      default="256"/>
</xs:attributeGroup>

As can be seen from the attribute typesafeEnumMaxMembers the default limit is 256. Parsing some XML Schema models, for example such as those representing XSD exports of C24 IO SWIFT message models, will result in that limit being encountered. The XJC parser will produce the following WARNING output indicating that the 256 limit has been reached:

[WARNING] Error while parsing schema(s).Location [ file:/Users/mattvickery/projects/l8mdv-si-samples/sample-messaging/src/main/resources/SWIFT%20FIN%20November%202011%20Data%20Dictionary.xsd{12060,57}].
org.xml.sax.SAXParseException: Simple type "Field503LoginSelectErrorCode" was not mapped to Enum due to EnumMemberSizeCap limit. Facets count: 599, current limit: 256. You can use customization attribute "typesafeEnumMaxMembers" to extend the limit.
 at ...warning(ErrorReporter.java:88)
 at ...shouldBeMappedToTypeSafeEnumByDefault(SimpleTypeBuilder.java:459)
 at ...find(SimpleTypeBuilder.java:419)
 at ...compose(SimpleTypeBuilder.java:296)
 at ...build(SimpleTypeBuilder.java:172)

Although it's a WARNING that's generated, the resulting enumeration class is not generated rather than partially generated with 256 enumeration constants.

In order to overcome this limitation a change in configuration is necessary for Enumeration binding generation, this can be done by creating an entry such as the following in a custom JAXB bindings file and making this available to the build system of choice.

<jaxb:bindings 
        schemaLocation="file:SWIFT-FIN-November-2011-Data-Dictionary.xsd">
        <jaxb:bindings>
            <jaxb:globalBindings typesafeEnumMaxMembers="600"/>
        </jaxb:bindings>
</jaxb:bindings>

Following this change, generation of Java Enumeration objects whose enumeration constants number greater than the default should be generated without WARNING and result in an ordinary class file.

No comments:

Post a Comment