JAXB 2.1 Propsoed Change List
=============================
Tue Oct 17 14:39:55 PDT 2006






Proposed Change: EaseOfUseAPI221
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=221


Background
----------

Today, it just takes too many lines to do a simple stuff with JAXB. One typical
example is the following code for reading XML from a file:

  File in = new File("FamilyData.xml");
  JAXBContext jc = JAXBContext.newInstance("kgh.geneology.xml");
  Unmarshaller u = jc.createUnmarshaller();
  JAXBElement junk = (JAXBElement)u.unmarshal(fin);
  DataFile df = (DataFile) junk.getValue();

(and if you count exception handling, add at least 4 lines for that.) Think of
the DataFile class as the top-level class generated by a schema compiler.

We need convenience methods that focus on typical simple use case.


Proposed Solution
-----------------

Define the JAXB class and the unmarshal/marshal methods on them.
Those methods generally look like this:

    public static <T> T unmarshal( SOMETHING xml, Class<T> type );
    public static void marshal( Object jaxbObject, SOMETHING xml );

These methods do not throw checked exceptions.


Spec Changes
------------

None, except in the API javadoc and source files. See the javadoc
for more details about this change.


Proposed Change: ExternalCustomization144
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=144


Background
----------

The most common customization that people specifies is the
globalBindings customization, and probably the schemaBindings
customization. But the current syntax for doing this is somewhat
verbose.

For example, to specify a global customization, you need to do this:

<jxb:bindings version="2.0"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
              xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <jaxb:bindings schemaLocation="path/to/some.xsd" node="/xs:schema">
     <jxb:globalBindings />
  </jxb:bindings>
</jxb:bindings>

The @schemaLocation and @node is pointless given that this is a
globalBindings. A similar problem applies to schemaBindings, where
@node is pointless.

This change rectifies this situation by not requiring those attributes
for globalBindings and schemaBindings. The user will be able to write
the same customization as follows:

<jxb:bindings version="2.0"
              xmlns:jxb="http://java.sun.com/xml/ns/jaxb">
  <jxb:globalBindings />
</jxb:bindings>

This also allows those customizations to be applied to other schemas
without any changes, as customization files no longer hard-code any
path names.



Spec Changes
------------

Change section 7.1.3 External Binding Declaration to

  - In the example, show that @schemaLocation and @node are optional

  - Insert the following sentence before the paragraph that follows
    the exmple: "The schemaLocation attribute is optional for
    specifying <globalBindings>, and The node attribute is optional
    for specifying <schemaBindings>."

Change section E.2
  
  - A sentence in 3.b will be "Then the target element will be the
    document element of the schema document identified by the
    absolutized URI. If there's no such schema document in the
    current input, it is an error."

  - A sentence at the end of 3 will be "We define the target element
    of a binding declaration to be the target element of its parent
    <jaxb:bindings> element. The only exception to this is
    <jaxb:globalBindings> binding declaraiton, in which case the
    target element will be the document element of any one of the
    schema documents being compiled (such choice is undeterministic,
    but the semantics of <jaxb:globalBindings> is not affected by this
    choice, so the end result will be the same.) It is an error if
    ..."


Proposed Change: MiscBugFixes222
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=222


Background
----------

This is an umbrella issue to fix miscellaneous typos and corrections
in the spec


Section 3.5.2.1

  Change the first sentence:

    The detection of complex schema constraint violations has been
    redesigned to have a JAXB 2.0 implementation delegate to the
    validation API in JAXP 1.3.

  This is to address the feedback from the TCK team.


Section 7.6.1.1 

  Remove the following constraints:

    If one source schema includes (via the include mechanism specified
    by XSD PART 1) a second source schema, then the <schemaBindings>
    declaration must be declared in the first including source schema.

  This is based on the implementation feedback. This restriction
  doesn't seem to be buying us anything.


Proposed Change: NoJAXBElementCustomization220
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=220


Background
----------

We discovered that the XML serialization technology in Microsoft .NET
often generates types like the following:

  <complexType name="foo">
    <sequence>
      <element name="name" type="string" minOccurs="0" nillable="true" />

The use of minOccurs="0", when combined with nillable="true", causes
JAXB to generate a property that uses JAXBElement:

  class Foo {
    JAXBElement<String> name;
  }

This was done so that we can correctly round-trip the absence of
<name/> and <name xsi:nil="true"/> as distinctive states, but when
users use JAXB to consume .NET services, this causes JAXBElement to be
everywhere, and significantly reduce the usability.

A similar issue, however on much smaller scale, can be seen with
Java-only use of JAXB. Some schema authors define this kind of
grammar, yet often application developers find such distinction
useless. So it is desirable to define a customization to allow users
to eliminate JAXBElements.

Because of the compatibility reasons, we cannot make such mode
default.



Proposed Solution
-----------------

Define one more attribute inside <jaxb:globalBindings> as
follows:

   <jaxb:globalBindings generateElementProperty="false" />

This @generateElementProperty is a three-state variable. It can be
true, false, or absent (The default is absent.) When false, nillable
and minOccurs=0 property generates a property that doesn't use
JAXBElement, as if <element nillable="false" />. If true, a property
is always generated as a JAXBElement property, as if <element
nillable="true" minOccurs="0" /> was specified. If absent, the current
behavior is retained.

The same attribute will be defined on <jaxb:property> customization.

The scoping rule applies between them. The non-absent
generateElementProperty customization on <jaxb:property/> would
override the generateElementProperty customization on
<jaxb:globalBindings/>

The 'true' value at the globalBindings level is almost useless, but it
improves the symmetry of the two cases, and simplifies the explanation.

This customization has been successfully implemented in the JAXB RI,
and we received feedback that it helped our users.



Spec Changes
------------

Section 7.5.1 "Usage":

    Add the following line into the synopsis:

        [ generateElementProperty = "true" | "false" | "1" | "0" ]

    Add the following bullet item to the list:

        - generateElementProperty if specified, controls the
          generation of JAXBElement property. The value must be one of
          "true", "false", "1", or "0". The default is absence of the
          value.

Add Section 7.5.7 "@generateElementProperty"

    Some schemas use both minOccurs="0" on element as well as
    nillable="true", causing the generation of JAXBElement. This
    customization lets you control this behavior. This attribute may
    take two values:

    true:

        Always generate properties to use JAXBElement, unless
        overriden by <jaxb:property generateElementProperty="false"/>
        on individual property.

    false:

        When generating properties from <element nillable="true"
        minOccurs="0" />, generate a property not to use JAXBElement,
        as if the element declaration were just <element
        nillable="true"/>, unless overriden by <jaxb:property
        generateElementProperty="true" /> on individual property.

        It is an error to specify this customization, when the
        property is required to be JAXBElement (such as when a
        property contains multiple elements with different names but
        of the same type.)

Section 7.8.1 "Usage"

    Add the following line into the synopsis:

        [ generateElementProperty = "true" | "false" | "1" | "0" ]

    Add the following bullet item to the list:

        - generateElementProperty if specified, controls the
          generation of JAXBElement property. The value must be one of
          "true", "false", "1", or "0". The default is absence of the
          value. It is an error for this attribute to be present if
          this customization is attached to local or global attribute
          declarations. This customization affects the binding as
          follows:

          true:

            Always generate properties to use JAXBElement.

          false:

            When generating properties from <element nillable="true"
            minOccurs="0" />, generate a property not to use
            JAXBElement, as if the element declaration were just
            <element nillable="true"/>.

          It is an error to specify this customization, when the
          property is required to be JAXBElement (such as when a
          property contains multiple elements with different names but
          of the same type.)


Proposed Change: OptimizePointlessChoice219
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=219


Background
----------

The current schema generation rules in the specification occasionally
require a generation of pointless <choice> elements that only have one
child element. This makes the output unnecessarily ugly, and shall be removed.



Spec Changes
------------

Section 8.9.2.2 "Mapping" Table 8-15 will be:

    {term}

    If Table 8-16 {particles} row results in single particle, then
    that single particle. Otherwise mapped as specified in Table 8-16.

Section 8.9.3.2 "Mapping" Table 8-19 will be:

    {term}
    
    If Table 8-20 {particles} row results in single particle, then
    that single particle. Otherwise mapped as specified in Table 8-20.

Section 8.9.4.2 "Mapping" Table 8-21 will be:

    {term}

    If Table 8-22 {particles} row results in a single particle, then
    that single particle. Otherwise mapped as specified in Table 8-22.


Proposed Change: SeparateCompilation38
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=38


Background
----------

It is a fairly common for a schema to be developed as a 'module', to
be used by other schemas. The idea is for the party X to develop a
'core' schema, then the party Y will develop additional schema on top
of the core. Examples of this can be seen in many places, including
W3C XML Schema itself, WSDL, WS-Addressing, SOAP, UBL, ...

When people develop corresponding Java libraries for these schemas,
there's often a need to compile the core schema and the additional
schema separately. That is, the party X generates (or even hand-write)
Java classes for the core schema, then the party Y compiles the
additional schema, in such a way that the generated classes refer to
the classes generated earlier (or hand-written) by X.

A similar problem applies to schema generation. Sometimes your Java
classes refer to other classes, which already have pre-generated (or
hand-written) corresponding schemas somewhere. In this case, it's
desirable to simply refer to that schema, as opposed to generate
definitions.

It is desirable for JAXB to support this notion. This feature has been
repeatedly asked from our users, and the JAX-WS 2.1 is planning to
rely on this feature, too.



Proposed Solution
-----------------

On the schema compiler side, we'll expand the <jaxb:class>
customization so that the references to the existing classes can be
specified. When such customizations are seen, a schema compiler must
not generate a class, and instead simply refer to the referenced
classes.

So for example, given the following schema:

   <schema targetNamespace="foo" ...>
     <complexType name="foo">
       <annotation><appinfo>
         <jaxb:class ref="org.acme.foo.Foo"/>
     
a schema compiler will simply assume that there's already such a class
called "org.acme.foo.Foo", and will not generate another class. All
the generated classes that reference this type will refer to
"org.acme.foo.Foo".

The same annotation can be applied on simple types.

We'll also define the map attribute on <schemaBindings> customization,
to disallow the code generation for the entire namespace (unless
otherwise overriden by <jaxb:class ref="..."/>). While we can
conceptually define such attributes on smaller units (such as on
<class> customization), given that a common use case of separate
compilation happens at the namespace level, it's unlikely to be
useful.

This allows a library to "hide" certain definitions that are globally
defined in XSD. (In schema, it's a common practice to define almost
everything as global types, which restricts Java library designer's
ability to design classes.

With this, one could write a schema like the following:

   <schema targetNamespace="foo" ...>
     <annotation><appinfo>
       <jaxb:schemaBindings map="false" />
     <complexType name="bar" />
     <complexType name="foo">
       <annotation><appinfo>
         <jaxb:class ref="org.acme.foo.Foo"/>
       <sequence>
         <element name="xyz" type="bar" />

The schemaBindings statement prevents any class generation from this
package, reference to the complex type "foo" will become a reference
to "org.acme.foo.Foo" type, and reference to the complex type "bar"
will be an error.



On the schema generator side, we'll add a new 'location'
annotation element to @XmlSchema annotation. When this attribute is
present, it points to the URI of the existing schema document that
defines the namespace. For example,

    @XmlSchema(namespace="foo")
    package foo;

    @XmlType
    class Foo {
      @XmlElement Bar zot;
    }

    @XmlSchema(namespace="bar",location="http://example.org/test.xsd")
    package bar;

    @XmlType
    class Bar {
      ...
    }

    <xs:schema targetNamespace="foo">
      <xs:import namespace="bar"
                 schemaLocation="http://example.org/test.xsd"/>
      <xs:complexType name="foo">
        <xs:sequence>
          <xs:element name="zot" type="bar:Bar" xmlns:bar="bar"/>
        </xs:sequence>
      </xs:complexType>
    </xs:schema>



Spec Changes
------------

Section 6.2.2.2 "Bind to a JAXB mapped class"

    Change the 2nd paragraph as follows:
    
    The binding of a named simple type definition to a Java value
    class is based on the abstract model properties in Section F.1.1,
    "Simple Type Definition Schema Component," on page 347. The Java
    value class must be defined as specified here, unless the ref
    attribute is specified on the <class> declaration, in which case
    the schema compiler will simply assume that the nominated class is
    already bound to this simple type.

Section 6.3.2 "Java value class":

    Change the first paragraph:

    The binding of a complex type definition to a Java value class is
    based on the abstract model properties in Section F.1.3, "Complex
    Type Definition Schema Component," on page 348. The Java value
    class must be defined as specified here, unless the ref attribute
    is specified on the <class> declaration, in which case the schema
    compiler will simply assume that the nominated class is already
    bound to this complex type.

Section 7.6.1 Usage:

    Add the following to the synopsis:

        <schemaBindings [map="boolean"]>

    Add the following paragraph after the synopsis:

        The following customizations are defined in the schema scope:

        * map : if specified, prevents the classes from being
          generated from this schema. When the value is "0" or
          "false", then no class/interface/enum will be generated from
          this package. map defaults to true.

        The semantics of the customization values, if not specified
        above, are specified when they are actually used in the
        binding declarations.

Section 7.7.1 Usage:

    Add the following to the synopsis and the bullet list that follows:

        [ref="className"]

        * ref if specified, is the name of the value class that is
          provided outside the schema compiler. This customization
          causes a schema compiler to refer to this external enum, as
          opposed to generate a definition. It must include the
          complete package name. This attribute is mutually exclusive
          with the className attribute and the implClass attribute.

Section 7.10.1 Usage:

    Add the following to the synopsis and the bullet list that follows:

        [ref="className"]

        * ref if specified, is the name of the enum class that is
          provided outside the schema compiler. This customization
          causes a schema compiler to refer to this external enum, as
          opposed to generate a definition. It must include the
          complete package name. This attribute is mutually exclusive
          with the className attribute and the map attribute.

Section 7.10.1 Usage:

    Add the following to the synopsis and the bullet list that follows:

        [ref="className"]

        * ref if specified, is the name of the enum class that is
          provided outside the schema compiler. This customization
          causes a schema compiler to refer to this external enum, as
          opposed to generate a definition. It must include the
          complete package name. This attribute is mutually exclusive
          with the className attribute and the map attribute.

Section 8.6.1.1 will be:

    @Retention(RUNTIME) @Target({PACKAGE})
    public @interface XmlSchema {
      XmlNs[] xmlns() default {};
      String namespace() default "";
      String location() default "";
      XmlNsForm elementFormDefault() default XmlNsForm.UNSET;
      XmlNsForm attributeFormDefault() default XmlNsForm.UNSET;
    }

Section 8.6.1.2 will be:

    If location() is "", a package annotated with @XmlSchema must be
    mapped as specified in Table 8-3, "Mapping: Package to XML target
    namespace," on page 234. Otherwise a package will not produce any
    schema document.

  Add another design note in 8.6.1.2:

    Note: When location() is present, this specification only
    guarantees that no schema is generated for the
    namespace. Implementations should generate <import> statements
    accordingly with the schemaLocation attribute pointing to the
    value of the @XmlSchema.location(), but <import> statements do not
    have corresponding schema components, and they are anyway just
    hints, so it's not possible to enforce such
    constraints. Implementations are also allowed to use values other
    than @XmlSchema.location() in <import schemaLocation="..."/> for
    example so that the reference points to a copy of the resource
    that's preferrable for the user.


Proposed Change: XmlElementWrapperRequired192
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=192


Background
----------

Currently there is no way to enforce the presence of an
@XmlElementWrapper, the wrapper is always generated with minOccurs=0.

So let's add @XmlElementWrapper.required(). This defaults to false to
be backward compatible, and when true, it will cause the wrapper
element to be generated minOccurs=1.


Spec Changes
------------

Modify Section 8.9.5.1 and add the required() element.

   @Retention(RUNTIME) @Target({FIELD, METHOD}
   public @interface XmlElementWrapper {
     String name() default "##default" ; // name for XML element
     String namespace() default "##default" ;
     boolean nillable() default false;
     boolean required() default false;
   }

Modify Section 8.9.5.2 Table 8-23 first row as follows:

   {minOccurs}

   if @XmlElementWrapper.nillable() is true or
   @XmlElementWrapper.required() is true, then 1; otherwise 0


Proposed Change: XmlSeeAlso201
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=201


Background
----------

For JAXB to operate, it needs to know a list of classes that it's
going to handle up front. This is the list of classes that are passed
to JAXBContext.newInstance(). While the implementation of this method
does a transitive type reference analysis, this analysis is unable to
find subclasses due to the way Java works.

At the runtime, the list of classes that JAX-WS knows to be bound by
JAXB is primarily those types that appear in the SEI. Any types that
are not transitively reachable from these classes will not be a part
of JAXBContext, and as such they'll fail to marshal/unmarshal.

What's needed here is for a portable way for the WSDL compiler tool to
pass a list of additional classes to the runtime. If such a mechanism
exist, then wscompile can capture all the generated types (by
communicating with xjc) to be used by runtime.

Since the JAX-WS implementation used at the development time and the
JAX-WS implementation at runtime might differ, any mechanism that
captures the list of classes need to be portable. That means this
requires a spec change.



Proposed Solution
-----------------

Define an annotation in JAXB that instructs JAXB runtime to bind other
classes. The feature is intended so that classes that are not
otherwise statically reachable will become reachable for the JAXB
runtime.

    @XmlSeeAlso({FooBeanEx.class,FooBean2.class,...})
    class FooBean {
      ...
    }

The semantics is that this would extend the transitive reference
closure computation. When the closure includes FooBean, this
annotation will add all the referenced classes into this closure.

To make this work with JAX-WS, JAX-WS spec will allow this annotation
to be placed on the web service class, and JAX-WS implementation needs
to be involved in passing this information to JAXB implementation (as
JAXB won't see the web service class itself as a bindable class.)

So for example, this can be used like this:

    @XmlSeeAlso({Bar.class,Zot.class})
    abstract class Foo {}
    class Bar extends Foo {}
    class Zot extends Foo {}

and "JAXBContext.newInstance(Foo.class)" will include all three
classes. (Without @XmlSeeAlso annotation on Foo,
"JAXBContext.newInstance(Foo.class)" will include only Foo.)

The JAX-WS 2.1 spec proposes to allow @XmlSeeAlso on the
SEI or endpoint implementation, like this:

    @XmlSeeAlso(Foo.class)
    interface SEI {
      Object echo(Object o);
    }

JAX-WS implementation will be responsible for making sure that the
JAXBContext it creates includes all the classes listed in
@XmlSeeAlso. This annotaion is allowed but not required.


Spec Changes
------------

Add the following to the spec.

8.7.3 @XmlSeeAlso

@XmlSeeAlso is an optional annotation that can be placed on a class to
instruct the JAXB runtime and the schema generator to also bind
classes listed in @XmlSeeAlso, when it binds the class that
@XmlSeeAlso is on.

8.7.3.1 Synopsis

@Rentention(RUNTIME)
@Target({TYPE})
public @interface XmlSeeAlso {
    Class[] value();
}


Proposed Change: XmlTransientOnClass216
------------------------------------------------------------
    See https://jaxb.dev.java.net/issues/show_bug.cgi?id=216


Background
----------

Java type hierarchy and XML type hierarchy may not always match one to
one. One such example is where you define a common base class between
various classes to share some utility code, yet such a base class
should be considered as an implementation detail.

  class AbstractModelObject {
    public void toString() {
      // use commons-lang to define a toString() for all
      return ToStringBuilder.reflectionToString(this);
    }
  }

  class Person extends AbstractModelObject { ... }
  class Computer extends AbstractModelObject { ... }

The user do not wish to create a complex type that corresponds to the
'abstractModelObject', since it's pointless. It's often even actively
harmful, because such a base class blocks the use of @XmlValue
annotation on Person and Computer classes.



Proposed Solution
-----------------

Allow @XmlTransient to be placed on a class, to indicate that it
doesn't have the corresponding XML representation. So in the above
example, one can do as follows to achieve the desired effect of not
defining 'abstractModelObject' complex type:

  @XmlTransient
  class AbstractModelObject {
    public void toString() {
      // use commons-lang to define a toString() for all
      return ToStringBuilder.reflectionToString(this);
    }
  }

  class Person extends AbstractModelObject { }
  class Computer extends AbstractModelObject { }

  <complexType name="person" />
  <complexType name="computer" />

The following example illustrates more general case:

  class Foo {
    @XmlElement String a;
  }

  @XmlTransient
  class Bar extends Foo {
    @XmlElement String b;
  }

  @XmlType(propOrder={"c","b"})
  class Zot extends Bar {
    @XmlElement String c;
  }

  <complexType name="foo">
    <sequence>
      <element name="a" type="string"/>

  <complexType name="zot">
    <complexContent>
      <extension base="foo">
        <sequence>
          <element name="c" type="string"/>
          <element name="b" type="string"/>

A few things to note:

  - Even if a class is marked as transient, you can still use JAXB
    annotations on its members, and they are bound as a part of the
    derived class. This is in accordance with the similar Java
    persistence API annotation @MappedSuperclass.

  - Since property 'b' is bound by Zot, you can freely change its
    order among other properties defined in Zot, as seen in this
    example.



Spec Changes
------------

Section 8.7.1.2 "Mapping" bullet 7:

    if the class, subClass, derives from another XML-bound class,
    baseClass directly or indirectly (other than java.lang.Object),
    then the subClass must not contain a mapped property or field
    annotated with @XmlValue annotation.

Section 8.7.1.2 Table 8-4 "Mapping: Class to Complex Type Definition" 

    {base type definition}

    "otherwise schema type to which the nearest XML-bound ancestor
    class is mapped"

  Also add the following text at the note:

    When class X with @XmlType derives from another class Y with
    @XmlTransient, which in turn derives from class X with @XmlType,
    then the above wording causes complex type X to derive from
    complex type Z, causing Y to skip.

 Add Section 8.7.3 @XmlTransient

    @XmlTransient is used to prevent the mapping of a class.

    8.7.3.1 Synopsis

    @Retention(RUNTIME) @Target({FIELD,METHOD,TYPE})
    public @interface XmlTransient {}

    8.7.3.2 Mapping

    The class must not be mapped. Any reference to this class from the
    other XML-bound classes will treated as if they are refering to
    the nearest XML-bound ancestor of this class (which could be
    java.lang.Object, which guarantees that there always exists such a
    class.)

    For the effect that this annotation causes on derived classes, see
    Table 8-4.

    Note that a class with @XmlTransient may still have properties and
    fields with JAXB annotations. Those are mapped to XML when a
    derived class is mapped to XML. See section 8.9 for more details.

    The following mapping constraints must be enforced:

    - @XmlTransient is mutually exclusive with all other mapping
      annotations.

Modify Section 8.9

    - read/write property as identified by
      java.beans.Introspector.getBeanInfo, where the stopClass is the
      nearest XML-bound super class.

    - non static, non transient field of all the ancestors up to the
      stopClass (but excluding itself); if ...

    A mapped property is a property found as above and mapped either
    by default or using a JAXB annotation.  A mapped field is a field
    found as above and mapped either by default or using a JAXB
    annotation.  A property or field that has been annotated with
    @XmlTransient is not mapped.

Modify Section 8.9.9.1 Synopsis

    @Retention(RUNTIME) @Target({FIELD,METHOD,TYPE})

Modify Section 8.12.3

    Unless @XmlTransient annotation is present, a class with a public
    or protected ...