/* GENERATED SOURCE. DO NOT MODIFY. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.okhttp.internal; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; /** * Duck-typing for methods: Represents a method that may or may not be present on an object. * * @param the type of the object the method might be on, typically an interface or base class */ 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 */ public 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(Object, Object...)}. * * @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; } }