Hi David,

I looked into the issue a bit more after creating a simple test
case...the following workaround should do the trick for you:

Since Castor deals with collections incrementally, the "underlying"
FieldHandler is expecting to recieve one item at a time during
unmarshalling.

So the collection passed as an argument to your convertUponSet method
will only contain one item since Castor will call this method each time
it sees the item in your XML file.

So change your convertUponSet method as such:

Instead of looping through the passed in collection and creating a new
collection...grab only the item and return it's converted value, not a
collection as such:

        if (value instanceof ArrayList) {
            ArrayList list = (ArrayList)value;
            return  new URI((String)list.get(0));
        }


I've tested it here and it seems to work fairly well.

Your get method can remain the way it is.

Hope that helps,


--Keith

Keith Visco wrote:
> 
> Hi David,
> 
> Great e-mail, I appreciate the level of detail. I'll take a look into
> it. Looks like I overlooked collections a bit when integrating the
> GeneralizedFieldHandler. Sorry about that. It definately looks like I'll
> have to make some changes to prevent the CollectionHandlers from getting
> in the way and converting your collection to an Enumeration before it's
> passed to the convertUponGet method. And also make sure the set method
> is called instead of assuming an actual reference to the collection is
> being passed back from the get.
> 
> I'll get it patched up ASAP.
> 
> Thanks,
> 
> --Keith
> 
> > David Nemeshazy wrote:
> >
> > Hi there!
> >
> > I would like to have a collection of objects that are
> > marshalled/umarshalled to/from XML with an handler or some other
> > mechanism without handling the collection myself. For example, I would
> > like to have a collection of URI objects in my main object and that
> > Castor sees a collection of  Strings.
> >
> > I have tried to do this by using my own custom GeneralizedFieldHandler
> > to handle the elements of a Collection, without handling the whole
> > collection, is it possible?
> >
> > Example :  the field uriTests in class BoardBean (following is shown
> > the mapping). In fact, the BoardBean class has a collection of URI
> > elements :
> >
> > <class name="mdf.test.bean.BoardBean">
> >         <map-to xml="Board"/>
> >         <field name="uriTests" type="java.lang.String"
> > handler="com.odcgroup.otf.castor.fieldHandler.URIFieldHandler"
> > collection="collection">
> >
> >         <bind-xml name="Board.uriTests" node="element"/>
> >         </field>
> > </class>
> >
> > I tried it, but it does not seems to work, because when marshalling,
> > the convertUponGet is called and given an Enumeration. I can convert
> > the elements to what I want and
> >
> > put them into a collection that I return, I tried and it works, but
> > when unmarshalling, I receive a collection and the convertUponSet
> > receives a collection also, which is strange.
> >
> > And each time the convertUponGet method returns a collection, the
> > convertUponSet is not called anymore and therefore, I only have the
> > first element in my collection!
> >
> > As far as I have checked, it seems that Castor takes the collection
> > and add the elements directly without calling the set method, even if
> > I set the setReuseObjects to false.
> >
> > Did anybody tried this already and made it work?
> > I guess it was not planned to use a custom GeneralizedFieldHandler for
> > elements of a Collection, but would it be an expensive work to do?
> >
> > Thanks a lot,
> >
> > David
> >
> > P.S Following one can find my custom GeneralizedFieldHandler that
> > works when marshalling, but not unmarshalling, I only get the first
> > element of the collection:
> >
> > public class URIFieldHandler extends GeneralizedFieldHandler {
> >
> >         /**
> >          * Used to "identify" this field handler
> >          */
> >         public java.lang.Class getFieldType(){
> >         return URI.class;
> >     }
> >
> >         /**
> >          * Used during marshalling
> >          * @see
> > org.exolab.castor.mapping.GeneralizedFieldHandler#convertUponGet(Object)
> >
> >          */
> >         public Object convertUponGet(Object obj) {
> >                 if (obj == null)
> >                         return null;
> >                 try {
> >                         if (obj instanceof URI) {
> >                                 URI uri = (URI)obj;
> >                                 return uri.toString();
> >                         } else if (obj instanceof Enumeration) {
> >                                 Enumeration enum = (Enumeration)obj;
> >                                 Collection c = new ArrayList();
> >                                 if (!enum.hasMoreElements())
> >                                         return null;
> >                                 while (enum.hasMoreElements()) {
> >                                         Object next =
> > ((Enumeration)obj).nextElement();
> >                                         if (next instanceof URI) {
> >                                                 URI uri = (URI)next;
> >                                                 c.add(uri.toString());
> >
> >                                         }
> >                                 }
> >                                 return c;
> >                         }
> >                 } catch (Exception e) {
> >                         System.out.println("Unable to
> > convertUpdonGet!");
> >                         e.printStackTrace();
> >                 }
> >                 return null;
> >         }
> >
> >         /**
> >          * Used during unmarshalling
> >          * @see
> > org.exolab.castor.mapping.GeneralizedFieldHandler#convertUponSet(Object)
> >
> >          */
> >         public Object convertUponSet(Object obj) {
> >                 if (obj == null)
> >                         return null;
> >                 try {
> >                         if (obj instanceof String) {
> >                                 return new URI((String)obj);
> >                         } else if (obj instanceof Collection) {
> >                                 Iterator i =
> > ((Collection)obj).iterator();
> >                                 return new URI((String)i.next());
> >                         }
> >                 } catch (Exception e) {
> >                         System.out.println("Unable to
> > convertUpdonSet!");
> >                         e.printStackTrace();
> >                 }
> >                 return null;
> >         }
> >
> > }
> >
> > __________________________________________________________________________
> >
> > � This email and any files transmitted with it are CONFIDENTIAL and
> > intended
> > solely for the use of the individual or entity to which they are
> > addressed.
> > � Any unauthorized copying, disclosure, or distribution of the
> > material within
> > this email is strictly forbidden.
> > � Any views or opinions presented within this e-mail are solely those
> > of the
> > author and do not necessarily represent those of Odyssey Asset
> > Management
> > Systems SA unless otherwise specifically stated.
> > � An electronic message is not binding on its sender.  Any message
> > referring to
> > a binding engagement must be confirmed in writing and duly signed.
> > � If you have received this email in error, please notify the sender
> > immediately
> > and delete the original.
> 
> -----------------------------------------------------------
> 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