License     Codehaus     OpenEJB     OpenJMS     OpenORB     Tyrex     

Old releases
  General
  Release 1.3
  Release 1.3rc1
  Release 1.2

Main
  Home
  About
  Features
  Download
  Dependencies
  Reference guide
  Publications
  JavaDoc
  Maven 2 support
  Maven 2 archetypes
  DTD & Schemas
  Recent HTML changes
  News Archive
  RSS news feed
  Project Wiki

Development/Support
  Mailing Lists
  SVN/JIRA
  Contributing
  Support
  Continuous builds
  Prof. services

Related projects
  Spring ORM support
  Spring XML factories
  WS frameworks

XML
  XML

XML Code Generator
  XML Code Generator

JDO
  Introduction
  First steps
  Using JDO
  JDO Config
  Types
  JDO Mapping
  JDO FAQ
  JDO Examples
  JDO HOW-TOs
  Tips & Tricks
  Other Features
  JDO sample JAR

Tools
  Schema generator

Advanced JDO
  Caching
  OQL
  Trans. & Locks
  Design
  KeyGen
  Long Trans.
  Nested Attrs.
  Pooling Examples
  LOBs
  Best practice

DDL Generator
  Using DDL Generator
  Properties
  Ant task
  Type Mapping

More
  The Examples
  3rd Party Tools
  JDO Tests
  XML Tests
  Configuration
 
 

About
  License
  User stories
  Contributors
  Marketplace
  Status, Todo
  Changelog
  Library
  Contact
  Project Name

  



Castor XML -- Code generator bindings

Documentation Author(s):
Werner Guttmann


Introduction
Binding File
    <binding> element
    <include> element
    <package> element
    <namingXML> element
    <componentBinding> element
    <java-class> element
    <member> element
    <contentMember> element
        Syntax
        Description
        Example
    <enumBinding> element
        Example
    Not implemented yet
        <javadoc>
        <interface> element
Class generation conflicts
    Collision reporting
        Reporting mode 'warnViaConsoleDialog'
    Automatic collision resolution
        Selecting the strategy
        'XPATH' strategy
        'TYPE' strategy
        Conflicts covered


Introduction

This section defines the Castor XML binding file and describes, with examples, how to use it.

The default binding used to generate the Java Object Model from an XML schema may not meet your expectations. For instance, the default binding doesn't deal with naming collisions that can appear because XML Schema allows an element declaration and a complexType definition to use the same name. The source generator will attempt to create two Java classes with the same qualified name. However, the second class generated will simply overwrite the first one.

Another example of where the default source generator binding may not meet your expectations is when you want to change the default datatype binding provided by Castor or when you want to add validation rules by implementing your own validator and passing it to the Source Generator.

Binding File

The Binding declaration is an XML-based language that allows the user to control and tweak details about source generation for the generated classes. The aim of this section is to provide an overview of the binding file and a definition of the several XML components used to define this binding file.

A more in-depth presentation will be available soon in the Source Generator User Document (PDF).

<binding> element

<binding
    defaultBindingType = (element|type)>
    (include*,
     package*,
     namingXML?,
     elementBinding*,
     attributeBinding,
     complexTypeBinding,
     groupBinding)
</binding>

The binding element is the root element and contains the binding information.

NameDescriptionDefaultRequired?
defaultBindingType Controls the class creation mode for details on the available modes. Please note that the mode specified in this attribute will override the binding type specified in the castorbuilder.properties file. element No

<include> element

<include
    URI = xsd:anyURI/>

-URI:The URI of the binding file to include.

This element allows you to include a binding declaration defined in another file. This allows reuse of Binding files defined for various XML Schemas.

<package> element

<package>
    name = xsd:string
    (namespace|schemaLocation) = xsd:string>
</package>

- name:A fully qualified java package name.
- namespace:An XML namespace that will be mapped to the package name defined by the name element.
- schemaLocation:A URL that locates the schema to be mapped to the package name defined by the name element.

The targetNamespace attribute of an XML Schema identifies the namespace in which the XML schema elements are defined. This language namespace is defined in the generated Java source as a package declaration. The <package/> element allows you to define the mapping between an XML namespace and a Java package.

Moreover, XML Schema allows you to factor the definition of an XML Schema identified by a unique namespace by including several XML Schemas instances to build one XML Schema using the <xsd:include/> element. Please make sure you understand the difference between <xsd:include/> and <xsd:import/>. <xsd:include/> relies on the URI of the included XML schema. This element allows you to keep the structure hierarchy defined in XML Schema in a single generated Java package. Thus the binding file allows you to define the mapping between a schemaLocation attribute and a Java package.

<namingXML> element

<namingXML>
   (elementName,complexTypeName,modelGroupName)
</namingXML>

<elementName|complexTypeName|modelGroupName>
    (prefix?, suffix?) = xsd:string
</elementName|complexTypeName|modelGroupName>

- prefix:The prefix to add to the names of the generated classes.
- suffix:The suffix to append to the the names of the generated classes.

One of the aim of the binding file is to avoid naming collisions. Indeed, XML Schema allows elements and complexTypes to share the same name, resulting in name collisions when generating sources. Defining a binding for each element and complexType that share the same name is not always a convenient solution (for instance the BPML XML Schema and the UDDI v2.0 XML Schema use the same names for top-level complexTypes and top-level elements). The aim of the <naming/> XML element is to define a prefix and a suffix for the names of the classes generated for an element, a complexType or a model group definition.

Note:It is not possible to control the names of the classes generated to represent nested model groups (all, choice, and sequence).

<componentBinding> element

<elementBinding|attributeBinding|complexTypeBinding|groupBinding
    name = xsd:string>
   ((java-class|interface|member|contentMember),
     elementBinding*,
     attributeBinding*,
     complexTypeBinding*,
     groupBinding*)
</elementBinding|attributeBinding|complexTypeBinding|groupBinding>

name:
The name of the XML schema component for which we are defining a binding.

These elements are the tenets of the binding file since they contain the binding definition for an XML Schema element, attribute, complexType and modelGroup definition. The first child element (<java-class/>, <interface>, <member> or <contentMember/>) will determine the type of binding one is defining. Please note that defining a <java-class> binding on an XML Schema attribute will have absolutely no effect.

The binding file is written from an XML Schema point of view; there are two distinct ways to define the XML Schema component for which we are defining a binding. First we can define it through the name attribute.

The value of the name attribute uniquely identifies the XML Schema Component. It can refer to the top-level component using the NCName of that component or it can use a location language based on XPath3. The grammar of that language can be defined by the following BNF:

            [1]Path         ::= '/'LocationPath('/'LocationPath)*
            [2]LocationPath ::= (Complex|ModelGroup|Attribute|Element|Enumeration)
            [3]Complex      ::= 'complexType:'(NCName)
            [4]ModelGroup   ::= 'group:'NCName
            [5]Attribute    ::= '@'NCName
            [6]Element      ::= NCName
            [7]Enumeration  ::= 'enumType':(NCName)
        

Please note that as of Castor 1.1, all values for the name attribute have to start with a '/'.

The second option to identify an XML Schema Component is to embed its binding definition inside its parent binding definition.

For instance, the following binding definitions are equivalent and identify the element 'foo' defined in the top-level complexType 'fooType'.

<elementBinding name="/complexType:fooType/foo>
   <member name="MyFoo" handler="mypackage.myHandler"/>
</elementBinding>

<complexTypeBinding name="/fooType">
   <elementBinding name="/foo>
      <member name="MyFoo" handler="mypackage.myHandler"/>
   </elementBinding>
<complexTypeBinding>

<java-class> element

<java-class
    name? = xsd:string
    package? = xsd:string
    final? = xsd:boolean
    abstract? = xsd:boolean
    equals? = xsd:boolean
    bound? = xsd:boolean
    (implements*,extends?)
</java-class>

This element defines all the options for the class to be generated, including common properties such as class name, package name, and so on.

name:
The name of the class that will be generated.
package:
The package of the class to be generated. if set, this option overrides the mapping defined in the <package/> element.
final:
If true, the generated class will be final.
abstract:
If true, the generated class will be abstract.
equals:
If true, the generated class will implement the equals() and hashCode() method.
bound:
If true, the generated class will implement bound properties, allowing property change notification.

For instance, the following binding definition instructs the source generator to generate a class CustomTest for a global element named 'test', replacing the default class name Test with CustomTest.

<elementBinding name="/test">
   <java-class name="CustomTest" final="true"/>
</elementBinding>

In addition to the properties listed above, it is possible to define that the class generated will extend a class given and/or implement one or more interfaces.

For instance, the following binding definition instructs the source generator to generate a class TestWithInterface that implements the interface org.castor.sample.SomeInterface in addition to java.io.Serializable.

<elementBinding name="/test">
   <java-class name="TestWithInterface">
      <implements>org.castor.sample.SomeInterface</implements>
   </java-class>
</elementBinding>

The subsequent binding definition instructs the source generator to generate a class TestWithExtendsAndInterface that implements the interface org.castor.sample.SomeInterface in addition to java.io.Serializable, and extends from a (probably abstract) base class SomeAbstractBaseClass.

<elementBinding name="/test">
   <java-class name="TestWithExtendsAndInterface">
      <extends>org.castor.sample.SomeAbstractBaseClass</extends>
      <implements>org.castor.sample.SomeInterface</implements>
   </java-class>
</elementBinding>

The generated class SomeAbstractBaseClass will have a class signature as shown below:

...

public class TestWithExtendsAndInterface
   extends SomeAbstractBaseClass
   implements SomeInterface, java.io.Serializable {
   ...
        

<member> element

 <member
  name? = xsd:string
  java-type? = xsd:string
  wrapper? = xsd:boolean
  handler? = xsd:string
  visibility? = (public|protected|private)
  collection? = (array|vector|arraylist|hashtable|collection|odmg|set|map|sortedset)
  validator? = xsd:string/>

This element represents the binding for class member. It allows the definition of its name and java type as well as an implementation of FieldHandler to help the Marshaling framework in handling that member. Defining a validator is also possible. The names given for the validator and the fieldHandler must be fully qualified.

name:
The name of the class member that will be generated.
java-type:
the fully qualified name of the java type.
wrapper:
If true, a wrapper object will be generated in case the Java type is a java primitive.
handler:
The fully qualified name of the FieldHandler to use.
collection:
If the schema component can occur more than once then this attribute allows specifying the collection to use to represent the component in Java.
validator:
The fully qualified name of the FieldValidator to use.
visibility:
A custom visibility of the content class member generated, with the default being public.

For instance, the following binding definition:

   <elementBinding name="/root/members">
      <member collection="set"/>
   </elementBinding>

instructs the source generator to generate -- within a class Root -- a Java member named members using the collection type java.util.Set instead of the default java.util.List:

public class Root {

   private java.util.Set members;

   ...

}

The following (slightly amended) binding element:

   <elementBinding name="/root/members">
      <member name="memberSet" collection="set"/>
   </elementBinding>

instructs the source generator to generate -- again within a class Root -- a Java member named memberSet (of the same collection type as in the previous example), overriding the name of the member as specified in the XML schema:

public class Root {

   private java.util.Set memberSet;

   ...

}

<contentMember> element

Syntax

 <contentMember
  name? = xsd:string
  visiblity? = (public|protected|private)

Description

This element represents the binding for content class member generated as a result of a mixed mode declaraiton of a complex type definition. It allows the definition of its name and its visibility

name:
The name of the class member that will be generated, overriding the default name of _content.
visibility:
A custom visibility of the content class member generated, with the default being public.

Example

For complex type definition declared to be mixed such as follows ...

<complexType name="RootType" mixed="true">
   <sequence>
      ...
   >/sequence>
>/complexType>

... the following binding definition ...

   <elementBinding name="/complexType:RootType">
      <contentMember name="customContentMember"/>
   </elementBinding>

instructs the source generator to generate -- within a class RootType -- a Java member named customContentMember of type java.lang.String:

public class RootType {

   private java.util.String customContentMember;

   ...
}

<enumBinding> element

<enumBinding>
   (enumDef)
</enumBinding>

<enumDef>
   (enumClassName = xsd:string, enumMember*)
</enumDef>

<enumMember>
   (name = xsd:string, value = xsd:string)
</enumMember>

The <enumBinding> element allows more control on the code generated for type-safe enumerations, which are used to represent an XML Schema <simpleType> enumeration.

Example

For instance, given the following XML schema enumeration definition:

<xs:simpleType name="durationUnitType">
  <xs:restriction base='xs:string'>
    <xs:enumeration value='Y' />
    <xs:enumeration value='M' />
    <xs:enumeration value='D' />
    <xs:enumeration value='h' />
    <xs:enumeration value='m' />
    <xs:enumeration value='s' />
  </xs:restriction>
</simpleType>

the Castor code generator would generate code where the default naming convention used during the generation would overwrite the first constant definition for value 'M' with the one generated for value 'm'.

The following binding definition defines -- through the means of an <enumMember> definition for the enumeration value 'M' -- a special binding for this value:

<enumBinding name="/enumType:durationUnitType">
  <enum-def>
    <enumMember>
      <value>M</value>
      <javaName>CUSTOM_M</javaName>
    </enumMember>
  </enum-def>
</enumBinding>

and instructs the source generator to generate -- within a class DurationUnitType -- a constant definition named CUSTOM_M for the enumeration value M.

Not implemented yet

<javadoc>

The <javadoc> element allows one to enter the necessary JavaDoc representing the generated classes or members.

<interface> element

    <interface>
        name = xsd:string
    </interface>

-name:The name of the interface to generate.

This element specifies the name of the interface to be generated for an XML schema component.

Class generation conflicts

As mentioned previously, you use a binding file for two main reasons:

- To customize the Java code generated
-To avoid class generation conflicts.

For the latter case, you'll (often) notice such collisions by looking at generated Java code that frequently does not compile. Whilst this is realtively easy for small(ish) XML schema(s), this task gets tedious for more elaborate XML schemas. To ease your life in the context of this 'collision detection', the Castor XML code generator provides you with a few advanced features. The following sections cover these features in detail.

Collision reporting

During code generation, the Castor XML code generator will run into situations where a class (about to be generated, and as such about to be written to the file system) will overwrite an already existing class. This, for example, is the case if within one XML schema there's two (local) element definitions within separate complex type definitions with the same name. In such a case, Castor will emit warning messages that inform the user that a class will be overwritten.

As of release 1.1, the Castor XML code generator supports two reporting modes that allow different levels of control in the event of such collisions, warnViaConsoleDialog and informViaLog mode.

ModeDescriptionSince
warnViaConsoleDialog Emits warning messages to stdout and ask the users whether to continue. 0.9
informViaLog Emits warning messages only via the standard logger. 1.1

Please select the reporting mode of your choice according to your needs, the default being warnViaConsoleDialog. Please note that the informViaLog reporting mode should be the preferred choice when using the XML code generator in an automated environment.

In general, the warning messages produced are very useful in assisting you in your creation of the binding file, as shown in below example for the warnViaConsoleDialog mode:

    Warning: A class name generation conflict has occurred between element
            '/Data/OrderReceipt/LineItem' and element '/Data/PurchaseOrder/LineItem'.
            Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
    Warning: A class name generation conflict has occurred between element
            '/Data/OrderReceipt/LineItem' and element '/Data/PurchaseOrder/LineItem'.
            Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
    Warning: A class name generation conflict has occurred between element
            '/Data/OrderReceipt/LineItem' and element '/Data/PurchaseOrder/LineItem'.
            Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
    Warning: A class name generation conflict has occurred between element
            'complexType:ReceiptLineItemType/Sku' and element 'complexType:LineItemType/Sku'.
            Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
    Warning: A class name generation conflict has occurred between element
            'complexType:ReceiptLineItemType/Sku' and element 'complexType:LineItemType/Sku'.
            Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
    Warning: A class name generation conflict has occurred between element
            'complexType:ReceiptLineItemType/Sku' and element 'complexType:LineItemType/Sku'.
            Please use a Binding file to solve this problem.Continue anyway [not recommended] (y|n|?)y
          

Reporting mode 'warnViaConsoleDialog'

As already mentioned, this mode emits warning messages to stdout, and asks you whether you want to continue with the code generation or not. This allows for very fine grained control over the extent of the code generation.

Please note that there is several setter methods on the org.exolab.castor.builder.SourceGenerator that allow you to fine-tune various settings for this reporting mode. Genuinly, we belive that for automated code generation through either Ant or Maven, the new informViaLog is better suited for these needs.

Automatic collision resolution

As of Castor 1.1.1, support has been added to the Castor XML code generator for a (nearly) automatic conflict resolution. To enable this new mode, please override the following property in your custom property file as shown below:

# Specifies whether automatic class name conflict resolution
# should be used or not; defaults to false.
#
org.exolab.castor.builder.automaticConflictResolution=true

As a result of enabling automatic conflict resolution, Castor will try to resolve such name collisions automatically, using one of the following two strategies:

NameDescriptionSinceDefault
xpath Prepends an XPATH fragment to make the suggested Java name unique. 1.1.1 Yes
type Appends type information to the suggested Java name. 1.1.1 No

Selecting the strategy

For selecting one of the two strategies during XML code generation, please see the documentation for the following code artefacts:

-setClassNameConflictResolver
-org.exolab.castor.builder.SourceGeneratorMain"
-Ant task definition
-Maven plugin for Castor XML

In order to explain the modus operandi of these two modes, please assume two complex type definitions AType and BType in an XML schema, with both of them defining a local element named c.

<complexType name="AType">
	<sequence>
		<element name="c" type="CType1" />
	</sequence>
</complexType>	          

<complexType name="BType">
	<sequence>
		<element name="c" type="CType2" />
	</sequence>
</complexType>

Without automatic collision resolution enabled, Castor will create identically named classes C.java for both members, and one will overwrite the other. Please note the different types for the two c element definitions, which requires two class files to be generated in order not to lose this information.

'XPATH' strategy

This strategy will prepend an XPATH fragment to the default Java name as derived during code generation, the default name (frequently) being the name of the XML schema artefact, e.g. the element name of the complex type name. The XPATH fragment being prepended is minimal in the sense that the resulting rooted XPATH is unique for the XML schema artefact being processed.

With automatic collision resolution enabled and the strategy 'XPATH' selected, Castor will create the following two classes, simply prepending the name of the complex type to the default element name:

-ATypeC.java
-BTypeC.java

'TYPE' strategy

This strategy will append 'type' information to the default Java name as derived during code generation, the default name (frequently) being the name of the XML schema artefact, e.g. the element name of the complex type name.

With automatic collision resolution enabled and the strategy 'TYPE' selected, Castor will create the following two classes, simply appending the name of the complex type to the default element name (with a default 'By' inserted):

-CByCType1.java
-CByCType2.java

To override the default 'By' inserted between the default element name and the type information, please override the following property in your custom property file as shown below:

# Property specifying the 'string' used in type strategy to be inserted 
# between the actual element name and the type name (during automatic class name 
# conflict resolution); defaults to 'By'.
org.exolab.castor.builder.automaticConflictResolutionTypeSuffix=ByBy

Conflicts covered

The Castor XML code generator, with automatic collision resolution enabled, is capable of resolving the following collisions automatically:

-Name of local element definition same as name of a global element
-Name of local element definition same as name of another local element definition.

Please note that collision resolution for a local to local collision will only take place for the second local element definition encountered (and subsequent ones).

 
   
  
   
 


Copyright © 1999-2005 ExoLab Group, Intalio Inc., and Contributors. All rights reserved.
 
Java, EJB, JDBC, JNDI, JTA, Sun, Sun Microsystems are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and in other countries. XML, XML Schema, XSLT and related standards are trademarks or registered trademarks of MIT, INRIA, Keio or others, and a product of the World Wide Web Consortium. All other product names mentioned herein are trademarks of their respective owners.