Malachi de Aelfweald wrote:
>As a possible extension of this issue, I would like to recommend that
>xsd:union be handled differently.
>
>
Thanks for your feedback. Comments below.
>For example, take the case of specifying screen alignment. You want
>either LEFT, RIGHT, CENTER (xsd:string enumeration), an int (exact
>position), or a
>percentage (pattern restriction).
>
>Currently, you will pass in and return Serializabl
>
> That is not very
>useful. Perhaps a better way would be to create a class that represents
>that xsd:union, with get/set/isSet methods for the enumeration, the int,
>and the string. Or possibly a getType().
>
For default binding, the most minimalistic approach that avoided
generating additional classes
was always taken. The design pattern for typesafe enum pattern and the
fact that J2SE 1.5 will
formally support typesafe enums in the Java lanaguage made the mapping
of xml enumerations
to Java class a non-controversial mapping that did introduce a class.
Mapping a choice model group
or a xsd:union to Java interface with setters/getters for each member
was considered to introduce too much
overhead for a default binding.
Your suggested binding was considered as a possible custom binding for
union in the past.
However, since anonymous simple type definitions can occur within a
xs:union, it would not be possible to always
generate properties based on meaningful union member type names, this
complication led to droping this custom
binding for union late in the JAXB 1.0 specification development.
See below for how you can achieve the functionality that you are
requesting just using the
builtin Java operation instanceof and the information generated in the
javadoc.
>
>Ie: I would expect something like:
> setSomeVar(MyUnionType myUnionType)
> MyUnionType getSomeVar()
>And
>
Given following schema fragment containing a union:
<xsd:complexType name="USAddress">
<xsd:sequence>
...
<xsd:element name="state">
<xsd:simpleType>
<xsd:union memberTypes="StateAbbreviation xsd:string"/>
</xsd:element>
...
</xsd:complexType>
<xsd:simpleType name="StateAbbreviation">
<xsd:restriction base="xsd:NCName">
<xsd:enumeration value="MA"/>
<xsd:enumeration value="CA"/>
<!-- rest of states -->
</xsd:restriction>
</xsd:simpleType>
The generated javadoc for a JAXB property representing a union does list
the types of the union in the
getter and setter method's javadoc.
public interface USAddress {
/**
* @return possible object is
* {_at_link java.lang.String}
* {_at_link primer.po.StateAbbreviation}
*/
java.lang.Object getState();
/**
* @param value allowed object is
* {_at_link java.lang.String}
* {_at_link primer.po.StateAbbreviation}
*/
void setState(java.lang.Object value);
**************************************
For your example, here is how it could be coded w/o introducing a new
class for the union.
Note again that the javadoc for the JAXB property does list all the Java
datatypes that represent
the members of the xsd:union so there would be assistence on what types
to expect to be
returned.
setSomeVar(0bject unionInstance)
Object getSomeVar()
Object var = X.getSomeVar();
if (var instanceof java.lang.Integer) {
....
} else if (var instanceof java.lang.String) {
....
} else if (var instanceof AlignType) {
....
}
Your request for a more semantically rich binding of xsd:union to a Java
representation via
a customization will be considered for a future version of JAXB.
-Joe Fialli, Sun Microsystems
> if(myUnionType.getType() == myUnionType.TYPE_INT)
> System.out.println("int: " + myUnionType.getInt());
> else if(myUnionType.getType() == myUnionType.TYPE_STRING)
> System.out.println("percent: " +
>myUnionType.getString());
> else if(myUnionType.getType() == myUnionType.TYPE_ALIGN)
> {
> AlignType type = myUnionType.getAlign();
> if(type == AlignType.LEFT)
> System.out.println("Align: LEFT");
> else if(type == AlignType.RIGHT)
> System.out.println("Align: RIGHT");
> else
> System.out.println("Align: CENTER");
> }
>
>
>Or somesuch thing. IE: you currently do a great job on the
>Enumerations, but they go out the window when they are unioned with
>something else like an int.
>
>Malachi
>
>-----Original Message-----
>From: Joseph Fialli [mailto:joseph.fialli_at_sun.com]
>Sent: Thursday, August 21, 2003 1:31 PM
>To: users_at_jaxb.dev.java.net
>
>
>
>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