users@jaxb.java.net

Re: [jaxb-20-comments] cannot adapt an XmlRootElement ?

From: Sekhar Vajjhala <Sekhar.Vajjhala_at_Sun.COM>
Date: Fri, 13 Jan 2006 15:25:39 -0500

Mark Hansen wrote:

> It appears that you cannot get JAXB to adapt a root element class.
> So, there is no way to marshal a bound type to a global element.

Thanks for the feedback and interest in JAXB 2.0.

I agree this case needs to be supported.

The spec already supports this case but requires a partial
fix. Details below

>
>
> The spec requires a "point of reference" for the bound type. And when
> the bound type is the root element class, then there is no point of
> reference. This seems like a problem with the specification.

You are correct that there is no "point of reference" in the bound
type, MyFoo i.e. there is no property/field that reference
MyFoo. However, marshalling and unmarshalling is still required to
adapt the class using MyFooAdapter. This is required by the runtime
processing model specified in Appendix B, "Runtime Processing", that
deals with marshalling/unmarshalling of XML instances. Referenced
below are sections from Appendix B which shows the requirements for
the adapter to be used.

Unmarshalling:
=============

The use of adapter for unmarshalling is required by section B.3.1,
"Gobally Declared Root Element", page 305 , bullet item b. of the
Proposed Final Draft which contains the following:

------- begin excerpt from the JAXB 2.0 spec ---------
b. if a type annotated with @XmlRootElement is found and is not
   annotated with @XmlJavaTypeAdapter, then the valueType is type that
   has been annotated. For e.g.

       @XmlRootElement(...)
       public class Foo { ... }

   The valueType is Foo.

   if a type annotated with @XmlRootElement is found and is annotated
   with @XmlJavaTypeAdapter, then the valueType is the type that has
   been specified in @XmlJavaTypeAdapter.value().
------- end excerpt from the JAXB 2.0 spec ---------

Marshalling:
============
Marshalling is covered by section, Section B.4,
"Marshalling". Sub section b.4.2.1, "JAXBElement" requires the use of
adapter when a JAXBElement instance is being marshalled. From Bullet
item 6.

-------- begin excerpt from Appendix B ---------
6. determine the valueType to be marshalled. If the program element
   being processed is associated with @XmlJavaTypeAdapter then
   boundType is valueType =
        @XmlJavaTypeAdapter.value().marshal(boundType)
   otherwise valueType is boundType.
-------- end excerpt from Appendix B ---------

However, the requirement on the use of an adapter is missing from
section section B.4.2, "Class" when a type annotated with
XmlRootElement is marshalled. This was an omission, which I will
correct.

>
>
> I.e., you should be able to do this (Foo is the value type and MyFoo
> is the bound type):
>
> @XmlRootElement
> @XmlJavaTypeAdapter(MyFooAdapter.class)
> public class MyFoo {
> ....
> }
>
>
> @XmlRootElement
> public class Foo {
> ....
> }
>
>
> Given the above, when you marshal an instance of MyFoo, it should
> produce the XML that is mapped from Foo. But, the Sun RI does not
> work like this. It seems to ignore the adapter. It seems that this
> behavior is consistent with the specification - since there is not
> "point of reference" for MyFoo in the actual class definition of
> MyFoo. However, the upshot is that you can't marshal a boutn type to
> a global element. That seems like a common use case that JAXB 2.0
> should handle.
>
> Pleasse let me know if I am missing something.
>
> -- Mark


regards
Sekhar Vajjhala