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 }