/** * Finds method that accessible from specified class. * * @param method object that represents found method * @param generic generic type that is used to find accessible method * @return object that represents accessible method * @throws NoSuchMethodException if method is not accessible or is not found in specified * superclass or interface */ private static Method findAccessibleMethod(Method method, Type generic) throws NoSuchMethodException { String name = method.getName(); Class<?>[] params = method.getParameterTypes(); if (generic instanceof Class) { Class<?> type = (Class<?>) generic; return findAccessibleMethod(type.getMethod(name, params)); } if (generic instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) generic; Class<?> type = (Class<?>) pt.getRawType(); for (Method m : type.getMethods()) { if (m.getName().equals(name)) { Class<?>[] pts = m.getParameterTypes(); if (pts.length == params.length) { if (Arrays.equals(params, pts)) { return findAccessibleMethod(m); } Type[] gpts = m.getGenericParameterTypes(); if (params.length == gpts.length) { if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) { return findAccessibleMethod(m); } } } } } } throw new NoSuchMethodException("Method '" + name + "' is not accessible"); }
/** * Finds method that is accessible from public class or interface through class hierarchy. * * @param method object that represents found method * @return object that represents accessible method * @throws NoSuchMethodException if method is not accessible or is not found in specified * superclass or interface */ public static Method findAccessibleMethod(Method method) throws NoSuchMethodException { Class<?> type = method.getDeclaringClass(); if (Modifier.isPublic(type.getModifiers()) && isPackageAccessible(type)) { return method; } if (Modifier.isStatic(method.getModifiers())) { throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible"); } for (Type generic : type.getGenericInterfaces()) { try { return findAccessibleMethod(method, generic); } catch (NoSuchMethodException exception) { // try to find in superclass or another interface } } return findAccessibleMethod(method, type.getGenericSuperclass()); }
/** * Checks validness of the method. The valid method should be public and should have the specified * name. * * @param method the object that represents method * @return {@code true} if the method is valid, {@code false} otherwise */ @Override protected boolean isValid(Method method) { return super.isValid(method) && method.getName().equals(this.name); }