users@jaxb.java.net

Re: Setting one element into another element with the same type

From: Joseph Fialli <joseph.fialli_at_sun.com>
Date: Thu, 28 Aug 2003 13:43:19 -0400

Franklin, Brian wrote:

>Joe, sorry for the delay in response.
>
>It is my feeling that no decent solution for these issues can be found
>without using type substitution. Regarding your example, I would say that
>you would use neither the B nor C element name--you would leave the element
>named A with an xsi:type="Derived" attribute.
>
>Let me take this opportunity to discuss the way that type instances are
>marshalled by themselves (as root content instances). I am pretty sure a
>discussion similar to this has come up before, but I'm not exactly sure what
>its purpose or solution was. Please bear with me.
>
>Let's say you have the following schema fragment:
>
> <complexType name="Container">
> <sequence>
> <element name="InnerElement" type="int" />
> </sequence>
> </complexType>
>
>And that in your code you do this:
>
> ...
> Container c = objectFactory.createContainer();
> c.setInnerElement(5);
> marshaller.marshal( c, output );
> ...
>
>You will only get the contents of Container without the container tag, like
>this:
>
> <InnerElement>5</InnerElement>
>
>While this may actually be required by the XML Schema / XML instance
>document standards (not sure), you unfortunately lose the identity of this
>instance. I think that you should instead get output like this:
>
> <Container>
> <InnerElement>5</InnerElement>
> </Container>
>
I disagree with your suggestion to promote the name of the complex type
to an XML element.

However, we do agree that JAXB RI's current output is not desirable.
The following solutions have been considered (but yet not acted upon)
for addressing the
case when a marshal method is called with in an instance of a type
definition.
These solutions do maintain the proper element and its content model
relationship,
while introducing potentially some suprise element in the marshalled output.

One solution is to check if there exist any global element declarations
of the type
definition in the current namespace uri's known to the JAXBContext. The
element tag
could be non-deterministically chosen from one of the eligible global
element declarations.
(Solutions wth non-deterministic behavior is not desirable, but if user
could not care to
provide a global element to marshal, it is the best that can be done in
general.)

If above did not work, then the next step would be to use a jaxb
specific "unknown" element tag.

<jaxb:unknownElementTag xsi:type="somePrefix:Container" xmlns:jaxb="jaxb
namespace uri">
    <InnerElement>5</InnerElement>
</jaxb:unknownElementTag>

This solution introduces a well-defined unknown element tag but suffers
from being JAXB specific.

If one would prefer neither of the potentially suprising situations,
just throwing an exception would be the
desirable handling when the marshaller encounters an instance that needs
an xml element name and none
are associated with the instance.

-Joe

>
>In analogy to Java code, this would be as if
>
> marshaller.marshal( new HashMap() );
>
>and
>
> Map myMap = new HashMap();
> marshaller.marshal( myMap );
>
>yielded different marshalled outputs. This seems flawed.
>
>
>Thanks, as always, for your time.
>
>Brian Franklin
>
>
>-----Original Message-----
>From: Joseph Fialli [mailto:joseph.fialli_at_sun.com]
>Sent: Thursday, August 21, 2003 4:31 PM
>To: users_at_jaxb.dev.java.net
>Subject: Re: Setting one element into another element with the same type
>
>
>
>
>Brian Franklin wrote:
>
>
>
>>Ok, I have now realized that it will only automatically wrap the type
>>in an element if it's directly that type, and not a child type, which
>>makes sense. But that's now back to being quite unfortunate.
>>
>>
>
>Thanks for this usability feedback. Since element substitution is
>experimentally supported in JAXB 1.0.1
>standard implementation, there is time to consider how this should be
>specified in JAXB 2.0.
>
>Would you prefer that the implementation non-deterministically compute a
>possible element name if
>only the element's value is provided to the JAXB property setter
>representing an element substitution
>group.
>
>For example, if one has elements A, B and C in an element substutition
>group and element A has
>XML type Base and elements B and C have XML type Derived, which derives
>by extension from Base,
>calling the property setter with a Java instance of a type matching
>"Derived", it would be ambiguous whether
>the element name should be B or C.
>
>It is a difficult trade off to determine whether :
>1. to non-deterministically do something that is a validbut potentially
>suprising
>2. giving immediate feedback that the element name is not provided(via
>an exception)
>3. optional feedback (via Validation of the content) that the property
>is not set with
> enough info to determine an element name. (here's hoping that
>validation flags this case)
>
>-Joe
>
>
>
>
>>Sorry for having a conversation with myself.
>>
>>I would like to reiterate my request for an expeditious release of the
>>JAXB RI with type substitution support. 8-}
>>
>>Brian Franklin
>>
>>
>>On Wednesday, August 20, 2003, at 10:01 PM, Brian Franklin wrote:
>>
>>
>>
>>>Never mind about the "trade-off" comment. I did a quick test, and I
>>>see that it automatically wraps the type in an element with the
>>>referenced element's name. That's quite fortunate.
>>>
>>>Brian Franklin
>>>
>>>
>>>On Wednesday, August 20, 2003, at 05:32 PM, Franklin, Brian wrote:
>>>
>>>
>>>
>>>>Thanks for the excellent information.
>>>>
>>>>We actually have been using element substitution. I was reluctant
>>>>to use it
>>>>in a particular situation because it normally affects the generated
>>>>method
>>>>name, but I had forgotten about using a property name customization to
>>>>override it. Also, because of the loss of functionality mentioned
>>>>below.
>>>>
>>>>So, for anyone else who is reading and doesn't follow, this is a
>>>>possible
>>>>workaround for the situation:
>>>>
>>>>New schema fragment:
>>>>(Compile with -extension argument for command line or extension="true"
>>>>attribute for Ant task.)
>>>>
>>>> <complexType name="SomeType">
>>>> <sequence>
>>>> <element name="Something" type="int" />
>>>> </sequence>
>>>> </complexType>
>>>> <element name="SomeElement" type="this:SomeType" />
>>>>
>>>> <element name="Container">
>>>> <complexType>
>>>> <sequence>
>>>> <element ref="this:SomeElement">
>>>> <annotation><appinfo>
>>>> <!-- Without this your
>>>>method name would be getSomeElement() instead of getInnerElement() -->
>>>> <jaxb:property
>>>>name="InnerElement" />
>>>> </appinfo></annotation>
>>>> </sequence>
>>>> </complexType>
>>>> </element>
>>>>
>>>>
>>>>The only down side to this, if I'm not mistaken is that you can no
>>>>longer do
>>>>the following, which you could do previously:
>>>>
>>>> SomeType someType = objFact.createSomeType();
>>>> someType.setSomething(5);
>>>> Container container = objFact.createContainer();
>>>> container.setInnerElement( someType );
>>>>
>>>>So, it seems to currently be a trade-off until the new spec comes out.
>>>>
>>>>Joe, if I misunderstood what you were saying, am wrong in any of the
>>>>examples, or if there is a better way to do this, please let me know.
>>>>
>>>>Thanks again,
>>>>Brian Franklin
>>>>
>>>>-----Original Message-----
>>>>From: Joseph Fialli [mailto:joseph.fialli_at_sun.com]
>>>>Sent: Wednesday, August 20, 2003 4:16 PM
>>>>To: users_at_jaxb.dev.java.net
>>>>Subject: Re: Setting one element into another element with the same
>>>>type
>>>>
>>>>
>>>>
>>>>
>>>>Franklin, Brian wrote:
>>>>
>>>>
>>>>
>>>>>I believe this issue (or at least one similar to it) has been
>>>>>brought up in
>>>>>previous threads (1), but I wanted to confirm something and ask the
>>>>>team
>>>>>
>>>>>
>>>>how
>>>>
>>>>
>>>>
>>>>>this will work in the future. Questions are near the bottom.
>>>>>
>>>>>Kohsuke gave a pretty simple example previously that I *think* is
>>>>>the same
>>>>>thing, but just to be sure, here's an example that I know behaves
>>>>>
>>>>>
>>>>strangely.
>>>>
>>>>
>>>>
>>>>>Schema fragment:
>>>>> <complexType name="SomeType">
>>>>> <sequence>
>>>>> <element name="Something" type="int" />
>>>>> </sequence>
>>>>> </complexType>
>>>>> <element name="SomeElement" type="this:SomeType" />
>>>>>
>>>>> <element name="Container">
>>>>> <complexType>
>>>>> <sequence>
>>>>> <element name="InnerElement"
>>>>>type="this:SomeType" />
>>>>> </sequence>
>>>>> </complexType>
>>>>> </element>
>>>>>
>>>>>Sample code fragment:
>>>>>
>>>>> SomeType someType = objFact.createSomeElement();
>>>>> someType.setSomething(5);
>>>>>
>>>>> Container container = objFact.createContainer();
>>>>> container.setInnerElement( someType );
>>>>>
>>>>> marshaller.marshal( ...output... );
>>>>>
>>>>>Resulting output fragment:
>>>>>
>>>>> <Container>
>>>>> <InnerElement>
>>>>> <SomeElement>
>>>>> <Something>5</Something>
>>>>> </SomeElement>
>>>>> </InnerElement>
>>>>> </Container>
>>>>>
>>>>>
>>>>>Questions:
>>>>>
>>>>>1) Is this how this will behave in the future?
>>>>>
>>>>>
>>>>>
>>>>The JAXB 1.0 Specification definitely does not specify this marshalled
>>>>behavior.
>>>>You are observing a behavior in the current implementation.
>>>>
>>>>The JAXB property setter method definitely allows for an instance of
>>>>javax.xml.bind.Element to be
>>>>set on a JAXB property, this behavior was necessary to support a JAXB
>>>>property representing
>>>>a wildcard <xsd:any>, or in the future, to support element substitution
>>>>groups. Both these
>>>>cases required the JAXB setter to be able to dynamically provide an
>>>>element name to use for validation and marshalling.
>>>>
>>>>The example above demonstrates when the schema has a fixed element name
>>>>for the JAXB
>>>>property InnerElement representing a local child element
>>>>AND the application also dynamically provides an element name by
>>>>calling
>>>>the JAXB setter property for InnerElement with an instance of
>>>>javax.xml.bind.Element.
>>>>
>>>>We plan to address this hole in the JAXB 1.0 Specification that you
>>>>have
>>>>pointed out
>>>>(we have been aware of it) and identify a user-friendly, deterministic
>>>>solution in
>>>>the JAXB 2.0 expert group.
>>>>
>>>>
>>>>
>>>>>2) Will the inclusion of type substitution change how this
>>>>>looks/behaves?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>Type substitution does not allow for an element name to be changed for
>>>>JAXB property.
>>>>
>>>>Actually, element substitution group support is the interesting feature
>>>>where a JAXB setter
>>>>can take as a parameter an element instance with an element name
>>>>different than is specified in the
>>>>constraining schema AND the setter provided element name REPLACES the
>>>>schema element reference.
>>>>This support is already implemented in JAXB 1.0.1 with xjc -extension
>>>>mode and it
>>>>does not suffer from the issue that your case identifies. For this
>>>>case, the implementation
>>>>is always allowing the element name provided by the JAXB setter to
>>>>override
>>>>the schema reference to the element substitution group header element,
>>>>thus, both
>>>>element names are not output by the marshaller.
>>>>
>>>>
>>>>
>>>>>3) If the ability to "T getType()" and "setType(T)" of an element is
>>>>>implemented in the future, will this be handled automatically in
>>>>>this case?
>>>>>
>>>>>
>>>>>
>>>>Automatically handling this case or throwing an exception when the JAXB
>>>>setter
>>>>method is called with a javax.xml.bind.Element instance are two
>>>>possible
>>>>solutions.
>>>>If the automated handling can not be deterministically specified,
>>>>throwing an
>>>>exception would be the preferable path.
>>>>
>>>>
>>>>Thanks for your feedback.
>>>>
>>>>-Joe
>>>>
>>>>
>>>>
>>>>>4) If this is going to continue to behave this way, shouldn't
>>>>>setting an
>>>>>Element into another Element field of the same type throw an
>>>>>exception or
>>>>>something?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>Thanks, as always, for your time and hard work.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>Brian Franklin
>>>>>
>>>>>----
>>>>>Footnotes: (following the trend that Ryan seems to be pushing)
>>>>>
>>>>>(1) For those of you who want to search the archives, the following
>>>>>topics
>>>>>seemed to be at least somewhat relevant to the issue:
>>>>> "Marshalling a content sub-tree"
>>>>> "Help!! Elements & types"
>>>>>
>>>>>
>>>>>---------------------------------------------------------------------
>>>>>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>>>>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>---------------------------------------------------------------------
>>>>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>>>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>>>
>>>>---------------------------------------------------------------------
>>>>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>>>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>>>
>>>>
>>>
>>>---------------------------------------------------------------------
>>>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>>
>>>
>>
>>---------------------------------------------------------------------
>>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>>
>>
>>
>
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>---------------------------------------------------------------------
>To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
>For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
For additional commands, e-mail: users-help_at_jaxb.dev.java.net