/**************************************************************************************
* Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved. *
* http://aspectwerkz.codehaus.org *
* ---------------------------------------------------------------------------------- *
* The software in this package is published under the terms of the LGPL license *
* a copy of which has been included with this distribution in the license.txt file. *
**************************************************************************************/
package test.thistarget;
import org.codehaus.aspectwerkz.definition.Pointcut;
import org.codehaus.aspectwerkz.definition.Pointcut;
import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
import junit.framework.TestCase;
/**
* @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
*/
public class ThisTargetAspect {
//------------------------- Method execution
/**
* @Expression execution(* test.thistarget.*.target())
*/
Pointcut exe_target;
/**
* @Expression execution(* test.thistarget.*.targetAbstract())
*/
Pointcut exe_targetAbstract;
// interface
/**
* @Before exe_target && target(t)
*/
public void beforeITarget(ITarget t) {
validate(t, ITarget.class);
TargetTest.log("before_ITarget");
}
/**
* @Around exe_target && target(t)
*/
public Object aroundITarget(JoinPoint jp, ITarget t) throws Throwable {
validate(t, ITarget.class);
TargetTest.log("pre_ITarget");
Object o = jp.proceed();
TargetTest.log("post_ITarget");
return o;
}
/**
* @After exe_target && target(t)
*/
public void afterITarget(ITarget t) {
validate(t, ITarget.class);
TargetTest.log("after_ITarget");
}
// interface implementation
/**
* @Before exe_target && target(t) && this(callee)
*/
public void beforeTargetIWithThis(TargetI t, Object callee) {
validate(t, TargetI.class);
validate(callee, TargetI.class);
TargetTest.log("before_TargetI");
}
/**
* @Around exe_target && target(t)
*/
public Object aroundTargetI(JoinPoint jp, TargetI t) throws Throwable {
validate(t, TargetI.class);
TargetTest.log("pre_TargetI");
Object o = jp.proceed();
TargetTest.log("post_TargetI");
return o;
}
/**
* @After exe_target && target(t)
*/
public void afterTargetI(TargetI t) {
validate(t, TargetI.class);
TargetTest.log("after_TargetI");
}
// super class
/**
* @Before exe_target && target(t)
*/
public void beforeSuperTarget(SuperTarget t) {
validate(t, SuperTarget.class);
TargetTest.log("before_SuperTarget");
}
/**
* @Around exe_target && target(t)
*/
public Object aroundSuperTarget(JoinPoint jp, SuperTarget t) throws Throwable {
validate(t, SuperTarget.class);
TargetTest.log("pre_SuperTarget");
Object o = jp.proceed();
TargetTest.log("post_SuperTarget");
return o;
}
/**
* @After exe_target && target(t)
*/
public void afterSuperTarget(SuperTarget t) {
validate(t, SuperTarget.class);
TargetTest.log("after_SuperTarget");
}
// super class abstract method
/**
* @Before exe_targetAbstract && target(t)
*/
public void beforeSuperTargetA(SuperTarget t) {
validate(t, SuperTarget.class);
TargetTest.log("before_SuperTargetA");
}
/**
* @Around exe_targetAbstract && target(t)
*/
public Object aroundSuperTargetA(JoinPoint jp, SuperTarget t) throws Throwable {
validate(t, SuperTarget.class);
TargetTest.log("pre_SuperTargetA");
Object o = jp.proceed();
TargetTest.log("post_SuperTargetA");
return o;
}
/**
* @After exe_targetAbstract && target(t)
*/
public void afterSuperTargetA(SuperTarget t) {
validate(t, SuperTarget.class);
TargetTest.log("after_SuperTargetA");
}
//------------------------- Ctor call
/**
* @Expression this(caller) && call(test.thistarget.*.new()) && withincode(* test.*.*.testConstructorCallTargetThis(..))
*/
Pointcut cctor_this(TargetTest caller) {
return null;
}
// interface
/**
* @Before cctor_this(caller) && target(t)
*/
public void beforeITarget(ITarget t, Object caller) {
validate(t, null);
validate(caller, TargetTest.class);
TargetTest.log("before_ITarget");
}
/**
* @Around cctor_this(caller) && target(t)
*/
public Object aroundITarget(JoinPoint jp, ITarget t, Object caller) throws Throwable {
validate(t, null);
validate(caller, TargetTest.class);
TargetTest.log("pre_ITarget");
Object o = jp.proceed();
validate(o, ITarget.class);
validate(t, null);// in an around advice, target is a local variable so even if jp has set callee, the local
// instance is not.
TargetTest.log("post_ITarget");
return o;
}
/**
* @After cctor_this(caller) && target(t)
*/
public void afterITarget(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, TargetTest.class);
TargetTest.log("after_ITarget");
}
// interface implementation
/**
* @Before cctor_this(caller) && target(t)
*/
public void beforeTargetI(TargetI t, Object caller) {
validate(t, null);
validate(caller, TargetTest.class);
TargetTest.log("before_TargetI");
}
/**
* @Around cctor_this(caller) && target(t)
*/
public Object aroundTargetI(JoinPoint jp, TargetI t, Object caller) throws Throwable {
validate(t, null);
validate(caller, TargetTest.class);
TargetTest.log("pre_TargetI");
Object o = jp.proceed();
validate(o, TargetI.class);
validate(t, null);// still null
TargetTest.log("post_TargetI");
return o;
}
/**
* @After cctor_this(caller) && target(t)
*/
public void afterTargetI(TargetI t, Object caller) {
validate(t, TargetI.class);
validate(caller, TargetTest.class);
TargetTest.log("after_TargetI");
}
// super class
/**
* @Before cctor_this(caller) && target(t)
*/
public void beforeSuperTarget(SuperTarget t, Object caller) {
validate(t, null);
validate(caller, TargetTest.class);
TargetTest.log("before_SuperTarget");
}
/**
* @Around cctor_this(caller) && target(t)
*/
public Object aroundSuperTarget(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
validate(t, null);
validate(caller, TargetTest.class);
TargetTest.log("pre_SuperTarget");
Object o = jp.proceed();
validate(o, SuperTarget.class);
validate(t, null);//still null - local variable
TargetTest.log("post_SuperTarget");
return o;
}
/**
* @After cctor_this(caller) && target(t)
*/
public void afterSuperTarget(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("after_SuperTarget");
}
//------------------------- Method call
/**
* @Expression this(caller) && call(* test.thistarget.*.call()) && withincode(* test.*.*.testMethodCallTargetThis(..))
*/
Pointcut call_this(TargetTest caller) {
return null;
}
/**
* @Expression this(caller) && call(* test.thistarget.*.callAbstract()) && withincode(* test.*.*.testMethodCallTargetThis(..))
*/
Pointcut callAbstract_this(TargetTest caller) {
return null;
}
// interface
/**
* @Before call_this(caller) && target(t)
*/
public void beforeICall(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, TargetTest.class);
TargetTest.log("before_ITarget");
}
/**
* @Around call_this(caller) && target(t)
*/
public Object aroundICall(JoinPoint jp, ITarget t, Object caller) throws Throwable {
validate(t, ITarget.class);
validate(caller, TargetTest.class);
TargetTest.log("pre_ITarget");
Object o = jp.proceed();
validate(t, ITarget.class);
// instance is not.
TargetTest.log("post_ITarget");
return o;
}
/**
* @After call_this(caller) && target(t)
*/
public void afterICall(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, TargetTest.class);
TargetTest.log("after_ITarget");
}
// interface implementation
/**
* @Before call_this(caller) && target(t)
*/
public void beforeCallI(TargetI t, Object caller) {
validate(t, TargetI.class);
validate(caller, TargetTest.class);
TargetTest.log("before_TargetI");
}
/**
* @Around call_this(caller) && target(t)
*/
public Object aroundCallI(JoinPoint jp, TargetI t, Object caller) throws Throwable {
validate(t, TargetI.class);
validate(caller, TargetTest.class);
TargetTest.log("pre_TargetI");
Object o = jp.proceed();
validate(t, TargetI.class);
TargetTest.log("post_TargetI");
return o;
}
/**
* @After call_this(caller) && target(t)
*/
public void afterCallI(TargetI t, Object caller) {
validate(t, TargetI.class);
validate(caller, TargetTest.class);
TargetTest.log("after_TargetI");
}
// super class
/**
* @Before call_this(caller) && target(t)
*/
public void beforeSuperCall(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("before_SuperTarget");
}
/**
* @Around call_this(caller) && target(t)
*/
public Object aroundSuperCall(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("pre_SuperTarget");
Object o = jp.proceed();
validate(t, SuperTarget.class);
TargetTest.log("post_SuperTarget");
return o;
}
/**
* @After call_this(caller) && target(t)
*/
public void afterSuperCall(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("after_SuperTarget");
}
// super class - abstract method
/**
* @Before callAbstract_this(caller) && target(t)
*/
public void beforeSuperCallA(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("before_SuperTargetA");
}
/**
* @Around callAbstract_this(caller) && target(t)
*/
public Object aroundSuperCallA(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("pre_SuperTargetA");
Object o = jp.proceed();
validate(t, SuperTarget.class);
TargetTest.log("post_SuperTargetA");
return o;
}
/**
* @After callAbstract_this(caller) && target(t)
*/
public void afterSuperCallA(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, TargetTest.class);
TargetTest.log("after_SuperTargetA");
}
//------------------------- Ctor exe
/**
* @Expression this(self) && execution(test.thistarget.*.new())
*/
Pointcut ector_this(Object self) {
return null;
}
// interface
/**
* @Before ector_this(caller) && target(t)
*/
public void ector_beforeITarget(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, ITarget.class);
TargetTest.logCtorExe("before_ITarget");
}
/**
* @Around ector_this(caller) && target(t)
*/
public Object ector_aroundITarget(JoinPoint jp, ITarget t, Object caller) throws Throwable {
validate(t, ITarget.class);
validate(caller, ITarget.class);
TargetTest.logCtorExe("pre_ITarget");
Object o = jp.proceed();
//validate(o, ITarget.class);
validate(t, ITarget.class);
// instance is not.
TargetTest.logCtorExe("post_ITarget");
return o;
}
/**
* @After ector_this(caller) && target(t)
*/
public void ector_afterITarget(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, ITarget.class);
TargetTest.logCtorExe("after_ITarget");
}
// interface implementation
/**
* @Before ector_this(caller) && target(t)
*/
public void ector_beforeTargetI(TargetI t, Object caller) {
validate(t, TargetI.class);
validate(caller, TargetI.class);
TargetTest.logCtorExe("before_TargetI");
}
/**
* @Around ector_this(caller) && target(t)
*/
public Object ector_aroundTargetI(JoinPoint jp, TargetI t, Object caller) throws Throwable {
validate(t, TargetI.class);
validate(caller, TargetI.class);
TargetTest.logCtorExe("pre_TargetI");
Object o = jp.proceed();
//validate(o, TargetI.class);
validate(t, TargetI.class);
TargetTest.logCtorExe("post_TargetI");
return o;
}
/**
* @After ector_this(caller) && target(t)
*/
public void ector_afterTargetI(TargetI t, Object caller) {
validate(t, TargetI.class);
validate(caller, TargetI.class);
TargetTest.logCtorExe("after_TargetI");
}
// super class
/**
* @Before ector_this(caller) && target(t)
*/
public void ector_beforeSuperTarget(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, SuperTarget.class);
TargetTest.logCtorExe("before_SuperTarget");
}
/**
* @Around ector_this(caller) && target(t)
*/
public Object ector_aroundSuperTarget(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
validate(t, SuperTarget.class);
validate(caller, SuperTarget.class);
TargetTest.logCtorExe("pre_SuperTarget");
Object o = jp.proceed();
//validate(o, SuperTarget.class);
validate(t, SuperTarget.class);
TargetTest.logCtorExe("post_SuperTarget");
return o;
}
/**
* @After ector_this(caller) && target(t)
*/
public void ector_afterSuperTarget(SuperTarget t, Object caller) {
validate(t, SuperTarget.class);
validate(caller, SuperTarget.class);
TargetTest.logCtorExe("after_SuperTarget");
}
//------------------------- Method call while "this" is subclassed
/**
* @Expression this(caller) && call(* test.thistarget.*.call()) && withincode(* test.*.*.callFrom(..))
*/
Pointcut call_thisSubinterface(IThis caller) {
return null;
}
// interface, while this implements the interface we match
/**
* @Before call_thisSubinterface(caller) && target(t)
*/
public void beforeICallSubinterface(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, IThis.class);
TargetTest.log("before_ITarget");
}
/**
* @Around call_thisSubinterface(caller) && target(t)
*/
public Object aroundICallSubinterface(JoinPoint jp, ITarget t, Object caller) throws Throwable {
validate(t, ITarget.class);
validate(caller, IThis.class);
TargetTest.log("pre_ITarget");
Object o = jp.proceed();
TargetTest.log("post_ITarget");
return o;
}
/**
* @After call_thisSubinterface(caller) && target(t)
*/
public void afterICallSubinterface(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, IThis.class);
TargetTest.log("after_ITarget");
}
/**
* @Expression this(caller) && call(* test.thistarget.*.call()) && withincode(* test.*.*.callFrom(..))
*/
Pointcut call_thisSubclass(SuperThis caller) {
return null;
}
// interface, while this subclass the class we match
/**
* @Before call_thisSubclass(caller) && target(t)
*/
public void beforeICallSubclass(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, SuperThis.class);
TargetTest.log("before_ITarget");
}
/**
* @Around call_thisSubclass(caller) && target(t)
*/
public Object aroundICallSubclass(JoinPoint jp, ITarget t, Object caller) throws Throwable {
validate(t, ITarget.class);
validate(caller, SuperThis.class);
TargetTest.log("pre_ITarget");
Object o = jp.proceed();
TargetTest.log("post_ITarget");
return o;
}
/**
* @After call_thisSubclass(caller) && target(t)
*/
public void afterICallSubclass(ITarget t, Object caller) {
validate(t, ITarget.class);
validate(caller, SuperThis.class);
TargetTest.log("after_ITarget");
}
/**
* We need to validate the bounded this/target since if the indexing is broken, we may have
* the joinpoint instance instead etc, and if not used, the VM will not complain.
*
* @param t
* @param checkCast
*/
static void validate(Object t, Class checkCast) {
if (checkCast == null && t != null) {
TestCase.fail("should ne null: " + t.getClass().getName());
} else if (checkCast != null) {
if (!checkCast.isAssignableFrom(t.getClass())) {
TestCase.fail("t " + t.getClass().getName() + " is not instance of " + checkCast.getName());
}
}
}
}