001package org.junit.validator;
002
003import java.util.concurrent.ConcurrentHashMap;
004
005/**
006 * Creates instances of Annotation Validators.
007 *
008 * @since 4.12
009 */
010public 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}