Hi Jody,

Thanks for the clarification. Let me summarize what you are doing in a
way that makes it more clear for me: you are using multiple
FieldDescriptors to describe a single field. The field is a collection
of objects which all extend a particular abstract type.

The reason that duplicate elements are created during marshalling is
that the Descriptor API was really intended to have one Descriptor per
field, not multiple Descriptors per field...so each Descriptor will get
called.

Upon unmarshalling it works properly because Castor really doesn't care
where the FieldHandler puts the values and it simply uses the
FieldDescriptor which best matches the element name.

As a side note, the reason Castor's source code generator doesn't face
this same issue is that it creates a wrapper class (for example in your
case this would be MessageItem) that can hold a single value of all the
possible types:

public class MessageItem {
    public void setMessage1(...)
    public Message1 getMessage1();
    public void setMessage2(...);
    public Message2 getMessage2();
    ...
}

And the collection is simply a collection of MessageItems, so only one
FieldDescriptor is used to describe the collection. Ok...enough about
that, I thought I would just throw that on the table...

The problem you are facing in not unique to your case however. This is a
problem that faces both the Mapping Framework and Descriptor API. It was
brought to my attention by one of my employees, Sebastien Gignoux, who
was trying to do a similar thing using a mapping file. We are working on
an easier solution which allows mulitple names to be mapped to a single
FieldDescriptor and the name is chosen by the class type. However we
haven't committed any code to the CVS yet.

It affects the Mapping Framework more than the Descriptor API however,
because at least in the Descriptor API you can write your work arounds
in the Java code.

And lucky for you that you are using the Descriptor API, so there are
probably a few solutions to solving the problem you face.

One such solution would be to do disable the get methods (simply return
null) for the "specific" FieldDescriptors (message1, message2), then add
an additional generic FieldDescriptor and disable the "set" method and
getName method. The current descriptors you are using will be used for
Unmarshalling, the new generic descriptor will be used for Marshalling.

Here are the steps...

1. Modify the FieldHandlers for message1 and message2 so that the
getValue method returns null as follows:

public Object getValue() {
  return null;
}

These FieldDescriptors/Handlers will be used during unmarshalling only.

2. Then add a generic XMLFieldDescriptor which will be used during
Marshalling.

3. The getXMLName method should return null for this "generic"
descriptor. This will force the Marshalling framework to create an XML
name based on the name of the Class type of each object returned in the
collection. Otherwise all the names will be same.

4. The set method for the FieldHandler associated with the generic
descriptor can simply do nothing...hopefully it will never get called.

I hope that helps...

--Keith









"TERRILL,JODY (HP-Boise,ex1)" wrote:
> 
> The problem I am having is that when I have multiple field descriptors that
> map to one bean property the marshalling framework gives me each entry using
> each field descriptor.  So if I have three descriptors that map three unique
> xml names to one abstract bean property this creates objects of the correct
> class (each extending the abstract class) and places them in the bean
> property.  When the marshalling framework is executed, it appears that each
> of the three descriptors gets a chance to marshall each property.  For each
> entry in the property, this manifests itself as one XML element with the
> 'correct' desciptor and two with the 'generic' version of the element.
> 
> FYI, my example below shows only 2 field descriptors at work with 2 elements
> in the property.  So this manifests itself as 2 xml elements coming in
> (unmarshalled) and four xml elements out (marshalled).
> 
> I am hoping this is just a stupid user trick and there is a way to marshall
> abstract elements where there are multiple possible xml names mapping into
> this one abstract property.  I am sure it works just fine where you have
> only one XML name mapping to the abstraction.
> 
> Thanks in advance for any help on this,
> 
> Jody
> 
> > -----Original Message-----
> > From: Keith Visco [mailto:[EMAIL PROTECTED]]
> > Sent: Thursday, December 13, 2001 3:25 AM
> > To: [EMAIL PROTECTED]
> > Subject: Re: [castor-dev] Marshall abstract array element
> >
> >
> >
> > Hi Jody,
> >
> > see below...
> >
> > > "TERRILL,JODY (HP-Boise,ex1)" wrote:
> > >
> > > Hello,
> > >
> > > I am trying to do some XML un/marshalling with Castor 0.9.3 and am
> > > hitting a block when I try to marshall an abstract Array element.
> > > FYI, I am using only the Descriptor framework (no mapping or
> > > reflection).
> > >
> > > I wish to have an element that contains only an abstract base class
> > > that contains the child elements.  An example of this follows:
> > >
> > > public class Root{
> > >     private java.util.ArrayList _messageList; // holds
> > Message objects
> > > with appropriate getters/setters
> > > }
> > >
> > > public abstract class Message;
> > > public class Message1 extends Message;
> > > public class Message2 extends Message;
> > >
> > > An XML instance can look like ...
> > >
> > > <Root>
> > >     <Message1 IDA="1"/>
> > >     <Message2 IDB="2"/>
> > > </Root>
> > >
> > > In the RootDescriptor, I can add an XMLFieldDescriptorImpl
> > for each of
> > > the concrete Messages (i.e. Message1 & Message2) that details their
> > > XML name and base class.  I then can add an XMLFieldHandler to each
> > > that creates the correct object and gets/sets it into the
> > > messageList.  As expected, this works fine for unmarshalling.
> > >
> > > When I marshall the class (to XML), it appears that each
> > > FieldDescriptor is invoked so that I get the following XML out.
> > >
> > > <Root>
> > >     <Message1 IDA="1"/>
> > >     <Message1 IDB="2"
> > > xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
> > > xsi:type="java:message2"/>
> > >     <Message2 IDA="1"
> > > xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
> > > xsi:type="java:message1"/>
> > >     <Message2 IDB="2"/>
> > > </Root>
> > >
> > > I tried creating my own FieldDescriptor, etc.. but didn't have any
> > > luck.  Is there a way to map one attribute to many xml
> > field names and
> > > objects for both marshalling and unmarshalling?
> >
> > I am a little confused as to what issues you are facing? Are
> > you trying
> > to remove the xsi:type information that gets output? Or am I missing
> > something?
> >
> > If you are trying to supress xsi:type, you can try:
> >
> > Marshaller myMarshaller = new Marshaller();
> > myMarshaller.setMarshalExtendedType(false)
> >
> > The method name "setMarshalExtendedType" is pretty non-intuitive...but
> > the Javadoc description of the method is accurate.
> >
> > If I misunderstood the error...please try posting again with
> > maybe some
> > more clarifying information.
> >
> > Thanks,
> >
> > --Keith
> >
> > -----------------------------------------------------------
> > If you wish to unsubscribe from this mailing, send mail to
> > [EMAIL PROTECTED] with a subject of:
> >       unsubscribe castor-dev
> >

----------------------------------------------------------- 
If you wish to unsubscribe from this mailing, send mail to
[EMAIL PROTECTED] with a subject of:
        unsubscribe castor-dev

Reply via email to