apache > cocoon
 

Cocoon Forms: Datatypes

Context

Datatypes are used by certain widgets, more specifically the field and multivaluefield widgets, to allow them to edit different types of data (e.g. strings, numbers, dates). For a general introduction of the relationship between the widget and the datatype, see the documentation of the field widget.

General information

In its most basic form a datatype is declared as follows:

<fd:datatype base="...">

The base attribute refers to one of the built-in datatypes such as string or long.

Convertors

A datatype needs a convertor. The purpose of a convertor is to convert between string and object representations of values. There is always a default convertor, but you change or configure that using the fd:convertor element. Here's an example for dates:

<fd:datatype base="date">
  <fd:convertor type="formatting">
    <fd:patterns>
      <fd:pattern>dd/MM/yyyy</fd:pattern>
    </fd:patterns>
  </fd:convertor>
</fd:datatype>

The type attribute on the fd:convertor element is optional, if not specified the default one will be used (configured in the cocoon.xconf). Any further content of the fd:convertor element is specific to the convertor implementation and will be documented in a seperate section.

Available datatypes

CForms datatype

Java class

Convertors

string

java.lang.String

Strings obviously don't support any convertors, since there's no purpose in converting a string to a string.

decimal

java.math.BigDecimal

formatting (decimal), plain

integer

java.lang.Integer

similar as decimal datatype

long

java.lang.Long

similar as decimal datatype

double

java.lang.Double

similar as decimal datatype

date

java.util.Date

formatting (date), millis

enum

Enumerated type

enum

char

java.lang.Char

only the default char convertor

Enumerated datatype

The enum datatype is meant to be used with types implementing Joshua Bloch's typesafe enum pattern. The following is a possible implementation:

package com.example;

public class Sex {

    public static final Sex MALE = new Sex("M");
    public static final Sex FEMALE = new Sex("F");
    private String code;

    private Sex(String code) { this.code = code; }
}

The following snippet shows the usage of this type:

<fd:field id="sex">
  <fd:label>Sex</fd:label>
  <fd:datatype base="enum">
    <fd:convertor type="enum">
      <fd:enum>com.example.Sex</fd:enum>
    </fd:convertor>
  </fd:datatype>
  <fd:selection-list type="enum" class="com.example.Sex"/>
</fd:field>

If your enumerated type does not provide a toString() method, the enum convertor will use the fully qualified class name, followed by the name of the public static final field referring to each instance, i.e. "com.example.Sex.MALE", "com.example.Sex.FEMALE" and so on.

If you provide a toString() method which returns something different, you should also provide a fromString(String, Locale) method to convert those strings back to instances.

The enum datatype is typically used together with the enum selection list type.

Available convertors

Decimal convertors

Numeric or decimal types can be formatted in two ways: plain and formatted. The first is very simple, the second provides locale-dependent formatting.

plain

This convertor is not locale-dependent. It shows the full precision of the number and uses dot as the decimal separator.

Configuration example:

<fd:datatype base="decimal">
   <fd:convertor type="plain"/>
</fd:datatype>

Output of this field with a value of 1234.5678 would be

1234.5678

formatting (decimal)

This convertor uses the java.text.DecimalFormat class (or com.ibm.icu.text.DecimalFormat class if it is present in the classpath). This means it can perform locale-dependent, pattern-based formatting of numbers.

Configuration pseudo-schema:

<fd:convertor type="formatting" variant="integer|number|currency|percent" ? >
  <fd:patterns>
    <fd:pattern>....</fd:pattern> ?
    <fd:pattern locale="lang-COUNTRY">....</fd:pattern> *
  </fd:patterns> ?
</fd:convertor>

The variant attribute and patterns element are optional. By default, the "number" variant is used (or for longs: the "integer" variant).

You can supply either a locale-independent formatting pattern or locale-dependent formatting patterns. See the javadoc of the DecimalFormat class for the supported pattern syntax. CForms will always use the pattern that is most specific for the current locale.

Example:

<fd:datatype base="decimal">
   <fd:convertor type="formatting">
      <fd:patterns>
         <fd:pattern locale="en-US">#,###.##</fd:pattern>
         <fd:pattern locale="nl-NL">####,####</fd:pattern>
      </fd:patterns>
   </fd:convertor>
</fd:datatype>

Output of this field with a value of 1234.5612 would be

With locale = en-US: 1,234.56

With locale = nl-NL: 1234,5612

Date convertors

The date datatype can be used both for dates as times. The date datatype supports the following convertors:

formatting (date)

This convertor uses the java.text.SimpleDateFormat class (or com.ibm.icu.text.SimpleDateFormat class if it is present in the classpath). This means it can perform locale-dependent, pattern-based formatting of dates.

Configuration pseudo-schema:

<fd:convertor type="formatting" variant="date|time|datetime" ? 
    style="short|medium|long|full" ?
    timeStyle="short|medium|long|full" ?
    lenient="true|false" ?>
  <fd:patterns>
    <fd:pattern>....</fd:pattern> ?
    <fd:pattern locale="lang-COUNTRY">....</fd:pattern> *
  </fd:patterns> ?
</fd:convertor>

Usually you will use either the variant and style attributes or the pattern(s).

For example, the following convertor configuration:

<fd:convertor type="formatting" variant="date" style="short">

Will give the following for July 15, 2003: 7/15/03. Using style medium it gives "Jul 15, 2003", style long gives "July 15, 2003", and style full gives "Tuesday, July 15, 2003". These result are locale-dependent of course. By default the value of the style attribute applies to both the date and time components, but you can specify a different style preference for times using the timeStyle attribute.

Here's an example of using a formatting pattern:

<fd:convertor type="formatting">
  <fd:patterns>
    <fd:pattern>dd/MM/yyyy</fd:pattern>
  </fd:patterns>
</fd:convertor>

Using the same date, this will now give "15/07/2003".

It is also possible to use different patterns for different locales by using multiple fd:pattern elements with "locale" attributes, for example:

<fd:convertor type="formatting">
  <fd:patterns>
    <fd:pattern>MM/dd/yyyy</fd:pattern>
    <fd:pattern locale="nl-BE">dd/MM/yyyy</fd:pattern>
    <fd:pattern locale="fr">dd-MM-yyyy</fd:pattern>
  </fd:patterns>
</fd:convertor>

In this case, if the locale is "nl-BE", the second pattern will be used; if the locale is "en", the first pattern will be used; and if the locale is "fr-BE" the third pattern will be used (because when fr-BE is not found, it will first search for "fr" before using the locale-indepent pattern).

The "lenient" attribute governs whether date parsing is lenient or not. The default is lenient, which means that the convertor will try to convert a somewhat invalid date like "Dec. 32, 2005" into "Jan. 1, 2006". If the value of the "lenient" attribute is false, such a date won't validate.

Note
Note that when binding XML documents you can also specify the final pattern in which the date is stored. More information can be found on the binding framework page. The same holds true for numbers.

millis

The millis convertor for dates uses the number of milliseconds since January 1, 1970, 00:00:00 GMT as string representation. This will likely not be used to present dates to the user, but may be useful in selection lists retrieved from external sources.