6.6 Formatters/Validators

Subclasses of IFmt are responsible for converting primitive XMA types (see IAtomic ) to the UI and back. The former operation is usually called formatting , the latter validation . Both operations are encapsulated in an instance of a class derived from IFmt. The next figure show the involved data-flow:

formatting/verifieing data flow

Figure 6.5. formatting/verifieing data flow


Every type defines a so called internal encoding , that's how the value is stored in widget-models and also transmitted over the wide area network between XMA client and XMA server. Every formatter is able to map the internal encoding to an external encoding , that's the string-representation how the value is displayed in the SWT-widget to the end-user.

The next interaction-diagram shows an event-flow to demonstrate how validation works in XMA:


On every keystroke, two operations are performed:

Formatting is the process of mapping an internal string-encoding of a supported XMA type to an UI-encoding adequate for the end-user, see the next interaction diagram:


Method IFmt.format does all the work.

Custom formatters are created by using the class FmtFactory and providing a string-pattern. See FmtFactory 's javadoc for a list of permissible string-patterns. The create -methods of class FmtFactory require a string-pattern and return an object derived from IFmt , which is the base class for all custom formatters.

If performance is of great importance in your application, do not use FmtFactory . Instead, create the formatters directly by using the getInstance() -methods in the classes ABcdFmt , ADateFmt , AStringFmt and ATimeStampFmt .

The following table gives some examples of formatter-patterns, although this list is just an example. For a complete description please refer to FmtFactory .


XMA provides a built-in set of formatters in the package at.spardat.enterprise.fmt . Writing your own formatters is usually done by subclassing one of the provided formatter-classes. Creating your own formatter-classes is recommended if you can reuse the formatter for many text-fields, so that the formatting/validation-code can be shared. Suppose, numeric input should be constrained for a particular field in a way, that only integer numbers x having (x%1000==0) with a maximum length of 10 digits are allowed. Then your subclass may look like that:

public class MyNumberFmt extends ABcdFmtDefault {

     /**
      * Constructor
      */
     public MyNumberFmt (int style, Locale l) {
         super (10, 0, style, l);
     }

     /**
      * @see at.spardat.enterprise.fmt.IFmt#parse(String)
      */
     public String parse (String external) throws AParseException {
         /**
          * Call all the validation-logic of the super-class. This call would throw an exception if something
          * would went wrong.
          */
         String internal = super.parse (external);

         /**
          * Create an Atom from the internal string
          */
         Atom   atom = Atom.newInstance (Types.T_BCD, internal);
         if (atom.hasValue()) {
             long       val = (long) atom.toDouble();
             if ((val%1000) != 0) throw new AParseException ("Please enter a number that divides by 1000.");
         }
         return internal;
     }
} 
Conclusion: Narrowing the validation rules is accomplished by extending method parse , but do not forget to call parse on the superclass.