1   /***************************************************************************************
2    * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved.                 *
3    * http://aspectwerkz.codehaus.org                                                    *
4    * ---------------------------------------------------------------------------------- *
5    * The software in this package is published under the terms of the LGPL license      *
6    * a copy of which has been included with this distribution in the license.txt file.  *
7    **************************************************************************************/
8   package test.thistarget;
9   
10  import org.codehaus.aspectwerkz.definition.Pointcut;
11  import org.codehaus.aspectwerkz.definition.Pointcut;
12  import org.codehaus.aspectwerkz.joinpoint.JoinPoint;
13  import junit.framework.TestCase;
14  
15  /***
16   * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur</a>
17   */
18  public class ThisTargetAspect {
19  
20      //------------------------- Method execution
21  
22      /***
23       * @Expression execution(* test.thistarget.*.target())
24       */
25      Pointcut exe_target;
26  
27      /***
28       * @Expression execution(* test.thistarget.*.targetAbstract())
29       */
30      Pointcut exe_targetAbstract;
31  
32      // interface
33  
34      /***
35       * @Before exe_target && target(t)
36       */
37      public void beforeITarget(ITarget t) {
38          validate(t, ITarget.class);
39          TargetTest.log("before_ITarget");
40      }
41  
42      /***
43       * @Around exe_target && target(t)
44       */
45      public Object aroundITarget(JoinPoint jp, ITarget t) throws Throwable {
46          validate(t, ITarget.class);
47          TargetTest.log("pre_ITarget");
48          Object o = jp.proceed();
49          TargetTest.log("post_ITarget");
50          return o;
51      }
52  
53      /***
54       * @After exe_target && target(t)
55       */
56      public void afterITarget(ITarget t) {
57          validate(t, ITarget.class);
58          TargetTest.log("after_ITarget");
59      }
60  
61      // interface implementation
62  
63      /***
64       * @Before exe_target && target(t) && this(callee)
65       */
66      public void beforeTargetIWithThis(TargetI t, Object callee) {
67          validate(t, TargetI.class);
68          validate(callee, TargetI.class);
69          TargetTest.log("before_TargetI");
70      }
71  
72      /***
73       * @Around exe_target && target(t)
74       */
75      public Object aroundTargetI(JoinPoint jp, TargetI t) throws Throwable {
76          validate(t, TargetI.class);
77          TargetTest.log("pre_TargetI");
78          Object o = jp.proceed();
79          TargetTest.log("post_TargetI");
80          return o;
81      }
82  
83      /***
84       * @After exe_target && target(t)
85       */
86      public void afterTargetI(TargetI t) {
87          validate(t, TargetI.class);
88          TargetTest.log("after_TargetI");
89      }
90  
91      // super class
92  
93      /***
94       * @Before exe_target && target(t)
95       */
96      public void beforeSuperTarget(SuperTarget t) {
97          validate(t, SuperTarget.class);
98          TargetTest.log("before_SuperTarget");
99      }
100 
101     /***
102      * @Around exe_target && target(t)
103      */
104     public Object aroundSuperTarget(JoinPoint jp, SuperTarget t) throws Throwable {
105         validate(t, SuperTarget.class);
106         TargetTest.log("pre_SuperTarget");
107         Object o = jp.proceed();
108         TargetTest.log("post_SuperTarget");
109         return o;
110     }
111 
112     /***
113      * @After exe_target && target(t)
114      */
115     public void afterSuperTarget(SuperTarget t) {
116         validate(t, SuperTarget.class);
117         TargetTest.log("after_SuperTarget");
118     }
119 
120     // super class abstract method
121 
122     /***
123      * @Before exe_targetAbstract && target(t)
124      */
125     public void beforeSuperTargetA(SuperTarget t) {
126         validate(t, SuperTarget.class);
127         TargetTest.log("before_SuperTargetA");
128     }
129 
130     /***
131      * @Around exe_targetAbstract && target(t)
132      */
133     public Object aroundSuperTargetA(JoinPoint jp, SuperTarget t) throws Throwable {
134         validate(t, SuperTarget.class);
135         TargetTest.log("pre_SuperTargetA");
136         Object o = jp.proceed();
137         TargetTest.log("post_SuperTargetA");
138         return o;
139     }
140 
141     /***
142      * @After exe_targetAbstract && target(t)
143      */
144     public void afterSuperTargetA(SuperTarget t) {
145         validate(t, SuperTarget.class);
146         TargetTest.log("after_SuperTargetA");
147     }
148 
149     //------------------------- Ctor call
150 
151     /***
152      * @Expression this(caller) && call(test.thistarget.*.new()) && withincode(* test.*.*.testConstructorCallTargetThis(..))
153      */
154     Pointcut cctor_this(TargetTest caller) {
155         return null;
156     }
157 
158 
159     // interface
160 
161     /***
162      * @Before cctor_this(caller) && target(t)
163      */
164     public void beforeITarget(ITarget t, Object caller) {
165         validate(t, null);
166         validate(caller, TargetTest.class);
167         TargetTest.log("before_ITarget");
168     }
169 
170     /***
171      * @Around cctor_this(caller) && target(t)
172      */
173     public Object aroundITarget(JoinPoint jp, ITarget t, Object caller) throws Throwable {
174         validate(t, null);
175         validate(caller, TargetTest.class);
176         TargetTest.log("pre_ITarget");
177         Object o = jp.proceed();
178         validate(o, ITarget.class);
179         validate(t, null);// in an around advice, target is a local variable so even if jp has set callee, the local
180         // instance is not.
181         TargetTest.log("post_ITarget");
182         return o;
183     }
184 
185     /***
186      * @After cctor_this(caller) && target(t)
187      */
188     public void afterITarget(ITarget t, Object caller) {
189         validate(t, ITarget.class);
190         validate(caller, TargetTest.class);
191         TargetTest.log("after_ITarget");
192     }
193 
194     // interface implementation
195 
196     /***
197      * @Before cctor_this(caller) && target(t)
198      */
199     public void beforeTargetI(TargetI t, Object caller) {
200         validate(t, null);
201         validate(caller, TargetTest.class);
202         TargetTest.log("before_TargetI");
203     }
204 
205     /***
206      * @Around cctor_this(caller) && target(t)
207      */
208     public Object aroundTargetI(JoinPoint jp, TargetI t, Object caller) throws Throwable {
209         validate(t, null);
210         validate(caller, TargetTest.class);
211         TargetTest.log("pre_TargetI");
212         Object o = jp.proceed();
213         validate(o, TargetI.class);
214         validate(t, null);// still null
215         TargetTest.log("post_TargetI");
216         return o;
217     }
218 
219     /***
220      * @After cctor_this(caller) && target(t)
221      */
222     public void afterTargetI(TargetI t, Object caller) {
223         validate(t, TargetI.class);
224         validate(caller, TargetTest.class);
225         TargetTest.log("after_TargetI");
226     }
227 
228     // super class
229 
230     /***
231      * @Before cctor_this(caller) && target(t)
232      */
233     public void beforeSuperTarget(SuperTarget t, Object caller) {
234         validate(t, null);
235         validate(caller, TargetTest.class);
236         TargetTest.log("before_SuperTarget");
237     }
238 
239     /***
240      * @Around cctor_this(caller) && target(t)
241      */
242     public Object aroundSuperTarget(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
243         validate(t, null);
244         validate(caller, TargetTest.class);
245         TargetTest.log("pre_SuperTarget");
246         Object o = jp.proceed();
247         validate(o, SuperTarget.class);
248         validate(t, null);//still null - local variable
249         TargetTest.log("post_SuperTarget");
250         return o;
251     }
252 
253     /***
254      * @After cctor_this(caller) && target(t)
255      */
256     public void afterSuperTarget(SuperTarget t, Object caller) {
257         validate(t, SuperTarget.class);
258         validate(caller, TargetTest.class);
259         TargetTest.log("after_SuperTarget");
260     }
261 
262 
263 
264 
265 
266     //------------------------- Method call
267 
268     /***
269      * @Expression this(caller) && call(* test.thistarget.*.call()) && withincode(* test.*.*.testMethodCallTargetThis(..))
270      */
271     Pointcut call_this(TargetTest caller) {
272         return null;
273     }
274 
275     /***
276      * @Expression this(caller) && call(* test.thistarget.*.callAbstract()) && withincode(* test.*.*.testMethodCallTargetThis(..))
277      */
278     Pointcut callAbstract_this(TargetTest caller) {
279         return null;
280     }
281 
282     // interface
283 
284     /***
285      * @Before call_this(caller) && target(t)
286      */
287     public void beforeICall(ITarget t, Object caller) {
288         validate(t, ITarget.class);
289         validate(caller, TargetTest.class);
290         TargetTest.log("before_ITarget");
291     }
292 
293     /***
294      * @Around call_this(caller) && target(t)
295      */
296     public Object aroundICall(JoinPoint jp, ITarget t, Object caller) throws Throwable {
297         validate(t, ITarget.class);
298         validate(caller, TargetTest.class);
299         TargetTest.log("pre_ITarget");
300         Object o = jp.proceed();
301         validate(t, ITarget.class);
302         // instance is not.
303         TargetTest.log("post_ITarget");
304         return o;
305     }
306 
307     /***
308      * @After call_this(caller) && target(t)
309      */
310     public void afterICall(ITarget t, Object caller) {
311         validate(t, ITarget.class);
312         validate(caller, TargetTest.class);
313         TargetTest.log("after_ITarget");
314     }
315 
316     // interface implementation
317 
318     /***
319      * @Before call_this(caller) && target(t)
320      */
321     public void beforeCallI(TargetI t, Object caller) {
322         validate(t, TargetI.class);
323         validate(caller, TargetTest.class);
324         TargetTest.log("before_TargetI");
325     }
326 
327     /***
328      * @Around call_this(caller) && target(t)
329      */
330     public Object aroundCallI(JoinPoint jp, TargetI t, Object caller) throws Throwable {
331         validate(t, TargetI.class);
332         validate(caller, TargetTest.class);
333         TargetTest.log("pre_TargetI");
334         Object o = jp.proceed();
335         validate(t, TargetI.class);
336         TargetTest.log("post_TargetI");
337         return o;
338     }
339 
340     /***
341      * @After call_this(caller) && target(t)
342      */
343     public void afterCallI(TargetI t, Object caller) {
344         validate(t, TargetI.class);
345         validate(caller, TargetTest.class);
346         TargetTest.log("after_TargetI");
347     }
348 
349     // super class
350 
351     /***
352      * @Before call_this(caller) && target(t)
353      */
354     public void beforeSuperCall(SuperTarget t, Object caller) {
355         validate(t, SuperTarget.class);
356         validate(caller, TargetTest.class);
357         TargetTest.log("before_SuperTarget");
358     }
359 
360     /***
361      * @Around call_this(caller) && target(t)
362      */
363     public Object aroundSuperCall(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
364         validate(t, SuperTarget.class);
365         validate(caller, TargetTest.class);
366         TargetTest.log("pre_SuperTarget");
367         Object o = jp.proceed();
368         validate(t, SuperTarget.class);
369         TargetTest.log("post_SuperTarget");
370         return o;
371     }
372 
373     /***
374      * @After call_this(caller) && target(t)
375      */
376     public void afterSuperCall(SuperTarget t, Object caller) {
377         validate(t, SuperTarget.class);
378         validate(caller, TargetTest.class);
379         TargetTest.log("after_SuperTarget");
380     }
381 
382     // super class - abstract method
383 
384     /***
385      * @Before callAbstract_this(caller) && target(t)
386      */
387     public void beforeSuperCallA(SuperTarget t, Object caller) {
388         validate(t, SuperTarget.class);
389         validate(caller, TargetTest.class);
390         TargetTest.log("before_SuperTargetA");
391     }
392 
393     /***
394      * @Around callAbstract_this(caller) && target(t)
395      */
396     public Object aroundSuperCallA(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
397         validate(t, SuperTarget.class);
398         validate(caller, TargetTest.class);
399         TargetTest.log("pre_SuperTargetA");
400         Object o = jp.proceed();
401         validate(t, SuperTarget.class);
402         TargetTest.log("post_SuperTargetA");
403         return o;
404     }
405 
406     /***
407      * @After callAbstract_this(caller) && target(t)
408      */
409     public void afterSuperCallA(SuperTarget t, Object caller) {
410         validate(t, SuperTarget.class);
411         validate(caller, TargetTest.class);
412         TargetTest.log("after_SuperTargetA");
413     }
414 
415 
416 
417 
418     //------------------------- Ctor exe
419 
420     /***
421      * @Expression this(self) && execution(test.thistarget.*.new())
422      */
423     Pointcut ector_this(Object self) {
424         return null;
425     }
426 
427 
428     // interface
429 
430     /***
431      * @Before ector_this(caller) && target(t)
432      */
433     public void ector_beforeITarget(ITarget t, Object caller) {
434         validate(t, ITarget.class);
435         validate(caller, ITarget.class);
436         TargetTest.logCtorExe("before_ITarget");
437     }
438 
439     /***
440      * @Around ector_this(caller) && target(t)
441      */
442     public Object ector_aroundITarget(JoinPoint jp, ITarget t, Object caller) throws Throwable {
443         validate(t, ITarget.class);
444         validate(caller, ITarget.class);
445         TargetTest.logCtorExe("pre_ITarget");
446         Object o = jp.proceed();
447         //validate(o, ITarget.class);
448         validate(t, ITarget.class);
449         // instance is not.
450         TargetTest.logCtorExe("post_ITarget");
451         return o;
452     }
453 
454     /***
455      * @After ector_this(caller) && target(t)
456      */
457     public void ector_afterITarget(ITarget t, Object caller) {
458         validate(t, ITarget.class);
459         validate(caller, ITarget.class);
460         TargetTest.logCtorExe("after_ITarget");
461     }
462 
463     // interface implementation
464 
465     /***
466      * @Before ector_this(caller) && target(t)
467      */
468     public void ector_beforeTargetI(TargetI t, Object caller) {
469         validate(t, TargetI.class);
470         validate(caller, TargetI.class);
471         TargetTest.logCtorExe("before_TargetI");
472     }
473 
474     /***
475      * @Around ector_this(caller) && target(t)
476      */
477     public Object ector_aroundTargetI(JoinPoint jp, TargetI t, Object caller) throws Throwable {
478         validate(t, TargetI.class);
479         validate(caller, TargetI.class);
480         TargetTest.logCtorExe("pre_TargetI");
481         Object o = jp.proceed();
482         //validate(o, TargetI.class);
483         validate(t, TargetI.class);
484         TargetTest.logCtorExe("post_TargetI");
485         return o;
486     }
487 
488     /***
489      * @After ector_this(caller) && target(t)
490      */
491     public void ector_afterTargetI(TargetI t, Object caller) {
492         validate(t, TargetI.class);
493         validate(caller, TargetI.class);
494         TargetTest.logCtorExe("after_TargetI");
495     }
496 
497     // super class
498 
499     /***
500      * @Before ector_this(caller) && target(t)
501      */
502     public void ector_beforeSuperTarget(SuperTarget t, Object caller) {
503         validate(t, SuperTarget.class);
504         validate(caller, SuperTarget.class);
505         TargetTest.logCtorExe("before_SuperTarget");
506     }
507 
508     /***
509      * @Around ector_this(caller) && target(t)
510      */
511     public Object ector_aroundSuperTarget(JoinPoint jp, SuperTarget t, Object caller) throws Throwable {
512         validate(t, SuperTarget.class);
513         validate(caller, SuperTarget.class);
514         TargetTest.logCtorExe("pre_SuperTarget");
515         Object o = jp.proceed();
516         //validate(o, SuperTarget.class);
517         validate(t, SuperTarget.class);
518         TargetTest.logCtorExe("post_SuperTarget");
519         return o;
520     }
521 
522     /***
523      * @After ector_this(caller) && target(t)
524      */
525     public void ector_afterSuperTarget(SuperTarget t, Object caller) {
526         validate(t, SuperTarget.class);
527         validate(caller, SuperTarget.class);
528         TargetTest.logCtorExe("after_SuperTarget");
529     }
530 
531 
532     //------------------------- Method call while "this" is subclassed
533 
534     /***
535      * @Expression this(caller) && call(* test.thistarget.*.call()) && withincode(* test.*.*.callFrom(..))
536      */
537     Pointcut call_thisSubinterface(IThis caller) {
538         return null;
539     }
540 
541     // interface, while this implements the interface we match
542 
543     /***
544      * @Before call_thisSubinterface(caller) && target(t)
545      */
546     public void beforeICallSubinterface(ITarget t, Object caller) {
547         validate(t, ITarget.class);
548         validate(caller, IThis.class);
549         TargetTest.log("before_ITarget");
550     }
551 
552     /***
553      * @Around call_thisSubinterface(caller) && target(t)
554      */
555     public Object aroundICallSubinterface(JoinPoint jp, ITarget t, Object caller) throws Throwable {
556         validate(t, ITarget.class);
557         validate(caller, IThis.class);
558         TargetTest.log("pre_ITarget");
559         Object o = jp.proceed();
560         TargetTest.log("post_ITarget");
561         return o;
562     }
563 
564     /***
565      * @After call_thisSubinterface(caller) && target(t)
566      */
567     public void afterICallSubinterface(ITarget t, Object caller) {
568         validate(t, ITarget.class);
569         validate(caller, IThis.class);
570         TargetTest.log("after_ITarget");
571     }
572 
573     /***
574      * @Expression this(caller) && call(* test.thistarget.*.call()) && withincode(* test.*.*.callFrom(..))
575      */
576     Pointcut call_thisSubclass(SuperThis caller) {
577         return null;
578     }
579 
580     // interface, while this subclass the class we match
581 
582     /***
583      * @Before call_thisSubclass(caller) && target(t)
584      */
585     public void beforeICallSubclass(ITarget t, Object caller) {
586         validate(t, ITarget.class);
587         validate(caller, SuperThis.class);
588         TargetTest.log("before_ITarget");
589     }
590 
591     /***
592      * @Around call_thisSubclass(caller) && target(t)
593      */
594     public Object aroundICallSubclass(JoinPoint jp, ITarget t, Object caller) throws Throwable {
595         validate(t, ITarget.class);
596         validate(caller, SuperThis.class);
597         TargetTest.log("pre_ITarget");
598         Object o = jp.proceed();
599         TargetTest.log("post_ITarget");
600         return o;
601     }
602 
603     /***
604      * @After call_thisSubclass(caller) && target(t)
605      */
606     public void afterICallSubclass(ITarget t, Object caller) {
607         validate(t, ITarget.class);
608         validate(caller, SuperThis.class);
609         TargetTest.log("after_ITarget");
610     }
611 
612 
613     /***
614      * We need to validate the bounded this/target since if the indexing is broken, we may have
615      * the joinpoint instance instead etc, and if not used, the VM will not complain.
616      *
617      * @param t
618      * @param checkCast
619      */
620     static void validate(Object t, Class checkCast) {
621         if (checkCast == null && t != null) {
622             TestCase.fail("should ne null: " + t.getClass().getName());
623         } else if (checkCast != null) {
624             if (!checkCast.isAssignableFrom(t.getClass())) {
625                 TestCase.fail("t " + t.getClass().getName() + " is not instance of " + checkCast.getName());
626             }
627         }
628     }
629 
630 }