| // |
| // Copyright (c) 2020 Contributors to the Eclipse Foundation |
| // |
| |
| == Binding XML Schema to Java Representations |
| |
| This chapter describes binding of XML schema |
| components to Java representations. The default binding is identified in |
| this chapter and the next chapter specifies the customizations that |
| override default binding. |
| |
| === Overview |
| |
| The abstract model described in [XSD Part 1] |
| is used to discuss the default binding of each schema component type. |
| Each schema component is described as a list of properties and their |
| semantics. References to properties of a schema component as defined in |
| [XSD Part 1] are denoted using the notation _{schema property}_ |
| throughout this section. References to properties of information items |
| as defined in [XML-Infoset] are denoted by the notation *[property]*. |
| |
| All JAXB implementations are required to |
| implement the default bindings specified in this chapter. However, users |
| and JAXB implementors can use the global configuration capabilities of |
| the custom binding mechanism to override the defaults in a portable |
| manner. |
| |
| For each binding of a schema component to its |
| Java representation, there is a description of Java mapping |
| annotation(s), described in link:jaxb.html#a2236[See Java Types |
| To XML]“, to be generated with the Java representation. The |
| standardization of these mapping annotations assist in specifying the |
| portability of a schema-derived JAXB-annotated classes. All JAXB |
| implementations are required to be able to unmarshal/marshal another |
| implementation’s schema-derived Java value classes by interpreting the |
| specified mapping annotations. Note that each mapping annotation is |
| described independent of whether it is the default mapping or a |
| customized mapping, JAXB implementations are allowed to optimize away |
| redundant mapping annotations that are the default mapping annotation. |
| |
| [NOTE] |
| .Design Note |
| ==== |
| Note that the mapping annotations generated on the schema derived |
| classes do not capture all aspects from the original schema. |
| A schema generated from the mapping annotations of the schema derived |
| classes differs from the original schema used to generate |
| the schema-derived classes. The original schema is more precise |
| for validation purposes than the one generated from the schema-derived classes. |
| |
| ==== |
| |
| All examples are non-normative. Note that in |
| the examples, the schema-derived code does not list all required mapping |
| annotations. In the interest of being terse, only the mapping |
| annotations directly connected to the schema component being discussed |
| are listed in its example. |
| |
| === Simple Type Definition |
| |
| A schema component using a simple type |
| definition typically binds to a Java property. Since there are different |
| kinds of such schema components, the following Java property attributes |
| (common to the schema components) are specified here and include: |
| |
| * base type |
| * collection type if any |
| * predicate |
| |
| The rest of the Java property attributes are |
| specified in the schema component using the simple type definition. |
| |
| While not necessary to perform by default, |
| this section illustrates how a simple type definition is bound to a JAXB |
| mapped class. This binding is necessary to preserve a simple type |
| definition referred to by `xsi:type` attribute in an Xml instance |
| document. See link:jaxb.html#a1582[See Usage]“for the |
| customization that enables this binding. |
| |
| ==== Type Categorization |
| |
| The simple type definitions can be categorized as: |
| |
| * schema built-in datatypes [XSD PART2] |
| * user-derived datatypes |
| |
| Conceptually, there is no difference between |
| the two. A schema built-in datatype can be a primitive datatype. But it |
| can also, like a user-derived datatype, be derived from a schema |
| built-in datatype. Hence no distinction is made between the schema |
| built-in and user-derived datatypes. |
| |
| The specification of simple type definitions |
| is based on the abstract model described in Section 4.1, “Simple Type |
| Definition” [XSD PART2]. The abstract model defines three varieties of |
| simple type definitions: atomic, list, union. The Java property |
| attributes for each of these are described next. |
| |
| ==== Atomic Datatype |
| |
| If an atomic datatype has been derived by |
| restriction using an “enumeration” facet, the Java property attributes |
| are defined by link:jaxb.html#a829[See Enum Type].” Otherwise |
| they are defined as described here. |
| |
| The base type is derived upon the XML |
| built-in type hierarchy [XSD PART2, Section 3] reproduced below. |
| |
| .XML Built-In Type Hierarchy |
| image::images/xmlb-15.png[image] |
| |
| |
| The above diagram is the same as the one in |
| [XSD PART2] except for the following: |
| |
| * Only schema built-in atomic datatypes derived by restriction have been shown. |
| * The schema built-in atomic datatypes have been annotated with Java data types |
| from the “Java Mapping for XML Schema Built-in Types” table below. |
| |
| [NOTE] |
| .Design Note |
| ==== |
| xs:anyURI is not bound to java.net.URI by default since not all |
| possible values of xs:anyURI can be passed to the java.net.URI constructor. |
| Using a global JAXB customization described in Section 7.9, “<javaType> Declaration“, |
| a JAXB user can override the default mapping to map xs:anyURI to java.net.URI. |
| |
| ==== |
| |
| |
| The following is a mapping for subset of the |
| XML schema built-in data types to Java data types. This table is used to |
| specify the base type later. |
| |
| .[[a725]]Java Mapping for XML Schema Built-in Types |
| [cols="2*",options="header"] |
| |=== |
| |XML Schema Datatype |Java Datatype |
| | *xsd:string* | *java.lang.String* |
| | *xsd:integer* | *java.math.BigInteger* |
| | *xsd:int* | *int* |
| | *xsd:long* | *long* |
| | *xsd:short* | *short* |
| | *xsd:decimal* | *java.math.BigDecimal* |
| | *xsd:float* | *float* |
| | *xsd:double* | *double* |
| | *xsd:boolean* | *boolean* |
| | *xsd:byte* | *byte* |
| | *xsd:QName* | *javax.xml.namespace.QName* footnote:jaxp[JAXP defines package |
| `javax.xml.datatype` and `javax.xml.namespace`] |
| | xsd:dateTime |javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] |
| | *xsd:base64Binary* | *byte[]* |
| | *xsd:hexBinary* | *byte[]* |
| | xsd:unsignedInt | long |
| | xsd:unsignedShort | int |
| | xsd:unsignedByte | short |
| | xsd:time | javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] |
| | xsd:date | javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] |
| | xsd:g* | javax.xml.datatype.XMLGregorianCalendar footnote:jaxp[] |
| | xsd:anySimpleType + |
| (for xsd:element of this type)footnote:[enable type substitution for element of xsd:anySimpleType] | java.lang.Object |
| | xsd:anySimpleType + |
| (for xsd:attribute of this type) | java.lang.String |
| | xsd:duration | javax.xml.datatype.Duration footnote:jaxp[] |
| | xsd:NOTATION | javax.xml.namespace.QName footnote:jaxp[] |
| |=== |
| |
| The base type is determined as follows: |
| |
| . Map by value space bounding facets + |
| If the simple type derives from or is `xsd:integer` and has either a |
| constraining lower and/or upper bounds facet(s) or totalDigits facet, |
| check if the following optimized binding is possible: |
| * If the simple type derives from or is |
| `xsd:short`, `xsd:byte` or `xsd:unsignedByte`, go to step 2. |
| * If the value space for the simple type is |
| representable in the range of `java.lang.Integer.MIN_VALUE` and |
| `java.lang.Integer.MAX_VALUE`, map to java primitive type, `int`. |
| * If the value space for the simple type is |
| representable in the range of `java.lang.Long.MIN_VALUE` and |
| `java.lang.Long.MAX_VALUE`, map to java primitive type, `long`. |
| * Else go to step 2. |
| . Map by datatype + |
| If a mapping is defined for the simple type in Table 6.1, the base type |
| defaults to its defined Java datatype. |
| . Map by base datatype + |
| Otherwise, the base type must be the result obtained by repeating the |
| step 1 and 2 using the _{base type definition}_. For schema datatypes |
| derived by restriction, the _{base type definition}_ represents the |
| simple type definition from which it is derived. Therefore, repeating |
| step 1 with _{base type definition}_ essentially walks up the XML Schema |
| built-in type hierarchy until a simple type definition which is mapped |
| to a Java datatype is found. |
| |
| The Java property predicate must be as |
| specified in “Simple Type Definition Validation Rules,” Section |
| 4.1.4[XSD PART2]. |
| |
| *_Example:_* + |
| The following schema fragment (taken from |
| Section 4.3.1, “Length” [XSD PART2]): |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:simpleType name="productCode"> |
| <xs:restriction base="xs:string"> |
| <xs:length value="8" fixed="true"/> |
| </xs:restriction> |
| </xs:simpleType> |
| ---- |
| |
| The facet “length” constrains the length of a |
| product code (represented by `productCode`) to 8 characters (see |
| section 4.3.1 [XSD PART2] for details). |
| |
| The Java property attributes corresponding to |
| the above schema fragment are: |
| |
| * There is no Java datatype mapping for `productCode`. |
| So the Java datatype is determined by walking up the |
| built-in type hierarchy. |
| * The `{base type definition}` of `productCode` |
| is `xs:string`. `xs:string` is mapped to `java.lang.String` |
| (as indicated in the table, and assuming no customization). Therefore, |
| `productCode` is mapped to the Java datatype `java.lang.String`. |
| * The predicate enforces the constraints on the length. |
| |
| ===== Notation |
| |
| Given that the value space of `xsd:NOTATION` |
| is the set of `xsd:QName`, bind `xsd:NOTATION` type to |
| `javax.xml.namespace.QName`. |
| |
| For example, the following schema: |
| |
| [source,xml] |
| ---- |
| <xs:schema targetNamespace="http://e.org" xmlns:e="http://e.org" |
| xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
| <xs:notation name="jpeg" public="image/jpeg" system="jpeg.exe"/> |
| <xs:notation name="png" public="image/png" system="png.exe"/> |
| <xs:simpleType name="pictureType"> |
| <xs:restriction base="xs:NOTATION"> |
| <xs:enumeration value="e:jpeg"/> |
| <xs:enumeration value="e:png"/> |
| </xs:restriction> |
| </xs:simpleType> |
| <xs:complexType name="Picture"> |
| <xs:simpleContent> |
| <xs:extension base="xs:hexBinary"> |
| <xs:attribute name="format" type="e:pictureType"/> |
| </xs:extension> |
| </xs:simpleContent> |
| </xs:complexType> |
| </xs:schema> |
| ---- |
| |
| is mapped to the following Java code: |
| |
| [source,java] |
| ---- |
| package org.e; |
| import javax.xml.namespace.QName; |
| public class Picture { |
| void setValue(byte[] value) {...} |
| byte[] getValue() {...} |
| void setFormat(QName value)\{...} |
| QName getFormat() {...} |
| } |
| ---- |
| |
| With the following usage scenario: |
| |
| [source,java,indent=4] |
| ---- |
| Picture pic = ...; |
| pic.setFormat(new QName("http://e.org","jpeg")); |
| ---- |
| |
| ===== Bind to a JAXB mapped class |
| |
| By default, a named simple type definition is |
| not bound to a Java class. This binding is only necessary to enable the |
| precise type of an `xsi:type` substitution to be preserved as described |
| in link:jaxb.html#a1158[See Type Substitution of a Simple Type |
| Definition]“. This binding is enabled via the global binding |
| customization attribute _@mapSimpleTypeDef_ specified in |
| link:jaxb.html#a1582[See Usage]“. |
| |
| The binding of a named simple type definition |
| to a Java value class is based on the abstract model properties in |
| link:jaxb.html#a4867[See Simple Type Definition Schema |
| Component]. The Java value class must be defined as specified here, |
| unless the ref attribute is specified on the `<jaxb:class>` declaration, |
| in which case the schema compiler will simply assume that the nominated |
| class is already bound to this simple type. |
| |
| * *name*: name is the Java identifier |
| obtained by mapping the XML name _{name}_ using the name mapping |
| algorithm, specified in link:jaxb.html#a4656[See The Name to |
| Identifier Mapping Algorithm]. Note that anonymous simple type |
| definition’s are never bound to a Java value class. |
| * *package*: The schema-derived Java value class is generated |
| into the Java package that represents the binding of _{target namespace}_ |
| * *outer class name*: There is no outer class name for a global |
| simple type definition. |
| * *base class*: Due to a constraint specified for @XmlValue |
| in Section 8, this class can not extend any other class. The derivation |
| by restriction hierarchy for simple type definitions can not be captured |
| in the schema-derived Java value class. |
| * *value property*: Same as the binding of simple content in |
| link:jaxb.html#a973[See Simple Content Binding] to an @XmlValue |
| annotated JAXB property. |
| |
| The next two examples illustrate the binding |
| of a simple type definition to a Java value class when the appropriate |
| JAXB schema customization is enabled. |
| |
| [#a816] |
| .Simple type definition |
| [source,xml,indent=4] |
| ---- |
| <xs:simpleType name="productCode"> |
| <xs:restriction base="xs:string"> |
| <xs:length value="8" fixed="true"/> |
| </xs:restriction> |
| </xs:simpleType> |
| ---- |
| |
| .Binding of <<a816>> |
| [source,java,indent=4] |
| ---- |
| @XmlType(name="productCode") |
| public class ProductCode { |
| @XmlValue |
| String getValue(); |
| void setValue(String value); |
| } |
| ---- |
| |
| ===== Annotations for standard XML datatypes |
| |
| By default, a schema-derived JAXB property |
| bound from one of the following standard XML datatypes is annotated with |
| the specified mapping annotation. |
| |
| [cols="2*",options="header"] |
| |=== |
| | `*Schema Type*` | `*JAXB Property Annotation*` |
| | `xsd:ID` | `@XmlID` |
| | `xsd:IDREF` | `@XmlIDREF` |
| | `ref:swaRef` | `@XmlAttachmentRef` |
| |=== |
| |
| Note that JAXB schema customizations could |
| override these default binding. |
| |
| ==== Enum Type |
| |
| The default mapping for a named atomic type |
| that is derived by restriction with enumeration facet(s) and whose |
| restriction base type (represented by _{base type definition}_) is |
| `xs:String` footnote:[Exception cases that |
| do not bind to enum type: when the base type is or derives from `xs:ID` |
| and `xs:IDREF`. Rationale for not binding these type definitions to an |
| enum type is in link:jaxb.html#a2126[See Customizable Schema |
| Elements]“.] or derived from it is mapped to an |
| enum type. The *[typesafeEnumBase]* attribute customization described in |
| link:jaxb.html#a1580[See <globalBindings> Declaration]," enables |
| global configuration to alter what Xml built-in datatypes are bound by |
| default to an enum type. An anonymous simple type definition is never |
| bound to an enum class by default, but it can be customized as described |
| in link:jaxb.html#a2090[See <typesafeEnum> Declaration]” to bind |
| to an enum type. |
| |
| ===== Example binding |
| |
| An example is provided first followed by a |
| more formal specification. |
| |
| XML Schema fragment: |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:simpleType name="USState"> |
| <xs:restriction base="xs:NCName"> |
| <xs:enumeration value="AK"/> |
| <xs:enumeration value="AL"/> |
| </xs:restriction> |
| </xs:simpleType> |
| ---- |
| |
| The corresponding enum type binding is: |
| |
| [source,java,indent=4] |
| ---- |
| public enum USState { |
| AK, AL; |
| public String value() { return name(); } |
| public static USState fromValue(String value) {...} |
| }; |
| ---- |
| |
| ===== Enum type binding |
| |
| The characteristics of an _enum type_ are |
| derived in terms of the properties of the |
| link:jaxb.html#a4867[See Simple Type Definition Schema |
| Component] as follows: |
| |
| The enum type binding is defined as follows: |
| |
| * *name*: The default name of the enum type, |
| _enumType_, is computed by applying the XML Name to Java identifier |
| mapping algorithm to the _{name}_ of the simple type definition. There |
| is no mechanism to derive a name for an anonymous simple type |
| definition, the customization must provide the *name*. |
| * *package name*: The package name is |
| determined from the _{targetnamespace}_ of the schema that directly |
| contains the simple type definition. |
| * *outer class name*: |
| ** There is no *outer class name* for a global |
| simple type definition. |
| ** There is no *outer class name* when schema |
| customization, *[jaxb:globalBindings]* _@localScoping_ , specified in |
| Section link:jaxb.html#a1582[See Usage], has a value of |
| _toplevel_. |
| ** The *outer class name* for an anonymous |
| simple type definition is computed by traversing up the anonymous simple |
| type definition’s ancestor tree until the first ancestor is found that |
| is: |
| *** an XML component that is mapped to a Java value class, the *outer |
| class name* is composed of the concatenation of this Java value class’s |
| *outer class name*, "**.**", and its *name*. |
| *** a global declaration or definition is reached. There is no *outer |
| class name* for this case. |
| * *enum constants*: Specified in next section. |
| |
| Note that since a Java enum type is |
| essentially a final class, it is not possible for it to be subclassed. |
| Thus, any derivations of a simple type definition bound to an enum type |
| can not be captured by an equivalent Java inheritance relationship. |
| |
| The schema-derived enum is annotated, either |
| explicitly or by default mapping annotations, with the mapping |
| annotation @XmlEnum, specified in Section 8. The @XmlEnum annotation |
| elements are derived in terms of the abstract model properties for a |
| simple type definition summarized in link:jaxb.html#a4867[See |
| Simple Type Definition Schema Component] as follows: |
| |
| .Annotate enum type with @XmlEnum element-value pairs |
| [cols="2*",options="header"] |
| |=== |
| | @XmlEnum element | @XmlEnum value |
| | name | simple type definition's {name} |
| | namespace | {target namespace} |
| | value | the java type binding of the simple type definition’s _{base type definition}_ |
| |=== |
| |
| ===== Enum Constant |
| |
| An enum constant is derived for each |
| enumeration facet of the atomic type definition. The characteristics of |
| an _enum constant_ of the enum type are derived in terms of the properties |
| of the link:jaxb.html#a4899[See Enumeration Facet Schema |
| Component] as follows: |
| |
| * *name*: The name is either specified via |
| customization, `jaxb:typesafeEnumMember` described in |
| link:jaxb.html#a2092[See Usage]“, or the name is computed as |
| specified in link:jaxb.html#a863[See XML Enumvalue-to-Java |
| Identifier Mapping]“. |
| * *type*: The Java type binding of the simple |
| type definition’s _{base_type_definition}_. |
| * *value* : The conversion of string |
| _{value}_ to *type*. *Value* is manipulated via the following |
| generated enum type methods: |
| |
| public type value(); |
| public static enumTypeName fromValue(type value); |
| |
| To assist an application in manipulating the |
| enum constants that comprise an enum type, all enum types have the |
| following two implicitly declared static methods as specified in Section |
| 8.9 in [JLS3]. The enum type’s static method `values()` returns an array |
| of all enum constants. The static method `valueOf(String name)` returns |
| the enum constant represented by the name parameter. |
| |
| ===== XML Enumvalue-[[a863]]to-Java Identifier Mapping |
| |
| The default name for the enum constant is |
| based on mapping of the XML enumeration value to a Java identifier as |
| described below. |
| |
| The XML enumeration value _{value}_ is |
| mapped to a Java Identifier using the algorithm specified in |
| link:jaxb.html#a4773[See Deriving a legal Java identifier from |
| an enum facet value]“. If there is a collision among the generated |
| constant fields *name* or if it is not possible to generate a legal Java |
| identifier for one or more of the generated constant field names, see |
| link:jaxb.html#a1633[See @typesafeEnumMemberName]“for |
| customization options to resolve this error case. |
| |
| ===== Enum Constant Name differs from its Value |
| |
| For all cases where there exist at least one |
| enumeration constant name that is not the same as the enumeration |
| constant’s value, the generated enum type must have a final value field |
| that is set by the enum type’s constructor. The code generation template |
| is the following: |
| |
| .At least one enum constant name differs from its value. |
| [source,java] |
| ---- |
| public enum enumType { |
| EnumConstantName1(EnumConstantValue1), |
| ... |
| EnumConstantNameX(EnumConstantValueX); |
| public EnumConstantValueType value() { return value; } |
| public static enumType fromValue(EnumConstantValueType val) |
| {...} |
| |
| final private EnumConstantValueType value; |
| private enumType(EnumConstantValueType value) { |
| this.value = value; |
| } |
| } |
| ---- |
| |
| .Code template when enum constant name is same as its enum constant value. |
| [source,java,subs="+quotes,+macros"] |
| ---- |
| public enum enumType { |
| EnumConstantName1, ..., EnumConstantNameX; |
| public Stringfootnote:[Note for this case, the _enumConstantValueType_ is always `java.lang.String`.] value() { return name(); } |
| public static enumType fromValue(String value) {...} |
| } |
| ---- |
| |
| The schema-derived enum constant is |
| annotated, either explicitly or by default mapping annotations, with the |
| mapping annotation specified in Section 8. The `@XmlEnumValue` |
| annotation elements are derived in terms of the abstract model |
| properties for a enumerated facet summarized in |
| link:jaxb.html#a4899[See Enumeration Facet Schema Component] as |
| follows: |
| |
| .Annotate enum constant with @XmlEnumValue element-value pairs |
| [cols="2*",options="header"] |
| |=== |
| | @XmlEnumValue element | @XmlEnumValue value |
| | value | Enumeration facet’s {value} |
| |=== |
| |
| |
| Given following schema fragment: |
| |
| .Schema-derived enum type when enumeration facet’s value does not match enum constant name. |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:simpleType name="Coin"> |
| <!-- Assume jaxb customization that binds Coin to an enumType --> |
| <xs:restriction base="xs:int"> + |
| <!-- Assume jaxb customization specifying enumConstantName --> |
| <xs:enumeration value="1"/> <!-- name="penny"--> |
| <xs:enumeration value="5"/> <!-- name="nickel"--> |
| <xs:enumeration value="10"/><!-- name="dime"--> |
| <xs:enumeration value="25"/><!-- name="quarter--> |
| </xs:restriction> |
| </xs:simpleType> |
| ---- |
| |
| Schema-derived enum type: |
| |
| [source,java,indent=4] |
| ---- |
| @XmlEnum(value="java.lang.Integer.class") |
| public enum Coin { |
| @XmlEnumValue("1") PENNY(1), |
| @XmlEnumValue("5") NICKEL(5), |
| @XmlEnumValue("10") DIME(10), |
| @XmlEnumValue("25") QUARTER(25); |
| |
| public int value() { return value; } |
| public static Coin fromValue(int value) {...} |
| |
| private final Integer value; |
| Coin(int value) { this.value = value; } |
| } |
| ---- |
| |
| ==== List |
| |
| A list simple type definition can only |
| contain list items of atomic or union datatypes. The item type within |
| the list is represented by the schema property _{item type definition}_. |
| |
| The Java property attributes for a list |
| simple type definition are: |
| |
| * The _base type_ is derived from the _{item type definition}_ as follows. |
| If the Java datatype for _{item type definition}_ is a Java primitive type, |
| then the base type is the wrapper |
| class for the Java primitive type. Otherwise, the Java datatype is |
| derived from the XML datatype as specified in |
| link:jaxb.html#a715[See Atomic Datatype]” and |
| link:jaxb.html#a829[See Enum Type].” |
| * The _collection type_ defaults to an |
| implementation of `java.util.List`. Note that this specification does |
| not specify the default implementation for the interface |
| `java.util.List`, it is implementation dependent. |
| * The _predicate_ is derived from the “Simple |
| Type Definition Validation Rules,” in section 4.1.4,[XSD PART2]. |
| |
| *_Example:_* + |
| For the following schema fragment: |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:simpleType name="xs:USStateList"> |
| <xs:list itemType="xs:string"/> |
| </xs:simpleType> |
| ---- |
| |
| The corresponding Java property attributes |
| are: |
| |
| * The _base type_ is derived from _{item type definition}_ |
| which is XML datatype, `_"xs:string"_` , thus the Java |
| datatype is `java.util.String` as specified in |
| link:jaxb.html#a725[See Java Mapping for XML Schema Built-in |
| Types]. |
| * The _collection type_ defaults to an implementation of `java.util.List`. |
| * The _predicate_ only allows instances of |
| _base type_ to be inserted into the list. When failfast check is being |
| performedfootnote:[link:jaxb.html#a1582[See Usage] |
| describes the `enableFailFastCheck` customization and |
| link:jaxb.html#a256[See Validation]” defines fail-fast |
| checking.], the list’s mutation methods apply the |
| property’s predicate to any non-`null` value before adding that value |
| to the list or replacing an existing element’s value with that value; |
| the predicate may throw a `TypeConstraintException`. |
| |
| The schema-derived property is annotated, |
| either explicitly or by default mapping annotations, with the mapping |
| annotation @XmlList, specified in Section 8. |
| |
| ==== Union Property |
| |
| A union property _prop_ is used to bind a |
| union simple type definition schema component. A union simple type |
| definition schema component consists of union members which are schema |
| datatypes. A union property, is therefore, realized by: |
| |
| [source,java,indent=8] |
| ---- |
| public Type getId(); |
| public void setId(Type value); |
| ---- |
| |
| where `_Id_` is a metavariable that represents |
| the Java method identifier computed by applying the name mapping |
| algorithm described in link:jaxb.html#a4656[See The Name to |
| Identifier Mapping Algorithm] to _prop_ . |
| |
| The _base type_ is String. If one of the |
| member types is derived by list, then the Union property is represented |
| as the appropriate collection property as specified by the customization |
| `<jaxb:globalBindings>` *@collectionType* value, specified in |
| link:jaxb.html#a1582[See Usage].” |
| |
| * The `getId` method returns the set value. |
| If the property has no set value then the value `null` is returned. The |
| value returned is Type. |
| * The `setId` method sets the set value. + |
| If value is `null`, the property’s _set value_ is discarded. Prior to |
| setting the property’s value when TypeConstraint validation is enabled, |
| a non-`null` value is validated by applying the property’s predicate, |
| which may throw a `TypeConstraintException`. No setter is generated if |
| the union is represented as a collection property. |
| |
| *_Example: Default Binding: Union_* |
| |
| The following schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="CTType"> |
| <xs:attribute name="state" type="ZipOrName"/> |
| </xs:complexType> |
| <xs:simpleType name="ZipOrName" |
| memberTypes="xs:integer xs:string"/> |
| ---- |
| |
| is bound to the following Java representation. |
| |
| [source,java] |
| ---- |
| public class CTType { |
| String getState() {...} |
| void setState(String value) {...} |
| } |
| ---- |
| |
| ==== Union |
| |
| A simple type definition derived by a union |
| is bound using the union property with the following Java property |
| attributes: |
| |
| * the _base type_ as specified in |
| link:jaxb.html#a899[See Union Property].” |
| * if one of the member types is derived by `<xs:list>`, |
| then the union is bound as a Collection property. |
| * The _predicate_ is the schema constraints |
| specified in “Simple Type Definition Validation Rules,” Section 4.1.4 |
| [XSD PART2]. |
| |
| === Complex Type Definition |
| |
| ==== Aggregation of Java Representation |
| |
| A Java representation for the entire schema |
| is built based on aggregation. A schema component aggregates the Java |
| representation of all the schema components that it references. This |
| process is done until all the Java representation for the entire schema |
| is built. Hence a general model for aggregation is specified here once |
| and referred to in different parts of the specification. |
| |
| The model assumes that there is a schema |
| component _SP_ which references another schema component _SC_. The Java |
| representation of _SP_ needs to aggregate the Java representation of |
| _SC_. There are two possibilities: |
| |
| * _SC_ is bound to a property set. |
| * _SC_ is bound to a Java datatype or a Java value class. |
| |
| Each of these is described below. |
| |
| ===== Aggregation of Datatype/Class |
| |
| If a schema component _SC_ is bound to a Java |
| datatype or a Java value class, then _SP_ aggregates _SC’s_ Java |
| representation as a simple property defined by: |
| |
| * *name*: the name is the class/interface |
| name or the Java datatype or a name determined by SP. The name of the |
| property is therefore defined by the schema component which is |
| performing the aggregation. |
| * *base type*: If SC is bound to a Java |
| datatype, the base type is the Java datatype. If SC is bound to a Java |
| value class, then the base type is the class name, including a dot |
| separated list of class names within which SC is nested. |
| * *collection type*: There is no collection type. |
| * *predicate*: There is no predicate. |
| |
| ===== Aggregation of Property Set |
| |
| If _SC_ is bound to a property set, then _SP_ |
| aggregates by adding _SC’s_ property set to its own property set. |
| |
| Aggregation of property sets can result in |
| name collisions. A name collision can arise if two property names are |
| identical. A binding compiler must generate an error on name collision. |
| Name collisions can be resolved by using customization to change a |
| property name. |
| |
| ==== Java value class |
| |
| The binding of a complex type |
| definition to a Java value class is based on the abstract model |
| properties in link:jaxb.html#a4907[See Complex Type Definition |
| Schema Component]. The Java value class must be defined as specified |
| here, unless the ref attribute is specified on the _<jaxb:class>_ |
| customization, in which case the schema compiler will simply assume that |
| the nominated class is already bound to this complex |
| type.footnote:[Note that |
| link:jaxb.html#a1084[See Binding of an anonymous complex type |
| definition] defines the name and package property for anonymous type |
| definitions occurring within an element declaration.] |
| |
| * *name*: name is the Java identifier |
| obtained by mapping the XML name _{name}_ using the name mapping |
| algorithm, specified in link:jaxb.html#a4656[See The Name to |
| Identifier Mapping Algorithm]. For the handling of an anonymous complex |
| type definition, see link:jaxb.html#a1084[See Binding of an |
| anonymous complex type definition]” for how a *name* value is derived |
| from its parent element declaration. |
| * *package*: |
| ** For a global complex type definition, the |
| derived Java value class is generated into the Java package that |
| represents the binding of _{target namespace}_ |
| ** For the value of *package* for an anonymous |
| complex type definition, see link:jaxb.html#a1084[See Binding of |
| an anonymous complex type definition]". |
| * *outer class name*: |
| ** There is no outer class name for a global |
| complex type definition. |
| ** link:jaxb.html#a1084[See Binding of |
| an anonymous complex type definition]" defines how to derive this |
| property from the element declaration that contains the anonymous |
| complex type definition. |
| * *base class*: A complex type definition |
| can derive by restriction or extension (i.e. _{derivation method}_ is |
| either "extension" or "restriction"). However, since there is no concept |
| in Java programming similar to restriction, both are handled the same. |
| If the _{base type definition}_ is itself mapped to a Java value class |
| (Ci2), then the base class must be Ci2. This must be realized as: |
| + |
| -- |
| [source,java] |
| ---- |
| public class Ci1 extends Ci2 { |
| ..... |
| } |
| ---- |
| -- |
| + |
| See example of derivation by extension at the |
| end of this section. |
| |
| * *abstract*: The generated Java class is |
| abstract when the complex type definition’s _{abstract}_ property is |
| `true`. |
| * *property set*: The Java representation of |
| each of the following must be aggregated into Java value class’s |
| property set (link:jaxb.html#a918[See Aggregation of Java |
| Representation]). |
| ** A subset of _{attribute uses}_ is |
| constructed. The subset must include the schema attributes corresponding |
| to the `<xs:attribute>` children and the _{attribute uses}_ of the |
| schema attribute groups resolved by the <ref> attribute. Every |
| attribute’s Java representation (link:jaxb.html#a1252[See Attribute use]) |
| in the set of attributes computed above must be aggregated. |
| ** If the optional _{attribute wildcard}_ is |
| present, either directly or indirectly, a property defined by |
| link:jaxb.html#a1306[See Attribute Wildcard]“is generated. |
| ** The Java representation for _{content type}_ must be aggregated. |
| + |
| For a “Complex Type Definition with complex |
| content,” the Java representation for _{content type}_ is specified in |
| link:jaxb.html#a1332[See Content Model - Particle, Model Group, |
| Wildcard].” |
| + |
| For a complex type definition which is a “Simple Type Definition with |
| simple content,” the Java representation for _{content type}_ is |
| specified in link:jaxb.html#a973[See Simple Content Binding].” |
| ** If a complex type derives by restriction, |
| there is no requirement that Java properties representing the attributes |
| or elements removed by the restriction to be disabled. This is because |
| (as noted earlier), derivation by restriction is handled the same as |
| derivation by extension. |
| * When the complex type definition’s |
| _{abstract}_ property is `false`, a factory method is generated in the |
| package’s `ObjectFactory` class introduced in |
| link:jaxb.html#a482[See Java Package]. The factory method |
| returns the type of the Java value class. The name of the factory method |
| is generated by concatenating the following components: |
| ** The string constant `create`. |
| ** The _name_ of the Java value class. |
| |
| The schema-derived Java value class is |
| annotated, either explicitly or by default mapping annotations, with the |
| mapping annotation @XmlType, specified in Section |
| link:jaxb.html#a2578[See @XmlType]. The @XmlType annotation |
| elements are derived in terms of the abstract model properties for a |
| complex type definition summarized in link:jaxb.html#a4907[See |
| Complex Type Definition Schema Component] as follows: |
| |
| .[[a956]]Annotate Java value class with @XmlType element-value pairs |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| | @XmlType element | @XmlType value |
| | name | complex type definition's {name} |
| | namespace | {target namespace} |
| | propOrder a | When \{content type} is element-only |
| {content model} and top-level {compositor} is xs:sequence, ordered |
| list of JAXB property names representing order of xs:elements in |
| {content model}. |
| + |
| |
| All other cases do not need to set propOrder. |
| |
| |=== |
| |
| *_Example:_* Complex Type: Derivation by Extension |
| |
| XML Schema Fragment (from XSD PART 0 primer): |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="Address"> |
| <xs:sequence> |
| <xs:element name="name" type="xs:string"/> |
| <xs:element name="street" type="xs:string"/> |
| <xs:element name="city" type="xs:string"/> |
| </xs:sequence> |
| </xs:complexType> |
| <xs:complexType name="USAddress"> |
| <xs:complexContent> |
| <xs:extension base="ipo:Address"> |
| <xs:sequence> |
| <xs:element name="state" type="xs:string"/> |
| <xs:element name="zip" type="xs:integer"/> |
| </xs:sequence> |
| </xs:extension> |
| </xs:complexContent> |
| </xs:complexType> |
| ---- |
| |
| Default Java binding: |
| |
| [source,java,indent=4] |
| ---- |
| public class Address { |
| String getName() {...} |
| void setName(String) {...} |
| String getStreet() {...} |
| void setStreet(String) {...} |
| void getCity() {...} |
| void setCity(String) {...} |
| } |
| |
| import java.math.BigInteger; |
| |
| public class USAdress extends Address { |
| String getState() {...} |
| void setState(String) {...} { |
| BigInteger getZip() {...} |
| void setZip(BigInteger) {...} |
| } |
| |
| class ObjectFactory { |
| Address createAddress() {...} |
| USAddress createUSAddress() {...} |
| } |
| ---- |
| |
| ===== Simple Content Binding |
| |
| ====== Binding to Property |
| |
| By default, a complex type definition with |
| simple content is bound to a Java property defined by: |
| |
| * *name*: The property name must be `value`. |
| * *base type, predicate, collection type*: |
| As specified in [XSD Part 1], when a complex type has simple content, |
| the content type (_{content type}_) is always a simple type schema |
| component. And a simple type component always maps to a Java datatype |
| (link:jaxb.html#a702[See Simple Type Definition]”). Values of |
| the following three properties are copied from that Java type: |
| ** base type |
| ** predicate |
| ** collection type |
| |
| The schema-derived JAXB property representing |
| simple content is annotated, either explicitly or by default mapping |
| annotations, with the mapping annotation @XmlValue, specified in Section |
| link:jaxb.html#a3331[See @XmlValue]. |
| |
| *_Example:_* Simple Content: Binding To Property |
| |
| XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="internationalPrice"> |
| <xs:simpleContent> |
| <xs:extension base="xs:decimal"> |
| <xs:attribute name="currency" type="xs:string"/> |
| </xs:extension> |
| </xs:simpleContent> |
| </xs:complexType> |
| ---- |
| |
| Default Java binding: |
| |
| [source,java,indent=4] |
| ---- |
| class InternationalPrice { |
| /** Java property for simple content */ |
| @XmlValue |
| java.math.BigDecimal getValue() {...} |
| void setValue(java.math.BigDecimal value) {...} |
| |
| /** Java property for attribute */ |
| String getCurrency() {...} |
| void setCurrency(String) {...} |
| } |
| ---- |
| |
| ==== xsd:anyType |
| |
| `xsd:anyType` is the root of the type |
| definition hierarchy for a schema. All complex type definitions in a |
| schema implicitly derive from `xsd:anyType`. Given that the JAXB |
| architecture does not define a common base class for all JAXB class |
| bindings of complex type definitions, the only possible binding property |
| base type binding for `xsd:anyType` is to `java.lang.Object`. This |
| binding enables all possible type and element substitutions for an |
| element of type `xsd:anyType`. |
| |
| .Binding of element with type _xsd:anyType_ |
| [source,xml,indent=4] |
| ---- |
| <xs:element name="anyContent/> <!-- @type defaults to xs:anyType --> |
| <xs:complexType name="base"> |
| <xs:sequence> |
| <xs:element ref="anyContent/> |
| <xs:element name="anyContentAgain" type="xs:anyType"/> |
| </xs:sequence> |
| </xs:complexType> |
| ---- |
| [source,java,indent=4] |
| ---- |
| public class Base { |
| void setAnyContent(Object obj); |
| Object getAnyContent(); |
| void setAnyContentAgain(Object obj); |
| Object getAnyContentAgain(); |
| } |
| ---- |
| |
| A schema author defines an element to be of |
| type `xs:anyType` to defer constraining an element to a particular type |
| to the xml document author. Through the use of `xsi:type` attribute or |
| element substitution, an xml document author provides constraints for an |
| element defined as `xs:anyType`. The JAXB unmarshaller is able to |
| unmarshal a schema defined `xsd:anyType` element that has been |
| constrained within the xml document to an easy to access JAXB mapped |
| class. However, when the xml document does not constrain the |
| `xs:anyType` element, JAXB unmarshals the unconstrained content to an |
| element node instance of a supported DOM API. |
| |
| Type substitution is covered in more detail |
| in Section link:jaxb.html#a1148[See Type Substitution of a |
| Complex Type Definition] and link:jaxb.html#a1158[See Type |
| Substitution of a Simple Type Definition]. Element substitution is |
| covered in more detail in Section link:jaxb.html#a1223[See Bind |
| to a Simple Element property]. |
| |
| === Attribute Group Definition |
| |
| There is no default mapping for an attribute |
| group definition. When an attribute group is referenced, each attribute |
| in the attribute group definition becomes a part of the _[attribute uses]_ |
| property of the referencing complex type definition. Each attribute is |
| mapped to a Java property as described in |
| link:jaxb.html#a1252[See Attribute use]“. If the attribute group |
| definition contains an attribute wildcard, denoted by the |
| `xs:anyAttribute` element, then the referencing complex type definition |
| will contain a property providing access to wildcard attributes as |
| described in link:jaxb.html#a1306[See Attribute Wildcard]“. |
| |
| === Model Group Definition |
| |
| When a named model group definition is |
| referenced, the JAXB property set representing its content model is |
| aggregated into the Java value class representing the complex type |
| definition that referenced the named model group definition as |
| illustrated in link:jaxb.html#a999[See Binding for a reference |
| to a model group definition.]” |
| |
| .[[a999]]Binding for a reference to a model group definition. |
| image::images/xmlb-16.png[image] |
| |
| This binding style results in the same |
| properties occurring within both Java value class’s A and C to represent |
| the referenced Model Group B’s content model. |
| |
| When a model group definition’s content model |
| contains an XML Schema component that is to be bound to a Java value |
| class, element class or enum type, it is desirable to only create a |
| single Java representation, not one for each complex content that |
| references the named model group definition. This default binding from a |
| model group definition’s content model is defined in |
| link:jaxb.html#a1012[See Deriving Class Names for Named Model |
| Group Descendants]." |
| |
| To meet the JAXB goal of predictable |
| unmarshalling of invalid XML content, the JAXB 1.0 customization for |
| binding a model group to a JAXB mapped class is no longer supported. |
| link:jaxb.html#a386[See Flexible Unmarshalling]“details the |
| rationale behind this change. |
| |
| ==== Bind to a set of properties |
| |
| A non-repeating reference to a model group |
| definition, when the particle referencing the group has _{max occurs}_ |
| equal to one, results in a set of content properties being generated to |
| represent the content model. link:jaxb.html#a1332[See Content |
| Model - Particle, Model Group, Wildcard]” describes how a content model |
| is bound to a set of properties and has examples of the binding. |
| |
| ==== Bind to a list property |
| |
| A reference to a model group definition from |
| a particle with a repeating occurrence is bound by default as specified |
| in link:jaxb.html#a1402[See Bind a repeating occurrence model |
| group]“. |
| |
| *_Example:_* + |
| Schema fragment contains a particle that |
| references the model group definition has a _{maxOccurs}_ value greater |
| than one. |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:group name="AModelGroup"> |
| <xs:choice> |
| <xs:element name="A" type="xs:int"/> |
| <xs:element name="B" type="xs:float"/> |
| </xs:choice> |
| </xs:group> |
| |
| <xs:complexType name="foo"> |
| <xs:sequence> |
| <xs:group ref="AModelGroup" maxOccurs="unbounded"/> |
| <xs:element name="C" type="xs:float"/> |
| </xs:sequence> |
| </xs:complexType> |
| ---- |
| |
| Derived Java representation: |
| |
| [source,java,indent=4] |
| ---- |
| public class Foo { |
| /** A valid general content property of AModelGroup content model.*/ |
| @XmlElements({ |
| @XmlElement(type=Integer.class, name="A"), |
| @XmlElement(type=Float.class, name="B")}) |
| java.util.List<Object> getAModelGroup() {...} |
| |
| float getC() {...} |
| void setC(float value) {...} |
| }; |
| ---- |
| |
| ==== Deriving Class Names for Named Model Group Descendants |
| |
| When a model group definition’s content model |
| contains XML Schema components that need to be bound to a Java class or |
| interface, this section describes how to derive the package and name for |
| the Java value class, enum type or element class derived from the |
| content model of the model group definition. The binding of XML Schema |
| components to Java classes/interfaces is only performed once when the |
| model group definition is processed, not each time the model group |
| definition is referenced as is done for the property set of the model |
| group definition. |
| |
| XML Schema components occurring within a |
| model group definition’s content model that are specified by this |
| chapter and the customization chapter to be bound to a Java value class, |
| interface or typesafe enum class are bound as specified with the |
| following naming exceptions: |
| |
| * *package*: The element class, Java value |
| class or typesafe enum class is bound in the Java package that |
| represents the target namespace containing the model group definition. |
| * *name*: The name of the interface or |
| class is generated as previously specified with one additional step to |
| promote uniqueness between interfaces/classes promoted from a model |
| group definition to be bound to a top-level class within a Java package. |
| By default, a prefix for the interface/class name is computed from the |
| model group definition’s _{name}_ using the XML name to Java identifier |
| algorithm. If the schema customization *[jaxb:globalBindings]* |
| _@localScoping_ has a value of _toplevel_, then a prefix is not |
| generated from the model group definition’s _{name}_. |
| |
| For example, given a model group definition |
| named _Foo_ containing an element declaration named _bar_ with an |
| anonymous complex type definition, the anonymous complex type definition |
| is bound to a Java value class with the name _FooBar_. The following |
| figure illustrates this example. |
| |
| .Default binding for anonymous type def within a model group definition. |
| image::images/xmlb-17.png[image] |
| |
| |
| Note that even customization specified Java |
| value class, interface or typesafe enum class names are prepended with |
| the model group definition’s name. Thus, if a model group definition |
| named `Foo` contains an anonymous simple type definition with a typesafe |
| enum class customization name of `Colors`, the enum type name is |
| `FooColors`. |
| |
| === Attribute Declaration |
| |
| An attribute declaration is bound to a Java |
| property when it is referenced or declared, as described in |
| link:jaxb.html#a1252[See Attribute use],” from a complex type |
| definition. |
| |
| ==== Bind global attribute to a QName Constant |
| |
| To assist the dynamic access to schema-defined global attributes |
| described in Section 6.9, “Attribute Wildcard", a global attribute |
| declaration is bound to a JAXB QName constant, derived in terms of |
| the properties of the “Attribute Declaration Schema Component” |
| as follows: |
| |
| * A _package name_, which is either computed from the attribute |
| declaration _{target namespace}_ or specified by binding |
| customization of the target namespace or a specified package |
| name for components that are scoped to no target namespace. |
| * The _name_ of the generated constant is derived from |
| the element declaration _{name}_ using the XML Name to Java |
| identifier mapping algorithm for a constant name or |
| specified by a binding customization of the attribute’s name. |
| * The QName constant is a JAXB constant property in class _ObjectFactory_. |
| * The QName constant value is initialized using the attribute declaration’s |
| _{target namespace}_ and _{name}_. |
| |
| .Bind global attribute declaration to a JAXB QName constant |
| [source,xml,indent=4] |
| ---- |
| <xs:schema targetNamespace="http://e.org" xmlns:a="http://e.org"> |
| <xs:attribute name="isOpen" type="xs:boolean"/> |
| </xs:schema> |
| ---- |
| [source,java,indent=4] |
| ---- |
| package org.e; |
| public class ObjectFactory { |
| /** <xs:attribute name="{http://e.org}isOpen" type="xs:boolean"/> */ |
| public static final javax.xml.namespace.QName IS_OPEN = |
| new QName("http://e.org", "isOpen"); |
| ... |
| } |
| ---- |
| |
| === Element Declaration |
| |
| This section describes the binding of an XML |
| element declaration to a Java representation. For a description of how |
| this binding has changed since the previous version, see |
| link:jaxb.html#a680[See Java Element Representation Summary]“. |
| This section introduces why a JAXB technology user has to use instances |
| of JAXB element as opposed to instances of Java datatypes or Java value |
| class when manipulating XML content. |
| |
| An XML element declaration is composed of the |
| following key components: |
| |
| * its qualified name is _{target namespace}_ and _{name}_ |
| * its value is an instance of the Java class binding of its _{type definition}_ |
| * whether the element’s content is _{nillable}_ |
| |
| Typically, an instance of |
| `jakarta.xml.bind.JAXBElement<T>`, returned by an element factory method, |
| represents an element declaration’s key components. An instance of a |
| Java value class or content interface represents only the value of an |
| element. Commonly in JAXB binding, the Java representation of XML |
| content enables one to manipulate just the value of an XML element, not |
| an actual element instance. The binding compiler statically associates |
| the XML element qualified name to a content property and this |
| information is used at unmarshal/marshal time. For cases where the |
| element name can be dynamically altered at runtime, the JAXB user needs |
| to manipulate elements, not element values. The following schema/derived |
| Java code example illustrates this point. |
| |
| *_Example:_* + |
| |
| Given the XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="chair_kind"> |
| <xs:sequence> |
| <xs:element name="has_arm_rest" type="xs:boolean"/> |
| </xs:sequence> |
| </xs:complexType> |
| ---- |
| |
| Schema-derived Java value class: |
| [source,java,indent=4] |
| ---- |
| public class ChairKind { |
| boolean isHasArmRest() {...} |
| void setHasArmRest(boolean value) {...} |
| } |
| ---- |
| |
| A user of the Java value class `ChairKind` |
| never has to create a Java instance that both has the value of local |
| element `has_arm_rest` and knows that its XML element name is |
| `has_arm_rest`. The user only provides the value of the element to the |
| content-property `hasArmRest`. A JAXB implementation associates the |
| content-property `hasArmRest` with XML element name `has_arm_rest` when |
| marshalling an instance of `ChairKind`. |
| |
| The next schema/derived Java code example |
| illustrates when XML element information can not be inferred by the |
| derived Java representation of the XML content. Note that this example |
| relies on binding described in link:jaxb.html#a1384[See Bind |
| wildcard schema component].” |
| |
| *_Example:_* |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="chair_kind"> |
| <xs:sequence> |
| <xs:any/> |
| </xs:sequence> |
| </xs:complexType> |
| ---- |
| |
| [source,java,indent=4] |
| ---- |
| public class ChairKind { |
| @XmlAnyElement(lax="true") |
| java.lang.Object getAny() {...} |
| void setAny(java.lang.Object elementOrValue) {...} |
| } |
| ---- |
| |
| For this example, the user can provide an |
| Element instance to the `any` content-property that contains both the |
| value of an XML element and the XML element name since the XML element |
| name could not be statically associated with the content-property `any` |
| when the Java representation was derived from its XML Schema |
| representation. The XML element information is dynamically provided by |
| the application for this case. link:jaxb.html#a1332[See Content |
| Model - Particle, Model Group, Wildcard] cover additional circumstances |
| when one can use JAXB elements. |
| |
| ==== Bind to _JAXBElement<T>_ Instance |
| |
| The characteristics of the generated |
| ObjectFactory element factory method that returns an `JAXBElement<T>` |
| instance are derived in terms of the properties of the |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| as follows: |
| |
| * The element factory method is generated |
| into the `ObjectFactory` class in the Java package that represents the |
| binding of the element declaration’s _{target namespace}_. |
| * The element factory method returns an |
| instance of `jakarta.xml.bind.JAXBElement<T>`, where `T` is the Java |
| value class representing the _{type definition}_ of the element |
| declaration. The factory method sets the element name of the returned |
| instance to the element declaration’s fully qualified name. |
| * The element factory method has a single |
| parameter that is an instance of type `T`, where `T` is the Java value |
| class representing the _{type definition}_ of the element declaration. |
| * The name of the factory method is generated |
| by concatenating the following components: |
| ** The string constant `create`. |
| ** By default, if the element declaration is |
| nested within another XML Schema component, then the concatenation of |
| all outer Java class names representing those XML Schema components. If |
| the schema customization *[jaxb:globalBindings]* _@localScoping_ has a |
| value of toplevel, skip this step. |
| ** A name that is generated from the element |
| declaration's _{name}_ using the XML Name to Java identifier name |
| mapping algorithm specified in link:jaxb.html#a4656[See The Name |
| to Identifier Mapping Algorithm]. |
| * The `JAXBElement<T>` property for nil |
| test whether an element’s content model is `xsi:nil="true"`. |
| |
| For example, an element declaration named |
| `Foo` with a type of `xs:int` that is nested within the content |
| model of complex type definition `Bar` would have the following factory |
| method generated in the containing Java package's `ObjectFactory` class: |
| |
| [source,java,indent=8] |
| ---- |
| JAXBElement<Integer> createBarFoo(Integer value) {...} |
| ---- |
| |
| Default binding rules require an element |
| declaration to be bound to element factory method under the following |
| conditions: |
| |
| * All non-abstract, named element |
| declarations with global _{scope}_ are bound to an element factory method |
| that returns an `JAXBElement<T>` instance. The rationale is that any |
| global element declaration can occur within a wildcard context and one |
| might want to provide element instances, not instances of the element’s |
| type, the element’s value, for this case. |
| * All local element declarations, having a |
| _{scope}_ of a complex type definition, occurring within content that is |
| mapped to a general content property of JAXB elements must have an |
| element factory method generated. General content property is specified |
| in link:jaxb.html#a1344[See General content property]” An |
| example of when a content model is mapped to a general content property, |
| forcing the generation of element declarations is at |
| link:jaxb.html#a1359[See Examples].” |
| |
| The schema-derived element factory method is |
| annotated, either explicitly or by default mapping annotations, with the |
| mapping annotation `@XmlElementDecl`, specified in Section 8. The |
| `@XmlElementDecl` annotation elements are derived in terms of the |
| abstract model properties for an element declaration summarized in |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| as follows: |
| |
| .Annotate element instance factory with @XmlElementDecl element-value pairs. |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| | @XmlElementDecl element |@XmlElementDecl value |
| | name | element declaration's _{name}_ |
| | namespace | _{target namespace}_ |
| | scope | If _{scope}_ is _global_, `JAXBElement.GlobalScope.class` else the JAXB |
| Java value class representing the __{scope}__ing complex type definition. |
| | substitutionHeadName | If optional _{substitution group affiliation}_ exists, |
| its local name. |
| | substitutionHeadNamespace | If optional _{substitution group affiliation}_ exists, |
| its namespace. |
| |=== |
| |
| The element declaration’s _{type}_ can |
| result in additional JAXB annotations being generated on the element |
| instance factory. For more details, see link:jaxb.html#a820[See |
| Annotations for standard XML datatypes]“and @XmlList in |
| link:jaxb.html#a883[See List]“. |
| |
| The schema-derived ObjectFactory class |
| containing the @XmlElementDecl annotations is annotated with |
| @XmlRegistry annotation. |
| |
| ==== Bind to Element Class |
| |
| link:jaxb.html#a1698[See <class> |
| Declaration]“customization enables the binding of an element declaration |
| with a named type definition to a schema-derived Element class. The |
| characteristics of the schema-derived Element class are derived in terms |
| of the properties of the link:jaxb.html#a4937[See Element |
| Declaration Schema Component] as follows: |
| |
| * The _name_ of the generated Java Element |
| class is derived from the element declaration _{name}_ using the XML Name |
| to Java identifier mapping algorithm for class names. |
| * Each generated Element class must extend |
| the Java value class `jakarta.xml.bind.JAXBElement <T>`. The next bullet |
| specifies the schema-derived Java class name to use for generic |
| parameter `T`. |
| * If the element declaration’s _{type definition}_ is |
| ** Anonymous |
| + |
| Generic parameter `T` from the second bullet |
| is set to the schema-derived class represented the anonymous type |
| definition generated as specified in Section 6.7.3. |
| ** Named |
| + |
| Generic parameter `T` from the second bullet is |
| set to the Java class representing the element declaration’s |
| _{type definition}_. |
| * The `ObjectFactory` method to create an |
| instance of _name_ has a single parameter that is an instance of type `T`. |
| By default, the name of the ObjectFactory method is derived by |
| concatenating _outerClassNames_ and _name_. When schema customization, |
| *[jaxb:globalBindings]* _@localScoping,_ specified in Section |
| _link:jaxb.html#a1582[See Usage],_ has a value of _toplevel_, |
| then the outer Classnames are ommitted from the factory method name. |
| * If _{scope}_ is |
| ** *Global*: The derived Element class is |
| generated into the Java package that represents the binding of |
| _{target namespace}_. |
| ** *A Complex Type Definition*: By default, |
| the derived Element class is generated within the Java value class |
| represented by the complex type definition value of _{scope}_. When |
| _@localScoping_ is _toplevel_ , the derived element class is generated |
| as a toplevel class. |
| * The property for nil test whether element’s content model is `xsi:nil="true"`. |
| * Optional _{value constraint}_ property with |
| pair of `default` or `fixed` and a value. + |
| If a default or fixed value is specified, the data binding system must |
| substitute the default or fixed value if an empty tag for the element |
| declaration occurs in the XML content. |
| |
| A global binding customization, |
| *@generateElementClass*, specified in link:jaxb.html#a1580[See |
| <globalBindings> Declaration]“enables this binding over the default |
| binding specified in the previous subsection. |
| |
| ==== Binding of an anonymous complex type definition |
| |
| An anonymous complex type definition is bound |
| to a generated schema-derived Java value class by default. |
| |
| The naming characteristics of the generated |
| Java value class is derived in terms of the properties of the |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| as follows: |
| |
| * The _name_ of the generated Java value class |
| is derived from the element declaration _{name}_ using the XML Name to |
| Java identifier. |
| * The _package_ of the generated Java value |
| class is the same as the package derived from the element declaration’s |
| _{target namespace}_. |
| * The _outer class names_ of the generated |
| Java value class is determined by the element declaration’s _{scope}_. |
| If _{scope}_ is: |
| ** Global + |
| There is no outer class name. |
| ** A Complex Type Definition + |
| By default, the derived Java value class is generated nested within the |
| Java value class represented by the complex type definition value of |
| _{scope}_. The derived Java value is not generated nested when schema |
| customization *[globalBindings]* has attribute _@localScoping_ with a |
| value of _toplevel_. |
| * _base class_: Same as defined in |
| link:jaxb.html#a933[See Java value class]“. |
| * _property set_: As defined in |
| link:jaxb.html#a933[See Java value class]“. |
| * A type factory method is generated in the |
| package’s `ObjectFactory` class introduced in |
| link:jaxb.html#a482[See Java Package].” The factory method |
| returns the type of the Java value class. The name of the factory method |
| is generated by concatenating the following components: |
| ** The string constant `create`. |
| ** If the element declaration containing the |
| anonymous complex type definition is nested within another complex type |
| definition representing a value class and [globalBindings] @localScoping |
| has a value of _nested_ , then the concatenation of all outer Java class |
| names. This step is skipped when @localScoping has a value of _toplevel_. |
| ** The _name_ of the Java value class. |
| |
| The schema-derived value class is annotated |
| with the mapping annotation `@XmlType`, specified in Section |
| link:jaxb.html#a2578[See @XmlType]. The `@XmlType` annotation |
| elements are set as described in link:jaxb.html#a956[See |
| Annotate Java value class with @XmlType element-value pairs] with one |
| exception: `@XmlType.name()` is set to the empty string. |
| |
| As long as the element declaration is not one |
| of the exception cases specified in link:jaxb.html#a1113[See |
| Bind Element Declaration to JAXBElement]", the schema-derived value |
| class is annotated with the mapping annotation `@XmlRootElement` |
| specified in Section 8. The `@XmlRootElement` annotation elements are |
| derived in terms of the abstract model properties for the referenced |
| global element declaration summarized in |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| as follows: |
| |
| .Annotate JAXB Mapped Class with @XmlRootElement element-value pairs |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| | @XmlRootElement element | @XmlRootElement value |
| |namespace a| When element declaration _{target namespace}_ is absent, + |
| (i.e. unqualified local element declaration), @XmlElement.namespace() is |
| not set. + |
| |
| Otherwise, set @XmlElement.namespace() to |
| value of _{target namespace}_. (either a qualified local element |
| declaration or a reference to a global element) |
| |
| Note: same result could be achieved with |
| package level annotation of @XmlSchema and not setting |
| @XmlElement.namespace. |
| | name | element declaration _{name}_ |
| |=== |
| |
| *_Example:_* |
| |
| Given XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:element name="foo"> |
| <xs:complexType> |
| <xs:sequence> |
| <xs:element name="bar" type="xs:int"/> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:element> |
| ---- |
| |
| Derived Java code: |
| [source,java,indent=4] |
| ---- |
| /* Value class representing element |
| declaration with an anonymous complex type definition. */ |
| @XmlType(name="") |
| @XmlRootElement(namespace="", name="foo") |
| public class Foo { |
| int getBar() {...} |
| void setBar(int value) {...} |
| }; |
| class ObjectFactory { |
| // type factory method |
| Foo createFoo() {...} |
| // element factory method |
| JAXBElement<Foo> createFoo(Foo value) {...} |
| } |
| ---- |
| |
| ===== Bind Element Declaration to JAXBElement |
| |
| An element declaration with an anonymous |
| complex type definition is not bound to a `@XmlRootElement`,annotated |
| schema-derived class when the element declaration is: |
| |
| * nillable |
| * the head element or a member of a |
| substitution group |
| * non-global (i.e. declared within a complex |
| type definition) |
| |
| When one or more of the above conditions are |
| met, the schema-derived class representing the anonymous complex type |
| definition must not be annotated with `@XmlRootElement`. Instead, an |
| element factory that returns `JAXBElement<__anonymousTypeValueClass__>` |
| may be generated as specified in link:jaxb.html#a1040[See |
| Bind to JAXBElement<T> Instance]“. |
| |
| *_Example:_* |
| |
| Given XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:element name="foo" nillable="true"> |
| <xs:complexType> |
| <xs:sequence> |
| <xs:element name="bar" type="xs:int"/> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:element> |
| ---- |
| |
| Derived Java code: |
| [source,java,indent=4] |
| ---- |
| /* Value class representing anonymous complex type definition. */ |
| @XmlType(name="") |
| public class Foo { |
| int getBar() {...} |
| void setBar(int value) {...} |
| }; |
| @XmlRegistry |
| class ObjectFactory { |
| // type factory method |
| Foo createFoo() {...} |
| // element factory method |
| @XmlElementDecl(name="foo", namespace="", nillable="true") |
| JAXBElement<Foo> createFoo(Foo value) {...} |
| } |
| ---- |
| |
| ==== Bind to a Property |
| |
| A local element declaration is bound by |
| default to a Java property as described in |
| link:jaxb.html#a541[See Properties]. The characteristics of the |
| Java property are derived in terms of the properties of the |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| and link:jaxb.html#a5022[See Particle Schema Component] as |
| follows: |
| |
| * The _name_ of the Java property is derived |
| from the _{element declaration}_ property’s _{name}_ property using the |
| XML Name to Java Identifier mapping algorithm described in |
| link:jaxb.html#a4656[See The Name to Identifier Mapping |
| Algorithm]. |
| * A _base type_ for the Java property is |
| derived from the `{element declaration}` property’s `{type |
| definition}` property as described in binding of Simple Type Definition |
| in _link:jaxb.html#a702[See Simple Type Definition]_ .” or |
| link:jaxb.html#a917[See Complex Type Definition]". If the base |
| type is initially a primitive type and this JAXB property is _optional_, |
| the *[jaxb:globalBinding]* customization `@optionalProperty` controls |
| the binding of an optional primitive property as described in |
| link:jaxb.html#a1582[See Usage]“. |
| * An optional _predicate_ for the Java |
| property is constructed from the `{element declaration}` property’s |
| `{type definition}` property as described in the binding of simple type |
| definition to a Java representation. |
| * An optional _collection type_ for the Java property is derived from: |
| ** `{element declaration}` property’s |
| `{type definition}` property as described in the binding of simple type |
| definition to a Java representation |
| ** the `{particle}` property’s `{max occurs}` |
| value being greater than one. |
| * Element defaulting + |
| The default value is derived from the element declaration’s \{value |
| constraint} property’s value. Unlike attribute defaulting, an element |
| only defaults when there is an empty element tag in an xml document. The |
| element’s default value is captured by mapping annotation |
| `@XmlElement.defaultValue()`. The unmarshaller sets the property to |
| this default value when it encounters an empty element tag. The |
| marshaller can output an empty element tag whenever the element’s |
| `@XmlValue` property value is the same as its defaulted value.. |
| * A local element declaration that binds to a |
| JAXB property with a primitive base type is bound as an _optional_ JAXB |
| property if the element declaration is a member of a choice model group |
| or the element declaration’s particle has optional occurrence, `{min |
| occurs}` value is `"0"`, or belongs to a model group that has optional |
| occurrence. By default, the optional JAXB property binds the property’s |
| base type to the Java wrapper class for the primitive type. One can test |
| and set the absence of an optional property using null. The |
| *[jaxb:globalBinding]* customization `@optionalProperty` controls |
| alternative bindings of an optional primitive property as described in |
| link:jaxb.html#a1582[See Usage]“. |
| * If the element declaration’s _{nillable}_ |
| property is `"true"` , the base type for the Java property is mapped to |
| the corresponding Java wrapper class for the Java primitive type. |
| Setting the property to the `null` value indicates that the property has |
| been set to the XML Schema concept of `@xs:nil="true"`. |
| |
| This Java property is a member of the Java |
| value class that represents the binding of the complex type definition |
| containing the local element declaration or reference to global element. |
| |
| The schema-derived JAXB property getter |
| method is annotated, either explicitly or by default mapping |
| annotations, with the mapping annotation `@XmlElement`, specified in |
| Section 8, “@XmlElement”. The `@XmlElement` annotation elements are |
| derived in terms of the abstract model properties for the referenced |
| global element declaration summarized in |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| as follows: |
| |
| .Annotate JAXB Property with @XmlElement element-value pairs |
| [width="100%",cols="50%,50%",options="header",] |
| |=== |
| | @XmlElement element | @XmlElement value |
| |namespace a| When element declaration _{target namespace}_ is absent, + |
| (i.e. unqualified local element declaration), @XmlElement.namespace() is |
| not set. + |
| |
| Otherwise, set @XmlElement.namespace() to |
| value of _{target namespace}_. (either a qualified local element |
| declaration or a reference to a global element) |
| |
| Note: same result could be achieved with |
| package level annotation of @XmlSchema and not setting |
| @XmlElement.namespace. |
| | name | element declaration _{name}_ |
| | nillable | element declaration _{nillable}_ |
| | defaultValue |if element declaration _{value constraint}_ is not absent, |
| set defaultValue() to _{value constraint}_ ’s value. |
| |=== |
| |
| link:jaxb.html#a1240[See Xml Schema |
| example containing an element substitution group]illustrates how to |
| define an element substitution group and to reference the head element |
| of the substitution group within an Xml Schema. |
| link:jaxb.html#a1242[See avo binding of Xml Schema from CODE |
| EXAMPLE 6-5] illustrates the Java bindings of the element substation |
| enabled schema. link:jaxb.html#a1244[See Element substitution |
| using Java bindings from CODE EXAMPLE 6-6] demonstrates element |
| substitution using the JAXB API.link:jaxb.html#a1246[See Invalid |
| element substitution using Java bindings from CODE EXAMPLE 6-6] |
| illustrates invalid element substitution handling. |
| |
| ===== Type Substitution of a Complex Type Definition |
| |
| link:jaxb.html#a917[See Complex Type |
| Definition]“describes that when a complex type definition is mapped to |
| Java value class that the type definition derivation hierarchy is |
| preserved in the Java class hierarchy. This preservation makes it quite |
| natural for Java to support the Xml Schema mechanism type substitution |
| across all complex type definitions. |
| |
| Performing an invalid type substitution is |
| not detected as a fail-fast check when setting the JAXB property or |
| checked as part of marshalling the element declaration. Invalid type |
| substitution can be checked by optional validation that can be enabled |
| as part of unmarshalling or marshalling process. |
| |
| The following three code examples illustrate |
| how type substitution is supported in JAXB for a complex type |
| definition hierarchy. |
| |
| .[[a1152]]Xml Schema example containing type derivation hierarchy |
| [source,xml,indent=4,subs=+quotes] |
| ---- |
| <xs:schema targetNamespace="travel:acme" xmlns:a="travel:acme"> |
| |
| <!-- Define type definition derivation hierarchy --> |
| <xs:complexType name="**TransportType**">...</xs:complexType> |
| <xs:complexType name="**PlaneType**"> |
| <xs:extension base="a:TransportType">...</xs:complexType> |
| <xs:complexType name="**AutoType**"> |
| <xs:extension base="a:TransportType">...</xs:complexType> |
| <xs:complexType name="**SUV**"> |
| <xs:extension base="a:AutoType">...</xs:complexType> |
| |
| <xs:complexType name="**itinerary**"> |
| <xs:sequence> |
| <!-- Type substitution possible for "transport". --> |
| <xs:element name="**transport**" type="**TransportType**"/> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:schema> |
| ---- |
| |
| .[[a1154]]Java binding of Xml Schema from link:jaxb.html#a1240[See Xml Schema example containing an element substitution group] |
| [source,java,indent=4,subs=+quotes] |
| ---- |
| package travel.acme; |
| |
| // Type derivation hierarchy from schema is preserved in Java binding. |
| public class *TransportType* {...} |
| public class *PlaneType* extends TransportType {...} |
| public class *AutoType* extends TransportType {...} |
| public class *SUV* extends AutoType {...} |
| |
| public class ObjectFactory { |
| // Type Factories |
| TransportType createTransportType() {...} |
| AutoType createAutoType() {...} |
| PlaneType createPlaneType() {...} |
| TrainType createSUV() {...} |
| } |
| |
| public class Itinerary { |
| // Simple property supports type substitution. |
| *TransportType* getTransport() {...} |
| void setTransport(**TransportType** value) |
| } |
| ---- |
| |
| .Type substitution using Java bindings from link:jaxb.html#a1242[See avo binding of Xml Schema from CODE EXAMPLE 6-5] |
| [source,java,indent=8,subs=+quotes] |
| ---- |
| ObjectFactory of = ...; |
| Itinerary itinerary = of.createItinerary(); |
| itinerary.setTransport(of.createTransportType); // Typical Use |
| |
| *// Type Substitution* |
| // transport marshalled as <e:transport xsi:type="e:AutoType"> |
| itinerary.setTransport(of.createAutoType()); |
| |
| // transport marshalled as <e:transport xsi:type="e:PlaneType"> |
| itinerary.setTransport(of.createPlaneType()); |
| ---- |
| |
| ===== Type Substitution of a Simple Type Definition |
| |
| An XML element declaration having a simple |
| type definition is bound most naturally to a JAXB property with a base |
| type that is a primitive Java datatype. Unfortunately, this strongly |
| typed binding conflicts with fully supporting type substitution of a |
| simple type definition. Unlike the JAXB binding of complex type |
| definitions, the simple type derivation hierarchy is not preserved when |
| binding builtin XML Schema simple type definitions to corresponding Java |
| datatypes as specified in link:jaxb.html#a715[See Atomic |
| Datatype]“. Since there is not a natural Java inheritance hierarchy to |
| support simple type substitution, a JAXB property customization is |
| required to enable optimal support of simple type substitution. |
| |
| For example, the most natural binding of an |
| XML Schema built-in datatype `xs:int` is to the Java primitive datatype, |
| `int`. However, simple type substitution implies that an `xs:short` or |
| a complex type definition that derives by extension from `xs:int` can be |
| type substituted for an `xs:int` within an XML document using the |
| `xsi:type` attribute. The strongly typed JAXB property with Java type |
| `int` would never allow for a Java value class for the complex type to |
| be assigned to a JAXB property of type `int`. |
| |
| By default, unmarshalling handles simple type |
| substitution by assigning the relevant part of the type substituted |
| content to the JAXB property. When the value of the xsi:type attribute |
| resolves to: |
| |
| * a type that derives by restriction from the |
| element’s schema type. |
| The substituted value is always parsable into a legal value of the base |
| type of the JAXB property being type substituted. |
| * a complex type that derives by extension |
| from element’s schema type. The JAXB binding |
| of the substituted complex type definition must have |
| one JAXB property annotated with an `@XmlValue` that is assignable to |
| the type substituted JAXB property’s base type. Attribute(s) associated |
| with the complex type definition can not be preserved by the default |
| binding. |
| |
| The rationale behind the default binding is |
| that substitution of a simple type definition occurs rarely. The default |
| JAXB binding is more convenient and precise for programmer to use. Its |
| one drawback is that it does not faithfully preserve `xsi:type` |
| occurring in an XML document. |
| |
| To enable more comprehensive support of |
| simple type substituting of an XML element with a simple type |
| definition, the JAXB property customization specified in |
| link:jaxb.html#a1809[See Generalize/Specialize baseType with |
| attribute @name] enables setting the property’s base type to the more |
| general type of `java.lang.Object`. This binding allows for retention of |
| the XML document `xsi:type` and attributes associated with complex type |
| definition substituted for an XML element with a simple type definition. |
| When an `xsi:type` value refers to a type definition not registered with |
| `JAXBContext` instance, the content is unmarshalled as the element’s |
| schema type. |
| |
| To preserve an application-defined simple |
| type definition involved in simple type substitution, it must be mapped |
| to a JAXB mapped class as described in link:jaxb.html#a803[See |
| Bind to a JAXB mapped class]“. This can be achieved for all simple type |
| definitions in a schema using the customization `<jaxb:globalBinding |
| mapSimpleTypeDefs="true"/>` or it can be achieved per simple type |
| definition using <jaxb:class> customization. An invalid simple type |
| substitution can be detected by JAXP validation enabled at unmarshal |
| or marshal time |
| |
| Below are examples of the type substitution |
| of an XML element’s simple type definition for the default and |
| customized binding. |
| |
| .[[a1168]]Schema fragment to illustrate simple type substitution |
| [source,xml,indent=4,subs=+quotes] |
| ---- |
| <xsd:element name="Price"> |
| <xsd:complexType> |
| <xsd:sequence> |
| <xsd:element name="name" type="xsd:string"/> |
| _<!-- element price subject to type substitution -->_ |
| <xsd:element name="price" type="xsd:int"/> |
| </xsd:sequence> |
| </xsd:complexType> |
| </xsd:element> |
| <xsd:complexType name="AmountType"> |
| <xsd:simpleContent> _<!-- type substitutable for xs:int -->_ |
| <xsd:extension base="xsd:int"> |
| <xsd:attribute name="currency" type="xsd:string"/> |
| </xsd:extension> |
| </xsd:simpleContent> |
| </xsd:complexType> |
| <xsd:simpleType name="AppInt"> |
| <xsd:restriction base="xsd:int"/> |
| </xsd:simpleType> |
| ---- |
| |
| .[[a1170]]XML documents with simple type substitution |
| [source,xml,indent=4,subs=+quotes] |
| ---- |
| <product> |
| <name>hotdog</name> |
| <price>3</price> |
| </product> |
| |
| <product> |
| <name>peanuts</name> |
| <price **xsi:type="short"**>4</price> |
| </product> |
| |
| <product> |
| <name>popcorn</name> |
| <price **xsi:type="AppInt"**>5</price> |
| </product> |
| |
| <product> |
| <name>sushi</name> |
| <price **xsi:type="AmountType"** currency="yen">500</price> |
| </product> |
| ---- |
| |
| ====== Default Handling of Simple Type Substitution |
| |
| .[[a1176]]Default JAXB binding of link:jaxb.html#a1168[See Schema fragment to illustrate simple type substitution] |
| [source,java,indent=4] |
| ---- |
| public class AmountType { |
| @XmlValue |
| int getValue() {...} void setValue(int value) {...} |
| String getCurrency() {...} void setCurrency(String value) {...} |
| } |
| |
| @XmlRootElement(namespace="", name="product") |
| public class Product { |
| int getPrice() {...} void setPrice(int value) {...} |
| int getName() {...} void setName(String value) {...} |
| } |
| ---- |
| |
| Unmarshalling XML document fragments from |
| link:jaxb.html#a1170[See XML documents with simple type |
| substitution] into link:jaxb.html#a1176[See Default JAXB binding |
| of CODE EXAMPLE 6-1] JAXB binding of element `product` results in the |
| `xsi:type` and attributes associated with JAXB mapped class `Price` |
| being lost as part of the unmarshal process. This loss is illustrated by |
| comparing link:jaxb.html#a1179[See Product instances from |
| unmarshalling XML docs from CODE EXAMPLE 6-2] with |
| link:jaxb.html#a1204[See Product instances from unmarshalling |
| XML docs from CODE EXAMPLE 6-2]. |
| |
| .[[a1179]]Product instances from unmarshalling XML docs from link:jaxb.html#a1170[See XML documents with simple type substitution] |
| [width="100%",cols="20%,20%,20%,20%,20%",options="header",] |
| |=== |
| | document xsi:type | Product.name + |
| value | Product.price + |
| value | Product.price + |
| type | marshal Product.price xsi:type |
| | | hotdog | 3 | int | |
| | xs:short | peanuts | 4 | int | |
| | AppInt | popcorn | 5 | int | |
| | AmountType | sushi | 500 | int | |
| |=== |
| |
| ====== Simple Type Substitution enabled by JAXB customizations. |
| |
| The simple type definition `AppInt` is mapped |
| to a JAXB class either by `<jaxb:class>` customization or by |
| `<jaxb:globalBindings mapSimpleTypeDef="true"/>`. The JAXB property |
| `Product.Price` is mapped to a JAXB property with a general base type of |
| `java.lang.Object` with following external JAXB schema customization: |
| |
| [source,xml,indent=4] |
| ---- |
| <jaxb:bindings schemaLocation="CODE EXAMPLE" |
| node="//xsd:element[@name=’price’]"> |
| <jaxb:property> |
| <jaxb:baseType name="java.lang.Object" /> |
| </jaxb:property> |
| </jaxb:bindings> |
| ---- |
| |
| specified in link:jaxb.html#a1809[See |
| Generalize/Specialize baseType with attribute @name]“. |
| |
| .[[a1201]]Customized JAXB binding of link:jaxb.html#a1168[See Schema fragment to illustrate simple type substitution] |
| [source,java,indent=4] |
| ---- |
| public class AmountType { |
| @XmlValue |
| int getValue() {...} void setValue(int value) {...} |
| String getCurrency() {...} void setCurrency(String value) {...} |
| } |
| |
| public class AppInt { |
| @XmlValue |
| int getValue() {...} void setValue(int value) {...} |
| } |
| |
| public class Product { |
| // enable simple type substitution with base type of Object |
| @XmlElement(type=java.lang.Integer.class) |
| Object getPrice() {...} void setPrice(Object value) {...} |
| int getName() {...} void setName(String value) {...} |
| } |
| ---- |
| |
| Unmarshalling XML document fragments from |
| link:jaxb.html#a1170[See XML documents with simple type |
| substitution] into link:jaxb.html#a1201[See Customized JAXB |
| binding of CODE EXAMPLE 6-1] JAXB binding of element `product` preserves |
| the `xsi:type` and attributes associated with JAXB mapped class |
| `AmountType` is illustrated in link:jaxb.html#a1204[See Product |
| instances from unmarshalling XML docs from CODE EXAMPLE 6-2]. |
| |
| .[[a1204]]Product instances from unmarshalling XML docs from link:jaxb.html#a1170[See XML documents with simple type substitution] |
| [width="100%",cols="20%,20%,20%,20%,20%",options="header",] |
| |=== |
| | document xsi:type | Product.name + |
| value | Product. + |
| price + |
| value | Product. + |
| price + |
| Java type | Marshal + |
| Product. + |
| price + |
| xsi:type |
| | | hotdog | 3 | Integer | |
| | xs:short | peanuts | 4 | Short | xs:short |
| | AppInt | popcorn | 5 | AppInt | AppInt |
| | AmountType | sushi | {value=500, + |
| currency=”yen”} | AmountType | AmountType |
| |=== |
| |
| ==== Bind to a Simple Element property |
| |
| Element substitution group is an Xml Schema |
| mechanism that enables the substitution of one named element for |
| another. This section uses terms and concepts described in Section 4.6 |
| of [XSD Part 0] and normatively defined in Section 2.2.2.2 of [XSD Part |
| 1]. |
| |
| The following constraints assist in defining |
| the Java binding that enables element substitution group: |
| |
| . Element substitution is only possible for a |
| reference to a global element. |
| .. Assuming the absence of the Xml Schema |
| constraints on substitution, any global element can be made the head |
| element of a substitution group. |
| . All elements in a substitution group must |
| derive from or have the same type definition as the head element. |
| |
| To support element substitution, for |
| each global element reference to a head element of a substitution group |
| or to an abstract element, it is necessary to generate the Element |
| property bindings defined in link:jaxb.html#a630[See Element |
| Property].footnote:[Element substitution |
| extensibility does allow element substitution(s) to be defined in a |
| separate schema than a global element reference occurs. When schemas are |
| not compiled at same time, the schema to java binding declaration, |
| <jaxb:property generateElementProperty=”true”/> described in |
| link:jaxb.html#a1786[See Usage] forces the generation of an |
| element property for a global element reference, independent of it not |
| belonging to a element substitution group.] This property enables the overriding |
| of the schema-specified element name bound to a JAXB property by setting |
| and getting the JAXB element representation, |
| `jakarta.xml.bind.JAXBElement<T>`. The name property of the `JAXBElement<T>` |
| instance overrides the schema specified element declaration name. |
| To enable the passing of any element that could be part of the element |
| substitution group, it is necessary to accept any JAXBElement derivation |
| that extends Java binding of the head element’s type definition. Using |
| the upper bounded wildcard notation for a generic JAXBElement container, |
| `JAXBElement<? extends T>`, the element property is able to get and set |
| any element that has an element value that is a subtype of T. Compile |
| time checking will not allow invalid JAXBElement derivations to be |
| passed to the Element property setter. When the element type is correct |
| but the element name is not part of the substitution group, this invalid |
| scenario can only be caught at runtime by validation or optional |
| fail-fast checking by the element property |
| setter.footnote:[The desire to reduce |
| the overall number of schema-derived classes generated by default |
| influenced the decision to default to binding an element declaration to |
| an element instance factory. A customization described in |
| link:jaxb.html#a1580[See <globalBindings> Declaration] exists |
| that binds each element declaration to a Java element class so element |
| substitution checking can be enforced entirely by strongly typed method |
| signatures.] |
| |
| The schema-derived Element property getter |
| method is annotated, either explicitly or by default mapping |
| annotations, with the mapping annotation `@XmlElementRef`, specified in |
| Section 8.10.3, “@XmlElementRef”. The `@XmlElementRef` annotation |
| elements are derived in terms of the abstract model properties for the |
| referenced global element declaration summarized in |
| link:jaxb.html#a4937[See Element Declaration Schema Component] |
| as follows: |
| |
| .Annotate Element Property with @XmlElementRef element-value pairs |
| [cols="1,1",options="header",] |
| |=== |
| | @XmlElementRef element | @XmlElementRef value |
| | value | jakarta.xml.bind.JAXBElement.class |
| | namespace | referenced element declaration _{target namespace}_ |
| | name | referenced element declaration _{name}_ |
| |=== |
| |
| link:jaxb.html#a1240[See Xml Schema |
| example containing an element substitution group]illustrates how to |
| define an element substitution group and to reference the head element |
| of the substitution group within an Xml Schema. |
| link:jaxb.html#a1242[See avo binding of Xml Schema from CODE |
| EXAMPLE 6-5] illustrates the Java bindings of the element substation |
| enabled schema. link:jaxb.html#a1244[See Element substitution |
| using Java bindings from CODE EXAMPLE 6-6] demonstrates element |
| substitution using the JAXB API.link:jaxb.html#a1246[See Invalid |
| element substitution using Java bindings from CODE EXAMPLE 6-6] |
| illustrates invalid element substitution handling. |
| |
| .[[a1240]]Xml Schema example containing an element substitution group |
| [source,xml,indent=4] |
| ---- |
| <xs:schema targetNamespace="travel:acme" xmlns:a="travel:acme"> |
| |
| <!-- See type definition derivation hierarchy defined in CODE EXAMPLE for |
| complexType definitions TransportType, PlaneType, AutoType and SUV.--> |
| <!-- Define element substitution group. a:transport is head element. --> |
| <xs:element name="transport" type="a:TransportType"/> |
| <xs:element name="plane" type="a:PlaneType" substitutionGroup="a:transport" /> |
| <xs:element name="auto" type="a:AutoType" substitutionGroup="a:transport" /> |
| |
| <xs:complexType name="itinerary"> |
| <xs:sequence> |
| <!-- Global element reference. |
| References head element of element substitution group. --> |
| <xs:element ref="a:transport"/> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:schema> |
| ---- |
| |
| .[[a1242]]avoid binding of Xml Schema from link:jaxb.html#a1240[See Xml Schema example containing an element substitution group] |
| [source,java,indent=4] |
| ---- |
| package travel.acme; |
| public class ObjectFactory { |
| // Type Factories |
| TransportType createTransportType(); |
| AutoType createAutoType(); |
| PlaneType createPlaneType(); |
| TrainType createSUVType(); |
| |
| // Element Instance Factories |
| JAXBElement<AutoType> createAuto(AutoType value); |
| JAXBElement<PlaneType> createPlane(PlaneType value); |
| JAXBElement<TransportType> createTrain(TransportType value); |
| } |
| |
| // See Java binding of type derivation hierarchy in CODE EXAMPLE 6-5 |
| |
| public class Itinerary { |
| // Element substitution supported by See [Element Property] |
| JAXBElement<? extends TransportType> getTransport(); |
| void setTransport(JAXBElement<? extends TransportType> value); |
| } |
| ---- |
| |
| .[[a1244]]Element substitution using Java bindings from link:jaxb.html#a1242[See avo binding of Xml Schema from CODE EXAMPLE 6-5] |
| [source,java,indent=8,subs=+quotes] |
| ---- |
| ObjectFactory of = ...; |
| Itinerary itinerary = of.createItinerary(); |
| itinerary.setTransport(of.createTransportType()); // Typical use. |
| |
| **// Element substitution:** |
| __// Substitute <e:auto> for schema specified <e:transport>.__ |
| itinerary.setTransport(of.createAuto(of.createAutoType())); |
| |
| __// Substitute <e:plane> for schema specified <e:transport>__ |
| itinerary.setTransport(of.createPlane(of.createPlaneType())); |
| |
| **// Combination of element and type substitution:** |
| __// Substitutes <e:auto xsi:type="e:SUV"> for <e:transport>__ |
| itinerary.setTransport(of.createAuto(of.createSUV())); |
| ---- |
| |
| .[[a1246]]Invalid element substitution using Java bindings from link:jaxb.html#a1242[See avoid binding of Xml Schema from CODE EXAMPLE 6-5] |
| [source,xml,indent=4] |
| ---- |
| <!-- Add elements not part of element substitution group. --> |
| <xs:element name="apple" type="xsd:string"/> |
| <xs:complexType name="spaceShuttle"> |
| <xs:extension base="a:TransportType">...</xs:complexType> |
| <xs:element name="spaceShuttle" type="a:spaceShuttleType"> |
| ---- |
| |
| [source,java,indent=8,subs=+quotes] |
| ---- |
| ObjectFactory of = ...; |
| Itinerary itinerary = of.createItinerary(); |
| **// Invalid element substitution** |
| **// compile time error: method not found** |
| // Element apple of type JAXBElement<String> does not match |
| // bounded wildcard JAXBElement<? extends TransportType>. |
| itinerary.setTransport(of.createApple("granny smith")); |
| |
| **// Invalid element substitution detected by validation.** |
| // Element spaceShuttle not part of substitution group. |
| // Adding _substitutionGroup="transport"_ to line 4 fixes this. |
| itinerary.setTranport( |
| of.createSpaceShuttle(of.createSpaceShuttleType())); |
| ---- |
| |
| ==== Bind to an Element Collection property |
| |
| A repeating occurrence element declaration |
| that is element substitutable binds solely to a JAXB Collection property |
| of JAXBElement. |
| |
| .Bind repeating occurrence element substitution variant of link:jaxb.html#a1240[See Xml Schema example containing an element substitution group] |
| [source,xml,indent=4,subs=+quotes] |
| ---- |
| <!--deleted schema that remains same --> |
| <xs:complexType name="itinerary"> |
| <xs:sequence> |
| **<!-- Repeating occurance to substitutable global element reference. -->** |
| <xs:element ref="a:transport" **maxOccurs="unbounded"** /> |
| </xs:sequence> |
| </xs:complexType> |
| ---- |
| |
| Java Binding: |
| [source,java,indent=4] |
| ---- |
| public class Itinerary { |
| List<JAXBElement<? extends TransportType>> getTransport(); |
| } |
| ---- |
| |
| === Attribute use |
| |
| A ‘required’ or ‘optional’ attribute use is |
| bound by default to a Java property as described in |
| link:jaxb.html#a541[See Properties]. The characteristics of the |
| Java property are derived in terms of the properties of the |
| link:jaxb.html#a5012[See Attribute Use Schema Component] and |
| link:jaxb.html#a4965[See Attribute Declaration Schema Component] |
| as follows: |
| |
| * The _name_ of the Java property is derived |
| from the _{attribute declaration}_ property’s _{name}_ property using the |
| XML Name to Java Identifier mapping algorithm described in |
| link:jaxb.html#a4656[See The Name to Identifier Mapping |
| Algorithm]. |
| * A _base type_ for the Java property is |
| derived from the `{attribute declaration}` property’s `{type |
| definition}` property as described in binding of Simple Type Definition |
| in _link:jaxb.html#a702[See Simple Type Definition]_ . If the |
| base type is initially a primitive type and this JAXB property is |
| _optional_ , the *[jaxb:globalBinding]* customization |
| `@optionalProperty` controls the binding of an optional primitive |
| property as described in link:jaxb.html#a1582[See Usage]“. |
| * An optional _predicate_ for the Java |
| property is constructed from the `{attribute declaration}` property’s |
| `{type definition}` property as described in the binding of simple type |
| definition to a Java representation. |
| * An optional _collection type_ for the Java |
| property is derived from the `{attribute declaration}` property’s |
| `{type definition}` property as described in the binding of simple type |
| definition to a Java representation. |
| * The _default value_ for the Java property |
| is the _value_ from the attribute use’s _{value constraint}_ property. If |
| the optional _{value constraint}_ is absent, the default value for the |
| Java property is the Java default value for the base type. |
| * The JAXB property is _optional_ when the |
| attribute use’s `{required}` property is `false`. |
| |
| This Java property is a member of the Java |
| value class that represents the binding of the complex type definition |
| containing the attribute use |
| |
| The JAXB property getter for this attribute |
| is annotated, either explicitly or via default mapping, with the mapping |
| annotation @XmlAttribute, specified in Section |
| link:jaxb.html#a3230[See @XmlAttribute]. The @XmlAttribute |
| element values are derived in terms of the properties of the |
| link:jaxb.html#a5012[See Attribute Use Schema Component] and |
| link:jaxb.html#a4965[See Attribute Declaration Schema Component] |
| as follows: |
| |
| .[[a1262]]Annotate Attribute property getter method with @XmlAttribute annotation |
| [cols="1,1",options="header",] |
| |=== |
| | @XmlAttribute element | @XmlAttribute value |
| | name | attribute declaration's _{name}_ |
| | namespace | if attribute declaration’s _{target namespace}_ absent, |
| set to “” + |
| otherwise, set to _{target namespace}_ |
| | required | attribute use's _{required}_ |
| |=== |
| |
| [NOTE] |
| .Design Note |
| ==== |
| Since the target namespace is not being considered when mapping |
| an attribute to a Java property, two distinct attributes |
| that have the same _{name}_ property but not the same _{target namespace}_ |
| will result in a Java property naming collision. |
| As specified generically in Section D.2.1, “Collisions and conflicts”, |
| the binding compiler detect this name collision between |
| the two distinct properties and reports the error. |
| The user can provide a customization that provides an alternative |
| Java property name to resolve this situation. |
| |
| ==== |
| |
| *_Example:_* + |
| |
| Given XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="USAddress"> |
| <xs:attribute name="country" type="xs:string"/> |
| </xs:complexType> |
| ---- |
| |
| Default derived Java code: |
| [source,java,indent=4] |
| ---- |
| public class USAddress { |
| @XmlAttribute(name="country", targetNamespace="", required="false"); |
| public String getCountry() {...} |
| public void setCountry(String value) {...} |
| } |
| ---- |
| |
| ==== Bind to a Java Constant property |
| |
| Rather than binding to a read/write JAXB |
| property, an attribute use with a `fixed` _{value constraint}_ property |
| can be bound to a Java Constant property. This mapping is not performed |
| by default since `fixed` is only a validation constraint. The user must |
| set the binding declaration attribute `fixedAttributeToConstantProperty` |
| on `<jaxb:globalBinding>` element as specified in |
| link:jaxb.html#a1582[See Usage] or on`<jaxb:property>` element |
| as specified in link:jaxb.html#a1786[See Usage] to enable this |
| mapping. |
| |
| *_Example:_* + |
| |
| Given XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:annotation><xs:appinfo> |
| <jaxb:globalBindings fixedAttributeAsConstantProperty="true"/> |
| </xs:appinfo></xs:annotation> |
| <xs:complexType name="USAddress"> |
| <xs:attribute name="country" type="xs:NMTOKEN" fixed="US"/> |
| </xs:complexType> |
| ---- |
| |
| If the appropriate binding schema |
| customization enables mapping a fixed XML value to Java constant |
| property, the following Java code fragment is generated. |
| |
| [source,java,indent=4] |
| ---- |
| public class USAddress { |
| @XmlAttribute |
| public static final String COUNTRY="US"; |
| ... |
| } |
| ---- |
| |
| The schema-derived constant for this fixed |
| attribute is annotated, either explicitly or via default mapping, with |
| the mapping annotation `@XmlAttribute`. The elements of `@XmlAttribute` |
| are set as described in link:jaxb.html#a1262[See Annotate |
| Attribute property getter method with @XmlAttribute annotation] |
| |
| Note that if derivation by restriction |
| constrains an existing attribute declaration to be fixed, this |
| refinement must not be bound to a constant property. The initial binding |
| of the attribute to a JAXB property remains the only binding of the |
| attribute in the Java class hierarchy. |
| |
| ===== Contributions to Local Structural Constraint |
| |
| If the attribute use’s _{required}_ property |
| is true, the local structural constraint for an instance of the Java |
| value class requires that the corresponding Java property to be set when |
| the Java value class instance is validated. |
| |
| ==== Binding an IDREF component to a Java property |
| |
| An element or attribute with a type of |
| `xs:IDREF` refers to the element in the instance document that has an |
| attribute with a type of `xs:ID` or derived from type `xs:ID` with the |
| same value as the `xs:IDREF` value. Rather than expose the Java |
| programmer to this XML Schema concept, the default binding of an |
| `xs:IDREF` component maps it to a Java property with a base type of |
| `java.lang.Object`. The caller of the property setter method must be |
| sure that its parameter is identifiable. An object is considered |
| identifiable if one of its properties is derived from an element or |
| attribute that is or derives from type `xs:ID`. The JAXB mapped class |
| must have one property annotated with an `@XmlID` program annotation as it |
| is specified in Section 8. There is an expectation that all instances |
| provided as values for properties’ representing an `xs:IDREF` should |
| have the Java property representing the `xs:ID` of the instances set |
| before the content tree containing both the `xs:ID` and `xs:IDREF` is |
| marshalled. If a property representing an `xs:IDREF` is set with an |
| object that does not have its `xs:ID` set, the `NotIdentifiableEvent` is |
| reported by marshalling. |
| |
| * The _name_ of the Java property is derived |
| from the _{name}_ property _of the attribute or element_ using the XML Name |
| to Java Identifier mapping algorithm described in |
| link:jaxb.html#a4656[See The Name to Identifier Mapping |
| Algorithm]. |
| * A _base type_ for the Java property is java.lang.Object. |
| * There is no _predicate_ for a property representing an `xs:IDREF`. |
| * An optional _collection type_ |
| * Default and fixed values can not be |
| supported for an attribute with type `xs:IDREF`. |
| |
| The schema-derived JAXB property representing |
| xs:IDREF(s) is annotated, either explicitly or by default mapping |
| annotations, with the mapping annotation @XmlIDREF, specified in Section |
| 8. |
| |
| *_Example:_* + |
| |
| Given XML Schema fragment: |
| [source,xml,indent=4,subs=+quotes] |
| ---- |
| <xs:complexType name="Book"> |
| <xs:sequence> |
| __<xs:element name="author" type="xs:IDREF"/>__ |
| <!-- ... --> |
| </xs:sequence> |
| </xs:complexType> |
| <xs:complexType name="AuthorBio"> |
| <xs:sequence> <!-- ... --> </xs:sequence> |
| __<xs:attribute name="name" type="xs:ID"/>__ |
| </xs:complexType> |
| ---- |
| |
| Schema-derived Java value class: |
| [source,java,indent=4] |
| ---- |
| public class Book { |
| @XmlIDREF |
| java.lang.Object getAuthor() {...} |
| |
| /** Parameter referencedObj should have an attribute or |
| * child element with base type of xs:ID by validation |
| * or marshal time. |
| */ |
| void setAuthor(java.lang.Object referencedObj) {...} |
| } |
| public class AuthorBio { |
| @XmlID |
| String getName() {...} |
| void setName(String value) {...} |
| } |
| ---- |
| |
| Demonstration of a Java content instance |
| referencing another instance: |
| |
| [source,java,indent=8] |
| ---- |
| Book book = ...; |
| AuthorBio authorBio = ...; |
| book.setAuthor(authorBio); |
| authorBio.setName("<some author’s name>"); |
| // The content instance root used to validate or marshal book must |
| // also include "authorBio" as a child element somewhere. |
| // A Java content instance is not included |
| ---- |
| |
| Note that `ID` and `IDREF` mechanisms do not |
| incorporate type definitions that can be referenced. To generate |
| stronger typing for a JAXB property representing an IDREF, the schema |
| customization described in link:jaxb.html#a1809[See |
| Generalize/Specialize baseType with attribute @name]" can be used to |
| specialize the binding.. link:jaxb.html#a1820[See Specialize |
| binding of an IDREF via customization] illustrates the generation of |
| stronger typing for the above example. |
| |
| === Attribute Wildcard |
| |
| Attribute wildcard is an extensibility |
| feature in XML Schema. It enables an XML document author to introduce |
| attribute(s) to an element that were not statically associated with the |
| element’s complex type definition. Obviously, it is not possible to bind |
| such an attribute to a strongly typed JAXB property as the previous |
| section describes for attribute use schema component. The JAXB binding |
| of a complex type definition that contains an attribute wildcard, |
| directly or indirectly, provides dynamic access to the wildcard |
| attributes via the following property: |
| [source,java,indent=8] |
| ---- |
| // Return, by reference, a mapping of |
| attribute QName and String. + |
| Map<QName, String> getOtherAttributes(); |
| ---- |
| The returned attribute map provides dynamic |
| access to wildcard attributes associated with a complex type definition. |
| The key to the map is the attribute’s QName and the key’s value is the |
| String value of the attribute. |
| |
| The schema-derived property getter method is |
| annotated, either explicitly or by default mapping annotations, with the |
| mapping annotation `@XmlAnyAttribute`, specified in Section 8. |
| |
| The following code examples show the JAXB |
| binding for xs:anyAttribute and how to manipulate wildcard attributes |
| using this binding. |
| |
| .Bind anyAttribute to a JAXB property |
| [source,xml,indent=4,subs=+quotes] |
| ---- |
| <xs:schema targetNamespace="http://a.org"> |
| <xs:complexType name="**widget**"> |
| <xs:anyAttribute/> |
| <xs:attribute name="color" type="xs:string"/> |
| </xs:complexType> |
| </xs:schema> |
| ---- |
| [source,java,indent=4,subs=+quotes] |
| ---- |
| package org.a; |
| import javax.xml.namespace.QName; |
| import java.util.Map; |
| public class **Widget** { |
| String getColor() {...} |
| void setColor(String value) {...} |
| @XmlAnyAttribute Map<QName, String> **getOtherAttributes** () {...} |
| } |
| ---- |
| |
| .Dynamic access to wildcard attribute and attribute use |
| [source,java,indent=4] |
| ---- |
| import jakarta.xml.bind.DatatypeConverter; |
| Widget w = ...; |
| Map attrs = w.getOtherAttributes(); |
| |
| // access schema-defined global attribute associated with |
| // complexType defintion widget via attribute wildcard. |
| QName IS_OPEN = new QName("http://example.org", "isOpen"); |
| boolean isOpen = DatatypeConverter.parseBoolean(attrs.get(IS_OPEN)); |
| |
| // set wildcard attribute value |
| attrs.put(IS_OPEN, DatatypeConverter.printBoolean(false)); |
| |
| // semantically the same results setting attribute use via |
| // dynamic or static setter for attribute use. |
| attrs.put(new QName("color"), "red"); |
| |
| // iterate over wildcard attributes |
| for (Map.Entry<QName,String> e: attrs.entrySet()) { |
| System.out.println("Attribute: " + e.getKey() + |
| " Value:" + e.getValue()); |
| } |
| ---- |
| |
| === Redefine |
| |
| Redefinition allows an existing XML Schema |
| component to be “renamed” and its new definition takes the place of the |
| old one. The binding of the redefined schema components, simple and |
| complex type definitions and model and attribute group declarations, are |
| described in the following subsections. |
| |
| ==== Bind Redefined Simple Type Definition |
| |
| As introduced in |
| link:jaxb.html#a702[See Simple Type Definition]“, a schema |
| component using a simple type definition typically binds to a JAXB |
| property. The base type, collection type and predicate of the JAXB |
| property are derived from the simple type definition. Thus, the redefine |
| of a simple type definition results in the redefinition of the simple |
| type definition being used to derive the base type, collection type and |
| predicate of the JAXB property. |
| |
| The one exception to this binding is that a |
| simple type definition with enum facets is sometimes bound to an enum |
| type. A redefined simple type definition that binds to an enum type, as |
| described in link:jaxb.html#a829[See Enum Type]“, is not bound |
| to a Java representation, only the redefinition is bound to an enum |
| type. |
| |
| ==== Bind Redefined Complex Type Definition |
| |
| A redefinition of a type definition must use |
| the original type definition as its base type definition. The redefined |
| complex type definition is bound to a Java value class or interface name |
| that prepends “_” to the class name. The redefinition complex type |
| definition is bound to a class that extends the JAXB class that |
| represents the redefined complex type definition. |
| |
| .Binding of a redefined complex type definition |
| [source,xml,indent=4] |
| ---- |
| File: v1.xsd: |
| <!-- Extracted from Section 4.2.2 of [XSD1] --> |
| <xs:complexType name="personName"> |
| <xs:sequence> |
| <xs:element name="title" type="xs:string" minOccurs="0"/> |
| <xs:element name="forename" type="xs:string" |
| minOccurs="0" maxOccurs="unbounded"/> |
| </xs:sequence> |
| </xs:complexType> |
| |
| File: v2.xsd: |
| <xs:redefine schemaLocation="v1.xsd"> |
| <xs:complexType name="personName"> |
| <xs:complexContent> |
| <xs:extension base="personName"> |
| <xs:sequence> |
| <xs:element name="generation" minOccurs="0"/> |
| </xs:sequence> |
| </xs:extension> |
| </xs:complexContent> |
| </xs:complexType> |
| </xs:redefine> |
| ---- |
| Java binding: |
| [source,java,indent=4] |
| ---- |
| // binding of file v1.xsd complex type definition for personName |
| @XmlType(name="_PersonName") |
| public class _PersonName { |
| void setTitle(String value); String getTitle(); |
| List<String> getForename(); |
| } |
| // binding of v2.xsd redefinition for complex type personName |
| @XmlType(name="PersonName") |
| public class PersonName extends _PersonName { |
| void setGeneration(Object value); Object getGeneration(); |
| } |
| ---- |
| |
| ==== Bind Redefined Group Definition |
| |
| The attribute or model group redefinition is |
| used instead of the initial group definition to construct the property |
| set of the content model(s) that reference the redefined attribute or |
| model group definition. The construction of a property set is described |
| in link:jaxb.html#a933[See Java value class]“. |
| |
| Since there is no binding of an attribute or |
| model group definition to a Java representation, no other special case |
| handling is required for this binding. |
| |
| === Identity Constraint |
| |
| An identity constraint does not represent any |
| data, it represents a constraint that is enforced by validation. These |
| constraints can be checked by optional validation that can be enabled at |
| either unmarshal and/or marshal time. |
| |
| === Content Model - Particle, Model Group, Wildcard |
| |
| This section describes the possible Java |
| bindings for the content model of a complex type definition schema |
| component with a _{content type}_ property of `mixed` or `element-only`. |
| The possible element content(s) and the valid ordering between those |
| contents are constrained by the _{particles}_ describing the complex type |
| definition’s content model. The Java binding of a content model is |
| realized by the derivation of one or more content-properties to |
| represent the element content constrained by the model group. Section |
| 6.12.1 through 6.12.7 describes the _element binding_ of a content |
| model. |
| |
| ==== Element binding style |
| |
| The ideal Java binding would be to map each |
| uniquely named element declaration occurring within a content model to a |
| single JAXB property. The model group schema component constraint, |
| element declarations consistent, specified in [XSD-Part 1] ensures that |
| all element declarations/references having the same {target namespace} |
| and {name} must have the same top-level type definition. This model |
| allows the JAXB technology user to specify only the content and the JAXB |
| implementation infers the valid ordering between the element content |
| based on the _{particles}_ constraints in the source schema. |
| |
| However, there do exist numerous scenarios that this ideal binding is not |
| possible for parts of the content model or potentially the entire |
| content model. For these cases, default binding has a fallback position |
| of representing the element content and the ordering between the content |
| using a _general content model_. The scenarios where one must fallback |
| to the general content model will be identified later in this |
| subsection. |
| |
| ==== Bind each element declaration name to a JAXB property |
| |
| This approach relies on the fact that a model |
| group merely provide constraints on the ordering between children |
| elements and the user merely wishes to provide the content. It is |
| easiest to introduce this concept without allowing for repeating |
| occurrences of model groups within a content model. Conceptually, this |
| approach presents all element declarations within a content model as a |
| set of element declaration __{name}__’s. Each one of the __{name}__’s is |
| mapped to a content-property. Based on the element content that is set |
| by the JAXB application via setting content-properties, the JAXB |
| implementation can compute the order between the element content using |
| the following methods. |
| |
| Computing the ordering between element |
| content within *[children]* of an element information item |
| |
| * Schema constrained fixed ordering or |
| semantically insignificant ordering |
| + |
| The sequence in the schema represents an |
| ordering between children elements that is completely fixed by the |
| schema. Schema-constrained ordering is not exposed to the Java |
| programmer when mapping each element in the sequence to a Java property. |
| However, it is necessary for the marshal/unmarshal process to know the |
| ordering. No new ordering constraints between children elements can be |
| introduced by an XML document or Java application for this case. |
| Additionally, the Java application does not need to know the ordering |
| between children elements. When the compositor is `all`, the ordering |
| between element content is not specified semantically and any ordering |
| is okay. So this additional case can be handled the same way. |
| |
| * Schema only constrains content and does not |
| significantly constrain ordering |
| + |
| If the ordering between the children elements |
| is significant and must be accessible to the Java application, then the |
| ordering is naturally preserved in Java representation via a collection. |
| Below are examples where schema provides very little help in |
| constraining order based on content. |
| + |
| -- |
| [source,xml,indent=4] |
| ---- |
| <xs:choice maxOccurs="unbounded"> ... </xs:choice> |
| <xs:sequence maxOccurs="unbounded"> ... </xs:sequence> |
| ---- |
| -- |
| |
| ==== General content property |
| |
| A general content property is, as its name |
| implies, the most general of all content properties. Such a property can |
| be used with any content specification, no matter how complex. A general |
| content property is represented as a List property as introduced in |
| link:jaxb.html#a595[See List Property]. Unlike the prior |
| approach where the JAXB implementation must infer ordering between the |
| element content, this approach always requires the JAXB technology user |
| to specify a valid ordering of element and text content. This approach |
| has the benefit of providing the application with more control over |
| setting and knowing the order between element content. |
| |
| A general content property is capable of |
| representing both element information items and character data items |
| occurring within *[children]* of an element information item. Character |
| data is inserted into the list as java.lang.String values. Element data |
| is added to the list as instances of JAXB element. To support wildcard |
| content occurring as part of a general content property, xml data |
| content with no static Java binding is added and accessed from the list |
| as instances of `org.w3c.org.dom.Node`. |
| |
| The schema-derived Collection property getter |
| method is annotated, either explicitly or by default mapping |
| annotations, with the mapping annotations reflecting what content is |
| within the Collection. |
| |
| * If the content model is mixed, the property |
| is annotated as `@XmlMixed`. See link:jaxb.html#a1369[See Bind |
| mixed content]“for details. |
| * link:jaxb.html#a1351[See Collection |
| of Element types]“describes an optimized binding of a collection of |
| element values, instead of a collection of JAXB elements annotated with |
| `@XmlElementRefs(@XmlElementRef, ...)`. |
| * If optimized binding can not be used, each |
| element in the content model is represented by an `@XmlElementRef`, |
| described in link:jaxb.html#a1223[See Bind to a Simple Element |
| property]“. If there is more than one element annotations needed, they |
| must occur as elements in the map annotation `@XmlElementRefs` specified |
| in Section 8.10.3, “@XmlElementRef”. |
| |
| ===== Collection of Element types |
| |
| If the content model for a general content |
| property meets all of the following constraints, the collection can be |
| optimized to be a list of value classes instead of a list of JAXB |
| elements. |
| |
| * If the content model is not mixed and does not contain a wildcard. |
| * If none of the element declarations in the |
| content model are abstract or the head of an element substitution group. |
| * If none of the element declarations in the |
| content model have a xml datatype that is or derives from xs:list or |
| xs:IDREF. |
| * For all element declarations in the content |
| model, there does not exist two distinct element declarations whose |
| types bind to the same Java datatype. |
| * If not more than one element declaration in |
| the content model is nillable. |
| |
| Such a collection is annotated with `@XmlElements` annotation, |
| specified in Section 8, that contains a |
| `@XmlElement` annotation for each unique Java datatype within the |
| collection. The `@XmlElement` annotation associates an element name with |
| each unique Java datatype in the collection |
| |
| ===== Examples |
| |
| *_Example 1:_ Complex content model of Elements with primitive types* + |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="Base"> |
| <xs:choice maxOccurs="unbounded"> |
| <xs:element name="A" type="xs:string"/> |
| <xs:element name="B" type="xs:string"/> |
| <xs:element name="C" type="xs:int"/> |
| </xs:choice> |
| </xs:complexType> |
| ---- |
| [source,java,indent=4] |
| ---- |
| public class ObjectFactory \{ |
| // Element instance factories. |
| JAXBElement<String> createBaseA(String value) {...} |
| JAXBElement<String> createBaseB(String value) {...} |
| JAXBElement<Integer> createBaseC(Integer value) {...} |
| // Type factories |
| Base createBase() {...} |
| } |
| |
| public class Base { |
| /** |
| * A general content list that can contain |
| * element instances representing A, B and/or C. |
| */ |
| @XmlElementRefs({ |
| @XmlElementRef(name="A", value=JAXBElement.class), |
| @XmlElementRef(name="B", value=JAXBElement.class), |
| @XmlElementRef(name="C", value=JAXBElement.class)}) |
| List<JAXBElement> getAOrBOrC()\{...} |
| } |
| ---- |
| |
| *_Example 2:_ Optimized Binding to a Collection of Element Types* + |
| XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="AType"/> |
| <xs:complexType name="BType"/> |
| <xs:complexType name="FooBar"> |
| <xs:choice maxOccurs="unbounded"> |
| <xs:element name="foo" type="AType"/> |
| <xs:element name="bar" type="BType"/> |
| </xs:choice> |
| </xs:complexType> |
| ---- |
| |
| Default derived Java code: |
| [source,java,indent=4] |
| ---- |
| public class AType {...} |
| public class BType {...} |
| |
| class ObjectFactory { |
| // element instance factories only |
| JAXBElement<AType> createFooBarFoo(AType value); |
| JAXBElement<BType> createFooBarBar(BType value); |
| } |
| |
| public class FooBar { |
| /** Collection of element types: AType and BType. */ |
| @XmlElements({ |
| @XmlElement(value=AType.class, name="Foo"), |
| @XmlElement(value=BType.class, name="Bar")}) |
| List<Object> getFooOrBar() {...} |
| }; |
| ---- |
| |
| ==== Bind mixed content |
| |
| When a complex type definition’s _{content type}_ |
| is “mixed,” its character and element information content is |
| bound to general content list as described in |
| link:jaxb.html#a1344[See General content property].” Character |
| information data is inserted as instances of `java.lang.String` into a |
| JAXB collection property. |
| |
| The schema-derived Collection property getter |
| method is annotated, either explicitly or by default mapping |
| annotations, with the mapping annotation `@XmlMixed`, specified in |
| Section 8. |
| |
| *_Example:_* + |
| |
| Schema fragment loosely derived from mixed |
| content example from [XSD Part 0]. |
| [source,xml,indent=4] |
| ---- |
| <xs:element name="letterBody"> |
| <xs:complexType mixed="true"> |
| <xs:sequence> |
| <xs:element name="name" type="xs:string"/> |
| <xs:element name="quantity" type="xs:positiveInteger"/> |
| <xs:element name="productName" type="xs:string"/> |
| <!-- etc. --> |
| </xs:sequence> |
| </xs:complexType> |
| </xs:element> |
| ---- |
| |
| Derived Java code: |
| [source,java,indent=4] |
| ---- |
| import java.math.BigInteger; |
| class ObjectFactory { |
| // element instance factories only |
| JAXBElement<LetterBody> createLetterBody(LetterBody value); |
| JAXBElement<String> createLetterBodyName(String value); |
| JAXBElement<BigInteger> createLetterBodyQuantity(BigInteger value); |
| JAXBElement<String> createLetterBodyProductName(String value); |
| } |
| |
| public class LetterBody implements JAXBElement<LetterBody> { |
| /** Mixed content can contain instances of Element classes |
| Name, Quantity and ProductName. Text data is represented as |
| java.util.String for text. */ |
| @XmlMixed |
| @XmlElementRefs( { |
| @XmlElementRef(name="productName", type=JAXBElement.class), |
| @XmlElementRef(name="quantity", type=JAXBElement.class), |
| @XmlElementRef(name="name", type=JAXBElement.class)}) |
| List getContent() {...} |
| } |
| ---- |
| |
| The following instance document |
| [source,xml,indent=4] |
| ---- |
| <letterBody> |
| Dear Mr.<name>Robert Smith</name> |
| Your order of <quantity>1</quantity> <productName>Baby |
| Monitor</productName> shipped from our warehouse. .... |
| </letterBody> |
| ---- |
| |
| could be constructed using JAXB API. |
| [source,java,indent=4] |
| ---- |
| LetterBody lb = ObjectFactory.createLetterBody(null); |
| List gcl = lb.getContent(); |
| gcl.add("Dear Mr."); |
| gcl.add(ObjectFactory.createLetterBodyName("Robert Smith")); |
| gcl.add("Your order of "); |
| gcl.add(ObjectFactory. |
| createLetterBodyQuantity(new BigInteger("1"))); |
| gcl.add(ObjectFactory.createLetterBodyProductName("Baby Monitor")); |
| gcl.add("shipped from our warehouse"); |
| ---- |
| |
| Note that if any element instance is placed |
| into the general content list, _gcl_, that is not an instance of |
| `LetterBody.Name`, `LetterBody.Quantity` or `LetterBody.ProductName`, |
| validation would detect the invalid content model. With the fail fast |
| customization enabled, element instances of the wrong type are detected |
| when being added to the general content list, _gcl_. |
| |
| ==== Bind wildcard schema component |
| |
| A wildcard is mapped to a simple content-property with: |
| |
| * Content-property name set to the constant “`any`”. |
| A binding schema customization could provide a more |
| semantically meaningful content-property name. |
| * Content-property _base type_ set to |
| `java.lang.Object` by default. |
| Wildcard content is represented as one of the |
| following: |
| .. JAXB element + |
| Either an instance of `jakarta.xml.bind.JAXBElement<T>` or a JAXB class |
| annotated with `@XmlRootElement`. + |
| Corresponds to a recognized global element tag name registered with |
| the instance `jakarta.xml.bind.JAXBContext`, meaning the schema(s) |
| describing the element content is registered with the _JAXBContext_ |
| instance, see link:jaxb.html#a298[See JAXBContext] on how |
| bindings are registered with a `JAXBContext` instance., |
| .. instance of `jakarta.xml.bind.JAXBElement`. + |
| Corresponds to an unknown element name but a recognized type |
| definition specified by *_@xsi:type_* on the element. JAXBElement |
| _declaredType_ is set to `java.lang.Object` since the unknown element |
| declaration’s default type is `xs:anyType`. |
| .. element node instance of a supported xml infoset API. + |
| Necessary to represent Xml data content that does not have a schema |
| defined element or type definition. Such content is allowed by element |
| *xs:any* with attribute *@processContents="lax"* or "`*skip*`". |
| * See content-property predicate for a wildcard. |
| * If the `maxOccurs` is greater than one, the |
| content property is mapped to a collection property. The default |
| collection property is a List property of base type java.lang.Object. |
| * There is no _default value_. |
| |
| Since the schema does not contain any |
| information about the element content of a wildcard content, even the |
| content-property, by default, can not infer an XML element tag for |
| wildcard element content. |
| |
| The schema-derived property getter method for |
| representing wildcard content is annotated, either explicitly or by |
| default mapping annotations, with the mapping annotation |
| `@XmlAnyElement`, specified in Section 8. The @XmlAnyElement annotation |
| element values are derived in terms of the abstract model properties for |
| wildcard summarized in link:jaxb.html#a5032[See Wildcard Schema |
| Component] as follows: |
| |
| .Annotate JAXB property with @XmlAnyElement element-value pairs |
| [cols="1,1",options="header"] |
| |=== |
| | @XmlAnyElement element | @XmlAnyElement element value |
| | lax | If wildcard schema component’s _{process contents}_ is `lax` or `strict_`, + |
| set `@XmlAnyElement.lax()` to `true`. + |
| + |
| else if _{process contents}_ is `skip`, set `@XmlAnyElement.lax()` to `false`. |
| | value | `jakarta.xml.bind.annotation.W3CDomHandler.class` |
| |=== |
| |
| ==== Bind a repeating occurrence model group |
| |
| A choice or sequence model group, containing |
| more than one member, with a repeating occurrence, `maxOccurs` attribute |
| greater than one, is bound to a general content property in the |
| following manner: |
| |
| * Content-property _name_ is derived in following ways: |
| ** If a named model group definition is being |
| referenced, the value of its _{name}_ property is mapped to a Java |
| identifier for a method using the algorithm specified in |
| link:jaxb.html#a4656[See The Name to Identifier Mapping |
| Algorithm]. |
| ** To derive a content property _name_ for |
| unnamed model group, see link:jaxb.html#a4780[See Deriving an |
| identifier for a model group]. |
| * Content-property _base type_ set to |
| `java.lang.Object`. A binding schema customization could provide a more |
| specialized java class. |
| * Content-property _predicate_ validates the |
| order between element instances in the list and whether the occurrence |
| constraints for each element instance type is valid according to the |
| schema. |
| * Since the `maxOccurs` is always greater |
| than one, the content property is mapped to a collection property. The |
| default collection property is a List property. |
| * There is no _default value_. |
| |
| The schema-derived collection property is |
| annotated as specified in link:jaxb.html#a1344[See General |
| content property] and link:jaxb.html#a1351[See Collection of |
| Element types]. |
| |
| *_Local structural Constraints_* |
| |
| The list content property’s value must |
| satisfy the content specification of the model group. The ordering and |
| element contents must satisfy the constraints specified by the model |
| group. |
| |
| ==== Content Model Default Binding |
| |
| The following rules define _element_ binding |
| style for a complex type definition’s content model. |
| |
| . If _{content type}_ is mixed, bind the |
| entire content model to a general content property with the |
| content-property name `"content"`. See |
| link:jaxb.html#a1369[See Bind mixed content] for more details. |
| . If (1) a particle has _{max occurs}_ >1 and |
| (2) its _{term}_ is a model group and (3) all the particles in the model |
| group have \{terms} that bind to different Java datatypes, bind to a |
| collection of element types. See complete list of constraints required |
| to perform this optimized binding in link:jaxb.html#a1351[See |
| Collection of Element types]. |
| . If (1) a particle has _{max occurs}_ >1 and |
| (2) its _{term}_ is a model group, then that particle and its descendants |
| are mapped to one general content property that represents them. See |
| link:jaxb.html#a1402[See Bind a repeating occurrence model |
| group] for details. |
| . Process all the remaining particles (1) |
| whose _{term}_ are wildcard particles and (2) that did not belong to a |
| repeating occurrence model group bound in step 2. If there is only one |
| wildcard, bind it as specified in link:jaxb.html#a1384[See Bind |
| wildcard schema component].” If there is more than one, then fallback to |
| representing the entire content model as a single general content |
| property. See link:jaxb.html#a1344[See General content |
| property]). |
| . Process all particles (1) whose _{term}_ are |
| element declarations and (2) that do not belong to a repeating |
| occurrence model group bound in step 2. |
| + |
| First, we say a particle has a label _L_ if it |
| refers to an element declaration whose _{name}_ is _L_. Then, for all the |
| possible pair of particles _P_ and _P’_ in this set, if the following |
| constraints are not met: |
| + |
| -- |
| .. If _P_ and _P’_ have the same label, then they |
| must refer to the same element declaration. |
| .. If _P_ and _P’_ refer to the same element |
| reference, then its closest common ancestor particle may not have |
| sequence as its _{term}_. |
| -- |
| + |
| If either of the above constraints are |
| violated, it is not possible to map each element declaration to a unique |
| content property. Fallback to representing the entire content model as a |
| single general content property. |
| |
| + |
| Otherwise, create a content property for each |
| label _L_ as follows: |
| |
| * The content property _name_ is derived from label name _L_. |
| * The _base type_ will be the Java type to |
| which the referenced element declaration maps. |
| * The content property _predicate_ reflects the |
| occurrence constraint. |
| * The content property _collection type_ |
| defaults to `‘list’` if there exist a particle with label _L_ that has |
| _{maxOccurs}_ > 1. |
| * For the default value, if all particles |
| with label _L_ has a _{term}_ with the same _{value constraint}_ default or |
| fixed value, then this value. Otherwise none. |
| |
| Below is an example demonstrating of not |
| meeting the uniqueness constraints of 5(a) and 5(b) specified above. |
| |
| [source,xml,indent=4] |
| ---- |
| <xs:sequence> |
| <xs:choice> |
| <xs:element ref="ns1:bar"/> (A) |
| <xs:element ref="ns2:bar"/> (B) |
| </xs:choice> |
| <xs:element ref="ns1:bar"/> (C) |
| </xs:sequence> |
| ---- |
| |
| The pair _(A,B)_ violates the first clause |
| because they both have the label “bar” but they refer to different |
| element declarations. The pair _(A,C)_ violates the second clause because |
| their nearest common ancestor particle is the outermost `<sequence>`. |
| This model group fragment is bound to a general content property. |
| |
| ===== Default binding of content model “derived by extension” |
| |
| If a content-property naming collision occurs |
| between a content-property that exists in an base complex type |
| definition and a content-property introduced by a “derive by extension” |
| derived complex type definition, the content-properties from the |
| colliding property on are represented by a general content property with |
| the default property name `rest`. |
| |
| *_Example:_* derivation by extension content model with a content-property collision. |
| |
| Given XML Schema fragment: |
| [source,xml,indent=4] |
| ---- |
| <xs:complexType name="Base"> |
| <xs:sequence> |
| <xs:element name="A" type="xs:int"/> |
| <xs:element name="B" type="xs:int"/> |
| </xs:sequence> |
| </xs:complexType> |
| |
| <xs:complexType name="Derived"> |
| <xs:complexContent> |
| <xs:extension base="Base"> |
| <xs:sequence> |
| <xs:element name="A" type="xs:int"/> |
| </xs:sequence> |
| </xs:extension> |
| </xs:complexContent> |
| </xs:complexType> |
| ---- |
| |
| Default binding derived Java codefootnote:[Specifying a |
| customization of the local element declaration A within Derived complex |
| type to a different property name than A would avoid the fallback |
| position for this case.]: |
| [source,java,indent=4] |
| ---- |
| public class Base { |
| int getA() {...} void setA(int) {...} |
| int getB() {...} void setB(int) {...} |
| } |
| |
| public class Derived extends Base { |
| /** |
| * Instances of Derived.A must be placed in this general |
| * content propert that represents the rest of the content |
| * model. */ |
| List getRest() {...} |
| } |
| |
| class ObjectFactory { |
| // element instance factories only |
| JAXBElement<Integer> createDerivedA(Integer value) {...} |
| } |
| ---- |
| |
| ===== Bind single occurrence choice group to a choice content property |
| |
| Setting the `choiceContentProperty` attribute |
| of `<jaxb:globalBindings>` as specified in |
| link:jaxb.html#a1582[See Usage] enables this customized binding |
| option. |
| |
| A non-repeating choice model group is bound |
| to a simple property. The simple choice content property is derived from |
| a choice model group as follows: |
| |
| * The choice content property name is either |
| the referenced model group definition _{name}_ or obtained using the |
| algorithm specified in link:jaxb.html#a4780[See Deriving an |
| identifier for a model group]. |
| * The choice content property `base type` is |
| the first common supertype of all items within the choice model group, |
| with `java.lang.Object` always being a common root for all Java |
| objects.footnote:[Note that primitive |
| Java types must be represented by their Java wrapper classes when base |
| type is used in the choice content property method signatures. Also, all |
| sequence descendants of the choice are treated as either a general |
| content property or are mapped to their own value class.] |
| * The predicate |
| * The collection type defaults to List if one |
| or more items in the choice model group bind to List. |
| * No default value. |
| |
| A choice property consists of the following |
| methods: |
| |
| * The `getChoiceID` method returns the set |
| value. If the property has no set value then the value `null` is |
| returned. Note that a set value of a primitive Java type is returned as |
| an instance of the corresponding Java wrapper class. |
| * The `setChoiceID` method has a single |
| parameter that is the type of the choice content property `base type`. |
| |
| The `globalBindings` and property |
| customization attribute, `choiceContentProperty`, enables this |
| customized binding. The customization is specified in |
| link:jaxb.html#a1580[See <globalBindings> Declaration]. |
| |
| *_Example:_* + |
| |
| XML Schema representation of a choice model group. |
| [source,xml,indent=4] |
| ---- |
| <xs:choice> |
| <xs:element name="foo" type="xs:int"/> |
| <xs:element name="bar" type="xs:string"/> |
| </xs:choice> |
| ---- |
| |
| Derived choice content property method |
| signatures: |
| [source,java,indent=8] |
| ---- |
| void setFooOrBar(Object) {...} |
| Object getFooOrBar() {...} |
| ---- |
| |
| === Modifying Schema-Derived Code |
| |
| There exist a number of use cases on why a |
| developer would find it beneficial to modify schema-derived classes. |
| Here are some of those use cases. |
| |
| * Add functionality to schema-derived |
| classes. + |
| Since schema-derived classes are derived from a data description |
| language, the derived classes only represent data and have no |
| object-level functionality. |
| * Add polymorphic methods to Java class hierarchy generated |
| from XML Schema type definition derivation hierarchy. |
| * Initialize a JAXB property or field |
| representing an XML element with a default value. Regretfully, XML |
| Schema element defaulting is insufficient to accomplish this. Note that |
| XML Schema attribute defaulting is sufficient and does not require this |
| approach. |
| |
| The JAXB schema-derived class was |
| designed to be easily understandable and modifiable by a developer. For |
| many development environments, it is not sufficient to only run the |
| schema compiler once due to modification of the schema-derived classes. |
| Since schemas evolve over time, it is desirable to have the ability to |
| regenerate schema-derived classes from an updated schema while |
| preserving modification made by a developer. Given the complexities of |
| supporting this capability, a JAXB implementation is not required to |
| support regeneration from a schema into previously modified |
| schema-derived classes. External tools, such as an IDE, could assist in |
| supporting the sophisticated task of regeneration of a modified |
| schema-derived class in the future. To enable tools to support |
| regeneration, a JAXB implementation is required to have an option for |
| generating an annotation that enables a portable means for |
| distinguishing between developer code and generated code in a |
| schema-derived class.The next section describes the portable format for |
| distinguishing between generated and developer added/modified methods |
| and/or fields in a schema-derived class. |
| |
| ==== Distinguish between generated and user added code |
| |
| A schema compiler must have an option to |
| generate the Jakarta Annotation, `@jakarta.annotation.Generated` |
| annotation, specified in [CA], on every generated class, method and |
| field. If a developer does modify an `@Generated` annotated method or |
| field, they must denote this modification by deleting the `@Generated` |
| annotation. If a developer adds a new method or field, it will not have |
| an `@Generated` annotation on it. Based on these conventions, a JAXB |
| implementation in conjunction with an IDE or other external tool, would |
| be able to support regeneration of schema-derived code while preserving |
| developer additions/modifications to methods and fields in a |
| schema-derived class. |
| |
| When schema compiler option to generate |
| `@Generated` annotation is selected, the table describes the annotation |
| to be generated. |
| |
| .Annotate generated class, field and property with @Generated element-value pairs |
| [cols="1,1",options="header"] |
| |=== |
| | @Generated element | @Generated element value |
| | value | fully qualified class name of schema compiler |
| | date | date of generation of schema-derived class. |
| Value must follow the ISO 8601 standard. |
| | comment | optional. Is implementation specific. |
| |=== |
| |
| === Default Binding Rule Summary |
| |
| Note that this summary is non-normative and |
| all default binding rules specified previously in the chapter take |
| precedence over this summary. |
| |
| * Bind the following to Java package: |
| ** XML Namespace URI |
| * Bind the following XML Schema components to Java value class: |
| ** Named complex type |
| * Bind to typesafe enum class: |
| ** A named simple type definition with a |
| basetype that derives from `"xs:NCName"` and has enumeration facets. |
| * Bind the following XML Schema components to |
| an element instance factory that returns `jakarta.xml.bind.JAXBElement<T>` |
| ** A global element declaration with a named type definition. |
| ** Local element declaration with a named type |
| definition that can be inserted into a general content list. |
| * Bind the following XML Schema components to a Java Element class |
| ** A global element declaration with anonymous |
| type definition to a Java value class. |
| ** Local element declaration with anonymous |
| type definition that can be inserted into a general content list. |
| * Bind to Java property |
| ** Attribute use |
| ** Particle with a term that is an element reference or local element declaration. |
| + |
| Additionally, generate an element property |
| for an element reference to the head element of a substitution group. |
| * Bind to JAXB property: + |
| `getOtherAttributes(): java.util.Map<QName, String>` |
| ** Attribute Wildcard occurring directly or |
| indirectly via an attribute group reference in a complex type |
| definition. |
| * Bind model group and wildcard content with |
| a repeating occurrence and complex type definitions with `mixed` |
| _{content type}_ to: |
| ** A general content property - a List |
| content-property that holds Java instances representing element |
| information items and character data items. To support dynamic Xml |
| content that validates against xs:any processContents=”lax” or “skip”, |
| allow instances of org.w3c.dom.Node into the list. |
| |
| .Summarize default XSD to Java binding for Figure 5.1 and Figure 5.2 |
| [cols="1,1",options="header"] |
| |=== |
| | XML Schema | Java Representation |
| | Schema targetNamespace | Package |
| | Global Element Declaration with named type definition | ObjectFactory.elementInstanceFactory method returning JAXBElement<T> |
| Value must follow the ISO 8601 standard. |
| | Global Complex Type Definition (Named) | value class/class + ObjectFactory.typeInstanceFactory method |
| a| Global Simple Type Definition |
| |
| * derive base of string |
| * has @enum facet(s) | enum type |
| | SimpleType facets | ConstraintPredicate |
| a| Attribute Uses |
| |
| Local Element Declaration | Property |
| a| facet *@maxOccurs > 1* xsd:list | PropertyStyle List |
| a| **@fixed**PropertyStyle | Constant |
| | Global Element Declaration with anonymous type definition | value class for anonymous type + ObjectFactory.typeInstanceFactory + ObjectFactory.elementInstanceFactory method |
| | Element reference to SubstitutionGroup Head maxOccurs = “1” | Simple + Element property |
| | Element reference to SubstitutionGroup Head maxOccurs > “1” | List<JAXBElement<T>> |
| |=== |
| |