Stephen,

On Wed, Mar 29, 2006 at 08:14:43PM -0500, Stephen Bash wrote:
> You've got the right ideas, there's just something wrong with the
> implementation (which we'll try to figure out).  First question is
> what version of Castor are you using? 

     I'm using the latest release, 9.9.1, though I really want to move
up to 1.0 as soon as it's final, to avoid the XmlSerializer dependency
(which I'm told might be problematic in production).

> Next, what method are you calling to unmarshal the XML?  If you use
> one of the static unmarshal calls, then the mapping you have loaded
> won't take affect.

     I'm using  an unmarshaller instance.   I've posted the  full full
test case  for your reading pleasure, including  example data, mapping
files, jar files and class files, at:

     http://darksleep.com/castortest

     There's also tar.gz of the whole thing:

     http://darksleep.com/castortest/castortest.tar.gz

     Note that in this version I've named the various instance
variables "instanceCustomer" and "instanceAddress", etc, so that 
a) it's clear that the example is meant to be with arbitrary XML tags
and java classes, and b) it's easy to see in the mapping files where
I'm referring to a Customer and where to the variable that holds
Customer instance.

     The exception is the ArrayList that holds the Item instances,
because the only way I've found to make it work seems to require
getItem()/setItem() singular, instead of getItems()/setItems().  See
the bit about this at the end of the message.

     I guess maybe I should have done something similar with the tag
names, (e.g. <CustomerTag>), maybe I'll do that on the third go-round.
I'm not always certain, from the docs, when an attribute wants a class
name or a tag name or an instance variable name.
 
> To address some of your specific issues.  I agree CustomerWrapper
> should be mapped using the location attribute.  Why it doesn't work is
> something else.
 
     Is it possible to put a field inside a field?  If so, I could try
marking the CustomerWrapper field as transient (but see below for
other worries with that approach).

> The WrapperDetail is really an extra element, so you should look into
> Unmarshaller.setIgnoreExtraElements, which instructs an unmarshaller
> to ignore elements that don't exist in the mapping file. 

     That works but it also means that other errors get swallowed and
items just comes out null :-(.  I've seen references to a
transient="true" attribute on <field>, so I tried defining a field
in the Order mapping file with transient="true".  Castor insisted
on having a name="" attribute on <field>, but doesn't care if the
name points to a missing class in this case:

         <field name="WrapperDetail" type="string" transient="true">
            <bind-xml name="WrapperDetail"/>
        </field>

     This worked, which is nice, but this "feature" may actually be
a bug that gets fixed in some future upgrade, so it might not be a
safe approach.
 
> Finally, there are two ways to handle the Items element.  You can
> either use the location attribute similar to CustomerWrapper, 

     I tried two approaches to this.  The first was to specify the
Item field in OrderMapping with location="Items", which got me:

org.exolab.castor.mapping.MappingException: The return type for method public 
java.util.ArrayList com.foo.Order.getItem() does not match the declared field 
type com.foo.Item

     The second was to specify each field in the ItemMapping.xml with
location="Items", which got me:

unable to find FieldDescriptor for 'Items' in ClassDescriptor of order{file: 
[not available]; line: 8; column: 12}

     However, I just saw the second response to my post; I'm boggled
that I could have missed that little detail of having the location
attribute on the correct tag... :-).

> or you can use the container attribute (goes in the field element in
> the mapping file).  I'm assuming your Java class has an array or
> List of Item objects that turn into the individual items in the XML.
> If you set container="false" (and provide the correct bind-xml
> name="Items") Castor will create the Items element for you.

     Interesting.  The container attribute isn't mentioned anywhere
in http://www.castor.org/xml-mapping.html

     I tried the obvious, the following in OrderMapping.xml:

        <field name="Item" type="com.foo.Item" container="true" 
collection="arraylist">
            <bind-xml name="Items"/>
        </field>

     This got me a java.lang.StackOverflowError.

     I've also noticed that in the approach that works, with no
enclosing <Items></Items> tags and the field mapping just looks like:

<field name="Item" type="com.foo.Item" collection="arraylist" />

     This works (if there's no <Items></Items>), BUT I have to specify
the field name as "Item" and I have to make sure the class has a
singular (not plural) getItem() and setItem(), AND they have to return
and take ArrayList, not List.  It might be that when we figure out
what I'm doing wrong and I can make it work with <Items></Items>,
those peculiarities will be resolved also.

     Also, in my current work project, the Order analog has started to
accrue a few bits and pieces of Item-list-specific logic, so it might
make sense to have an Items class after all... especially if doing so
makes the Castor mapping easier.

-- 
Steven J. Owens
[EMAIL PROTECTED]

"I'm going to make broad, sweeping generalizations and strong,
 declarative statements, because otherwise I'll be here all night and
 this document will be four times longer and much less fun to read.
 Take it all with a grain of salt." - http://darksleep.com/notablog


-------------------------------------------------
If you wish to unsubscribe from this list, please 
send an empty message to the following address:

[EMAIL PROTECTED]
-------------------------------------------------

Reply via email to