All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.envoyproxy.pgv.ReflectiveValidatorIndex Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
package io.envoyproxy.pgv;

import java.sql.Ref;
import java.util.concurrent.ConcurrentHashMap;

/**
 * {@code ReflectiveValidatorIndex} uses reflection to discover {@link Validator} implementations lazily the first
 * time a type is validated. If no validator can be found for {@code type}, a fallback validator
 * will be used (default ALWAYS_VALID).
 */
public final class ReflectiveValidatorIndex implements ValidatorIndex {
    private final ConcurrentHashMap VALIDATOR_INDEX = new ConcurrentHashMap<>();
    private final ValidatorIndex fallbackIndex;

    public ReflectiveValidatorIndex() {
        this(ValidatorIndex.ALWAYS_VALID);
    }

    /**
     * @param fallbackIndex a {@link ValidatorIndex} implementation to use if reflective validator discovery fails.
     */
    public ReflectiveValidatorIndex(ValidatorIndex fallbackIndex) {
        this.fallbackIndex = fallbackIndex;
    }

    /**
     * Returns the validator for {@code }, or {@code ALWAYS_VALID} if not found.
     */
    @Override
    @SuppressWarnings("unchecked")
    public  Validator validatorFor(Class clazz) {
        return VALIDATOR_INDEX.computeIfAbsent(clazz, c -> {
            try {
                return reflectiveValidatorFor(c);
            } catch (ReflectiveOperationException ex) {
                return fallbackIndex.validatorFor(clazz);
            }
        });
    }

    @SuppressWarnings("unchecked")
    private Validator reflectiveValidatorFor(Class clazz) throws ReflectiveOperationException {
        Class enclosingClass = clazz;
        while (enclosingClass.getEnclosingClass() != null) {
            enclosingClass = enclosingClass.getEnclosingClass();
        }

        String validatorClassName = enclosingClass.getName() + "Validator";
        Class validatorClass = clazz.getClassLoader().loadClass(validatorClassName);
        ValidatorImpl impl = (ValidatorImpl) validatorClass.getDeclaredMethod("validatorFor", Class.class).invoke(null, clazz);

        return proto -> impl.assertValid(proto, ReflectiveValidatorIndex.this);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy