Chapter 34. Using Simple Types

Abstract

XML Schema simple types are either XML Schema primitive types like xsd:int, or are defined using the simpleType element. They are used to specify elements that do not contain any children or attributes. They are generally mapped to native Java constructs and do not require the generation of special classes to implement them. Enumerated simple types do not result in generated code because they are mapped to Java enum types.

34.1. Primitive Types

Overview

When a message part is defined using one of the XML Schema primitive types, the generated parameter’s type is mapped to a corresponding Java native type. The same pattern is used when mapping elements that are defined within the scope of a complex type. The resulting field is of the corresponding Java native type.

Mappings

Table 34.1, “XML Schema Primitive Type to Java Native Type Mapping” lists the mapping between XML Schema primitive types and Java native types.

Table 34.1. XML Schema Primitive Type to Java Native Type Mapping

XML Schema TypeJava Type

xsd:string

String

xsd:integer

BigInteger

xsd:int

int

xsd:long

long

xsd:short

short

xsd:decimal

BigDecimal

xsd:float

float

xsd:double

double

xsd:boolean

boolean

xsd:byte

byte

xsd:QName

QName

xsd:dateTime

XMLGregorianCalendar

xsd:base64Binary

byte[]

xsd:hexBinary

byte[]

xsd:unsignedInt

long

xsd:unsignedShort

int

xsd:unsignedByte

short

xsd:time

XMLGregorianCalendar

xsd:date

XMLGregorianCalendar

xsd:g

XMLGregorianCalendar

xsd:anySimpleType [a]

Object

xsd:anySimpleType [b]

String

xsd:duration

Duration

xsd:NOTATION

QName

[a] For elements of this type.
[b] For attributes of this type.

Wrapper classes

Mapping XML Schema primitive types to Java primitive types does not work for all possible XML Schema constructs. Several cases require that an XML Schema primitive type is mapped to the Java primitive type’s corresponding wrapper type. These cases include:

  • An element element with its nillable attribute set to true as shown:

    <element name="finned" type="xsd:boolean"
             nillable="true" />
  • An element element with its minOccurs attribute set to 0 and its maxOccurs attribute set to 1, or its maxOccurs attribute not specified, as shown :

    <element name="plane" type="xsd:string" minOccurs="0" />
  • An attribute element with its use attribute set to optional, or not specified, and having neither its default attribute nor its fixed attribute specified, as shown:

    <element name="date">
      <complexType>
        <sequence/>
        <attribute name="calType" type="xsd:string"
                   use="optional" />
      </complexType>
    </element>

Table 34.2, “Primitive Schema Type to Java Wrapper Class Mapping” shows how XML Schema primitive types are mapped into Java wrapper classes in these cases.

Table 34.2. Primitive Schema Type to Java Wrapper Class Mapping

Schema TypeJava Type

xsd:int

java.lang.Integer

xsd:long

java.lang.Long

xsd:short

java.lang.Short

xsd:float

java.lang.Float

xsd:double

java.lang.Double

xsd:boolean

java.lang.Boolean

xsd:byte

java.lang.Byte

xsd:unsignedByte

java.lang.Short

xsd:unsignedShort

java.lang.Integer

xsd:unsignedInt

java.lang.Long

xsd:unsignedLong

java.math.BigInteger

xsd:duration

java.lang.String

34.2. Simple Types Defined by Restriction

Overview

XML Schema allows you to create simple types by deriving a new type from another primitive type or simple type. Simple types are described using a simpleType element.

The new types are described by restricting the base type with one or more facets. These facets limit the possible valid values that can be stored in the new type. For example, you could define a simple type, SSN, which is a string of exactly 9 characters.

Each of the primitive XML Schema types has their own set of optional facets.

Procedure

To define your own simple type do the following:

  1. Determine the base type for your new simple type.
  2. Determine what restrictions define the new type based on the available facets for the chosen base type.
  3. Using the syntax shown in this section, enter the appropriate simpleType element into the types section of your contract.

Defining a simple type in XML Schema

Example 34.1, “Simple type syntax” shows the syntax for describing a simple type.

Example 34.1. Simple type syntax

<simpleType name="typeName">
  <restriction base="baseType">
    <facet value="value" />
    <facet value="value" />
    ...
  </restriction>
</simpleType>

The type description is enclosed in a simpleType element and identified by the value of the name attribute. The base type from which the new simple type is being defined is specified by the base attribute of the xsd:restriction element. Each facet element is specified within the restriction element. The available facets and their valid settings depend on the base type. For example, xsd:string has a number of facets including:

  • length
  • minLength
  • maxLength
  • pattern
  • whitespace

Example 34.2, “Postal Code Simple Type” shows the definition for a simple type that represents the two-letter postal code used for US states. It can only contain two, uppercase letters. TX is a valid value, but tx or tX are not valid values.

Example 34.2. Postal Code Simple Type

<xsd:simpleType name="postalCode">
  <xsd:restriction base="xsd:string">
    <xsd:pattern value="[A-Z]{2}" />
  </xsd:restriction>
</xsd:simpleType>

Mapping to Java

Apache CXF maps user-defined simple types to the Java type of the simple type’s base type. So, any message using the simple type postalCode, shown in Example 34.2, “Postal Code Simple Type”, is mapped to a String because the base type of postalCode is xsd:string. For example, the WSDL fragment shown in Example 34.3, “Credit Request with Simple Types” results in a Java method, state(), that takes a parameter, postalCode, of String.

Example 34.3. Credit Request with Simple Types

<message name="stateRequest">
  <part name="postalCode" type="postalCode" />
</message>
...
<portType name="postalSupport">
  <operation name="state">
    <input message="tns:stateRequest" name="stateRec" />
    <output message="tns:stateResponse" name="credResp" />
  </operation>
</portType>

Enforcing facets

By default, Apache CXF does not enforce any of the facets that are used to restrict a simple type. However, you can configure Apache CXF endpoints to enforce the facets by enabling schema validation.

To configure Apache CXF endpoints to use schema validation set the schema-validation-enabled property to true. Example 34.4, “Service Provider Configured to Use Schema Validation” shows the configuration for a service provider that uses schema validation

Example 34.4. Service Provider Configured to Use Schema Validation

<jaxws:endpoint name="{http://apache.org/hello_world_soap_http}SoapPort"
                wsdlLocation="wsdl/hello_world.wsdl"
                createdFromAPI="true">
  <jaxws:properties>
    <entry key="schema-validation-enabled" value="BOTH" />
  </jaxws:properties>
</jaxws:endpoint>

For more information on configuring schema validation, see Section 24.3.4.7, “Schema Validation Type Values”.

34.3. Enumerations

Overview

In XML Schema, enumerated types are simple types that are defined using the xsd:enumeration facet. Unlike atomic simple types, they are mapped to Java enums.

Defining an enumerated type in XML Schema

Enumerations are a simple type using the xsd:enumeration facet. Each xsd:enumeration facet defines one possible value for the enumerated type.

Example 34.5, “XML Schema Defined Enumeration” shows the definition for an enumerated type. It has the following possible values:

  • big
  • large
  • mungo
  • gargantuan

Example 34.5. XML Schema Defined Enumeration

<simpleType name="widgetSize">
  <restriction base="xsd:string">
    <enumeration value="big"/>
    <enumeration value="large"/>
    <enumeration value="mungo"/>
    <enumeration value="gargantuan"/>
  </restriction>

Mapping to Java

XML Schema enumerations where the base type is xsd:string are automatically mapped to Java enum type. You can instruct the code generator to map enumerations with other base types to Java enum types by using the customizations described in Section 38.4, “Customizing Enumeration Mapping”.

The enum type is created as follows:

  1. The name of the type is taken from the name attribute of the simple type definition and converted to a Java identifier.

    In general, this means converting the first character of the XML Schema’s name to an uppercase letter. If the first character of the XML Schema’s name is an invalid character, an underscrore (_) is prepended to the name.

  2. For each enumeration facet, an enum constant is generated based on the value of the value attribute.

    The constant’s name is derived by converting all of the lowercase letters in the value to their uppercase equivalent.

  3. A constructor is generated that takes the Java type mapped from the enumeration’s base type.
  4. A public method called value() is generated to access the facet value that is represented by an instance of the type.

    The return type of the value() method is the base type of the XML Schema type.

  5. A public method called fromValue() is generated to create an instance of the enum type based on a facet value.

    The parameter type of the value() method is the base type of the XML Schema type.

  6. The class is decorated with the @XmlEnum annotation.

The enumerated type defined in Example 34.5, “XML Schema Defined Enumeration” is mapped to the enum type shown in Example 34.6, “Generated Enumerated Type for a String Bases XML Schema Enumeration”.

Example 34.6. Generated Enumerated Type for a String Bases XML Schema Enumeration

@XmlType(name = "widgetSize")
@XmlEnum
public enum WidgetSize {

    @XmlEnumValue("big")
    BIG("big"),
    @XmlEnumValue("large")
    LARGE("large"),
    @XmlEnumValue("mungo")
    MUNGO("mungo"),
    @XmlEnumValue("gargantuan")
    GARGANTUAN("gargantuan");
    private final String value;

    WidgetSize(String v) {
        value = v;
    }

    public String value() {
        return value;
    }

    public static WidgetSize fromValue(String v) {
        for (WidgetSize c: WidgetSize.values()) {
            if (c.value.equals(v)) {
                return c;
            }
        }
        throw new IllegalArgumentException(v);
    }

}

34.4. Lists

Overview

XML Schema supports a mechanism for defining data types that are a list of space separated simple types. An example of an element, primeList, using a list type is shown in Example 34.7, “List Type Example”.

Example 34.7. List Type Example

<primeList>1 3 5 7 9 11 13<\primeList>

XML Schema list types are generally mapped to Java List<T> objects. The only variation to this pattern is when a message part is mapped directly to an instance of an XML Schema list type.

Defining list types in XML Schema

XML Schema list types are simple types and as such are defined using a simpleType element. The most common syntax used to define a list type is shown in Example 34.8, “Syntax for XML Schema List Types”.

Example 34.8. Syntax for XML Schema List Types

<simpleType name="listType">
  <list itemType="atomicType">
    <facet value="value" />
    <facet value="value" />
    ...
  </list>
</simpleType>

The value given for atomicType defines the type of the elements in the list. It can only be one of the built in XML Schema atomic types, like xsd:int or xsd:string, or a user-defined simple type that is not a list.

In addition to defining the type of elements listed in the list type, you can also use facets to further constrain the properties of the list type. Table 34.3, “List Type Facets” shows the facets used by list types.

Table 34.3. List Type Facets

FacetEffect

length

Defines the number of elements in an instance of the list type.

minLength

Defines the minimum number of elements allowed in an instance of the list type.

maxLength

Defines the maximum number of elements allowed in an instance of the list type.

enumeration

Defines the allowable values for elements in an instance of the list type.

pattern

Defines the lexical form of the elements in an instance of the list type. Patterns are defined using regular expressions.

For example, the definition for the simpleList element shown in Example 34.7, “List Type Example”, is shown in Example 34.9, “Definition of a List Type”.

Example 34.9. Definition of a List Type

<simpleType name="primeListType">
  <list itemType="int"/>
</simpleType>
<element name="primeList" type="primeListType"/>

In addition to the syntax shown in Example 34.8, “Syntax for XML Schema List Types” you can also define a list type using the less common syntax shown in Example 34.10, “Alternate Syntax for List Types”.

Example 34.10. Alternate Syntax for List Types

<simpleType name="listType">
  <list>
    <simpleType>
      <restriction base="atomicType">
        <facet value="value"/>
        <facet value="value"/>
        ...
      </restriction>
    </simpleType>
  </list>
  </simpleType>

Mapping list type elements to Java

When an element is defined a list type, the list type is mapped to a collection property. A collection property is a Java List<T> object. The template class used by the List<T> is the wrapper class mapped from the list’s base type. For example, the list type defined in Example 34.9, “Definition of a List Type” is mapped to a List<Integer>.

For more information on wrapper type mapping see the section called “Wrapper classes”.

Mapping list type parameters to Java

When a message part is defined as a list type, or is mapped to an element of a list type, the resulting method parameter is mapped to an array instead of a List<T> object. The base type of the array is the wrapper class of the list type’s base class.

For example, the WSDL fragment in Example 34.11, “WSDL with a List Type Message Part” results in the method signature shown in Example 34.12, “Java Method with a List Type Parameter”.

Example 34.11. WSDL with a List Type Message Part

<definitions ...>
  ...
  <types ...>
    <schema ... >
      <simpleType name="primeListType">
        <list itemType="int"/>
      </simpleType>
      <element name="primeList" type="primeListType"/>
    </schemas>
  </types>
  <message name="numRequest"> <part name="inputData" element="xsd1:primeList" /> </message>
  <message name="numResponse">;
    <part name="outputData" type="xsd:int">
  ...
  <portType name="numberService">
    <operation name="primeProcessor">
      <input name="numRequest" message="tns:numRequest" />
      <output name="numResponse" message="tns:numResponse" />
    </operation>
    ...
  </portType>
  ...
</definitions>

Example 34.12. Java Method with a List Type Parameter

public interface NumberService {

    @XmlList
    @WebResult(name = "outputData", targetNamespace = "", partName = "outputData")
    @WebMethod
    public int primeProcessor(
        @WebParam(partName = "inputData", name = "primeList", targetNamespace = "...") java.lang.Integer[] inputData
    );
}

34.5. Unions

Overview

In XML Schema, a union is a construct that allows you to describe a type whose data can be one of a number of simple types. For example, you can define a type whose value is either the integer 1 or the string first. Unions are mapped to Java Strings.

Defining in XML Schema

XML Schema unions are defined using a simpleType element. They contain at least one union element that defines the member types of the union. The member types of the union are the valid types of data that can be stored in an instance of the union. They are defined using the union element’s memberTypes attribute. The value of the memberTypes attribute contains a list of one or more defined simple type names. Example 34.13, “Simple Union Type” shows the definition of a union that can store either an integer or a string.

Example 34.13. Simple Union Type

<simpleType name="orderNumUnion">
  <union memberTypes="xsd:string xsd:int" />
</simpleType>

In addition to specifying named types as a member type of a union, you can also define an anonymous simple type as a member type of a union. This is done by adding the anonymous type definition inside of the union element. Example 34.14, “Union with an Anonymous Member Type” shows an example of a union containing an anonymous member type that restricts the possible values of a valid integer to the range 1 through 10.

Example 34.14. Union with an Anonymous Member Type

<simpleType name="restrictedOrderNumUnion">
  <union memberTypes="xsd:string">
    <simpleType>
      <restriction base="xsd:int">
        <minInclusive value="1" />
        <maxInclusive value="10" />
      </restriction>
    </simpleType>
  </union>
</simpleType>

Mapping to Java

XML Schema union types are mapped to Java String objects. By default, Apache CXF does not validate the contents of the generated object. To have Apache CXF validate the contents you will must configure the runtime to use schema validation as described in the section called “Enforcing facets”.

34.6. Simple Type Substitution

Overview

XML allows for simple type substitution between compatible types using the xsi:type attribute. The default mapping of simple types to Java primitive types, however, does not fully support simple type substitution. The runtime can handle basic simple type substitution, but information is lost. The code generators can be customized to generate Java classes that facilitate lossless simple type substitution.

Default mapping and marshaling

Because Java primitive types do not support type substitution, the default mapping of simple types to Java primitive types presents problems for supporting simple type substitution. The Java virtual machine will balk if an attempt is made to pass a short into a variable that expects an int even though the schema defining the types allows it.

To get around the limitations imposed by the Java type system, Apache CXF allows for simple type substitution when the value of the element’s xsi:type attribute meets one of the following conditions:

  • It specifies a primitive type that is compatible with the element’s schema type.
  • It specifies a type that derives by restriction from the element’s schema type.
  • It specifies a complex type that derives by extension from the element’s schema type.

When the runtime does the type substitution it does not retain any knowledge of the type specified in the element’s xsi:type attribute. If the type substitution is from a complex type to a simple type, only the value directly related to the simple type is preserved. Any other elements and attributes added by extension are lost.

Supporting lossless type substitution

You can customize the generation of simple types to facilitate lossless support of simple type substitution in the following ways: