Using XML Schema, you can derive new complex types by either extending or restricting other complex types using the
complexContent
element. When generating the Java class to represent the derived complex type,
FUSE Services Framework extends the base type’s class. In this way, the generated Java code preserves the inheritance hierarchy intended in
the XML Schema.
You derive complex types from other complex types by using the complexContent
element,
and either the extension
element or the restriction
element. The
complexContent
element specifies that the included data description includes more than one field.
The extension
element and the restriction
element, which are children
of the complexContent
element, specify the base type being modified to create the new type. The
base type is specified by the base
attribute.
To extend a complex type use the extension
element to define the additional elements and
attributes that make up the new type. All elements that are allowed in a complex type description are allowable as part of the new
type’s definition. For example, you can add an anonymous enumeration to the new type, or you can use the
choice
element to specify that only one of the new fields can be valid at a time.
Example 13.15 shows an XML Schema fragment that defines two complex
types, widgetOrderInfo and widgetOrderBillInfo. widgetOrderBillInfo is derived by
extending widgetOrderInfo to include two new elements: orderNumber
and
amtDue
.
Example 13.15. Deriving a Complex Type by Extension
<complexType name="widgetOrderInfo"> <sequence> <element name="amount" type="xsd:int"/> <element name="order_date" type="xsd:dateTime"/> <element name="type" type="xsd1:widgetSize"/> <element name="shippingAddress" type="xsd1:Address"/> </sequence> <attribute name="rush" type="xsd:boolean" use="optional" /> </complexType> <complexType name="widgetOrderBillInfo"> <complexContent> <extension base="xsd1:widgetOrderInfo"> <sequence> <element name="amtDue" type="xsd:decimal"/> <element name="orderNumber" type="xsd:string"/> </sequence> <attribute name="paid" type="xsd:boolean" default="false" /> </extension> </complexContent> </complexType>
To restrict a complex type use the restriction
element to limit the possible values of the base
type's elements or attributes. When restricting a complex type you must list all of the elements and attributes of the base type. For
each element you can add restrictive attributes to the definition. For example, you can add a
maxOccurs
attribute to an element to limit the number of times it can occur. You can also use the
fixed
attribute to force one or more of the elements to have predetermined values.
Example 13.16 shows an example of defining a complex type by restricting
another complex type. The restricted type, wallawallaAddress, can only be used for addresses in Walla Walla,
Washington because the values for the city
element, the state
element, and the zipCode
element are fixed.
Example 13.16. Defining a Complex Type by Restriction
<complexType name="Address"> <sequence> <element name="name" type="xsd:string"/> <element name="street" type="xsd:short" maxOccurs="3"/> <element name="city" type="xsd:string"/> <element name="state" type="xsd:string"/> <element name="zipCode" type="xsd:string"/> </sequence> </complexType> <complexType name="wallawallaAddress"> <complexContent> <restriction base="xsd1:Address"> <sequence> <element name="name" type="xsd:string"/> <element name="street" type="xsd:short" maxOccurs="3"/> <element name="city" type="xsd:string" fixed="WallaWalla"/> <element name="state" type="xsd:string" fixed="WA" /> <element name="zipCode" type="xsd:string" fixed="99362" /> </sequence> </restriction> </complexContent> </complexType>
As it does with all complex types, FUSE Services Framework generates a class to represent complex types derived from another complex type. The Java class generated for the derived complex type extends the Java class generated to support the base complex type. The base Java class is also modified to include the @XmlSeeAlso
annotation. The base class' @XmlSeeAlso
annotation lists all of the classes that extend the base class.
When the new complex type is derived by extension, the generated class will include member variables for all of the added elements and attributes. The new member variables will be generated according to the same mappings as all other elements.
When the new complex type is derived by restriction, the generated class will have no new member variables. The generated class will simply be a shell that does not provide any additional functionality. It is entirely up to you to ensure that the restrictions defined in the XML Schema are enforced.
For example, the schema in Example 13.15 results in the generation of two
Java classes: WidgetOrderInfo
and WidgetBillOrderInfo
.
WidgetOrderBillInfo
extends WidgetOrderInfo
because
widgetOrderBillInfo is derived by extension from widgetOrderInfo.
Example 13.17 shows the generated class for widgetOrderBillInfo.
Example 13.17. WidgetOrderBillInfo
@XmlType(name = "widgetOrderBillInfo", propOrder = { "amtDue", "orderNumber" }) public class WidgetOrderBillInfo extends WidgetOrderInfo { @XmlElement(required = true) protected BigDecimal amtDue; @XmlElement(required = true) protected String orderNumber; @XmlAttribute protected Boolean paid; public BigDecimal getAmtDue() { return amtDue; } public void setAmtDue(BigDecimal value) { this.amtDue = value; } public String getOrderNumber() { return orderNumber; } public void setOrderNumber(String value) { this.orderNumber = value; } public boolean isPaid() { if (paid == null) { return false; } else { return paid; } } public void setPaid(Boolean value) { this.paid = value; } }