/usr/share/doc/aspectj-doc/progguide/semantics-pointcuts.html is in aspectj-doc 1.8.3-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 | <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Pointcuts</title><link rel="stylesheet" type="text/css" href="aspectj-docs.css"><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="The AspectJTM Programming Guide"><link rel="up" href="semantics.html" title="Appendix B. Language Semantics"><link rel="prev" href="semantics-joinPoints.html" title="Join Points"><link rel="next" href="semantics-advice.html" title="Advice"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Pointcuts</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="semantics-joinPoints.html">Prev</a> </td><th width="60%" align="center">Appendix B. Language Semantics</th><td width="20%" align="right"> <a accesskey="n" href="semantics-advice.html">Next</a></td></tr></table><hr></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="semantics-pointcuts"></a>Pointcuts</h2></div></div></div><p>
A pointcut is a program element that picks out join points and
exposes data from the execution context of those join points.
Pointcuts are used primarily by advice. They can be composed with
boolean operators to build up other pointcuts. The primitive
pointcuts and combinators provided by the language are:
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><code class="literal">call(<em class="replaceable"><code>MethodPattern</code></em>)</code></span></dt><dd>
Picks out each method call join point whose signature matches
<em class="replaceable"><code>MethodPattern</code></em>.
</dd><dt><span class="term"><code class="literal">execution(<em class="replaceable"><code>MethodPattern</code></em>)</code></span></dt><dd>
Picks out each method execution join point whose signature matches
<em class="replaceable"><code>MethodPattern</code></em>.
</dd><dt><span class="term"><code class="literal">get(<em class="replaceable"><code>FieldPattern</code></em>)</code></span></dt><dd>
Picks out each field reference join point whose signature matches
<em class="replaceable"><code>FieldPattern</code></em>.
[Note that references to constant fields (static final
fields bound to a constant string object or primitive value) are not
join points, since Java requires them to be inlined.]
</dd><dt><span class="term"><code class="literal">set(<em class="replaceable"><code>FieldPattern</code></em>)</code></span></dt><dd>
Picks out each field set join point whose signature matches
<em class="replaceable"><code>FieldPattern</code></em>.
[Note that the initializations of constant fields (static
final fields where the initializer is a constant string object or
primitive value) are not join points, since Java requires their
references to be inlined.]
</dd><dt><span class="term"><code class="literal">call(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></span></dt><dd>
Picks out each constructor call join point whose signature matches
<em class="replaceable"><code>ConstructorPattern</code></em>.
</dd><dt><span class="term"><code class="literal">execution(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></span></dt><dd>
Picks out each constructor execution join point whose signature matches
<em class="replaceable"><code>ConstructorPattern</code></em>.
</dd><dt><span class="term"><code class="literal">initialization(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></span></dt><dd>
Picks out each object initialization join point whose signature matches
<em class="replaceable"><code>ConstructorPattern</code></em>.
</dd><dt><span class="term"><code class="literal">preinitialization(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></span></dt><dd>
Picks out each object pre-initialization join point whose signature matches
<em class="replaceable"><code>ConstructorPattern</code></em>.
</dd><dt><span class="term"><code class="literal">staticinitialization(<em class="replaceable"><code>TypePattern</code></em>)</code></span></dt><dd>
Picks out each static initializer execution join point whose signature matches
<em class="replaceable"><code>TypePattern</code></em>.
</dd><dt><span class="term"><code class="literal">handler(<em class="replaceable"><code>TypePattern</code></em>)</code></span></dt><dd>
Picks out each exception handler join point whose signature matches
<em class="replaceable"><code>TypePattern</code></em>.
</dd><dt><span class="term"><code class="literal">adviceexecution()</code></span></dt><dd>
Picks out all advice execution join points.
</dd><dt><span class="term"><code class="literal">within(<em class="replaceable"><code>TypePattern</code></em>)</code></span></dt><dd>
Picks out each join point where the executing code is defined
in a type matched by <em class="replaceable"><code>TypePattern</code></em>.
</dd><dt><span class="term"><code class="literal">withincode(<em class="replaceable"><code>MethodPattern</code></em>)</code></span></dt><dd>
Picks out each join point where the executing code is defined in
a method whose signature matches
<em class="replaceable"><code>MethodPattern</code></em>.
</dd><dt><span class="term"><code class="literal">withincode(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></span></dt><dd>
Picks out each join point where the executing code is defined
in a constructor whose signature matches
<em class="replaceable"><code>ConstructorPattern</code></em>.
</dd><dt><span class="term"><code class="literal">cflow(<em class="replaceable"><code>Pointcut</code></em>)</code></span></dt><dd>
Picks out each join point in the control flow of any join point
<em class="replaceable"><code>P</code></em> picked out by
<em class="replaceable"><code>Pointcut</code></em>, including
<em class="replaceable"><code>P</code></em> itself.
</dd><dt><span class="term"><code class="literal">cflowbelow(<em class="replaceable"><code>Pointcut</code></em>)</code></span></dt><dd>
Picks out each join point in the control flow of any join point
<em class="replaceable"><code>P</code></em> picked out by
<em class="replaceable"><code>Pointcut</code></em>, but not
<em class="replaceable"><code>P</code></em> itself.
</dd><dt><span class="term"><code class="literal">this(<em class="replaceable"><code>Type</code></em> or <em class="replaceable"><code>Id</code></em>)</code></span></dt><dd>
Picks out each join point where the currently executing object
(the object bound to <code class="literal">this</code>) is an instance of
<em class="replaceable"><code>Type</code></em>, or of the type of the
identifier <em class="replaceable"><code>Id</code></em> (which must be bound in the enclosing
advice or pointcut definition).
Will not match any join points from static contexts.
</dd><dt><span class="term"><code class="literal">target(<em class="replaceable"><code>Type</code></em> or <em class="replaceable"><code>Id</code></em>)</code></span></dt><dd>
Picks out each join point where the target object (the object
on which a call or field operation is applied to) is an instance of
<em class="replaceable"><code>Type</code></em>, or of the type of the identifier
<em class="replaceable"><code>Id</code></em> (which must be bound in the enclosing
advice or pointcut definition).
Will not match any calls, gets, or sets of static members.
</dd><dt><span class="term"><code class="literal">args(<em class="replaceable"><code>Type</code></em> or <em class="replaceable"><code>Id</code></em>, ...)</code></span></dt><dd>
Picks out each join point where the arguments are instances of
the appropriate type (or type of the identifier if using that form). A
<code class="literal">null</code> argument is matched iff the static type of the
argument (declared parameter type or field type) is the same as, or a subtype of,
the specified args type.
</dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>PointcutId</code></em>(<em class="replaceable"><code>TypePattern</code></em> or <em class="replaceable"><code>Id</code></em>, ...)</code></span></dt><dd>
Picks out each join point that is picked out by the
user-defined pointcut designator named by
<em class="replaceable"><code>PointcutId</code></em>.
</dd><dt><span class="term"><code class="literal">if(<em class="replaceable"><code>BooleanExpression</code></em>)</code></span></dt><dd>
Picks out each join point where the boolean expression
evaluates to <code class="literal">true</code>. The boolean expression used
can only access static members, parameters exposed by the enclosing
pointcut or advice, and <code class="literal">thisJoinPoint</code> forms. In
particular, it cannot call non-static methods on the aspect or
use return values or exceptions exposed by after advice.
</dd><dt><span class="term"><code class="literal">! <em class="replaceable"><code>Pointcut</code></em></code></span></dt><dd>
Picks out each join point that is not picked out by
<em class="replaceable"><code>Pointcut</code></em>.
</dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>Pointcut0</code></em> && <em class="replaceable"><code>Pointcut1</code></em></code></span></dt><dd>
Picks out each join points that is picked out by both
<em class="replaceable"><code>Pointcut0</code></em> and
<em class="replaceable"><code>Pointcut1</code></em>.
</dd><dt><span class="term"><code class="literal"><em class="replaceable"><code>Pointcut0</code></em> || <em class="replaceable"><code>Pointcut1</code></em></code></span></dt><dd>
Picks out each join point that is picked out by either
pointcuts. <em class="replaceable"><code>Pointcut0</code></em> or
<em class="replaceable"><code>Pointcut1</code></em>.
</dd><dt><span class="term"><code class="literal">( <em class="replaceable"><code>Pointcut</code></em> )</code></span></dt><dd>
Picks out each join points picked out by
<em class="replaceable"><code>Pointcut</code></em>.
</dd></dl></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="pointcut-definition"></a>Pointcut definition</h3></div></div></div><p>
Pointcuts are defined and named by the programmer with the
<code class="literal">pointcut</code> declaration.
</p><pre class="programlisting">
pointcut publicIntCall(int i):
call(public * *(int)) && args(i);
</pre><p>
A named pointcut may be defined in either a class or aspect, and is
treated as a member of the class or aspect where it is found. As a
member, it may have an access modifier such as
<code class="literal">public</code> or <code class="literal">private</code>.
</p><pre class="programlisting">
class C {
pointcut publicCall(int i):
call(public * *(int)) && args(i);
}
class D {
pointcut myPublicCall(int i):
C.publicCall(i) && within(SomeType);
}
</pre><p>
Pointcuts that are not final may be declared abstract, and defined
without a body. Abstract pointcuts may only be declared within
abstract aspects.
</p><pre class="programlisting">
abstract aspect A {
abstract pointcut publicCall(int i);
}
</pre><p>
In such a case, an extending aspect may override the abstract
pointcut.
</p><pre class="programlisting">
aspect B extends A {
pointcut publicCall(int i): call(public Foo.m(int)) && args(i);
}
</pre><p>
For completeness, a pointcut with a declaration may be declared
<code class="literal">final</code>.
</p><p>
Though named pointcut declarations appear somewhat like method
declarations, and can be overridden in subaspects, they cannot be
overloaded. It is an error for two pointcuts to be named with the
same name in the same class or aspect declaration.
</p><p>
The scope of a named pointcut is the enclosing class declaration.
This is different than the scope of other members; the scope of
other members is the enclosing class <span class="emphasis"><em>body</em></span>.
This means that the following code is legal:
</p><pre class="programlisting">
aspect B percflow(publicCall()) {
pointcut publicCall(): call(public Foo.m(int));
}
</pre></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="context-exposure"></a>Context exposure</h3></div></div></div><p>
Pointcuts have an interface; they expose some parts of the
execution context of the join points they pick out. For example,
the PublicIntCall above exposes the first argument from the
receptions of all public unary integer methods. This context is
exposed by providing typed formal parameters to named pointcuts and
advice, like the formal parameters of a Java method. These formal
parameters are bound by name matching.
</p><p>
On the right-hand side of advice or pointcut declarations, in
certain pointcut designators, a Java identifier is allowed in place
of a type or collection of types. The pointcut designators that
allow this are <code class="literal">this</code>, <code class="literal">target</code>,
and <code class="literal">args</code>. In all such cases, using an
identifier rather than a type does two things. First, it selects
join points as based on the type of the formal parameter. So the
pointcut
</p><pre class="programlisting">
pointcut intArg(int i): args(i);
</pre><p>
picks out join points where an <code class="literal">int</code> (or
a <code class="literal">byte</code>, <code class="literal">short</code>, or
<code class="literal">char</code>; anything assignable to an
<code class="literal">int</code>) is being passed as an argument.
Second, though, it makes the value of that argument
available to the enclosing advice or pointcut.
</p><p>
Values can be exposed from named pointcuts as well, so
</p><pre class="programlisting">
pointcut publicCall(int x): call(public *.*(int)) && intArg(x);
pointcut intArg(int i): args(i);
</pre><p>
is a legal way to pick out all calls to public methods accepting an
int argument, and exposing that argument.
</p><p>
There is one special case for this kind of exposure. Exposing an
argument of type Object will also match primitive typed arguments,
and expose a "boxed" version of the primitive. So,
</p><pre class="programlisting">
pointcut publicCall(): call(public *.*(..)) && args(Object);
</pre><p>
will pick out all unary methods that take, as their only argument,
subtypes of Object (i.e., not primitive types like
<code class="literal">int</code>), but
</p><pre class="programlisting">
pointcut publicCall(Object o): call(public *.*(..)) && args(o);
</pre><p>
will pick out all unary methods that take any argument: And if the
argument was an <code class="literal">int</code>, then the value passed to
advice will be of type <code class="literal">java.lang.Integer</code>.
</p><p>
The "boxing" of the primitive value is based on the
<span class="emphasis"><em>original</em></span> primitive type. So in the
following program
</p><pre class="programlisting">
public class InstanceOf {
public static void main(String[] args) {
doInt(5);
}
static void doInt(int i) { }
}
aspect IntToLong {
pointcut el(long l) :
execution(* doInt(..)) && args(l);
before(Object o) : el(o) {
System.out.println(o.getClass());
}
}
</pre><p>
The pointcut will match and expose the integer argument,
but it will expose it as an <code class="literal">Integer</code>,
not a <code class="literal">Long</code>.
</p></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="primitive-pointcuts"></a>Primitive pointcuts</h3></div></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70642288"></a>Method-related pointcuts</h4></div></div></div><p>AspectJ provides two primitive pointcut designators designed to
capture method call and execution join points. </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">call(<em class="replaceable"><code>MethodPattern</code></em>)</code></li><li class="listitem"><code class="literal">execution(<em class="replaceable"><code>MethodPattern</code></em>)</code></li></ul></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70646464"></a>Field-related pointcuts</h4></div></div></div><p>
AspectJ provides two primitive pointcut designators designed to
capture field reference and set join points:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">get(<em class="replaceable"><code>FieldPattern</code></em>)</code></li><li class="listitem"><code class="literal">set(<em class="replaceable"><code>FieldPattern</code></em>)</code></li></ul></div><p>
All set join points are treated as having one argument, the value the
field is being set to, so at a set join point, that value can be
accessed with an <code class="literal">args</code> pointcut. So an aspect
guarding a static integer variable x declared in type T might be written as
</p><pre class="programlisting">
aspect GuardedX {
static final int MAX_CHANGE = 100;
before(int newval): set(static int T.x) && args(newval) {
if (Math.abs(newval - T.x) > MAX_CHANGE)
throw new RuntimeException();
}
}
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70652576"></a>Object creation-related pointcuts</h4></div></div></div><p>
AspectJ provides primitive pointcut designators designed to
capture the initializer execution join points of objects.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">call(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></li><li class="listitem"><code class="literal">execution(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></li><li class="listitem"><code class="literal">initialization(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></li><li class="listitem"><code class="literal">preinitialization(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></li></ul></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70659616"></a>Class initialization-related pointcuts</h4></div></div></div><p>
AspectJ provides one primitive pointcut designator to pick out
static initializer execution join points.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">staticinitialization(<em class="replaceable"><code>TypePattern</code></em>)</code></li></ul></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70662576"></a>Exception handler execution-related pointcuts</h4></div></div></div><p>
AspectJ provides one primitive pointcut designator to capture
execution of exception handlers:
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">handler(<em class="replaceable"><code>TypePattern</code></em>)</code></li></ul></div><p>
All handler join points are treated as having one argument, the value
of the exception being handled. That value can be accessed with an
<code class="literal">args</code> pointcut. So an aspect used to put
<code class="literal">FooException</code> objects into some normal form before
they are handled could be written as
</p><pre class="programlisting">
aspect NormalizeFooException {
before(FooException e): handler(FooException) && args(e) {
e.normalize();
}
}
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70668736"></a>Advice execution-related pointcuts</h4></div></div></div><p>
AspectJ provides one primitive pointcut designator to capture
execution of advice
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">adviceexecution()</code></li></ul></div><p>
This can be used, for example, to filter out any join point in the
control flow of advice from a particular aspect.
</p><pre class="programlisting">
aspect TraceStuff {
pointcut myAdvice(): adviceexecution() && within(TraceStuff);
before(): call(* *(..)) && !cflow(myAdvice) {
// do something
}
}
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70672944"></a>State-based pointcuts</h4></div></div></div><p>
Many concerns cut across the dynamic times when an object of a
particular type is executing, being operated on, or being passed
around. AspectJ provides primitive pointcuts that capture join
points at these times. These pointcuts use the dynamic types of
their objects to pick out join points. They may also be used to
expose the objects used for discrimination.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">this(<em class="replaceable"><code>Type</code></em> or <em class="replaceable"><code>Id</code></em>)</code></li><li class="listitem"><code class="literal">target(<em class="replaceable"><code>Type</code></em> or <em class="replaceable"><code>Id</code></em>)</code></li></ul></div><p>
The <code class="literal">this</code> pointcut picks out each join point where
the currently executing object (the object bound to
<code class="literal">this</code>) is an instance of a particular type. The
<code class="literal">target</code> pointcut picks out each join point where
the target object (the object on which a method is called or a field
is accessed) is an instance of a particular type. Note that
<code class="literal">target</code> should be understood to be the object the
current join point is transfering control to. This means that the
target object is the same as the current object at a method execution
join point, for example, but may be different at a method call join
point.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">args(<em class="replaceable"><code>Type</code></em> or <em class="replaceable"><code>Id</code></em> or "..", ...)</code></li></ul></div><p>
The args pointcut picks out each join point where the arguments are
instances of some types. Each element in the comma-separated list is
one of four things. If it is a type name, then the argument in that
position must be an instance of that type. If it is an identifier,
then that identifier must be bound in the enclosing advice or
pointcut declaration, and so the argument in that position must be an
instance of the type of the identifier (or of any type if the
identifier is typed to Object). If it is the "*" wildcard, then any
argument will match, and if it is the special wildcard "..", then any
number of arguments will match, just like in signature patterns. So the
pointcut
</p><pre class="programlisting">
args(int, .., String)
</pre><p>
will pick out all join points where the first argument is an
<code class="literal">int</code> and the last is a <code class="literal">String</code>.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70687824"></a>Control flow-based pointcuts</h4></div></div></div><p>
Some concerns cut across the control flow of the program. The
<code class="literal">cflow</code> and <code class="literal">cflowbelow</code> primitive
pointcut designators capture join points based on control flow.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">cflow(<em class="replaceable"><code>Pointcut</code></em>)</code></li><li class="listitem"><code class="literal">cflowbelow(<em class="replaceable"><code>Pointcut</code></em>)</code></li></ul></div><p>
The <code class="literal">cflow</code> pointcut picks out all join points that
occur between entry and exit of each join point
<em class="replaceable"><code>P</code></em> picked out by
<em class="replaceable"><code>Pointcut</code></em>, including
<em class="replaceable"><code>P</code></em> itself. Hence, it picks out the join
points <span class="emphasis"><em>in</em></span> the control flow of the join points
picked out by <em class="replaceable"><code>Pointcut</code></em>.
</p><p>
The <code class="literal">cflowbelow</code> pointcut picks out all join points
that occur between entry and exit of each join point
<em class="replaceable"><code>P</code></em> picked out by
<em class="replaceable"><code>Pointcut</code></em>, but not including
<em class="replaceable"><code>P</code></em> itself. Hence, it picks out the join
points <span class="emphasis"><em>below</em></span> the control flow of the join points
picked out by <em class="replaceable"><code>Pointcut</code></em>.
</p><div class="sect4"><div class="titlepage"><div><div><h5 class="title"><a name="idp70700352"></a>Context exposure from control flows</h5></div></div></div><p>
The <code class="literal">cflow</code> and
<code class="literal">cflowbelow</code> pointcuts may expose context
state through enclosed <code class="literal">this</code>,
<code class="literal">target</code>, and <code class="literal">args</code>
pointcuts.
</p><p>
Anytime such state is accessed, it is accessed through the
<span class="emphasis"><em>most recent</em></span> control flow that
matched. So the "current arg" that would be printed by
the following program is zero, even though it is in many
control flows.
</p><pre class="programlisting">
class Test {
public static void main(String[] args) {
fact(5);
}
static int fact(int x) {
if (x == 0) {
System.err.println("bottoming out");
return 1;
}
else return x * fact(x - 1);
}
}
aspect A {
pointcut entry(int i): call(int fact(int)) && args(i);
pointcut writing(): call(void println(String)) && ! within(A);
before(int i): writing() && cflow(entry(i)) {
System.err.println("Current arg is " + i);
}
}
</pre><p>
It is an error to expose such state through
<span class="emphasis"><em>negated</em></span> control flow pointcuts, such
as within <code class="literal">!
cflowbelow(<em class="replaceable"><code>P</code></em>)</code>.
</p></div></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70709824"></a>Program text-based pointcuts</h4></div></div></div><p>
While many concerns cut across the runtime structure of the program,
some must deal with the lexical structure. AspectJ allows aspects to
pick out join points based on where their associated code is defined.
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">within(<em class="replaceable"><code>TypePattern</code></em>)</code></li><li class="listitem"><code class="literal">withincode(<em class="replaceable"><code>MethodPattern</code></em>)</code></li><li class="listitem"><code class="literal">withincode(<em class="replaceable"><code>ConstructorPattern</code></em>)</code></li></ul></div><p>
The <code class="literal">within</code> pointcut picks out each join point
where the code executing is defined in the declaration of one of the
types in <em class="replaceable"><code>TypePattern</code></em>. This includes the
class initialization, object initialization, and method and
constructor execution join points for the type, as well as any join
points associated with the statements and expressions of the type.
It also includes any join points that are associated with code in a
type's nested types, and that type's default constructor, if there is
one.
</p><p>
The <code class="literal">withincode</code> pointcuts picks out each join point
where the code executing is defined in the declaration of a
particular method or constructor. This includes the method or
constructor execution join point as well as any join points
associated with the statements and expressions of the method or
constructor. It also includes any join points that are associated
with code in a method or constructor's local or anonymous types.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70426928"></a>Expression-based pointcuts</h4></div></div></div><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><code class="literal">if(<em class="replaceable"><code>BooleanExpression</code></em>)</code></li></ul></div><p>
The if pointcut picks out join points based on a dynamic property.
its syntax takes an expression, which must evaluate to a boolean
true or false. Within this expression, the
<code class="literal">thisJoinPoint</code> object is available. So one
(extremely inefficient) way of picking out all call join points would
be to use the pointcut
</p><pre class="programlisting">
if(thisJoinPoint.getKind().equals("call"))
</pre><p>
Note that the order of evaluation for pointcut expression
components at a join point is undefined. Writing <code class="literal">if</code>
pointcuts that have side-effects is considered bad style and may also
lead to potentially confusing or even changing behavior with regard
to when or if the test code will run.
</p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="signatures"></a>Signatures</h3></div></div></div><p>
One very important property of a join point is its signature, which is
used by many of AspectJ's pointcut designators to select particular
join points.
</p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70735408"></a>Methods</h4></div></div></div><p>
Join points associated with methods typically have method signatures,
consisting of a method name, parameter types, return type, the types of
the declared (checked) exceptions, and some type that the method could
be called on (below called the "qualifying type").
</p><p>
At a method call join point, the signature is a method signature whose
qualifying type is the static type used to <span class="emphasis"><em>access</em></span>
the method. This means that the signature for the join point created
from the call <code class="literal">((Integer)i).toString()</code> is different
than that for the call <code class="literal">((Object)i).toString()</code>, even
if <code class="literal">i</code> is the same variable.
</p><p>
At a method execution join point, the signature is a method signature
whose qualifying type is the declaring type of the method.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70740752"></a>Fields</h4></div></div></div><p>
Join points associated with fields typically have field signatures,
consisting of a field name and a field type. A field reference join
point has such a signature, and no parameters. A field set join point
has such a signature, but has a has a single parameter whose type is
the same as the field type.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70742320"></a>Constructors</h4></div></div></div><p>
Join points associated with constructors typically have constructor
signatures, consisting of a parameter types, the types of the declared
(checked) exceptions, and the declaring type.
</p><p>
At a constructor call join point, the signature is the constructor
signature of the called constructor. At a constructor execution join
point, the signature is the constructor signature of the currently
executing constructor.
</p><p>
At object initialization and pre-initialization join points, the
signature is the constructor signature for the constructor that started
this initialization: the first constructor entered during this type's
initialization of this object.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70745104"></a>Others</h4></div></div></div><p>
At a handler execution join point, the signature is composed of the
exception type that the handler handles.
</p><p>
At an advice execution join point, the signature is composed of the
aspect type, the parameter types of the advice, the return type (void
for all but around advice) and the types of the declared (checked)
exceptions.
</p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="matching"></a>Matching</h3></div></div></div><p>
The <code class="literal">withincode</code>, <code class="literal">call</code>,
<code class="literal">execution</code>, <code class="literal">get</code>, and
<code class="literal">set</code> primitive pointcut designators all use signature
patterns to determine the join points they describe. A signature
pattern is an abstract description of one or more join-point
signatures. Signature patterns are intended to match very closely the
same kind of things one would write when declaring individual members
and constructors.
</p><p>
Method declarations in Java include method names, method parameters,
return types, modifiers like static or private, and throws clauses,
while constructor declarations omit the return type and replace the
method name with the class name. The start of a particular method
declaration, in class <code class="literal">Test</code>, for example, might be
</p><pre class="programlisting">
class C {
public final void foo() throws ArrayOutOfBoundsException { ... }
}
</pre><p>
In AspectJ, method signature patterns have all these, but most elements
can be replaced by wildcards. So
</p><pre class="programlisting">
call(public final void C.foo() throws ArrayOutOfBoundsException)
</pre><p>
picks out call join points to that method, and the pointcut
</p><pre class="programlisting">
call(public final void *.*() throws ArrayOutOfBoundsException)
</pre><p>
picks out all call join points to methods, regardless of their name
name or which class they are defined on, so long as they take no
arguments, return no value, are both <code class="literal">public</code> and
<code class="literal">final</code>, and are declared to throw
<code class="literal">ArrayOutOfBounds</code> exceptions.
</p><p>
The defining type name, if not present, defaults to *, so another way
of writing that pointcut would be
</p><pre class="programlisting">
call(public final void *() throws ArrayOutOfBoundsException)
</pre><p>
The wildcard <code class="literal">..</code> indicates zero or more
parameters, so
</p><pre class="programlisting">
execution(void m(..))
</pre><p>
picks out execution join points for void methods named
<code class="literal">m</code>, of any number of arguments, while
</p><pre class="programlisting">
execution(void m(.., int))
</pre><p>
picks out execution join points for void methods named
<code class="literal">m</code> whose last parameter is of type
<code class="literal">int</code>.
</p><p>
The modifiers also form part of the signature pattern. If an AspectJ
signature pattern should match methods without a particular modifier,
such as all non-public methods, the appropriate modifier should be
negated with the <code class="literal">!</code> operator. So,
</p><pre class="programlisting">
withincode(!public void foo())
</pre><p>
picks out all join points associated with code in null non-public
void methods named <code class="literal">foo</code>, while
</p><pre class="programlisting">
withincode(void foo())
</pre><p>
picks out all join points associated with code in null void methods
named <code class="literal">foo</code>, regardless of access modifier.
</p><p>
Method names may contain the * wildcard, indicating any number of
characters in the method name. So
</p><pre class="programlisting">
call(int *())
</pre><p>
picks out all call join points to <code class="literal">int</code> methods
regardless of name, but
</p><pre class="programlisting">
call(int get*())
</pre><p>
picks out all call join points to <code class="literal">int</code> methods
where the method name starts with the characters "get".
</p><p>
AspectJ uses the <code class="literal">new</code> keyword for constructor
signature patterns rather than using a particular class name. So the
execution join points of private null constructor of a class C
defined to throw an ArithmeticException can be picked out with
</p><pre class="programlisting">
execution(private C.new() throws ArithmeticException)
</pre><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70779088"></a>Matching based on the declaring type</h4></div></div></div><p>
The signature-matching pointcuts all specify a declaring type,
but the meaning varies slightly for each join point signature,
in line with Java semantics.
</p><p>
When matching for pointcuts <code class="literal">withincode</code>,
<code class="literal">get</code>, and <code class="literal">set</code>, the declaring
type is the class that contains the declaration.
</p><p>
When matching method-call join points, the
declaring type is the static type used to access the method.
A common mistake is to specify a declaring type for the
<code class="literal">call</code> pointcut that is a subtype of the
originally-declaring type. For example, given the class
</p><pre class="programlisting">
class Service implements Runnable {
public void run() { ... }
}
</pre><p>
the following pointcut
</p><pre class="programlisting">
call(void Service.run())
</pre><p>
would fail to pick out the join point for the code
</p><pre class="programlisting">
((Runnable) new Service()).run();
</pre><p>
Specifying the originally-declaring type is correct, but would
pick out any such call (here, calls to the <code class="literal">run()</code>
method of any Runnable).
In this situation, consider instead picking out the target type:
</p><pre class="programlisting">
call(void run()) && target(Service)
</pre><p>
When matching method-execution join points,
if the execution pointcut method signature specifies a declaring type,
the pointcut will only match methods declared in that type, or methods
that override methods declared in or inherited by that type.
So the pointcut
</p><pre class="programlisting">
execution(public void Middle.*())
</pre><p>
picks out all method executions for public methods returning void
and having no arguments that are either declared in, or inherited by,
Middle, even if those methods are overridden in a subclass of Middle.
So the pointcut would pick out the method-execution join point
for Sub.m() in this code:
</p><pre class="programlisting">
class Super {
protected void m() { ... }
}
class Middle extends Super {
}
class Sub extends Middle {
public void m() { ... }
}
</pre></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70792608"></a>Matching based on the throws clause</h4></div></div></div><p>
Type patterns may be used to pick out methods and constructors
based on their throws clauses. This allows the following two
kinds of extremely wildcarded pointcuts:
</p><pre class="programlisting">
pointcut throwsMathlike():
// each call to a method with a throws clause containing at least
// one exception exception with "Math" in its name.
call(* *(..) throws *..*Math*);
pointcut doesNotThrowMathlike():
// each call to a method with a throws clause containing no
// exceptions with "Math" in its name.
call(* *(..) throws !*..*Math*);
</pre><p>
A <em class="replaceable"><code>ThrowsClausePattern</code></em> is a comma-separated list of
<em class="replaceable"><code>ThrowsClausePatternItem</code></em>s, where
</p><div class="variablelist"><dl class="variablelist"><dt><span class="term"><em class="replaceable"><code>ThrowsClausePatternItem</code></em> :</span></dt><dd><code class="literal">[ ! ]
<em class="replaceable"><code>TypeNamePattern</code></em></code></dd></dl></div><p>
</p><p>
A <em class="replaceable"><code>ThrowsClausePattern</code></em> matches the
throws clause of any code member signature. To match, each
<code class="literal">ThrowsClausePatternItem</code> must
match the throws clause of the member in question. If any item
doesn't match, then the whole pattern doesn't match.
</p><p>
If a ThrowsClausePatternItem begins with "!", then it matches a
particular throws clause if and only if <span class="emphasis"><em>none</em></span>
of the types named in the throws clause is matched by the
<code class="literal">TypeNamePattern</code>.
</p><p>
If a <em class="replaceable"><code>ThrowsClausePatternItem</code></em> does not
begin with "!", then it matches a throws clause if and only if
<span class="emphasis"><em>any</em></span> of the types named in the throws clause
is matched by the <span class="emphasis"><em>TypeNamePattern</em></span>.
</p><p>
The rule for "!" matching has one potentially surprising
property, in that these two pointcuts
</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"> call(* *(..) throws !IOException) </li><li class="listitem"> call(* *(..) throws (!IOException)) </li></ul></div><p>
will match differently on calls to
</p><div class="blockquote"><blockquote class="blockquote"><code class="literal">
void m() throws RuntimeException, IOException {}
</code></blockquote></div><p>
</p><p>
[1] will NOT match the method m(), because method m's throws
clause declares that it throws IOException. [2] WILL match the
method m(), because method m's throws clause declares the it
throws some exception which does not match IOException,
i.e. RuntimeException.
</p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="type-patterns"></a>Type patterns</h3></div></div></div><p>
Type patterns are a way to pick out collections of types and use them
in places where you would otherwise use only one type. The rules for
using type patterns are simple.
</p><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70810688"></a>Exact type pattern</h4></div></div></div><p>
First, all type names are also type patterns. So
<code class="literal">Object</code>, <code class="literal">java.util.HashMap</code>,
<code class="literal">Map.Entry</code>, <code class="literal">int</code> are all type
patterns.
</p><p>
If a type pattern is an exact type - if it doesn't
include a wildcard - then the matching works just
like normal type lookup in Java: </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">Patterns that have the same names as
primitive types (like <code class="literal">int</code>) match
those primitive types.</li><li class="listitem">Patterns that are qualified by package names
(like <code class="literal">java.util.HashMap</code>) match types
in other packages.
</li><li class="listitem">Patterns that are not qualified (like
<code class="literal">HashMap</code>) match types that are
resolved by Java's normal scope rules. So, for
example, <code class="literal">HashMap</code> might match a
package-level type in the same package or a type that
have been imported with java's
<code class="literal">import</code> form. But it would not match
<code class="literal">java.util.HashMap</code> unless the aspect
were in <code class="literal">java.util</code> or the type had
been imported.
</li></ul></div><p>
So exact type patterns match based on usual Java scope
rules.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70822896"></a>Type name patterns</h4></div></div></div><p>
There is a special type name, *, which is also a type pattern. * picks out all
types, including primitive types. So
</p><pre class="programlisting">
call(void foo(*))
</pre><p>
picks out all call join points to void methods named foo, taking one
argument of any type.
</p><p>
Type names that contain the two wildcards "*" and
"<code class="literal">..</code>" are also type patterns. The * wildcard matches
zero or more characters characters except for ".", so it can be used
when types have a certain naming convention. So
</p><pre class="programlisting">
handler(java.util.*Map)
</pre><p>
picks out the types java.util.Map and java.util.java.util.HashMap,
among others, and
</p><pre class="programlisting">
handler(java.util.*)
</pre><p>
picks out all types that start with "<code class="literal">java.util.</code>" and
don't have any more "."s, that is, the types in the
<code class="literal">java.util</code> package, but not inner types
(such as java.util.Map.Entry).
</p><p>
The "<code class="literal">..</code>" wildcard matches any sequence of
characters that start and end with a ".", so it can be used
to pick out all types in any subpackage, or all inner types. So
</p><pre class="programlisting">
within(com.xerox..*)
</pre><p>
picks out all join points where the code is in any
declaration of a type whose name begins with "<code class="literal">com.xerox.</code>".
</p><p>
Type patterns with wildcards do not depend on Java's
usual scope rules - they match against all types
available to the weaver, not just those that are
imported into an Aspect's declaring file.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70834560"></a>Subtype patterns</h4></div></div></div><p>
It is possible to pick out all subtypes of a type (or a collection of
types) with the "+" wildcard. The "+" wildcard follows immediately a
type name pattern. So, while
</p><pre class="programlisting">
call(Foo.new())
</pre><p>
picks out all constructor call join points where an instance of exactly
type Foo is constructed,
</p><pre class="programlisting">
call(Foo+.new())
</pre><p>
picks out all constructor call join points where an instance of any
subtype of Foo (including Foo itself) is constructed, and the unlikely
</p><pre class="programlisting">
call(*Handler+.new())
</pre><p>
picks out all constructor call join points where an instance of any
subtype of any type whose name ends in "Handler" is constructed.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70839712"></a>Array type patterns</h4></div></div></div><p>
A type name pattern or subtype pattern can be followed by one or more
sets of square brackets to make array type patterns. So
<code class="literal">Object[]</code> is an array type pattern, and so is
<code class="literal">com.xerox..*[][]</code>, and so is
<code class="literal">Object+[]</code>.
</p></div><div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="idp70843264"></a>Type patterns</h4></div></div></div><p>
Type patterns are built up out of type name patterns, subtype patterns,
and array type patterns, and constructed with boolean operators
<code class="literal">&&</code>, <code class="literal">||</code>, and
<code class="literal">!</code>. So
</p><pre class="programlisting">
staticinitialization(Foo || Bar)
</pre><p>
picks out the static initializer execution join points of either Foo or Bar,
and
</p><pre class="programlisting">
call((Foo+ && ! Foo).new(..))
</pre><p>
picks out the constructor call join points when a subtype of Foo, but
not Foo itself, is constructed.
</p></div></div><div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="pattern-summary"></a>Pattern Summary</h3></div></div></div><p>
Here is a summary of the pattern syntax used in AspectJ:
</p><pre class="programlisting">
MethodPattern =
[ModifiersPattern] TypePattern
[TypePattern . ] IdPattern (TypePattern | ".." , ... )
[ throws ThrowsPattern ]
ConstructorPattern =
[ModifiersPattern ]
[TypePattern . ] new (TypePattern | ".." , ...)
[ throws ThrowsPattern ]
FieldPattern =
[ModifiersPattern] TypePattern [TypePattern . ] IdPattern
ThrowsPattern =
[ ! ] TypePattern , ...
TypePattern =
IdPattern [ + ] [ [] ... ]
| ! TypePattern
| TypePattern && TypePattern
| TypePattern || TypePattern
| ( TypePattern )
IdPattern =
Sequence of characters, possibly with special * and .. wildcards
ModifiersPattern =
[ ! ] JavaModifier ...
</pre></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="semantics-joinPoints.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="semantics.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="semantics-advice.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Join Points </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Advice</td></tr></table></div></body></html>
|