Print Header

Related Topics

Related Case Studies

Contact Blue Fish

Blue Fish Development Group
701 Brazos St. #700
Austin, TX 78701
(512) 469-9300

Validation Strategy in WDK

Author Photo

April 5, 2005 - Article by Jason Duke

Learn how to use the WDK Validation Framework effectively.

Introduction

The WDK framework provides some powerful and versatile tools for handling validation of user input. There are some limitations to the validation framework, but once you learn your way around some of its quirks, it can be powerful and can help streamline input validation.

This article provides an overview of the WDK Validation Framework, along with some general tips for getting the most out of the WDK validators and knowing how to work around limitations. If you are looking for a discussion of the various validators WDK provides and how to use them, you may want to read Validation in WDK.

The strategies and tips discussed in this article are based on WDK 5.2.5, although it is likely that much of the content will remain relevant into future versions of WDK.

Background

The WDK validation framework consists primarily of validators, which are special controls which are used to validate other controls.

Documentum provides a wide array of validator implementations for many of their controls, but there is nothing preventing you from developing your own validators, if necessary.

A typical validator control – like all WDK controls – is specified by a tag class, a control class, and a tag definition.

This article, however, will focus exclusively on using the existing validators and validation framework.

Unless you are looking to write your own validators or modify the existing ones, you will not need to know much about the Java classes behind your validators. Instead, you should focus on familiarizing yourself with the different validator tags themselves.

The Blue Fish article “Validation in WDK” provides a good overview of the various validators, and of course the WDK documentation provides a complete validator reference.

How WDK Validation Works

Validators are specified on the JSP page for your component, using standard validator tags. For example, the tag below might be used to validate that the control “username” is not empty:

                                
<dmf:requiredfieldvalidator indicator='*'
                            cssclass='error'
                            name='usernameRequiredValidator'
                            controltovalidate='username'
                            nlsid='LABEL_REQUIRED_INPUT' />

                            

When the tag is rendered, it either evaluates to the indicator (if the field is valid or if the validator has never been called) or the error message (if the field is invalid).

Through the mechanics of the WDK form processing framework, the validators you specify are executed by the containing component’s validation methods when the form is submitted.

By default, all of a component’s visible validators are executed when a server-side event is fired. (See Turning Off Validation below, for details on how to override this default behavior.)

The validators are executed in the order in which they were added to the component, one by one. If a validator fails, its state is changed to invalid; the next time the component is rendered, any failed validators will display their error messages.

Note that the validators are evaluated before the event handler is called. By the time the event handler method is called, the validators have all been evaluated, and the component’s valid flag has been set.

Validation failure does not automatically stop your event from being executed! You must explicitly check whether validation failed or not using the Component method getIsValid.

There is no way to set a validator back to its valid state once it has evaluated as invalid. In fact, the only way to get a validator to evaluate to valid once it has evaluated to invalid is to populate the control with valid data and execute the validator. This means that once your event is fired and the validators are evaluated, any invalid validator will display its error message the next time the component is rendered.

There are two important things to understand about WDK Validation that may not be immediately apparent:

  1. All validation takes place on the server, not the client.
  2. A component must be rendered again after validation in order for validation messages to be displayed.

All validation happens at the server. This means that in order for validation rules to be processed, a server-side event must be fired; it also means that, unless you set your validation up to do otherwise, any time a server-side event is processed, your validators will be evaluated. This can be frustrating when some of your events should trigger validation and others should not. (But don’t worry, this article will cover how to get around that.)

Validation error messages are displayed in place of the validator tags themselves, but only if the component is allowed to render again. This means that if you want validation to actually stop an event from jumping to another component and instead display the validation messages, you must explicitly check the validity of the component in your event handler and make sure the event handler returns without jumping somewhere new (or doing anything else it shouldn’t do if input is invalid).

Example 1: Basic Validation, Validator Visibility

In this example, we will:

  1. See how a basic required validator is evaluated.
  2. Observe that validators on hidden panels are not evaluated.

Suppose we have a form with several required inputs and two buttons: Submit and Validate. When a user clicks the Submit button, the inputs should be validated and then the inputs should be processed; their values will determine which component to jump to. When the user clicks Validate, the inputs should simply be validated, with any error messages displayed to the user.

The solution to this example is simple. Once we have developed our JSP page with the various input controls, validators, and buttons, we must implement two event handlers: onSubmit and onValidate. When any event is fired on our form, validation will happen automatically. Our onValidate method can therefore be empty. The onSubmit method, however, will have to check whether validation succeeded or not using the public method getIsValid. If the input was valid, the event handler can jump to a new component based on the input; if the input is invalid, the event handler can simple return, which will cause the WDK framework to render the page again, with error messages prominently displayed.

The files below provide a basic implementation of the solution described above.

You may wish to experiment with the component from the example. Notice how the validator on the

Turning Off Validation

Fortunately, WDK provides a way to only execute validators for certain events. By default, the WDK framework automatically executes all visible validators contained by a component when any event on that component is triggered. By setting the validation attribute to false in your <dmf:webform> tag, you can instruct the WDK not to perform validation automatically. Then you can manually call the validate and getIsValid methods from your event handlers as needed.

Example 2: Turning Automatic Validation Off, Using Manual Validation

In this example, we will:

  1. See how the <dmf:webform> tag attribute validation can be used to turn off automatic validation.
  2. See how to call the validate method to manually execute component validation as needed.

Suppose we have a form with several inputs on it, similar to the form in Example 1. The two buttons on this form, however, are: Submit and Refresh. When a user clicks the Submit button, the onSubmit event handler method is called, and it processes the required data from the form. When the user clicks the Refresh button, the onRefresh event handler is called, and some business logic is executed to update some of the values displayed by the component.

The form may have “required” user input fields on it, but we probably don’t want to display error messages for empty fields when the user clicks Refresh. However, we do need for validation rules to be evaluated prior to processing of the data when the user clicks Submit. The solution is to turn off automatic validation using the <dmf:webform> validation attribute, then add calls to the public methods validate and getIsValid at the beginning of the onSubmit event handler.

The files below provide a basic implementation of the solution described above.

Note: You may have noticed that there is a protected method validate(boolean) in addition to the public validate() method. This is the method that is actually called by the WDK framework to evaluate the validators. The boolean argument instructs the method whether or not to ignore the validation attribute setting in the <dmf:webform> tag. If this method is called with an argument of true, the method will ignore any validation attribute from the <dmf:webform> tag and evaluate the validators no matter what. This is what happens when you call the public validate method. When the WDK framework calls this method, though, it passes in a boolean argument of false, which means the method will obey the validation attribute from <dmf:webform> and skip the validators if validation attribute is set to false. (We will discuss these validate methods in more detail later.

Overriding WDK Validation Methods

Sometimes, simply turning validation off and calling the validate method(s) directly is not sufficient, especially for more complex components. Perhaps certain validators should only be evaluated if certain business rules are met. Or maybe some of the validators should be run for one set of events, and different validators should be evaluated for another set of events. In these situations, it may be necessary to override one or both of the validate methods in your component class.

The protected method validate(boolean) is implemented in the Form class as well. This is the method which the WDK framework calls to validate the form when an event is fired (before it passes control to your event handler). Its boolean argument instructs the method whether or not to ignore the validation attribute of the <dmf:webform> tag. If this method is called with an argument of false, then the validators are only evaluated if the <dmf:webform> validation attribute is set to true (or not set at all, since it defaults to true). If this method is called with an argument of true, then the framework ignores the validation flag and evaluates the validators no matter what.

To evaluate the validators, the method simply goes through all the enabled validators in the component and evaluates them one by one. If any of the validators evaluates to false, then this method sets the isValid flag on the component to false.

The public method validate() is implemented in the Form class. It simply calls the protected method validate(boolean) with an argument of true, instructing it to execute all validators regardless of whether validation has been turned off using the validation attribute of the <dmf:webform> tag.

Although, the isValid is a private member of the Form class, you can set it to false by calling the protected Form method setInvalid. In this way it is possible to completely override the protected method validate(boolean) to execute any, all, or none of the validators as desired, calling setInvalid if the form should be considered invalid (which can then be checked later using getIsValid). The getValidators and getContainedControls methods might prove useful in this endeavor.

Unfortunately, WDK provides no way to set the component state back to ‘valid’ again, which means that once you have set the component invalid using setInvalid, there is no way to reset the state. The only way to get it back to valid is for the base Form class validate method to be called and for all enabled validators to return true.

This suggests two interesting ways of resetting an invalid component back to valid.

If you have already turned off automatic validation using the <dmf:webform> validation attribute, then it’s easy to get the validate method to set the component state to valid. Simply call the protected validate method from the Form class with the argument false. This allows the validate method to skip the validators, since automatic validation is turned off, and it will automatically set the component isValid flag back to true.

If you have not turned off automatic validation using the <dmf:webform> validation attribute, it’s a little more complicated. Because the only way to set the isValid flag is to call WDK’s protected validate method, which in turn evaluates all enabled validators, we must find a way to disable all validators prior to calling this method. One fairly simple, though not terribly intuitive solution, could be the following:

  1. Place all validators into a single panel (remember, panels can be nested, so you could still maintain the existing panel model on your page).
  2. Set that panel to hidden, which effectively disables all those validators.
  3. Call the Form.validate method, which will only evaluate enabled validators, of which there are none, and so it will set the component state back to valid.

At this point, you might be asking why you need to rely on the Form class’s implementation of the valid flag at all. What’s to stop us from abandoning the WDK validation methods entirely and calling all validator controls directly? Rather than go through all this rigamorale just to change the Form class’s private implementation of a boolean flag, couldn’t we just as easily implement the valid flag within our own class and call the validators ourselves?

The answer is yes, we could. And in many situations, this is the best route to take. But keep in mind that in order for your component to function properly inside of some WDK containers, it may be necessary to maintain the contract that validate and getIsValid do what they claim to do; any customized validation you do should fit into this model if you expect it to work within the larger context of some containers.

There is nothing to stop us, however, from overriding validate(), validate(boolean), setInvalid(), and getIsValid() to rely on our own member fields for validity state. As long as we maintain the contract of those four methods, we should be in good shape. Of course, if somewhere inside the Form class there are other methods which are checking or altering the isValid flag directly, we could run into trouble. But experience suggests this is probably nothing to be too concerned about.

Sometimes, it may even be desirable to abandon the existing validate method and provide your own way of executing validators.

Note: There is nothing to stop you from getting a specific validator by name and evaluating it directly, with validation turned off in <dmf:webform> and no calls to the built-in validate methods. Sometimes this can be very useful, but usually a more general approach is recommended.

Example 3: Overriding Validation Methods

In this example, we will:

  1. See how to override WDK validation methods in order to implement customized validation.

Suppose we have a form with several inputs on it. Like the form in Example 2, we have two buttons: Submit and Refresh. In this example, however, our input is a little more complex. All inputs are required, but input1 should only be validated if checkbox1 is checked. We need validation which is smart enough to only call the validator for input1 if checkbox1 is checked; if checkbox1 is not checked, the validator for input1 should not be evaluated at all.

To accomplish this, we will first want to turn automatic validation off in the <dmf:webform> tag. Our onRefresh and onSubmit methods should be the same as in Example 2; only the event handler for the Submit button should call validate() method. However, in order for the validate method to behave correctly and only validate input1 if checkbox1 is checked, we must override it and implement our own validation logic.

Since we are manually calling the public validate method from our onSubmit event handler method, we might like to override the public validate() method. This would be a mistake; if for some reason we ever turn automatic form validation back on, it would bypass our public method and call the protected validate method directly, breaking our checkbox-based validation rule. Therefore, we should instead override the protected validate(boolean) method.

There are a variety of ways to implement the checkbox-based evaluation of the validator. The example code shows an somewhat simple approach: our validate(boolean) method leverages the helper method deepValidate, which goes through all the validators in the component and evaluates them one by one, unless it finds a validator with the specific name ‘input1_reqval’, which it skips if the checkbox is not checked. In practice, this is a somewhat fragile implementation: if someone renames the validator, it breaks, and it is not particularly easy to apply it to multiple inputs. But for the purposes of this article, the sample implementation will suffice.

One thing you may notice about the validate(boolean) method in the sample code is that it makes a call to the super.validate(boolean) method. This is due to the limitation discussed previously. Once the component has been set invalid, there is no way for us to set it back to valid directly, even when the form is submitted again! It is necessary, therefore, to get the super.validate(boolean) method to set it to valid for us. Since in the example we have already turned validation off using the <dmf:webform> tag, we know that calling validate(false) will set the component back to valid, since it will skip all validators. In this way, we are able to reset the component to valid prior to doing our custom validation with deepValidate().

(If we had a component where we did not turn validation off, we would have to try something more involved to reset the component state to valid, such as placing all validators on a panel which we could make invisible prior to calling the super.validate method.)

The files below provide a basic implementation of the solution described above.

Conclusion

The WDK Validation Framework provides a handy way to implement server-side input validation. There are some limitations, but with the right workarounds and a good understanding of how the validation framework operates, these limitations are manageable.

 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 Votes | Average: 0 out of 5 (0 votes, average: 0 out of 5)
Loading ... Loading ...

Comment on this article:

You must be logged in to post a comment.

Notification

Subscribe to our newsletter to be notified when new articles are posted. You can unsubscribe at any time.