001: /**************************************************************************************
002: * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved. *
003: * http://aspectwerkz.codehaus.org *
004: * ---------------------------------------------------------------------------------- *
005: * The software in this package is published under the terms of the LGPL license *
006: * a copy of which has been included with this distribution in the license.txt file. *
007: **************************************************************************************/package examples.callback;
008:
009: import org.codehaus.aspectwerkz.joinpoint.StaticJoinPoint;
010: import org.codehaus.aspectwerkz.annotation.Around;
011:
012: import java.util.concurrent.Executor;
013: import java.util.concurrent.Executors;
014: import java.util.concurrent.ThreadFactory;
015:
016: /**
017: * Callback call from an async aspect
018: * Run with VM options:
019: * -javaagent:lib\aspectwerkz-core-2.0beta1.jar
020: * -Daspectwerkz.definition.file=src\jdk15\samples\examples\callback\aop.xml
021: * And optianally:
022: * -Daspectwerkz.transform.verbose=true
023: * <p/>
024: * Note: you can avoid use of -D...file=...aop.xml if you have the aop.xml in a META-INF folder somewhere in the classpath.
025: *
026: * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
027: */
028: public class Callback {
029:
030: /**
031: * This method is a callback - could be looked up with a custom @ or etc
032: */
033: public void callback(String message) {
034: System.out.println("Callback.callback " + message);
035: }
036:
037: /**
038: * Triggers the time consuming operation on callee
039: * Note that when used with "this(..) pcd, the caller method cannot be static else we won't match
040: * since caller instance is not available..
041: */
042: public void work() {
043: System.out.println("Callback.work - start");
044: Callee callee = new Callee();
045: callee.longOp(10000);
046: System.out.println("Callback.work - end");
047: }
048:
049: /**
050: * Sample
051: *
052: * @param args
053: * @throws Throwable
054: */
055: public static void main(String args[]) throws Throwable {
056: Callback caller = new Callback();
057: caller.work();
058: }
059:
060: /**
061: * Callee does a time consuming operation
062: */
063: public static class Callee {
064:
065: public void longOp(int howLong) {
066: System.out.println("Callback$Callee.longOp for " + howLong);
067: for (int i = 0; i < howLong; i++) {
068: ;
069: }
070: }
071: }
072:
073: public static class AsyncAspect {
074:
075: /**
076: * Java 5 thread utils
077: */
078: private Executor m_threadPool = Executors
079: .newCachedThreadPool(new ThreadFactory() {
080: public Thread newThread(Runnable target) {
081: Thread t = new Thread(target);
082: t.setDaemon(true);// use of daemon to run from Ant
083: return t;
084: }
085: });
086:
087: // a bit tedious to match inner class so I am a bit lazy here.
088: @Around("call(* *..*.*Callee.longOp(int)) && args(howLong) && this(caller)")
089: public Object doAsync(final StaticJoinPoint sjp, int howLong,
090: final Callback caller) throws Throwable {
091: System.out
092: .println("[AOP powered] - Callback$AsyncAspect.doAsync - for this long: "
093: + howLong);
094: m_threadPool.execute(new Runnable() {
095: public void run() {
096: try {
097: // proceed in a new thread
098: sjp.proceed();
099: // when done, triggers the callback
100: caller
101: .callback("[AOP powered] - I am done there .. "
102: + Thread.currentThread()
103: .getName());
104: } catch (Throwable e) {
105: throw new RuntimeException(e);
106: }
107: }
108: });
109: return null;
110: }
111: }
112:
113: }
|