- From: Hua, Hook (388C) <hook.hua@jpl.nasa.gov>
- Date: Thu, 21 Mar 2013 11:09:28 +0000
- To: Provenance Working Group <public-prov-wg@w3.org>
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 > > > > >
Received on Thursday, 21 March 2013 11:12:37 UTC