mirror of
				https://github.com/spring-projects/spring-security.git
				synced 2025-10-30 22:28:46 +00:00 
			
		
		
		
	Handle multiple Validators.support()ing a given class.
This commit is contained in:
		
							parent
							
								
									307cd35b9c
								
							
						
					
					
						commit
						c1d156e363
					
				| @ -16,8 +16,10 @@ | |||||||
| package net.sf.acegisecurity.domain.validation; | package net.sf.acegisecurity.domain.validation; | ||||||
| 
 | 
 | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
|  | import java.util.HashSet; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
|  | import java.util.Set; | ||||||
| 
 | 
 | ||||||
| import org.springframework.beans.BeansException; | import org.springframework.beans.BeansException; | ||||||
| import org.springframework.beans.factory.BeanFactory; | import org.springframework.beans.factory.BeanFactory; | ||||||
| @ -35,6 +37,29 @@ import org.springframework.validation.Validator; | |||||||
|  * Locates <code>Validator</code>s registered in bean factory. |  * Locates <code>Validator</code>s registered in bean factory. | ||||||
|  * </p> |  * </p> | ||||||
|  *  |  *  | ||||||
|  |  * <p>If more than one <code>Validator</code> can support a given object, the | ||||||
|  |  * supporting <code>Validator</code>s will be iterated and their bean factory | ||||||
|  |  * defined bean names will be used to attempt to select the "best matching" | ||||||
|  |  * <code>Validator</code>. The lowercase version of a given object's simplified | ||||||
|  |  * class name will be searched within the bean names. If more than one | ||||||
|  |  * <code>Validator</code> contains this search criteria, an exception will be | ||||||
|  |  * thrown as the actual intended <code>Validator</code> is unidentifiable. | ||||||
|  |  *  | ||||||
|  |  * <p>For example, say you had a PartyValidator which could validate | ||||||
|  |  * com.foo.Party, and also its subclass, com.foo.Person. There is also a | ||||||
|  |  * PersonValidator which can only validate Person. PartyValidator and | ||||||
|  |  * PersonValidator are registered in the bean container as "partyValidator" | ||||||
|  |  * and "personValidator". When <code>ValidationRegistryManagerImpl</code> | ||||||
|  |  * is asked to return the <code>Validator</code> for Person, it will locate | ||||||
|  |  * the two matching <code>Validator</code>s in the bean container. As there | ||||||
|  |  * are two matching, it will look at the lowercase representation of the | ||||||
|  |  * bean names and see if either contain the lower simplified class name of | ||||||
|  |  * the object being search for (com.foo.Person thus becomes simply "person"). | ||||||
|  |  * <code>ValidationRegistryManagerImpl</code> will then correctly return the | ||||||
|  |  * PersonValidator for Person. If the PartyValidator had been registered with | ||||||
|  |  * an ambiguous bean name of say "personAndPartyValidator", both bean names | ||||||
|  |  * would have matched and an exception would have been thrown. | ||||||
|  |  * | ||||||
|  * @author Matthew E. Porter |  * @author Matthew E. Porter | ||||||
|  * @author Ben Alex |  * @author Ben Alex | ||||||
|  * @version $Id$ |  * @version $Id$ | ||||||
| @ -69,19 +94,45 @@ public class ValidationRegistryManagerImpl implements ValidationRegistryManager, | |||||||
| 		 | 		 | ||||||
| 		// Attempt to find Validator via introspection | 		// Attempt to find Validator via introspection | ||||||
| 		Map<String,Validator> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, Validator.class, true, true); | 		Map<String,Validator> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(bf, Validator.class, true, true); | ||||||
|  | 		 | ||||||
|  | 		// Search all Validators for those that support the class | ||||||
|  | 		Set<String> candidateValidatorNames = new HashSet<String>(); | ||||||
| 		Iterator<String> iter = beans.keySet().iterator(); | 		Iterator<String> iter = beans.keySet().iterator(); | ||||||
| 		while (iter.hasNext()) { | 		while (iter.hasNext()) { | ||||||
| 			String beanName = iter.next(); | 			String beanName = iter.next(); | ||||||
| 			Validator validator = beans.get(beanName); | 			Validator validator = beans.get(beanName); | ||||||
| 			if (validator.supports(domainClass)) { | 			if (validator.supports(domainClass)) { | ||||||
| 				this.validatorMap.put(domainClass, beanName); | 				candidateValidatorNames.add(beanName); | ||||||
| 				return validator; |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
|  | 		if (candidateValidatorNames.size() == 0) { | ||||||
| 			// No Validator found | 			// No Validator found | ||||||
| 			this.validatorMap.put(domainClass, null); | 			this.validatorMap.put(domainClass, null); | ||||||
| 			return null; | 			return null; | ||||||
|  | 		} else if (candidateValidatorNames.size() == 1) { | ||||||
|  | 			// Only one Validator found, so return it | ||||||
|  | 			String validator = candidateValidatorNames.iterator().next(); | ||||||
|  | 			this.validatorMap.put(domainClass, validator); | ||||||
|  | 			return beans.get(validator); | ||||||
|  | 		} else { | ||||||
|  | 			// Try to locate an entry with simple class name in it | ||||||
|  | 			Iterator<String> iterCandidates = candidateValidatorNames.iterator(); | ||||||
|  | 			String lastFound = null; | ||||||
|  | 			int numberFound = 0; | ||||||
|  | 			while (iterCandidates.hasNext()) { | ||||||
|  | 				String candidate = iterCandidates.next(); | ||||||
|  | 				if (candidate.toLowerCase().contains(domainClass.getSimpleName().toLowerCase())) { | ||||||
|  | 					numberFound++; | ||||||
|  | 					lastFound = candidate; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 			if (numberFound != 1) { | ||||||
|  | 				throw new IllegalArgumentException("More than one Validator found that supports '" + domainClass + "' and cannot determine most specific Validator to use; give a hint by making bean name include the simple name of the target class"); | ||||||
|  | 			} | ||||||
|  | 			this.validatorMap.put(domainClass, lastFound); | ||||||
|  | 			return beans.get(lastFound); | ||||||
|  | 		} | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void registerValidator(Class domainClass, String beanName) { |     public void registerValidator(Class domainClass, String beanName) { | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user