Re: PROV-ISSUE-648: Can schema be made a bit more jaxb friendly? [XML Serialization]

H Hook,

Thanks for this analysis.

In this specific instance, I think that it is the element
   <xs:any namespace="##other" processContents="lax" minOccurs="0" />
occurring inside
   <xs:sequence maxOccurs="unbounded">
that causes these jaxb elements to be generated.

If you were to remove xsd:any there, jaxbElements would no longer be 
generated.

While we want to allow the possibility of elements from other schemas, do we
really want to allow them any where inside a document/bundle?

Luc


On 03/21/2013 11:09 AM, Hua, Hook (388C) wrote:
> Hi Luc,
>
> I'm using jaxb-ri-2.2.6 against our latest prov*.xsd and seeing slightly
> different bindings with JAXBElement:
>
> public class Document {
>      @XmlElementRefs({
>          @XmlElementRef(name = "hadPrimarySource", namespace =
> "http://www.w3.org/ns/prov#", type = JAXBElement.class, required = false),
>          @XmlElementRef(name = "agent", namespace =
> "http://www.w3.org/ns/prov#", type = JAXBElement.class, required = false),
>          @XmlElementRef(name = "activity", namespace =
> "http://www.w3.org/ns/prov#", type = JAXBElement.class, required = false),
>          @XmlElementRef(name = "organization", namespace =
> "http://www.w3.org/ns/prov#", type = JAXBElement.class, required = false),
>          @XmlElementRef(name = "softwareAgent", namespace =
> "http://www.w3.org/ns/prov#", type = JAXBElement.class, required = false),
> ....
>
>
>
> Some findings:
>
>
> (1) JAXB's generation of JAXBElement<T> classes seems to be a wrapper
> approach to preserve sufficient information in the schema for round-trip
> marshaling & unmarshalling of values in XML instances. More specifically,
> it wraps the data with a QName and a nillable flag [1].
>
> It appears that the a frequent cause of JAXB producing JAXBElement<T> is
> its attempt to preserve elements with both minOccurs=0 and nillable=true.
> JAXB needs to distinguish between the two cases where:
>
>    a. element missing, minOccurs=0, then jaxbElement==null
>    b. element present, xsi:nil=true, then jaxbElement.isNil()==true
>
> It would not be possible to distinguish between these two states if the
> bindings were the raw types.
>
>
>
> (2) It would be possible to customize the JAXB bindings [2] to ignore the
> full round-trip requirement. The "generateElementProperty=false"
> customization option "can be used to generate an alternate developer
> friendly but lossy binding" [3].
>
> I tried variations of a "bindings.xjb" customization file:
>
> <jaxb:bindings version="2.1"
>    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
>    xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
>    xmlns:xs="http://www.w3.org/2001/XMLSchema">
>    <jaxb:bindings schemaLocation="prov-core.xsd"
>      node="//xs:complexType[@name='Document']">
>      <jaxb:globalBindings generateElementProperty="false" />
>    </jaxb:bindings>
> </jaxb:bindings>
>
> $ xjc.sh -d BINDINGS -b bindings.xjb prov.xsd
>
> But none truly eliminated the JAXBElement<T> from the bindings.
>
>
>
> (3) Nowhere in our prov-core.xsd do we define minOccurs=0 in conjunction
> with nillable=true. In my attempts with JAXB, I'm seeing JAXBElements
> appearing in the bindings for the (a) Document class and (b)
> BundledConstructor class. Both types leverage the prov:documentElements
> grouping.
>
>    <xs:element name="document" type="prov:Document" />
> <xs:complexType name="Document">
>    <xs:sequence maxOccurs="unbounded">
>      <xs:group ref="prov:documentElements" minOccurs="0"/>
>      <xs:element name="bundleContent" type="prov:BundleConstructor"
> minOccurs="0"/>
>      <xs:any namespace="##other" processContents="lax" minOccurs="0" />
>    </xs:sequence>
>    </xs:complexType>
>
> It's unclear if there is some nillable-like affect that triggers JAXB to
> generate the JAXBElements.
>
>
>
> (4) On the upside, JAXB does provide an ObjectFactory class as part of the
> generated bindings that define creational factory methods to generate the
> JAXBElement instances. For example:
>
>    public JAXBElement<Usage> createUsed(Usage value)
>
> Still, I agree that it is not as clean.
>
>
> --Hook
>
>
> [1] http://docs.oracle.com/javaee/5/api/javax/xml/bind/JAXBElement.html
> [2]
> http://docs.oracle.com/cd/E17802_01/webservices/webservices/docs/1.5/tutori
> al/doc/JAXBUsing4.html#wp148515
> [3]
> http://docs.oracle.com/cd/E17802_01/webservices/webservices/reference/tutor
> ials/wsit/doc/DataBinding5.html
>
>
>
>
>
>
> On 3/8/13 4:20 AM, "Provenance Working Group Issue Tracker"
> <sysbot+tracker@w3.org> wrote:
>
>> PROV-ISSUE-648: Can schema be made a bit more jaxb friendly? [XML
>> Serialization]
>>
>> http://www.w3.org/2011/prov/track/issues/648
>>
>> Raised by: Luc Moreau
>> On product: XML Serialization
>>
>>
>> Hi
>>
>> I have ported the ProvToolbox and the ProvValidator to the new XML schema.
>> I just wanted to report on my experience with the schema and JAXB.
>> Obviously, others may have better experience with JAXB and may be able
>> to help on some of the issues I encountered.
>>
>> Everything worked fine, except:
>> - <xs:element ref="prov:internalElement abstract=true/>
>> - extensibility <xs:any namespace="##other"/> in Document and Bundle
>>
>>
>> These two constructs, while processable by JAXB, are not JAXB-friendly.
>>
>> Indeed, JAXB compiles the schema in a list containing all possible
>> statements.
>>
>>     protected List<Object> entityAndActivityAndWasGeneratedBy;
>>
>> However, the presence on an abstract element and an <any/> element result
>> in the
>> content of that list to be of type:
>>
>>
>>     @XmlElementRefs({
>>         @XmlElementRef(name = "used", namespace =
>> "http://www.w3.org/ns/prov#", type = JAXBElement.class),
>>         @XmlElementRef(name = "wasAssociatedWith", namespace =
>> "http://www.w3.org/ns/prov#", type = JAXBElement.class),
>>         @XmlElementRef(name = "person", namespace =
>> "http://www.w3.org/ns/prov#", type = JAXBElement.class),
>>         @XmlElementRef(name = "entity", namespace =
>> "http://www.w3.org/ns/prov#", type = JAXBElement.class),
>>         @XmlElementRef(name = "wasInfluencedBy", namespace =
>> "http://www.w3.org/ns/prov#"
>> ....
>>     })
>>
>>     @XmlAnyElement(lax = true)
>>     protected List<Object> entityAndActivityAndWasGeneratedBy;
>>
>> where all data structures are wrapped up in this unpleasant JAXBElement.
>>
>> Without these features, we get a much more natural mapping:
>>     @XmlElements({
>>         @XmlElement(name = "entity", namespace =
>> "http://www.w3.org/ns/prov#", type = Entity.class),
>>         @XmlElement(name = "activity", namespace =
>> "http://www.w3.org/ns/prov#", type = Activity.class),
>>         @XmlElement(name = "wasGeneratedBy", namespace =
>> "http://www.w3.org/ns/prov#", type = WasGeneratedBy.class),
>>         @XmlElement(name = "used", namespace =
>> "http://www.w3.org/ns/prov#", type = Used.class),
>>         @XmlElement(name = "wasInformedBy", namespace =
>> "http://www.w3.org/ns/prov#", type = WasInformedBy.class),
>>     ...
>> })
>>
>> So, how I did I solve the problem?  I inserted the extension schemas into
>> the schema file, and hence got rid of the abstract element.  I am ok with
>> this. We could possible provide the utility to that transformation.
>>
>> For the extensibility, I used a different definition. It happens to
>> parse prov-xml compliant xml. When serializing, it  puts all
>> extensibility elements at the end.  This is not a satisfactory
>> solution, and is likely to be dependent of the jaxb implementation
>> (though I am not entirely sure).
>>
>>
>>    <xs:complexType name="Document">
>>      <xs:sequence>
>>        <xs:choice maxOccurs="unbounded">
>>          <xs:group ref="prov:documentElements"/>
>>          <xs:element name="bundleContent" type="prov:NamedBundle"/>
>>        </xs:choice>
>>        <xs:any namespace="##other" processContents="lax" minOccurs="0"
>> maxOccurs="unbounded"/>
>>      </xs:sequence>
>>    </xs:complexType>
>>
>> Can something be done to make the XML schema a bit more jaxb friendly,
>> while still keeping the same flexibility?  Thoughts welcome.
>>
>> Cheers,
>> Luc
>>
>>
>>
>>
>>
>
>

-- 
Professor Luc Moreau
Electronics and Computer Science   tel:   +44 23 8059 4487
University of Southampton          fax:   +44 23 8059 2865
Southampton SO17 1BJ               email: l.moreau@ecs.soton.ac.uk
United Kingdom                     http://www.ecs.soton.ac.uk/~lavm

Received on Thursday, 21 March 2013 11:27:16 UTC