private Class<?> findShadowClass(Class<?> originalClass) { String declaredShadowClassName = getShadowClassName(originalClass); if (declaredShadowClassName == null) { return null; } return loadClass(declaredShadowClassName, classLoader); }
private Class<?>[] getParamClasses() { Class<?>[] paramClasses = new Class<?>[paramTypes.length]; for (int i = 0; i < paramTypes.length; i++) { paramClasses[i] = loadClass(paramTypes[i], classLoader); } return paramClasses; }
public Object shadowFor(Object instance) { Field field = getShadowField(instance); Object shadow = readField(instance, field); if (shadow != null) { return shadow; } String shadowClassName = getShadowClassName(instance.getClass()); if (debug) System.out.println("creating new " + shadowClassName + " as shadow for " + instance.getClass().getName()); try { Class<?> shadowClass = loadClass(shadowClassName, instance.getClass().getClassLoader()); Constructor<?> constructor = findConstructor(instance, shadowClass); if (constructor != null) { shadow = constructor.newInstance(instance); } else { shadow = shadowClass.newInstance(); } field.set(instance, shadow); injectRealObjectOn(shadow, shadowClass, instance); return shadow; } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } }
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; }