View Javadoc
1   package org.kuali.common.util.validate.hibernate.factory;
2   
3   import java.lang.annotation.Annotation;
4   import java.lang.reflect.Field;
5   import java.util.List;
6   import java.util.Map;
7   
8   import org.hibernate.validator.cfg.ConstraintDef;
9   import org.kuali.common.util.ReflectionUtils;
10  
11  import com.google.common.base.Preconditions;
12  import com.google.common.collect.ImmutableMap;
13  import com.google.common.collect.Lists;
14  import com.google.common.collect.Maps;
15  
16  public final class DefaultConstraintDefService implements ConstraintDefService {
17  
18  	private final Map<Class<? extends Annotation>, ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> factories;
19  
20  	private DefaultConstraintDefService(Builder builder) {
21  		this.factories = builder.factories;
22  	}
23  
24  	@Override
25  	public boolean supports(Class<? extends Annotation> annotationType) {
26  		Preconditions.checkNotNull(annotationType, "'annotationType' cannot be null");
27  		return factories.containsKey(annotationType);
28  	}
29  
30  	@Override
31  	public ConstraintDef<?, ?> getConstraintDef(Field annotatedField, Class<? extends Annotation> annotationType) {
32  		Preconditions.checkNotNull(annotatedField, "'annotatedField' cannot be null");
33  		Preconditions.checkNotNull(annotationType, "'annotationType' cannot be null");
34  		Preconditions.checkState(supports(annotationType), "[" + annotationType.getCanonicalName() + "] is not supported");
35  		ConstraintDefFactory<?, ?> factory = factories.get(annotationType);
36  		return factory.getConstraintDef(annotatedField);
37  	}
38  
39  	@Override
40  	public ConstraintDef<?, ?> getConstraintDef(Class<?> annotatedClass, Class<? extends Annotation> annotationType) {
41  		Preconditions.checkNotNull(annotatedClass, "'annotatedClass' cannot be null");
42  		Preconditions.checkNotNull(annotationType, "'annotationType' cannot be null");
43  		Preconditions.checkState(supports(annotationType), "[" + annotationType.getCanonicalName() + "] is not supported");
44  		ConstraintDefFactory<?, ?> factory = factories.get(annotationType);
45  		return factory.getConstraintDef(annotatedClass);
46  	}
47  
48  	public static Builder builder() {
49  		return new Builder();
50  	}
51  
52  	public static class Builder implements org.kuali.common.util.builder.Builder<DefaultConstraintDefService> {
53  
54  		private Map<Class<? extends Annotation>, ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> factories = getDefaultMappings();
55  
56  		private static Map<Class<? extends Annotation>, ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> getDefaultMappings() {
57  			List<ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> list = Lists.newArrayList();
58  			list.add(new AssertFalseDefFactory());
59  			list.add(new AssertTrueDefFactory());
60  			list.add(new CreditCardNumberDefFactory());
61  			list.add(new BulletProofPojoDefFactory());
62  			list.add(new BulletProofBuilderDefFactory());
63  			list.add(new ValidPortDefFactory());
64  			list.add(new DecimalMaxDefFactory());
65  			list.add(new DecimalMinDefFactory());
66  			list.add(new SizeDefFactory());
67  			list.add(new MinDefFactory());
68  			Map<Class<? extends Annotation>, ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> factories = Maps.newHashMap();
69  			for (ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?> element : list) {
70  				factories.put(element.getAnnotationType(), element);
71  			}
72  			return factories;
73  		}
74  
75  		public Builder factories(Map<Class<? extends Annotation>, ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> factories) {
76  			this.factories = factories;
77  			return this;
78  		}
79  
80  		public Builder register(ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?> factory) {
81  			factories.put(factory.getAnnotationType(), factory);
82  			return this;
83  		}
84  
85  		@Override
86  		public DefaultConstraintDefService build() {
87  			this.factories = ImmutableMap.copyOf(factories);
88  			DefaultConstraintDefService instance = new DefaultConstraintDefService(this);
89  			validate(instance);
90  			return instance;
91  		}
92  
93  		private void validate(DefaultConstraintDefService instance) {
94  			Preconditions.checkNotNull(instance.getFactories(), "'factories' cannot be null");
95  			Class<?> mapClass = instance.getFactories().getClass();
96  			boolean immutable = ReflectionUtils.isImmutableGuavaMap(mapClass);
97  			Preconditions.checkArgument(immutable, "[%s] is not an immutable Guava map", mapClass.getCanonicalName());
98  		}
99  	}
100 
101 	public Map<Class<? extends Annotation>, ConstraintDefFactory<? extends ConstraintDef<?, ?>, ?>> getFactories() {
102 		return factories;
103 	}
104 
105 }