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: - * - *

    - *
  1. - * First, the {@link #registerValidator(Class, Class)} method allows a - * Validator to be expressly registered for a given domain object - * class. - *
  2. - *
  3. - * Second, an attempt will be made to find the Validator by - * concatenating "Validator" to the fully qualified domain object classname - * (eg "foo.bah.PersonValidator"). - *
  4. - *
  5. - * Third, it takes the domain object's simple classname (without the package - * name), adds "Validator" to it, then looks in the {@link - * #validatorSearchPath} for the validator. - *
  6. - *
+ * Locates 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. - *

- * - * @param clazz the represents the 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); } }