View Javadoc
1   package org.kuali.common.util.validate;
2   
3   import java.lang.reflect.Field;
4   import java.util.HashSet;
5   import java.util.Set;
6   
7   import javax.validation.ConstraintValidator;
8   import javax.validation.ConstraintValidatorContext;
9   
10  import org.kuali.common.util.ReflectionUtils;
11  
12  import com.google.common.collect.HashMultiset;
13  import com.google.common.collect.Multiset;
14  
15  public class UniqueFieldNamesValidator implements ConstraintValidator<UniqueFieldNames, Object> {
16  
17  	@Override
18  	public void initialize(UniqueFieldNames constraintAnnotation) {
19  	}
20  
21  	@Override
22  	public boolean isValid(Object instance, ConstraintValidatorContext constraintContext) {
23  
24  		// Extract every field in the type hierarchy
25  		Set<Field> fields = ReflectionUtils.getAllFields(instance.getClass());
26  
27  		// These field names are duplicated
28  		Set<String> duplicates = getDuplicateFieldNames(fields);
29  
30  		if (duplicates.size() == 0) {
31  			return true;
32  		} else {
33  			constraintContext.disableDefaultConstraintViolation();
34  			String path = ReflectionUtils.getDeclarationPath(instance.getClass());
35  			for (String duplicate : duplicates) {
36  				String error = "Duplicate field declaration: In type [" + path + "] the field [" + duplicate + "] appears more than once in the type hierarchy";
37  				constraintContext.buildConstraintViolationWithTemplate(error).addConstraintViolation();
38  			}
39  			return false;
40  		}
41  	}
42  
43  	protected Set<String> getDuplicateFieldNames(Set<Field> fields) {
44  		// Keep track of field name counts
45  		Multiset<String> multiset = HashMultiset.create();
46  		for (Field field : fields) {
47  			multiset.add(field.getName());
48  		}
49  
50  		Set<String> duplicates = new HashSet<String>();
51  		for (String fieldName : multiset) {
52  			int count = multiset.count(fieldName);
53  			if (count > 1) {
54  				duplicates.add(fieldName);
55  			}
56  		}
57  		return duplicates;
58  	}
59  }