When Grails binds data e.g. when the controller’s bindData method is called, it instantiates a GrailsDataBinder to take the action. GrailsDataBinder configures itself with some basic ProperyEditors. The neat thing is you can extend that behaviour by adding an arbitrary named PropertyEditorRegistrar implementation to the application context. The PropertyEditorRegistrar registers one or multiple PropertyEditors.
A recent use case was the ability to look up some domain instance by a given key and use this for data binding. Coding a seperate PropertyEditor for each domain class would not really be DRY, so I decided to go the groovy way: a DomainClassLookupPropertyEditor:
public class DomainClassLookupPropertyEditor extends PropertyEditorSupport {
Class domainClass
String property
boolean doAssert = true
String getAsText() {
value."$property"
}
void setAsText(String text) {
value = domainClass."findBy${StringUtils.capitalize(property)}"(text)
assert doAssert && value, "no $domainClass found for $property '$text'"
}
}
The PropertyEditor calls the domain class’ findBy<Property> method to look up the desired instance. The PropertyRegistrar looks like this:
public class MyPropertyEditorRegistrar implements PropertyEditorRegistrar {
public void registerCustomEditors(PropertyEditorRegistry propertyEditorRegistry) {
propertyEditorRegistry.registerCustomEditor(Author, new DomainClassLookupPropertyEditor(domainClass: Author, property: "name"))
propertyEditorRegistry.registerCustomEditor(Book, new DomainClassLookupPropertyEditor(domainClass: Book, property: "isbn"))
}
}
Last, we need to configure that in resources.groovy:
beans = {
myEditorRegistrar(MyPropertyEditorRegistrar)
}
One reply on “Customizing Grails data binding with a “groovy” PropertyEditor”
Really nice post. I just posted something adapting this to create new domain instances if they don’t exist already: http://adhockery.blogspot.com/2010/02/using-custom-data-binder-with-grails.html