Wednesday, August 6, 2008

Alternative to Using Valang Custom Functions


Valang provides a rich set of validation tools and is pretty simple. However in some cases you want more. The most obvious case that we encounter is validating if a date is in future or past wrt the current time on server. I know we can parse and input date to a date object readily using initBinder function of a SimpleFormController. But to compare it with the current date using pure varlang is something I could not find.

Luckily valang has an ability to use custom function. However I found it cumbersome to make one separate class for each function I may need. It would make more sense to allow users to group functions in one class to build a custom library of functions. Not to mention I could not find a proper working example of a custom function. So till I get my hands on one and this implementation improves, I have a simple work around.

Step 1: Define valang validations in the config file


<bean id="webMessageFormValidator"
class="myPackage.validators.FormBeanValidator">
<property name="valang">
<value>
<![CDATA[
{to:? IS NOT BLANK:'Please enter email addresses
for recepients.'}
{subject:? IS NOT BLANK:'Mail can not be blank.'}
{from:(length(?)> 0):'Please specify at least one
address.'}
]]>
</value>
</property>
</bean>


Step 2: Define the validator as follows


package mypackage.validators;

import org.springframework.validation.Errors;
import org.springmodules.validation.valang.ValangValidator;
import mypackage.FormBean;


public class FormBeanValidator extends ValangValidator {

public void validate(Object object, Errors errors) {

FormBean form = (FormBean) object;

//perform all validations and raise error flag
//if you find an error
if(isFutureTime(form.myDate()){
errors.rejectValue("myDate", "error.futureDate"
,"Time cannot be in the future.");
}

//dont forget call to super so as the validations
//defined in XML take place
super.validate(object, errors);
}


private boolean isFutureTime(Date formDate,
int hours, int minutes){
//check if time is in future
return false;
}

1 comment:

Anonymous said...

hello,
I know there's a long time since you wrote this post, but i've just seen it :D

There's an easy way to compare a date with the current date. Valang uses the T construct, that represents the current timestamp. So you just have to compare your data with T in this way
{yourDate : ? > [T]:'your date must be greater than today'}

I've seen the solution in the book "Expert Spring MVC and Web Flow", page 271