prev | table of contents | next |
The schema language features a multi-tiered type hierarchy of built-in numeric datatypes. We'll discuss them briefly in this subsection.
Leaving double and float aside, the root of the tree is given by
xsd:decimal
. According to the XML Schema definition,
this data type represents decimal numbers with an
unspecified range of fractional and total digits. There is one Java type
providing just that: java.math.BigDecimal
. Doing away
with fractional digits, we arrive at xsd:integer
, which
still has an unspecified number of digits; hence
java.math.BigInteger
must be used. Although both types
can be constrained using facets to delimit the number of digits or
the value range, the Java code generated by JAXB does not reflect
any of this.
Below the integer type, the tree branches off into a hierarchy of non-negative integers, another one for their obscure cousins, the non-positive integers and the traditional line of integer types representing the typical two's complement ranges.
The types long
down to byte
are normally
mapped to Java's eponymous simple types. Exceptions result from
the property nillable
being set to true for an element
or attribute. This adds another value to the set of possible values,
i.e., nil, indicating that the element or attribute is
simply absent. Java provides null
as a convenient
value for this abstract nil value - but only for
descendants of Object
.
The non-negative types comprise xsd:nonNegativeInteger
and the unsigned variations of the binary integer types, from
xsd:unsignedLong
down to xsd:unsignedByte
.
Since xsd:nonNegativeInteger
is defined as a restriction
of xsd:integer
, it has to be represented by
java.math.BigInteger
. For xsd:unsignedLong
,
there is no fitting simple type, and therefore this type maps to
java.math.BigInteger
, too. With xsd:unsignedInt
,
xsd:unsignedShort
and xsd:unsignedByte
,
JAXB reverts to simple types, using the smallest type capable of
holding all values, e.g., short
for xsd:unsignedByte
.
The following schema snippet contains a selection of the types discussed so far.
<xsd:complexType name="NumericZooType"> <xsd:sequence> <xsd:element name="decimal" type="xsd:decimal"/> <xsd:element name="integer" type="xsd:integer"/> <xsd:element name="long" type="xsd:long"/> <xsd:element name="int" type="xsd:int" default="42"/> <xsd:element name="short_nil" type="xsd:short" nillable="true"/> <xsd:element name="byte" type="xsd:byte" default="13" nillable="true"/> <xsd:element name="nonNegative" type="xsd:nonNegativeInteger"/> <xsd:element name="unsignedLong" type="xsd:unsignedLong"/> <xsd:element name="unsignedInt" type="xsd:unsignedInt"/> </xsd:sequence> </xsd:complexType>And here is the resulting Java code, simplified for better readability.
public class NumericZooType { protected BigDecimal decimal; protected BigInteger integer; protected long _long; protected int _int; protected Short shortNil; protected Byte _byte; protected BigInteger nonNegative; protected BigInteger unsignedLong; protected long unsignedInt; public BigDecimal getDecimal() { return decimal; } public void setDecimal(BigDecimal value) { this.decimal = value; } // All other getters and setters follow the same pattern. // ... }
Well, it's quite a zoo indeed. Although applications dealing with
monetary quantities prosper on BigDecimal
, schema
designers who just want to express a simple integer counter (with
a moderate upper limit) are not at all pleased when one of the "Big"
types crops up in the generated Java code. So, the question is: can
you retain the more convenient simple types while defining suitable value
range limits?
The answer is yes, of course, and it's demonstrated in the schema snippet
shown below, where a simple type is defined as a restriction of the
built-in type xsd:int
.
<xsd:simpleType name="CounterType"> <xsd:restriction base="xsd:int"> <xsd:minInclusive value="0"/> </xsd:restriction> </xsd:simpleType> ... <xsd:element name="counter" type="CounterType"/>No separate Java class is generated for
CounterType
.
For some element such as counter
, JAXB simply
generates the type suitable for the base type of the restriction.
protected int counter; public int getCounter() { return counter; } public void setCounter(int value) { this.counter = value; }
prev | table of contents | next |