public boolean prepare() { Class<?>[] paramClasses = getParamClasses(); Class<?> originalClass = loadClass(clazz.getName(), classLoader); declaredShadowClass = findDeclaredShadowClassForMethod(originalClass, methodName, paramClasses); if (declaredShadowClass == null) { return false; } if (methodName.equals("<init>")) { methodName = "__constructor__"; } if (instance != null) { shadow = shadowFor(instance); method = getMethod(shadow.getClass(), methodName, paramClasses); } else { shadow = null; method = getMethod(findShadowClass(clazz), methodName, paramClasses); } if (method == null) { if (debug) { System.out.println("No method found for " + clazz + "." + methodName + "(" + Arrays.asList(paramClasses) + ") on " + declaredShadowClass.getName()); } return false; } if ((instance == null) != Modifier.isStatic(method.getModifiers())) { throw new RuntimeException("method staticness of " + clazz.getName() + "." + methodName + " and " + declaredShadowClass.getName() + "." + method.getName() + " don't match"); } method.setAccessible(true); return true; }
private Method getMethod(Class<?> clazz, String methodName, Class<?>[] paramClasses) { Method method = null; try { method = clazz.getMethod(methodName, paramClasses); } catch (NoSuchMethodException e) { try { method = clazz.getDeclaredMethod(methodName, paramClasses); } catch (NoSuchMethodException e1) { method = null; } } if (method != null && !isOnShadowClass(method)) { method = null; } return method; }
@Override public Object methodInvoked(Class clazz, String methodName, Object instance, String[] paramTypes, Object[] params) throws Throwable { InvocationPlan invocationPlan = new InvocationPlan(clazz, methodName, instance, paramTypes); if (!invocationPlan.prepare()) { reportNoShadowMethodFound(clazz, methodName, paramTypes); return null; } if (strictI18n && !invocationPlan.isI18nSafe()) { throw new I18nException("Method " + methodName + " on class " + clazz.getName() + " is not i18n-safe."); } try { return invocationPlan.getMethod().invoke(invocationPlan.getShadow(), params); } catch (IllegalArgumentException e) { throw new RuntimeException(invocationPlan.getShadow().getClass().getName() + " is not assignable from " + invocationPlan.getDeclaredShadowClass().getName(), e); } catch (InvocationTargetException e) { throw stripStackTrace(e.getCause()); } }
private Class<?> findDeclaredShadowClassForMethod(Class<?> originalClass, String methodName, Class<?>[] paramClasses) { Class<?> declaringClass = findDeclaringClassForMethod(methodName, paramClasses, originalClass); return findShadowClass(declaringClass); }