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

com.undefinedlabs.scope.deps.okhttp3.internal.platform.OptionalMethod Maven / Gradle / Ivy

Go to download

Scope is a APM for tests to give engineering teams unprecedented visibility into their CI process to quickly identify, troubleshoot and fix failed builds. This artifact contains dependencies for Scope.

There is a newer version: 0.14.0-beta.2
Show newest version
package com.undefinedlabs.scope.deps.okhttp3.internal.platform;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

class OptionalMethod {

    /** The return type of the method. null means "don't care". */
    private final Class returnType;

    private final String methodName;

    private final Class[] methodParams;

    /**
     * Creates an optional method.
     *
     * @param returnType the return type to required, null if it does not matter
     * @param methodName the name of the method
     * @param methodParams the method parameter types
     */
    OptionalMethod(Class returnType, String methodName, Class... methodParams) {
        this.returnType = returnType;
        this.methodName = methodName;
        this.methodParams = methodParams;
    }

    /**
     * Returns true if the method exists on the supplied {@code target}.
     */
    public boolean isSupported(T target) {
        return getMethod(target.getClass()) != null;
    }

    /**
     * Invokes the method on {@code target} with {@code args}. If the method does not exist or is not
     * public then {@code null} is returned. See also {@link #invokeOptionalWithoutCheckedException}.
     *
     * @throws IllegalArgumentException if the arguments are invalid
     * @throws InvocationTargetException if the invocation throws an exception
     */
    public Object invokeOptional(T target, Object... args) throws InvocationTargetException {
        Method m = getMethod(target.getClass());
        if (m == null) {
            return null;
        }
        try {
            return m.invoke(target, args);
        } catch (IllegalAccessException e) {
            return null;
        }
    }

    /**
     * Invokes the method on {@code target}.  If the method does not exist or is not public then
     * {@code null} is returned. Any RuntimeException thrown by the method is thrown, checked
     * exceptions are wrapped in an {@link AssertionError}.
     *
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public Object invokeOptionalWithoutCheckedException(T target, Object... args) {
        try {
            return invokeOptional(target, args);
        } catch (InvocationTargetException e) {
            Throwable targetException = e.getTargetException();
            if (targetException instanceof RuntimeException) {
                throw (RuntimeException) targetException;
            }
            AssertionError error = new AssertionError("Unexpected exception");
            error.initCause(targetException);
            throw error;
        }
    }

    /**
     * Invokes the method on {@code target} with {@code args}. Throws an error if the method is not
     * supported. See also {@link #invokeWithoutCheckedException(Object, Object...)}.
     *
     * @throws IllegalArgumentException if the arguments are invalid
     * @throws InvocationTargetException if the invocation throws an exception
     */
    public Object invoke(T target, Object... args) throws InvocationTargetException {
        Method m = getMethod(target.getClass());
        if (m == null) {
            throw new AssertionError("Method " + methodName + " not supported for object " + target);
        }
        try {
            return m.invoke(target, args);
        } catch (IllegalAccessException e) {
            // Method should be public: we checked.
            AssertionError error = new AssertionError("Unexpectedly could not call: " + m);
            error.initCause(e);
            throw error;
        }
    }

    /**
     * Invokes the method on {@code target}. Throws an error if the method is not supported. Any
     * RuntimeException thrown by the method is thrown, checked exceptions are wrapped in an {@link
     * AssertionError}.
     *
     * @throws IllegalArgumentException if the arguments are invalid
     */
    public Object invokeWithoutCheckedException(T target, Object... args) {
        try {
            return invoke(target, args);
        } catch (InvocationTargetException e) {
            Throwable targetException = e.getTargetException();
            if (targetException instanceof RuntimeException) {
                throw (RuntimeException) targetException;
            }
            AssertionError error = new AssertionError("Unexpected exception");
            error.initCause(targetException);
            throw error;
        }
    }

    /**
     * Perform a lookup for the method. No caching. In order to return a method the method name and
     * arguments must match those specified when the {@link OptionalMethod} was created. If the return
     * type is specified (i.e. non-null) it must also be compatible. The method must also be public.
     */
    private Method getMethod(Class clazz) {
        Method method = null;
        if (methodName != null) {
            method = getPublicMethod(clazz, methodName, methodParams);
            if (method != null
                    && returnType != null
                    && !returnType.isAssignableFrom(method.getReturnType())) {

                // If the return type is non-null it must be compatible.
                method = null;
            }
        }
        return method;
    }

    private static Method getPublicMethod(Class clazz, String methodName, Class[] parameterTypes) {
        Method method = null;
        try {
            method = clazz.getMethod(methodName, parameterTypes);
            if ((method.getModifiers() & Modifier.PUBLIC) == 0) {
                method = null;
            }
        } catch (NoSuchMethodException e) {
            // None.
        }
        return method;
    }
}






© 2015 - 2025 Weber Informatics LLC | Privacy Policy