views:

436

answers:

2

I am using spring MVC and would like to expose default validator for javascript to use. I have a bunch of controllers extending a common abstract class and bunch of validators implementing a common interface. The situation is something like this:

public abstract class AbstractController {
 protected Validator validator;
}

public class FooController extends AbstractController{}
public class BarController extends AbstractController{}

public interface Validator {}
public class FooValidator implementes Validator{}
public class BarValidator implementes Validator{}

I would like to automatically set the validator field for each concrete controller respectivelly (so that FooController.validator would be instance of FooValidator). The matching should be done by class names automatically.

+1  A: 

You could create a BeanPostProcessor to do this and register it in the application context. The post processor could look for AbstractController instances with the proper naming convention, generate the validator name, instantiate the validator object via reflection, and set it in the controller. Something like this:

public Object postProcessAfterInitialization(final Object bean, final String name) throws BeansException {
    if (bean instanceof AbstractController) {
        String controllerName = bean.getClass().getSimpleName();
        if(controllerName.endsWith("Controller")) {
         String validatorName = controllerName.replaceFirst("Controller$", "Validator");
         try {
             Class<?> validatorClass = Class.forName(validatorName);
             Validator validator = (Validator)validatorClass.newInstance();
             ((AbstractController)bean).setValidator(validator);
         } catch(Exception e) {
          throw new FatalBeanException("Cannot instantiate validator", e);
         }
        }
    }
    return bean;
}

Alternatively, if the validators are registered as Spring beans because they need dependency injection or whatever, you could create a BeanFactoryPostProcessor (not a BeanPostProcessor) that finds all the controller bean definitions by type or name, then looks up matching validator bean definitions by type or name, and adds the matching validator to the property list of each controller bean. I don't have sample code for that, but hopefully you get the idea.

Rob H
A: 

Couldn't you use something like this in your configuration:

<bean id="abstractControllerTemplate" abstract="true">
    <property name="validator" ref="myFormValidator"/>
</bean>
...
<bean id="someOtherConcreteController" class="com.myproj.controllers.SomeOtherConcreteController" parent="abstractControllerTemplate">
        <!-- other properties specific to this controller -->
</bean>
Juri
That's not what I meant by automatic assigning
awk