001    package org.junit.validator;
002    
003    import java.util.concurrent.ConcurrentHashMap;
004    
005    /**
006     * Creates instances of Annotation Validators.
007     *
008     * @since 4.12
009     */
010    public class AnnotationValidatorFactory {
011        private static final ConcurrentHashMap<ValidateWith, AnnotationValidator> VALIDATORS_FOR_ANNOTATION_TYPES =
012                new ConcurrentHashMap<ValidateWith, AnnotationValidator>();
013    
014        /**
015         * Creates the AnnotationValidator specified by the value in
016         * {@link org.junit.validator.ValidateWith}. Instances are
017         * cached.
018         *
019         * @return An instance of the AnnotationValidator.
020         *
021         * @since 4.12
022         */
023        public AnnotationValidator createAnnotationValidator(ValidateWith validateWithAnnotation) {
024            AnnotationValidator validator = VALIDATORS_FOR_ANNOTATION_TYPES.get(validateWithAnnotation);
025            if (validator != null) {
026                return validator;
027            }
028    
029            Class<? extends AnnotationValidator> clazz = validateWithAnnotation.value();
030            if (clazz == null) {
031                throw new IllegalArgumentException("Can't create validator, value is null in annotation " + validateWithAnnotation.getClass().getName());
032            }
033            try {
034                AnnotationValidator annotationValidator = clazz.newInstance();
035                VALIDATORS_FOR_ANNOTATION_TYPES.putIfAbsent(validateWithAnnotation, annotationValidator);
036                return VALIDATORS_FOR_ANNOTATION_TYPES.get(validateWithAnnotation);
037            } catch (Exception e) {
038                throw new RuntimeException("Exception received when creating AnnotationValidator class " + clazz.getName(), e);
039            }
040        }
041    
042    }