Home

News

Download (SourceForge Hosted)

Documentation

Articles

Feedback

XML Configuration Guide

Introduction

The configuration is where the meat of iScreen exists. Though the design supports multiple configuration types, the only currently supported format is XML.

DTD Reference

For a reference on individual elements, see the documented DTD.

XML Walkthrough

Within this walkthrough, elements may be identified uniquely. When this is the case, these names, when "unqualified" are tacked onto the end of the configuration file's namespace. A "fully qualified" name is one that has the namespace built in. The differentiation between the two formats is done by embedded periods. If an embedded period is found in a name that should be unique, then it is considered fully qualified (which means, if that namespace doesn't exist, the item won't be found, and you'll get a runtime exception). If no embedded period is found, the name is considered unqualified, and will have the namespace of the file containing it tacked on to the beginning.

The Root Element

The root element of the configuration file looks like this:

<validation-root namespace="my.namespace" default-resource="resource_ref"> ... ... </validation-root>

The namespace attribute must be unique across all configuration files being used by an application. It's used to uniquely identify items that are defined within the configuration file. It's tacked on the beginning like Java package names. This attribute is required.

The default-resource attribute is the id of the resource that will be used when none others are defined. This attribute is optional. The id can be fully qualified or unqualified.

Including Other Configuration Files

Many configuration files may be used to specify all of the validation configurations for an application. In fact, this is useful when segregating validations for different parts of an application into multiple places. However, a single "root" configuration must be used to tie all of the other configurations together. In order to do this, configuration files can reference other configuration files. This is done using the include element. It looks like this:

<validation-root namespace="my.namespace" default-resource="resource_ref"> <include file="file/to/include" /> ... </validation-root>

Note that the element doesn't have any content, and has only one attribute: file. This attribute specifies where the location of the other configuration file is (based upon a classpath search). Any number of include elements can be contained within the root element, allowing any number of configuration files to be included (and included files can contain other included files, as well).

Resources

Resources are key/value pairs that may be referenced by validators or validation sets to configure messages and such. Resources are meant to provide internationalization support. Any number of them may be added to any particular configuration file and may be referenced from other configuration files, as well (though make sure that the fully qualified namespace and name are used).

In addition, resources can reference other resource (see the ref attribute), allowing resources to "chain" together. Note that if this is done, that a resource, say resource A, if it references another resource, say resource B, and a particular message key is defined in both, then the message defined in the first resource, in this example, resource A, will be used, effectively over-riding the "parent" resource.

Resources look like this:

<resource id="resourceId" ref="parentResourceId"> <message key="messageKey">the value of the message</message> <resource-file file="classpath.resource.name" /> </resource>

The id attribute on the resource is required and must be unique across all configuration files (the namespace of the containing configuration file is prepended, so the uniqueness includes the namespace). The ref attribute is optional, and is used to reference a "parent" resource to "chain" resources together. When this is done, both the child and parent messages can be accessed.

The contained message element is not required and is mostly for "hard-coding" messages within a resource. It would not normally be used, but is there if there are few messages and an external resource bundle is not appropriate (though the message won't be internationalized).

The resource-file element and its file attribute are used to reference a resource bundle. The element is not required as part of a resource definition, but if used, the file attribute is required. Any number of resource-file elements may be added to a resource definition.

The message used by a particular message key (whether defined within a resource bundle or hard-coded in the configuration file) is some text that may contain embedded OGNL expressions (using the ${} characters to set them apart). The OGNL root used is org.iscreen.impl.OgnlRoot, but what's important is the properties that it provides:

  • failure : refers to the failure object that a Validator may provide when reporting a failure (see individual Validator documentation for these).
  • label : the label defined in the configuration.
  • validator : the configured Validator (and any of its properties).

For example, the following message is defined for the StringValidator when it reports a minimum length failure (in this case, the StringValidator provides the actual number of characters as the failure property). The StringValidator has a minLength property (there's a getMinLength() method on it) that returns the minimum length required by the Validator (once it's configured). Assume that the label provided is configured within a validator or use-validator element in configuration like this:

<label>The Label</label>

Given these OGNL root properties, a message utilizing them could look like the following:

For label ${label}, minimum length should be ${validator.minLength}, but was ${failure}.

When this failure is reported with the following property values, then the failure message generated will be as follows (minLength property is 10; actual length was 3; label as given above):

For label The Label, minimum length should be 10, but was 3.

Note that Validators are not required to report the failure object, so it's not guaranteed to exist (see individual Validators for documentation on what they report and when). Typically, however, they are consistently reported for a particular failure type (such as the minimum length failure that the StringValidator reports).

Validators

Validator definitions are just that: configurations that define an individual Validator. Validators can't be used or referenced from validation sets unless they've been defined via the validator configuration element. A basic Validator is configured as follows:

<validator id="validatorId" ref="parentValidatorRef" class="full.class.name.of.Validator" default-resource="defaultResourceId"> </validator>

The id attribute uniquely identifies the Validator. It must be unique within its namespace. The default-resource attribute defines the default resource that will be used by any configuration within the definition. The ref and class attributes are mutually exclusive: both cannot be specified. A ref attribute is an id of another, existing, Validator. Ultimately, a Validator must define the class of the Validator.

The ref attribute provides a powerful means of reusing Validator configurations. For example, assume a trivial definition of a Validator:

<validator id="baseId" class="some.Validator"> </validator>

Another Validator can be defined:

<validator id="anotherId" ref="baseId"> </validator>

Any configuration (meaning, contained elements) that are defined in the "child" Validator override configuration defined in the "parent." Also, they are additive. For example:

<validator id="baseId" class="some.Validator"> <constraint property="someProperty">constraint value</constraint> </validator> <validator id="childId" ref="baseId"> <constraint property="someProperty">override constraint value</constraint> <constraint property="someOtherProperty">additional constraint value</constraint> </validator>

In this example, the 'childId' Validator overrides the constraint for property 'someProperty' and adds an additional constraint called 'someOtherProperty.' In this way, hierarchies of configured Validators can be defined (and later referenced by Validation Sets).

The Validator definition takes five types of contained element configurations: constraints, failures, documentation, mappings, and labels.

Constraints are properties (set via OGNL or MVEL expressions) that provide basic configuration for Validators. Validators use these constraints as parameters to the logic they implement. For example, a StringValidator may use minLength and maxLength constraints to define a String's required minimum and maximum lengths.

In addition, constraints can reference externally defined services. For example, a Validator may need to make database calls and requires a DataSource in order to do so. These services are provided to the ValidationFactory when constructing a factory. Configuration is done by using the service-id attribute on the constraint element, where the service-id is the same as the key for the service map provided to the validation factory. When using the service-id attribute, the constraint element should not have any embedded content.

The failure configuration defines the validation failure messages that the Validator reports when a failure occurs. Typically, a Validator only reports a single type of failure message. The message can be defined in a resource or be defined directly in the configuration. The failure has an attribute called 'severity' that can be used to define the level of severity of the failure. The severity can be an integer, or one of three constants can be used: WARNING (value of 3), FAILURE (value of 5 and also the default value), and CRITICAL (value of 10). In addition, a 'msg' sub-element within a failure message can add additional "named" messages (there can be zero or many 'msg' sub-elements) that can be retrieved from the org.iscreen.ValidationFailure interface.

Documentation using the doc sub-element is used to provide dynamic, user-readable documentation for the Validator. The ValidationService interface provides access to this documentation. There can only be one documentation element within a Validator, but "child" Validators (or use-validator) can override the parent.

Mappings represent the mapping of the Java object being validated to the JavaBean that the individual Validator understands (the "Validate Bean").

The label represents a human-readable name or title of the validator, such as "First Name" or "Birth Date." Typically, it represents the field name on the form being displayed to the user. It can be referenced and used within failure messages, documentation, etc.

All five types of configuration for the Validator are shown in the following example. Note that the configuration elements are not required and that there may be many of them, not just one.

<validator id="someValidator"> <constraint property="constraintProperty">constraint value</constraint> <constraint property="serviceProperty" service-id="serviceKey" /> <failure property="failureProperty" resource-id="resourceId" key="messageId" /> <failure property="otherFailureProperty"> failure message <msg name="user_action">Please don't enter the wrong data.</msg> </failure> <doc>Some documentation on the ${label} in reference to some ${validator.constraintProperty}.</doc> </validator>

Note that the property attributes are OGNL expressions with the Validator instance acting as the OGNL root (or MVEL expressions and root, if using MVEL). Normally, assuming a JavaBeans approach, the property is just the JavaBeans property. For constraints, the value can be translated via OGNL's type conversions (meaning, standard conversions for basic primitive wrappers).

Validation Sets

A validation set is is set of configured validators that are grouped together to validate a particular object. Validation sets referenced configured validators as well as other validation sets. From an API perspective, validation sets are Validation services (i.e. org.iscreen.ValidationService), typically (some exceptions occurs, such as when using meta data, etc.).

The configuration for a validation set looks like the following:

<validation-set id="setId" default-resource="resourceId"> </validation-set>

The id attribute must be unique within the namespace. The default-resource attribute defines the resource that will be used when not directly referenced within any configuration within the validation set.

Within the validation set, three elements are possible: use-validator, use-validation-set and meta. The use-validator element references an existing, configured Validator. It has a ref attribute, a name attribute, an if attribute, and a fail-fast attribute. The ref attribute is the id of the configured Validator. The fail-fast attribute defaults to false and is not required. If set to true, and if the Validator being used reports a validation failure, then no more validation is performed beyond the configured Validator. The if attribute is an OGNL/MVEL expression (using the object being validated as the OGNL/MVEL root) that determines whether the validator is execute (if the expression results in false, then the validator is not called). The default value for the if attribute is true. Validations are performed in the order they are defined within the validation set. The name attribute is a non-unique identifier used by the API (see the ValidationFailure object) to reference the specific validator usage within the validation set. Basically, it's used by presentation frameworks to map specific validators to form fields. It's non-unique so that multiple validators can be referenced by the same form field.

Within the use-validator element, the same sub-elements that are used for the validator element are possible. They have the same meaning and are considered overrides for anything defined in the parent validator definition. In addition, the use-validator has an 'if' attribute that works identically to the 'if' attribute on the use-validation-set element.

The use-validation-set element is used to include an existing, configured validation set. It's a way to build validation sets from other validation sets. This element takes several attributes, with the only one required being the ref attribute, which is the id of the validation set being included.

The use-validation-set has a fail-fast attribute that acts the same as the fail-fast attribute of the use-validator element. The if attribute is an OGNL expression (using the object being validated as the OGNL root) that determines whether the validation set is included (if the expression results in false, then the set is ignored). The default value for the if attribute is true. The root of the OGNL/MVEL expression is the object being validated. The iterate attribute defaults to false and determines whether to iterate over the mapped object being forwarded to the validation set. The map attribute defines the property (an OGNL/MVEL expression) on the object being validated that will be forwarded to the validation set. If not specified, the object is passed as a whole (in other words, the OGNL/MVEL expression of #root is used). As the use-validator, the use-validation-set has the name attribute, and is used in the same way. This allows the developer to reference an entire validation set as a single reference in the presentation layer (i.e. associated with a single form field).

The meta element is a way to associate meta data with the validation set. This allows validation sets to be looked up via the meta data, as opposed to the validation set's unique id. Meta data doesn't need to be unique, and, in fact, multiple meta tags can be used.

The meta element can have one attribute, the property attribute. If it's not used, a default value of 'className' is used. The property attribute represents a name or id for the meta data. The meta data value is put as text data within the element.

A typical use of the meta tag would be to associate the class name of the JavaBean being validated, like this:

<meta>com.package.myBean</meta>

Instead of looking up the validation service using the validation set's unique id, the combination of meta property name and value can be used, instead:

ValidationService service = factory.getValidationService( "className", bean.getClass().getName() );

Please see the JavaDoc on the ValidationFactory, ValidationFactoryConfig, and ValidationServiceWrapper for additional ways of utilizing meta data on a validation set.

See the DTD for the configuration file for details on the format for the configuration.

Example XML Configuration

This example configuration would work for the following RegistrationInfo class:

public class RegistrationInfo { ... public String getFirstName() {...} public String getLastName() {...} public Date getRegistrationDate() {...} public Date getBirthDate() {...} public String getEmailAddress() {...} }

Configuration for RegistrationInfo's validation set:

<validation-root namespace="my.project"> <validation-set id="RegistrationInfoSet" default-resource="theResource"> <!-- First, let's validate the user's first name. --> <use-validator ref="org.iscreen.StringValidator"> <mapping from="firstName" /> <label key="label.FirstName" /> <constraint property="minLength">1</constraint> <constraint property="maxLength">25</constraint> </use-validator> <!-- Now the last name. --> <use-validator ref="org.iscreen.StringValidator"> <mapping from="lastName" /> <label key="label.LastName" /> <constraint property="minLength">1</constraint> <constraint property="maxLength">30</constraint> </use-validator> <!-- Make sure that the registration date is after the birthdate. --> <use-validator ref="org.iscreen.DateRangeValidator"> <mapping from="birthDate" to="from" /> <mapping from="registrationDate" to="to" /> <label key="label.RegistrationDate" /> <failure property="failure" key="failure.RegistrationDate" /> </use-validator> <!-- Check the email address. --> <use-validator ref="org.iscreen.StringValidator"> <mapping from="emailAddress" /> <label key="label.EmailAddress" /> <constraint property="minLength">1</constraint> <constraint property="maxLength">256</constraint> </use-validator> </validation-set> <resource id="theResource"> <resource-file file="messages" /> </resource> </validation-root>

Resource file messages.properties:

label.FirstName=First Name label.LastName=Last Name label.EmailAddress=Email Address label.RegistrationDate=Registration Date failure.RegistrationDate=The Registration Date must be on or after the Birth Date.

A modification on this configuration would simplify things slightly. The design of iScreen configuration was to provide reuse, which is to minimize duplication. Notice that the first and last name, as well as the email address, have a constraint defining the minimum size constraint. This constraint is the same for all three. The configuration can be changed to remove that duplication.

<validation-root namespace="my.project"> <validation-set id="RegistrationInfoSet" default-resource="theResource"> <!-- First, let's validate the user's first name. --> <use-validator ref="RequiredString"> <mapping from="firstName" /> <label key="label.FirstName" /> <constraint property="maxLength">25</constraint> </use-validator> <!-- Now the last name. --> <use-validator ref="RequiredString"> <mapping from="lastName" /> <label key="label.LastName" /> <constraint property="maxLength">30</constraint> </use-validator> <!-- Make sure that the registration date is after the birthdate. --> <use-validator ref="org.iscreen.DateRangeValidator"> <mapping from="birthDate" to="from" /> <mapping from="registrationDate" to="to" /> <label key="label.RegistrationDate" /> <failure property="failure" key="failure.RegistrationDate" /> </use-validator> <!-- Check the email address. --> <use-validator ref="RequiredString"> <mapping from="emailAddress" /> <label key="label.EmailAddress" /> <constraint property="maxLength">256</constraint> </use-validator> </validation-set> <validator id="RequiredString" ref="org.iscreen.StringValidator"> <constraint property="minLength">1</constraint> </validator> <resource id="theResource"> <resource-file file="messages" /> </resource> </validation-root>

Note that not much was gained: three config lines were replaced with a reference to three more config lines (the validator definition of RequiredString). However, in a more complex configuration, the opportunity this method provides can be considerable.

The Big Picture

Fundamentally, the interface to iScreen is via the ValidationService, where an application calls its validate() method. In turn, configured validators are called. The following model shows this representation a little clearer:

Note that the mapping action is the mapping of the "Object to validate" to the "beanToValidate" that the individual Validators create (i.e. the org.iscreen.SimpleBean in most cases). This allows the Validators to remain stateless (so that they only need to be configured once during their life time). The mapping element in the configuration defines this mapping.

Note that all the models presented here follow the Agile Draw modeling approach.