diff --git a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java index be79745ea5..d639a020d6 100644 --- a/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java +++ b/domain/src/main/java/org/acegisecurity/domain/validation/ValidationRegistryManagerImpl.java @@ -15,46 +15,24 @@ package net.sf.acegisecurity.domain.validation; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; - +import org.springframework.beans.factory.BeanFactoryUtils; +import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - import org.springframework.validation.Validator; -import java.util.HashMap; -import java.util.Map; - /** * A basic implementation of {@link ValidationRegistryManager}. * *
- * Like PropertyEditorManager,
- * this implementation uses three techniques for locating a
- * Validator for a given domain object class:
- *
- *
Validator to be expressly registered for a given domain object
- * class.
- * Validator by
- * concatenating "Validator" to the fully qualified domain object classname
- * (eg "foo.bah.PersonValidator").
- * Validators registered in bean factory.
*
*
* @author Matthew E. Porter
@@ -65,115 +43,53 @@ public class ValidationRegistryManagerImpl implements ValidationRegistryManager,
BeanFactoryAware {
//~ Static fields/initializers =============================================
- private static final String VALIDATOR_SUFFIX = "Validator";
-
//~ Instance fields ========================================================
- private AutowireCapableBeanFactory acbf;
+ private ListableBeanFactory bf;
private Map validatorMap = new HashMap();
- private String[] validatorSearchPath;
//~ Methods ================================================================
public void setBeanFactory(BeanFactory beanFactory)
throws BeansException {
- Assert.isInstanceOf(AutowireCapableBeanFactory.class, beanFactory,
- "BeanFactory must be AutowireCapableBeanFactory");
- this.acbf = (AutowireCapableBeanFactory) beanFactory;
- }
-
- public void setValidatorSearchPath(String[] validatorSearchPath) {
- this.validatorSearchPath = validatorSearchPath;
- }
-
- public String[] getValidatorSearchPath() {
- return validatorSearchPath;
+ Assert.isInstanceOf(ListableBeanFactory.class, beanFactory,
+ "BeanFactory must be ListableBeanFactory");
+ this.bf = (ListableBeanFactory) beanFactory;
}
public Validator findValidator(Class domainClass) {
Assert.notNull(domainClass, "domainClass cannot be null");
- Class validatorClass = null;
- Validator validator = null;
-
- if (validatorMap.containsKey(domainClass)) {
- // already known to our Map
- validatorClass = (Class) validatorMap.get(domainClass);
- } else {
- validatorClass = this.findValidatorClass(domainClass.getName()
- + VALIDATOR_SUFFIX);
-
- if (validatorClass == null) {
- String suffix = "." + ClassUtils.getShortName(domainClass)
- + VALIDATOR_SUFFIX;
-
- if (validatorSearchPath != null) {
- for (int i = 0;
- (i < validatorSearchPath.length)
- && (validatorClass == null); i++) {
- validatorClass = this.findValidatorClass(validatorSearchPath[i]
- + suffix);
- }
- }
- }
-
- // if we found a Validator, register it so we speed up future retrieval
- if (validatorClass != null) {
- this.registerValidator(domainClass, validatorClass);
- }
- }
-
- // Attempt to create an instance of the Validator
- if (validatorClass != null) {
- validator = obtainWiredValidator(validatorClass);
- }
-
- return validator;
+ if (validatorMap.containsKey(domainClass)) {
+ if (validatorMap.get(domainClass) == null) {
+ return null;
+ }
+ return (Validator) this.bf.getBean((String)validatorMap.get(domainClass), Validator.class);
+ }
+
+ // Attempt to find Validator via introspection
+ Map beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, Validator.class, true, true);
+ Iterator iter = beans.keySet().iterator();
+ while (iter.hasNext()) {
+ String beanName = (String) iter.next();
+ Validator validator = (Validator) beans.get(beanName);
+ if (validator.supports(domainClass)) {
+ this.validatorMap.put(domainClass, beanName);
+ return validator;
+ }
+ }
+
+ // No Validator found
+ this.validatorMap.put(domainClass, null);
+ return null;
}
- public void registerValidator(Class domainClass, Class validatorClass) {
+ public void registerValidator(Class domainClass, String beanName) {
Assert.notNull(domainClass, "domainClass cannot be null");
- Assert.notNull(validatorClass, "validatorClass cannot be null");
- Assert.isTrue(Validator.class.isAssignableFrom(validatorClass),
- "validatorClass must be an implementation of Validator");
- this.validatorMap.put(domainClass, validatorClass);
- }
-
- /**
- * Builds a new instance of the Validator.
- *
- *
- * By default, the AutowireCapableBeanFactory is used to build
- * the instance, and autowire its bean properties. Specialised
- * applications may wish to customise this behaviour, such as searching
- * through the ApplicationContext for an existing singleton
- * instance. This method is protected to enable such customisation.
- *
Validator instance required
- *
- * @return the requested Validator, fully wired with all
- * dependencies, or null if the
- * Validator could not be found or created
- */
- protected Validator obtainWiredValidator(Class clazz) {
- try {
- return (Validator) this.acbf.autowire(clazz,
- AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
- } catch (BeansException autowireFailure) {
- return null;
- }
- }
-
- private Class findValidatorClass(String validatorClassName) {
- Class validatorClass = null;
-
- try {
- ClassLoader contextClassLoader = Thread.currentThread()
- .getContextClassLoader();
- validatorClass = Class.forName(validatorClassName);
- } catch (ClassNotFoundException e) {}
-
- return validatorClass;
+ Assert.notNull(beanName, "beanName cannot be null");
+ Assert.isTrue(this.bf.containsBean(beanName), "beanName not found in context");
+ Assert.isInstanceOf(Validator.class, this.bf.getBean(beanName), "beanName '" + beanName + "' must be a Validator");
+ Assert.isTrue(((Validator)this.bf.getBean(beanName)).supports(domainClass), "Validator does not support " + domainClass);
+ this.validatorMap.put(domainClass, beanName);
}
}