Wednesday, May 26, 2010

Griffon Validation Plugin 0.3 Release

I am happy to announce the 0.3 release of GValidation plugin - a Griffon validation plugin designed to provide Grails like constraints and validation support. In this post I would like to introduce a few new features implemented in this release.

1.Custom Constraint Support

This is probably the biggest improvement introduced in this release. Inspired by Grails' Custom Constraint plugin, once upgraded GValidation will introduce a new type of artifact to your Griffon application - Constraint.

In previous version GValidation allows you to define a custom validator using a closure just like in Grails:

// Simple custom validator
even( validator: {
return (it % 2) == 0
})

However this kind of closure based simple validator is hard to reuse therefore you will have to rewrite them every single time, a major inconvenience and a violation of the DRY principle. In version 0.3 now you can create a top level reusable custom constraint by using the following script:

griffon create-constraint [package].[constraint-name]
A Groovy class will be created under griffon-app/constraints folder to allow you to define your custom validation logic, a typical custom constraint looks like this:

class MagicConstraint {

/**
* Generated message
*
* @param propertyValue value of the property to be validated
* @param bean object owner of the property
* @param parameter configuration parameter for the constraint
* @return true if validation passes otherwise false
*/
def validate(propertyValue, bean, parameter) {
if (!parameter)
return true

return propertyValue == 42
}

}

Once created a custom constraint pretty much behaves exactly like a built-in constraint, you can easily invoke them in your model by following the simple naming convention, with the above example you can apply the constraint on any field in your model by using the following declaration:

class DemoModel{
….

@Bindable int magicNumber

static constraints = {
….
magicNumber(magic: true)
….
}
2. Selective Validation

Originally proposed by Andres Almiray, GValidation now offers capability to perform validation on only a selected number of fields in the model instead of all. Here is a typical single field validation usage scenario:

model.validate('name')
...
if(model.hasErrors()){
// notify user
...
}
You can also perform selective validation on a list of fields:

model.validate(['name', 'email'])
...
if(model.hasErrors()){
// notify user
...
}
3. Default Catch-All Error Message Code

This is a minor enhancement however a great time saver for someone who has to perform a large number of validation in their app. In previous version validation plugin only generates model specific error message code:

[modelclass].[field].[validator].message
Now for every built-in and custom validator the plugin will also generate a default error message code additionally:

default.[validator].message

You can retrieve the error code and default error code from the Error object using the following fields respectively:


error.errorCode
error.defaultErrorCode


For a complete guide on the plugin, please check out the Wiki page.

2 comments:

Andres Almiray said...

Hi Nick, I believe formatting is getting in the way in some of your snippets. missing < and >

Nick Zhu said...

Thanks for pointing it out Andres, it should be fixed now, cheers.