users@jaxb.java.net

Re: unmarshaling to extender MyClass

From: Chase Barrett <chase.c.barrett_at_LMCO.COM>
Date: Tue, 15 Jul 2003 08:33:59 -0600

>Personally, I don't think this is good enough, so any feedback would be
>appreciated.

I've actually found the implClass customization useful, but I've found a problem with the Unmarshaller and XMLSerializable implementations generated with each schema-derived implementation (JAXB release 1.0.1).

For each complexType, I've created a class binding which points the "implClass" attribute to an adapter that extends one of the RI-generated implementations. The purpose of the adapter class is to wrap an instance of an existing business object and adapt that object to a schema-derived interface.

I was expecting the unmarshaller to invoke the various setXXX methods on my adapter subclass, which would then pass that setXXX message onto the appropriate method on the business object. Thus, the unmarshalling process would not only produce a schema-derived content tree, but at the same time, a populated business object.

Unfortunately, the unmarshaller does not use the setXXX methods, and the marshalling process does not use the getXXX methods. Instead, both processes directly reference fields on the implementation superclasses, leaving my adapter subclasses out of the loop.

Here is a summary of a typical implementation class:

===Code Snippet 1===========================================================
package foo.generated.impl;

public class RequestTypeImpl implements foo.generated.RequestType, ...
{
   protected foo.generated.AuthType _Auth;
   ...

   public void serializeElementBody(foo.generated.impl.runtime.XMLSerializer context)
      throws org.xml.sax.SAXException
   {
      context.startElement("urn:nuwss:space-sdc", "auth");
      context.childAsURIs(((com.sun.xml.bind.JAXBObject) _Auth));
      ...
   }

   public class Unmarshaller extends
      foo.generated.impl.runtime.AbstractUnmarshallingEventHandlerImpl
   {
      ...

      public void enterElement(String ___uri, String ___local,
            String ___qname, org.xml.sax.Attributes __atts)
         throws org.xml.sax.SAXException
      {
         ...

         _Auth = ((foo.adapters.AuthTypeAdapter)spawnChildFromEnterElement
                  ((foo.adapters.AuthTypeAdapter.class),
                  8, ___uri, ___local, ___qname, __atts));
         ...

      }
   }
}

===Code Snippet 1===========================================================

If instead of setting the field directly, the Unmarshaller invoked the setAuth() method and the XMLSerializable methods used the getAuth() method, then my adapter subclass would be in the loop whenever the Auth parameter is set/gotten:

===Code Snippet 2===========================================================
package foo.generated.impl;

public class RequestTypeImpl implements foo.generated.RequestType, ...
{
   protected foo.generated.AuthType _Auth;
   ...

   public void serializeElementBody(foo.generated.impl.runtime.XMLSerializer context)
      throws org.xml.sax.SAXException
   {
      context.startElement("urn:nuwss:space-sdc", "auth");
      context.childAsURIs(((com.sun.xml.bind.JAXBObject) getAuth()));
      ...
   }

   public class Unmarshaller extends
      foo.generated.impl.runtime.AbstractUnmarshallingEventHandlerImpl
   {
      ...

      public void enterElement(String ___uri, String ___local,
            String ___qname, org.xml.sax.Attributes __atts)
         throws org.xml.sax.SAXException
      {
         ...

         setAuth(((foo.adapters.AuthTypeAdapter)spawnChildFromEnterElement
                  ((foo.adapters.AuthTypeAdapter.class),
                  8, ___uri, ___local, ___qname, __atts)));
         ...

      }
   }
}

===Code Snippet 2===========================================================


===Code Snippet 3===========================================================
package foo.adapters;

public class RequestTypeAdapter extends RequestTypeImpl
    implements BusinessAdapter
{
    public AuthType getAuth()
    {
        Object authorization = BusinessAdapterFactory.getAdapter
           (businessObject.getAuthorization());
        return (AuthType)authorization;
    }

    public void setAuth(AuthType auth)
    {
        Object authorization = ((BusinessAdapter)auth).getAdaptee();
        businessObject.setAuthorization((Authorization)authorization);
    }
}
===Code Snippet 3===========================================================

Is there a way to accomplish this sort of functionality in the current release? How about a future enhancement? I can do what I need to do by individually transferring field values back and forth between the business object and the schema-derived object after each unmarshall and prior to each marshall, but it seems like such a waste.

Thanks in advance,
Chase