castor

Problem using Castor's Unmarshaller class with Spring framework's Inverstion of Control

Details

  • Type: Improvement Improvement
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 1.1
  • Fix Version/s: 1.1.1
  • Component/s: Spring XML
  • Labels:
    None
  • Number of attachments :
    1

Description

This issue was prompted by the following e-mail thread

http://www.nabble.com/Castor-unmarshalling---Spring-factory-bean-tf3534068.html#a9879105

This issue is in relation to Castor and the Spring Framework. The Spring framework is based on Inversion of Control (also known as Injection Dependency) in which objects are loaded through the Spring factory bean rather than being instantiated directly through the code.

The problem with Castor is that if we load the the Unmarshaller object through the Spring factory bean, as well as load the Java object that is to be marshalled to through the Spring factory bean, then it is not possible to use the Unmarshaller to marshal to that object. This is because the only way you can pass a pre-instantiated object to the Unmarshaller for unmarshalling is through the Unmarshaller(Object) constructor. But the Unmarshaller constructor cannot be called directly by our code, because (according to Inversion of Control) the Unmarshaller is loaded by the Spring factory bean.

There is two possible solutions for this delimma (let us assume in the solutions below that the object that we want to unmarshall to is called dvConfig):

1. First possible solution is to add a new method
called Unmarshaller.setObject(Object) or
Unmarshaller.setRootObject(Object), so that after I
obtain an instance of both the unmarshaller and the
dvConfig objects through the Spring factory bean, I
can call the setObject() method to set the dvConfig
object on the unmarshaller object.

For example, in the spring xml file we could have the
following DAO bean that would have access to both the
unmarshaller object and the dvConfig object:

<bean id="dvConfigDAO"
class="com.nget.japps.model.dv.DvConfigDAO">
<property name="unmarshaller" ref="unmarshaller" />
<property name="dvConfig" ref="dvConfig" />
</bean>

And inside of the dvConfigDAO we would write the
following code:

// Set the object that we want to unmarshall to
unmarshaller.setObject(dvConfig);
// Set the castor xml mapping file
unmarshaller.setMapping(map);

// Create a Reader to the file to unmarshall from
Reader reader = new FileReader(xmlFilePath);

// Unmarshall the xml into the dv config object
dvConfig = (DvConfig) unmarshaller.unmarshal(reader);

2. Second possible solution I think is to somehow
modify either the CastorResolverFactoryBean or
CastorUnmarshallerFactoryBean so that we could pass in
an instance of an object that we want to unmarshall
to. For example, in the spring xml file we would have
something like this:

<bean id="unmarshaller"
class="org.springframework.xml.castor.CastorUnmarshallerFactoryBean">
<property name="resolver" ref="resolver"/>
<property name="object" ref="dvConfig"/>
</bean>

Activity

Hide
Werner Guttmann added a comment -

Initial patch for Unmarshaller for review.

Show
Werner Guttmann added a comment - Initial patch for Unmarshaller for review.
Hide
Werner Guttmann added a comment -

Patch committed to SVN trunk.

Show
Werner Guttmann added a comment - Patch committed to SVN trunk.
Hide
Werner Guttmann added a comment -

Just looking at the second option right now: it would be (in theory) easy to add a new setRootObject() method to the CastorUnmarshallerFactoryBean to allow customization. Problem with this is that this 'unmarshaller' as configured in the Spring application context would be always hard-wired to a root object of the given type. Somehow I wonder whether this is actually desirable ?

Show
Werner Guttmann added a comment - Just looking at the second option right now: it would be (in theory) easy to add a new setRootObject() method to the CastorUnmarshallerFactoryBean to allow customization. Problem with this is that this 'unmarshaller' as configured in the Spring application context would be always hard-wired to a root object of the given type. Somehow I wonder whether this is actually desirable ?
Hide
Saladin Sharif added a comment -

I agree. If I use the setRootObject() of the CastorUnmarshallerFactoryBean then that would mean that in the spring xml file I would have to have an 'unmarshaller' configured for every single object that I want to unmarshall to. That is not a very elegant solution. I definitely think that using the first solution (i.e. Unmarshaller.setObject() ) is a much cleaner solution. And in fact I am using that solution in my code right now. It works wonderfully. Thanks for adding the Unmarshaller.setObject()

Show
Saladin Sharif added a comment - I agree. If I use the setRootObject() of the CastorUnmarshallerFactoryBean then that would mean that in the spring xml file I would have to have an 'unmarshaller' configured for every single object that I want to unmarshall to. That is not a very elegant solution. I definitely think that using the first solution (i.e. Unmarshaller.setObject() ) is a much cleaner solution. And in fact I am using that solution in my code right now. It works wonderfully. Thanks for adding the Unmarshaller.setObject()
Hide
Werner Guttmann added a comment -

Based upon above comments ....

Show
Werner Guttmann added a comment - Based upon above comments ....

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: