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
25 Set<Field> fields = ReflectionUtils.getAllFields(instance.getClass());
26
27
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
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 }