« Podcasting | Main | "Crypto" Book »

Creating 'Calendar' Instances with Betwixt

At work, I'm currently developing a prototype for mapping between legacy and modern messaging data structures. The modern data structures are actually JAX-RPC Web Service stubs generated from a Web Services Description Language (WSDL) document. The JAX-RPC reference implementation generates attributes of type java.util.Calendar to represent XML Schema 'datetime' elements. This is fine, exception that Calendar is not a valid Java Bean since it lacks a public default constructor.

This is normally not a problem, since a new instance of Calendar can be had by invoking 'Calendar.getInstance()'. However, I'm using Betwixt to load an XML document into the JAX-RPC stubs, and Betwixt assumes that the data structures are all Java Beans with default constructors. Betwixt chokes onces it tries to create a new instance of Calendar to hold date/time information.

So, I sought out a solution to configure Betwixt to construct Calendar appropriately. It turns out that Betwixt is lacking in documentation, or at least, well-organized documentation. I eventually figured out a good way to address the problem.

Create a class (i.e. CalendarCreator):

public class CalendarCreator implements ChainedBeanCreator

  public CalendarCreator() { }

  public Object create(ElementMapping mapping, ReadContext context, BeanCreationChain chain)
  {
    if (Calendar.class.equals(mapping.getType()))
    {
      return Calendar.getInstance();
    }

    return chain.create(mapping, context);
  }

}

Then, associate the CalendarCreator with the Creator Chain used by the BeanReader when reading your XML document:

BeanReader beanReader = new BeanReader();
beanReader.getXMLIntrospector().getConfiguration().setUseBeanInfoSearchPath(true);

// add Calendar creator to chain
BeanCreationList chain = BeanCreationList.createStandardChain();
chain.insertBeanCreator(1, new CalendarCreator());
beanReader.getReadConfiguration().setBeanCreationChain(chain);

This will result in the CalendarCreator instance being consulted regarding attributes of type Calendar. I'm sure that this approach can be applied to any class that needs to be constructed in a manner other than just with the default constructor.