AfterBurner { public void addOrInsertMethod(InsertableMethod insertableMethod) throws CannotCompileException, AfterBurnerImpossibleException { log.info("InsertableMethod : " + insertableMethod); String targetMethodName = insertableMethod.getTargetMethodName(); CtClass classToTransform = insertableMethod.getClassToInsertInto(); CtMethod targetMethod = extractExistingMethod(classToTransform, targetMethodName); log.info("Method : " + targetMethod); if (targetMethod != null) { InsertableMethodInjectorEditor injectorEditor = new InsertableMethodInjectorEditor( classToTransform, insertableMethod); targetMethod.instrument(injectorEditor); if (!injectorEditor.isSuccessful) { throw new CannotCompileException("Transformation failed. Insertion method not found.: " + targetMethodName); } } else { classToTransform.addMethod(CtNewMethod.make( insertableMethod.getFullMethod(), classToTransform)); } } AfterBurner(); void addOrInsertMethod(InsertableMethod insertableMethod); void beforeOverrideMethod(CtClass targetClass, String targetMethodName, String body); void afterOverrideMethod(CtClass targetClass, String targetMethodName, String body); void insertConstructor(InsertableConstructor insertableConstructor); CtMethod extractExistingMethod(final CtClass classToTransform,
            String methodName); boolean checkIfMethodIsInvoked(CtMethod withinMethod,
        String invokedMethod);  }
@Test public void testAddMethod() throws Exception { InsertableMethod insertableMethod = new SimpleInsertableMethod(target, "foo", null, null, null, "public boolean foo() { return true; }"); afterBurner.addOrInsertMethod(insertableMethod); targetClass = target.toClass(); targetInstance = targetClass.newInstance(); assertHasFooMethodWithReturnValue(target, true); }
@Test public void testInsertMethod_after() throws Exception { target.addMethod(CtNewMethod.make("public void bar() { }", target)); target.addMethod(CtNewMethod.make("public boolean foo() { bar(); return false; }", target)); target.addField(new CtField(CtClass.intType, "foo", target)); InsertableMethod insertableMethod = new SimpleInsertableMethod(target, "foo", null, "bar", "foo = 2;", null ); afterBurner.addOrInsertMethod(insertableMethod); targetClass = target.toClass(); targetInstance = targetClass.newInstance(); assertHasFooMethodWithReturnValue(target, false); assertHasFooFieldWithValue(target, 2); }
@Test public void testInsertMethod_before() throws Exception { target.addMethod(CtNewMethod.make("public void bar() { }", target)); target.addMethod(CtNewMethod.make("public boolean foo() { bar(); return false; }", target)); target.addField(new CtField(CtClass.intType, "foo", target)); InsertableMethod insertableMethod = new SimpleInsertableMethod(target, "foo", "bar", null, "foo = 2;", null); afterBurner.addOrInsertMethod(insertableMethod); targetClass = target.toClass(); targetInstance = targetClass.newInstance(); assertHasFooMethodWithReturnValue(target, false); assertHasFooFieldWithValue(target, 2); }
@Test(expected=AfterBurnerImpossibleException.class) public void testInsertMethod_not_before_not_after() throws Exception { target.addMethod(CtNewMethod.make("public void bar() { }", target)); target.addMethod(CtNewMethod.make("public boolean foo() { bar(); return false; }", target)); target.addField(new CtField(CtClass.intType, "foo", target)); InsertableMethod insertableMethod = new SimpleInsertableMethod(target, "foo", null, null, "foo = 2;", null); afterBurner.addOrInsertMethod(insertableMethod); fail(); }