UBC Theses and Dissertations

UBC Theses Logo

UBC Theses and Dissertations

Pointcuts by example McCormick, Edward J. 2006

Your browser doesn't seem to have a PDF viewer, please download the PDF to view this item.

Item Metadata

Download

Media
831-ubc_2006-0076.pdf [ 2.67MB ]
Metadata
JSON: 831-1.0051502.json
JSON-LD: 831-1.0051502-ld.json
RDF/XML (Pretty): 831-1.0051502-rdf.xml
RDF/JSON: 831-1.0051502-rdf.json
Turtle: 831-1.0051502-turtle.txt
N-Triples: 831-1.0051502-rdf-ntriples.txt
Original Record: 831-1.0051502-source.json
Full Text
831-1.0051502-fulltext.txt
Citation
831-1.0051502.ris

Full Text

Pointcuts by Example by Edward J. M c C o r m i c k  B . S c , Northeastern University, 2002  A THESIS S U B M I T T E D INPARTIAL F U L F I L M E N T O F T H E REQUIREMENTS F O RT H E D E G R E E O F Master of Science in The Faculty of Graduate Studies (Computer Science)  The University O f British Columbia December 16,2005 © Edward J. M c C o r m i c k 2005  Abstract The thesis of this dissertation is that it is possible to construct IDE-based tools that allow the editing of AspectJ pointcut expressions through direct manipulation of effective representations of join points in the code to which a pointcut applies. There are two reasons why providing tool support for managing pointcut expressions is important. The first reason is that the pointcut-advice mechanism obscures exactly what a given piece of code does. This is because the execution of any piece of code may trigger additional advice of which the developer may be unaware. T h e second reason is that the creation and maintenance of pointcut expressions that capture the intended set of join points is a difficult task. Pointcut expressions are typically based on assumed naming and structural patterns in the code. We argue that without proper tool support, it is difficult for the developer to properly verify that the conventions are followed strictly enough for a pointcut to remain robust Current tool support addresses these issues to some extent by alerting the developer to where the local join points exist in the code, and the advice that applies at that point. However, if the developer finds that the join points are incorrect he must open the aspect and edit the pointcut expression outside the context of the code where the join point should exist. In this dissertation we present the notion of  Pointcuts by Example.  Using this tech-  nique, a developer is able to specify examples in the code of join points that a pointcut expression  should  or  should-not  match. A s a constructive proof of existence, we de-  veloped prototype tool support for editing pointcuts by example called the  Wizard. The P W presents a G U I interface for editing add or remove operations at join point shadow sites.  ii  Pointcut  pointcut expressions by selecting  Contents Abstract  'i  Contents  iii  List of Tables  v  List of Figures  vi  1 Introduction  1  1.1  Thesis Statement  1  1.2  Background and Motivation for the Thesis  1  1.2.1  Aspect-Oriented Programming  1  1.2.2  Tool Support For Managing Pointcuts  2  1.2.3  Effective versus non-effective representations  4  1.3  1.4  Thesis Validation  6  1.3.1  Our Approach: Pointcut B y Example  6  1.3.2  A Prototype Implementation  7  Conclusion  7  2 Related Work The Difficulty of Writing Pointcuts  9  2.2  Current Language & Tool Support  10  2.3  3  9  2.1  2.2.1  Alternative Pointcut Languages  10  2.2.2  Pointcut Development Tools  12  Conclusions  14  The Tool 3.1  15  The A s p e c U Pointcut Language 3.1.1  15  Wild-card symbols  18  3.2  A User Interface for Shadow Browsing  3.3  The U I for Editing Pointcuts  22  3.3.1  Adding Shadows  22  3.3.2  Removing Shadows  25  3.3.3  Evaluating the Resulting Expression  28  3.4  Conclusion  19  29  iii  4  5  Implementation  30  4.1  Introduction  30  4.2  The Shadow M o d e l  32  4.3  The Disambiguator  35  4.4  The Normalizer  36  4.4.1  Rules for Converting an AspectJ pointcut to an Expression on Join Points  36  4.4.2  P C D N F : A Pointcut Expression in Disjunctive Normal F o r m .  39  4.4.3  Converting a P C D N F expression to AspectJ Pointcut Syntax  .  39  4.5  The Resolver  41  4.6  Conclusion  41  Conclusion  43  5.1  Contributions  43  5.1.1  A U I for Effective Views of Join Point Shadows  43  5.1.2  A n Architecture to Support Effective Views of Join Point Shadows  5.2  5.3  44  Future Work  44  5.2.1  Usability and Usefulness  45  5.2.2  Improvements to Current Features  45  Concluding Remarks  47  Bibliography  48  iv  List of Tables 3.1  Kinded Pointcuts  16  3.2  Lexical-Structure based pointcuts  16  3.3  Binding pointcuts  17  3.4  Control-flow and conditional pointcuts  17  v  List of Figures 1.1  Gutter annotations mark shadows in A J D T  1.2  The Cross-References view of A J D T  3 5  1.3  method Ship.fire()  5  3.1  T h e Pointcut Wizard  3.2  Pointcut callsWithinFire is now an Active Pointcut  20 21  3.3  Adding a Constructor Call to the Active Pointcut  24  3.4  Removing a Method Call from the Active Pointcut  27  4.1  Data F l o w Between Components  31  4.2  Shadow Signatures  33  4.3  The Shadow M o d e l  34  4.4  P C D N F representation  40  5.1  A U I for Editing Pointcut Properties  45  vi  Chapter 1  Introduction 1.1  Thesis Statement  T h e thesis of this dissertation is that it is possible to construct IDE-based tools that allow editing of Aspect! pointcut expressions through direct manipulation of effective representations of join points in the code to which a pointcut applies. This chapter consists of two sections. The first section explains and motivates the thesis statement. The second section describes our validation of the thesis statement.  1.2  Background and Motivation for the Thesis  1.2.1 Aspect-Oriented Programming Programming languages that support Aspect-Oriented Programming rely on the notion of a join  point  mechanism to specify when, where and how an aspect should alter  program execution. In this dissertation we focus on AspectT [13], which is probably the most well known and mature aspect-oriented language today. developer can create  pointcut expressions  With AspectT, a  to describe a set of join points at which to  apply some aspect functionality. Other aspect languages that offer similar support are Ceasar [17], DemeterJ [9] and Aspectual Collaborations [15]. A l l these aspect-oriented programming languages have one thing in common: the goal to provide novel language mechanisms to allow modularization of so-called crosscutting concerns. A concern is defined very generally as any kind of issue or problem that a developer would want to reason about in relative isolation. Two concerns are said to be crosscutting if a decomposition of the system that modularizes one concern tends to cut across a decomposition along the lines of the other concern. T h e existence of crosscutting concerns in a software system generally leads to  scattering  tangling  and  [19]. Tangling means that one module contains a mix of code addressing  several concerns. Scattering means that code addressing a single concern is scattered across multiple modules of the system. Tangling and scattering greatly increase the complexity of software understanding, evolution and maintenance. A n example of crosscutting concerns is given in [14]. T h e authors present a hypothetical situation of a developer creating a robotics application. The core concerns during his design process are motion management and path computation. T h e application is successfully developed, but later it becomes clear that path optimizations would greatly improve run-time results.  Since optimization was not a high-priority in the  initial design of the system, the system is mostly decomposed along the lines of the  1  functional concerns which are well modularized. The path optimization concern crosscuts the functional concerns of motion management and path computation. Therefore, the implementation of the optimization concern ends up scattered across many different modules, as well as tangled with the other concerns addressed by those modules. Future updates to the optimization code thereby become an exercise with much greater difficulty. The goal of AspectJ is to introduce a novel kind of modular unit, called an aspect, which provides the developer with the means to modularize crosscutting concerns such as the one in this example. If the modularization of the path optimization concern as an aspect is successful, all the concern-specific code will be localized within a small number of related aspects and classes and can be viewed and edited in relative isolation. An AspectJ developer can write code in terms of Aspectf's join point model, in which join points are principled points in the execution of a program. Using a syntactic element of AspectJ called a pointcut designator, the developer is able to describe a set of join points at which a particular piece of concern-specific code should execute. The code that the developer wishes to execute at the join points matched by a particular pointcut expression are contained in a modular structure similar to a Java method called an advice. Put simply, the advice of an aspect describes what should happen and the pointcut designator describes when.  1.2.2  Tool Support F o r Managing Pointcuts  In this dissertation we will be presenting a new technique for working with AspectJ pointcut expressions. There are two reasons why providing tool support for managing pointcut expressions is important. The first reason is that the pointcut-advice mechanism obscures exactly what a given piece of code does. This is because the execution of any piece of code may trigger additional advice of which the developer may be unaware. This problem is addressed by tools such as AJDT[5], which provide a visual representation of where in the code an AspectJ advice will be executed. The static representation of a dynamic join point is referred to as the join points shadow. Figure 1.1 shows the gutter annotation mechanism AJDT uses to denote a join point shadow. By hovering over the annotation the developer can view more specific information pertaining to the shadow, such as its signature and the pointcut expression which it is matched by. Additionally, a menu option at the shadow site allows the developer to hyperlink directly to the piece of advice which will be executed at the join point during the program's execution. Tools of this nature ease the burden on the developer of having to think both in terms of the base code and any advice that might be executed.  2  ••/•**  create  a bullet  and  fire  it  IIP  *•/  v o i d /f i r e ( ) { •/'/.  \ft.  f-icing'.a.,-shotxitakesv  energy  lad vised by SoundEffects.beforeQ: calls Within5hip,,r_EJf£RGY) )  •'Hi?' ISP  return; • / / c r e a t e - =a b u l l e t  - o b j e c t , so: ' i t . ' d o e s n l . t • I r i t •• , t h e ' s h i p . t h a t ' s v  f i r lng-i-it  ft-  double  xV = g e t X V e l f )  + BVLLET_SPEED  *  ft,  double  yV = getYVel()  +  * (Hath.siH(orlentation));  //  c r e a t e -,the.Jactua 1  new  EUULET_SPEED  Buliet  (Hath.cos(orlentation));  s  Bullet'(  ft  getGame(),  ft.  (getXPos()  +  UgetSizeQ/2  + 2)  (getYPos()  +  ( ( g e t S i z e ()/2  +  2)  i*  (Hath.cos(orientation)))  + xV),  *  (Hath.sin(orientatioaji);)  + ^yV)':,  Jfci|p§  yvj; (SSI  Figure 1.1: Gutter annotations mark shadows in A J D T  The second reason is that the creation and maintenance of pointcut expressions that capture the intended set of join points is a difficult task.  Pointcut expressions  are typically based on assumed naming and structural patterns in the code. We argue that without proper tool support, it is difficult for the developer to properly verify that the conventions are followed strictly enough for a pointcut to remain robust. If they are not, a pointcut constructed by the developer may result in false-positive or falsenegative join points occurring at run-time. This problem is also partially addressed by placing, as in A J D T , gutter annotations at join point shadow sites. Additionally, A J D T provides a  cross-references view,  as shown in Figure 1.2, with which the developer can  look up any advice associated with a join point shadow in the code, or alternatively any join point shadows associated with an aspect or advice. The drawback with these tools is that although they present information concerning the location and existence of join point shadows, they offer little help in correcting a malformed pointcut expression. It is left as a task for the developer to inspect the shadow sites and infer the error in the pointcut expression. In the following section we present another technique to support the Aspect! developer: effective views.  1.2.3  Effective versus non-effective representations  In this section we will explain what we mean with the word  effective  in the thesis  statement. We will illustrate the usefulness of having an effective tool by illustrating how a developer may use the powerful but non-effective Aspect! tool A J D T to edit a pointcut expression. A s discussed in the previous section, creating and maintaining correct pointcut expressions can be an onerous and error prone activity. The most common problem with pointcut expressions is that they either capture too many join points or too few. A J D T ' s gutter annotations provide some help by allowing developers to visit and inspect the join point sites in the code and spot sites that are incorrectly matched (included or excluded) by a pointcut. However, when such points are discovered A J D T provides no support to rectify the situation. To illustrate our point, we present a typical scenario based on the section of code shown in Figure 1.3, which was taken from an open source video game called Spacewar [1]. The object of Spacewar is for the player to shoot down enemy ships before being shot down. In this scenario, the developer would like to create a version of the game with sound effects. H e decides.that this feature can be added most easily through an aspect.  A s a first task, he'creates an advice to play a gunshot sound. The pointcut  for this advice must match every point during the execution of the program when a ship fires a bullet at another ship. To begin, he creates an Aspect and some advice to play the sound file. H e then explores the code base until he finds a method (shown in Figure 1.3) called f i r e in a class called S h i p . H e returns to the Aspect and creates the following pointcut to capture the execution of this method:  pointcut gunshot(): execution(void Ship.fire()) A J D T ' s cross references view confirms that a join point will be created for each execution of f i r e .  He then runs the program, but soon finds that his new sound  feature contains a bug: the sound is played every time the player attempts to fire the  4  method-call(boolean;spacewar.Ship.experidEriergy(double)y c£> advisedby ~ .i>- SoundEf f ects. bef ore(): callsWithiriShip.,, v  :  EJ  •{->• method-call(double )ava.lang;Math;cos(dbuble j) El • O advisedby <••••••••& SoundEf f ects. bef gre(): callsWithinShip.;'. • {•:;} method-call(double Java.lang.Math.sin(double))' ($> advisedby •tf>SoundEf f ects. bef ore(): callsWithinShip.. •'•{•;;}'• method-call(spacewaf.Game;spacew i- EJ-advjsecfby •SpuhdEff.ectSib.efore.Q; callsWithinShip.. {:;•}; meth ], g|.-.;. cj> advised by ^ SoundEffectsibeforei;):; callsWithinShip.:. B--%}-methGd-call(double;java.lang £]•••• c*> advisedby tf> SoundEffects.befpreQ: callsWithinShip.  Figure 1.2: The Cross-References view of A J D T class Ship { void fire() { / / f i r i n g a shot takes energy i f (!expendEnergy(BULLET_ENERGY)) return; double xV = getXVeK) double yV = getYVelO  + BULLET_SPEED * (Math.cos(orientation)); . + BULLET_SPEED * (Math.sin(orientation));  / / create the actual bullet new Bullet( getGame(), (getXPosO + ((getSize()/2 (getYPosO + ((getSize()/2 xV, yV) •;  + 2 ) * (Math.cos(orientation))) + 2 ) * (Math.sin(orientation)))  } } Figure 1.3: method Ship.fire() 5  + xV) + yV)  gun, even if he is out of bullets and no shot is actually fired. In order to fix the problem, he decides that he must refine his pointcut to capture only those join points where a bullet is actually fired. B y re-inspecting the Ship.fire method's code, the developer finds that the method only creates a B u l l e t object if an e x p e n d E n e r g y check (of line number 3) is passed. To address this, he edits the g u n s h o t pointcut as follows:  pointcut gunshot(): withincode(void Ship.fire()) && c a l l ( * Bullet.new(..)) } In this example, the developer diagnosed the bug in his program as an incorrectly formulated pointcut. To find the error in the pointcut, however, it was necessary for him to open and inspect the S h i p . f i r e method code. This was because the information necessary to form a correct pointcut existed at the join point shadow location, rather than within the pointcut expression. The developer found by analyzing the f i r e method body code that an appropriate fix was to create a pointcut which matched the call to the B u l l e t constructor inside the f i r e method body. We propose that at this point, it would have been desirable if tool support had allowed the developer to perform this change by operating directly on join point representations provided by the tool. Instead the developer was forced to produce the desired effect through an extra level of indirection: navigating outside the location of the join point shadows to the aspect where he could edit the corresponding pointcut expression. Following the terminology from [11], we say that A J D T produces a non-effective view of the join point representations in the code. A non-effective view allows you to see but not change what is contained in the view. The opposite of a "non-effective" is "effective". A n effective view of the join points matched by the pointcut would allow the developer to both see and change what join points a pointcut matches. This brings us back to the thesis of this dissertation, that it is possible to construct IDE-based tools that allow editing of pointcut expressions through direct manipulation of effective representations of join points in the code to which a pointcut applies.  1.3 Thesis Validation T h e validation for our thesis is a constructive proof of existence. In other words we constructed a prototype tool that provides an effective view of join point representations in code. T h e bulk of this dissertation describes the design and implementation of the prototype. In this section we explain the most important idea behind the tools design and provide an overview of the prototype.  1.3.1  O u r A p p r o a c h : Pointcut By Example  T h e main idea behind our approach towards building a tool that provides an effective representation of Aspect! pointcuts is to allow the developer to edit the pointcut expression by citing specific examples of shadows or non-shadows in the code. We believe that since pointcut expressions are written in terms of patterns in the base code, it is most natural to allow the developer to work on a pointcut from within the  6  base code. Our mechanism is called  pointcut by example  because join point shadows  in the base code can be used by the developer as specific examples of the kinds of join points he wishes to add or remove from the set of join points the pointcut matches.  1.3.2  A Prototype Implementation  T h e Pointcut Wizard is a tool to support creating pointcuts by example. U s i n g the tool, a developer can specify whether to add or remove a join point from the pointcut designator from the location of the join point site itself.  B y allowing the developer  to effect changes in the pointcut designator during the exploration process without a constant switching back and forth from the aspect code to the join point shadow site, we believe a great deal of time in both creating and editing pointcut expressions can be saved. T h e user interface to the Pointcut Wizard is similar to A J D T . It is an Eclipse plugin and uses gutter annotations to highlight join point shadows. However the Pointcut Wizard uses  effective  representations of join point shadows, allowing the developer to  edit the pointcut expression by specifying join point shadows in the code that it should or should-not match. The user interface the tool provides is in the form of a context menu at each possible join point site. If the shadow on a particular line is already matched by the pointcut expression, the developer is given the option of removing it from the set of shadows the pointcut matches. Alternatively, if a line of code contains shadows that are not currently matched, and the developer wishes for an advice to apply at that site, he may add the shadows to those matched by the pointcut through the same context menu.  1.4  Conclusion  In this chapter we introduced Aspect Oriented Programming, and in particular the A O P language AspectT. Aspect! programs can be difficult to maintain without proper tool support for two reasons: the first reason is that the pointcut-advice mechanism can obscure what a given piece of code does. T h e second reason is that it can be difficult to write a pointcut expression that correctly matches the intended join points. A J D T addresses these issues to some extent by alerting the developer to where the local join points exist in the code, and the advice that applies at that point. However, if the developer finds that the join points are incorrect he must open the aspect and edit the pointcut expression outside the context of the code where the join point should exist. The thesis of this dissertation is that it is possible to construct IDE-based tools that allow the editing of AspectT pointcut expressions through direct manipulation of effective representations of join points in the code to which a pointcut applies. To validate this thesis, we present the notion of  Pointcuts by Example.  U s i n g this  technique, a developer is able to specify examples in the code of join points that a pointcut expression  should  or  should-not  match. A s a constructive proof of existence, we  developed prototype tool support for editing pointcuts by example called the  7  Pointcut  Wizard. The Pointcut Wizard presents a G U I interface for editing pointcut expressions by selecting a d d or remove operations at join point shadow sites. In the following chapter we will examine related work in the area of pointcut editing tools. Chapter 3 will present a more detailed explanation of how the Pointcut Wizard can be used to edit pointcut expressions. In Chapter 4 we will describe the architecture of the Pointcut Wizard. We will conclude with Chapter 5 , where we will present our plans for future work in this area and concluding remarks.  8  Chapter 2 Related Work This dissertation introduces new tool support for creating and editing AspectJ pointcut expressions. In this chapter we present alternative methods for supporting the developer in these tasks. The chapter is divided into two sections. T h e first section reviews related work that motivates the need for better tool support for building and editing pointcut expressions. T h e second section discusses related work on developing tool support for writing and maintaining pointcut expressions.  2.1  The Difficulty of Writing Pointcuts  In this section we will motivate the need for better tool support for writing and maintaining AspectJ pointcut expressions.  We will first examine work by the developers  of A J D T which highlights the proper way to extract patterns from the base code in order to form pointcuts that express an intention as well as capture the correct set of join points. Then we will examine work that shows why the process of creating such a pointcut can often be difficult, due to the difficulty in both extracting patterns from the code and enforcing them once the pointcut has been written. In [ 5 ] the authors guide the AspectJ developer in effectively using patterns to design robust pointcuts. A  robust pointcut  accurately portrays the intentions of the developer,  capturing join points that exist in the current version of the code as well as raising the probability that pertinent shadows in future versions will be captured. According to the authors, the developer should include in the pointcut only that information which pertains to the join points he wishes to match. A l l other information should be considered extraneous and replaced with the appropriate wild-card symbol in the pointcut expression. There are three types of wild-card symbols available in AspectJ. T h e " * " will match any number of alpha-numeric characters in a type name or signature. T h e " . will match a dotted list containing alpha-numeric characters. T h e "+" must follow a type name and will match any sub-type of the type to which it is attached. Although the wild-card symbols of the AspectJ language offer the user a great deal of freedom in expressing his intentions, they may not always be sufficient. We see an example of such a case in [6], where the authors identify a major obstacle in extracting a particular cross-cutting concern. The authors state that extracting a concern often necessitated pointcuts referencing seemingly random, yet specific places within method boundaries of the original implementation. To capture the correct set of join points, the developer created pointcut expressions which were essentially an enumeration of pointcuts - each matching one of the so called  9  random, yet specific places.  The cause of  this situation, as stated by the authors, was that the code was (obviously) not designed with the Aspect in mind. This situation is described in more direct terms by the authors of [20].  This work  states that although the use of AspectJ may lead to greater modularity, it has not been proven to actually increase evolvability. They describe current A O P languages, and namely AspectJ, as  simplistic  because they are often unable to capture a crosscutting  concern without resorting to the enumeration method described above. The authors argue that join points that share common properties that the developer would like to capture with a single pointcut often do not share similarities in naming patterns. Since AspectJ relies on these naming patterns to capture crosscutting concerns, the developer may often find himself searching for patterns in the code that do not exist. When a pattern can not be found, he is left to capture a crosscutting concern by enumerating the patterns found at each join point location. In doing so, he creates very specific references to program elements spread across many modules - greatly increasing the coupling between aspect and base code. The authors believe that this situation occurs frequently enough to make a good case against using languages like AspectJ. They describe the situation as the  AOP paradox:  aspects, which are meant to increase the  evolvability of a system may be so closely coupled (and therefore dependent) on the systems current implementation that its evolvability is lessened. Creating a pointcut that enumerates each join point is a time consuming and errorprone process, and currently available tools do not directly support this method for AspectJ since the resulting pointcut creates a high degree of coupling between aspect and base code. In the following section we will introduce work that uses a more expressive pointcut syntax than AspectJ allows - creating the ability to base pointcuts on properties of join points, rather than patterns in their signatures. Additionally, we will introduce current work on providing tool support to assist the developer in evolving a system that has been made fragile by the coupling between aspect and base code.  2.2  Current Language & Tool Support  In this section we discuss related work on developing language and tool support for writing and maintaining pointcut expressions. Each work is an attempt to address the problem motivated in the previous section: that when a developer resorts to enumerating the set of desired join points in a pointcut, a high degree of coupling between aspect and base code is introduced into the system. This decreases the robustness of the aspect, lowering the evolvability of the system as a whole. T h e set of works we will look at can be loosely divided into two groups. T h e first group suggests an alternative, more expressive pointcut language to answer the coupling problem. The second presents a set of tools to alert the developer of the impact of any changes he is making to the base or aspect code.  2.2.1  Alternative Pointcut Languages  AspectJ's pointcut language is based on patterns, rather than properties in the code. The following two areas of research challenge this implementation. T h e first is based  10  on using a more expressive logic language to capture properties of join points. T h e second allows the developer to use meta-tags to annotate the code. Soul and Inductive Logic In [4], the authors present the use of a specialized pointcut managing environment to assist the developer in creating pointcut-like expressions written in the logic language Soul [21]. As an initial step, the environment gathers background knowledge of the source code in the form of logic facts. Once a database has been formed, the developer begins to create a pointcut by iteratively selecting and de-selecting elements from the source code that he wishes to be captured by the pointcut. A s this occurs, the tool actively maintains a set of logic rules that match the developers examples. A s a final step, the tool uses an inductive logic technique called relative least general generalization [16] to reduce the amount of redundancy in the expression. When an incorrect set of shadows is captured by an expression, the developer can either continue with more iterations of providing positive and negative source code examples to the inductive logic engine, or attempt to manually fix the expression. A n important aspect of this environment is that it continually checks the correctness of pointcut expressions. If the examples used to create the pointcut are refactored or removed, the logic engine recomputes the pointcut to take these changes into effect. This dynamic quality greatly increases the evolvability of an aspect oriented system, because the developer has the option of refactoring the base code without needing to worry about removing a necessary join point. This work is relevant to ours because the technique used to form and edit pointcut expressions is what this dissertation refers to as pointcut by example. The difference between the two is that Soul is a more expressive logic language than AspectT. Using Soul, the developer is able to express properties of a join point shadow other than its signature and lexical context. The challenge of our work was to create a environment that supported editing Aspect! pointcuts by example. Annotations Annotations are meta-data tags that developers can use to classify elements of the code. They are typically processed by build-time tools or run-time libraries. The A O P community has embraced the use of annotations, with tools such as JBoss [12], A s pectWerkz [3] and Aspect! [2] each providing tool support. Since we are focused on AspectT in this dissertation, we will here illustrate the support A J D T provides for programming with annotations using AspectT. A J D T allows the developer to both d e c l a r e annotations on elements of the code and to create pointcut expressions that match join points based on annotations. We will here provide an example based on the E J B 3.0 specifications [8], where methods have a transaction policy associated with them that can be annotated as follows: @Tx(TxType.REQUIRED) v o i d credit(Money amount)  {...}  11  Here, the @Tx denotes the type of the annotation, and the T x T y p e . R E Q U I R E D is the value of the annotation. If the developer wishes to use AspectJ to advise all method annotated with the R E Q U I R E D type, he can write the following pointcut:  pointcut transactionalMethodExecution(Tx tx) : execution(* *(..)) && © a n n o t a t i o n ( t x ) && i f ( t x == TxType.REQUIRED); The © a n n o t a t i o n pointcut is new to AspectJ version 5. It allows the developer to retrieve the value of the annotation (in this case the T x T y p e type) for each join point matched by the pointcut. This work is pertinent to ours because by using annotations the developer can explore a system of code and annotate program elements as having a property he wishes to capture with a pointcut expression. With AspectJ, it is also possible to use a d e c l a r e statement to automatically annotate program elements. The Pointcut Wizard performs a similar task, but the tools gutter annotations are only used by the tool; no meta-data is added directly to the code. Another difference is that the Pointcut Wizard allows the developer to edit a pointcut expression based on examples from the code. Using annotations, the developer has no control over the pointcut - he may only annotate program elements in the code and then write a pointcut expression to capture those join points based on their annotations. In the next section we will introduce other tools that support the developer in writing or editing pointcut expressions.  2.2.2  Pointcut Development Tools  Another important issue for AspectJ developers is that of making sure pointcuts continue to match intended join points as changes are made to the base code or the Aspect. This can be difficult without proper tool support because the developer may be unaware of where the join point shadows in the code are - and what properties they posses that make them a target join point for advice. In this section we will present some examples of how current tool support supports the developer in editing code while maintaining the operability of both aspect and base code.  AJDT A J D T [5] is the AspectJ tool suite developed by the AspectJ team. T h e tools contained in the suite are geared towards helping the developer to understand what impact an Aspect will have on the base code when the program is run. The suite is made up of four tools: • The Aspect Visualizer presents the developer with a macro-view of the impact an aspect will have on his system. B y selecting an aspect, a view is presented in the manner of SeeSoft [7], with join point shadows in the code highlighted in a color determined by the developer.  12  •  T h e Cross-References view, shown on page 5, provides a structured view of advice and join point shadows in the base code. This view allows a developer to view an outline of which advice applies to the join points in the code with which he is working. Alternatively, an Aspect developer can use this view to determine where an advice he is working on will apply in the base code. This view updates dynamically as changes in the code are made.  •  The Crosscutting Comparison View presents a view of how changes the developer has made to either the base code or Aspect code have affected the number o f join points. Whereas the other views reveal information about how the aspect is  currently joining with the base  code, this view shows join points that have either  recently appeared or recently disappeared as a result of changes to the code. Gutter annotations appear in both Aspects and Java classes for a developer using A J D T . If the developer is viewing an Aspect, the annotations provide a list of hyperlinks to shadows in the code. If the developer is viewing a join point shadow in the base code, hyperlinks are provided for the developer to open the advice which will be executed at the shadow. These annotations are an intuitive way of keeping the developer alert to the interaction of Aspect and base code in the system he is working with. E a c h of these tools provides the developer with an important view o f how the aspect code is interacting with the base code. However, none of the tools directly supports the editing of pointcut expressions. It is up to the developer to deduce from the current set of join points how and why a pointcut expression is failing to match shadows he wishes to capture. Additionally, none of these tools are  effective;  they present information  dynamically, but provide no support in diagnosing or fixing problems. Therefore, if the developer needs to troubleshoot a pointcut that is capturing too many join points, he must first navigate to the advice which will execute at the join point. Then he must navigate to the pointcut on which the advice is based. H e must then begin an iterative process of changing the pointcut and observing join points listed in the outline view until the correct set appears.  PCDiff P C D i f f [18] provides the same information as the Crosscutting Comparison View of A J D T , but with a better visualization. T h e tool uses three different types of views. Firstly, if a change the developer has made in the base code has added or removed a join point, a  plus or minus sign  appears in the gutter next to the affected position. A d -  ditionally, the creators of this tool make use of the Eclipse task view. Entries to the task view are made every time a shadow is added or removed. Should the developer find that a change he has made has negatively impacted the Aspect's functionality, he may find this view very useful to scan through, in order to diagnose the problem. Lastly, the tool provides a separate view which is very similar to the Crosscutting Comparison View. A s the shadows are added or removed they appear in a structured view which lists the Java compilation unit, the Java class, the shadow type, and the advice whose join points have been affected. Although this tool provides the developer with a better visualization than A J D T for how a change has impacted the number of join points, similarly to A J D T it provides no assistance in diagnosing or fixing the associated pointcut.  13  2.3  Conclusions  Our dissertation states that it is possible to construct IDE-based tools that allow editing of AspectJ pointcut expressions through direct manipulation of effective representations of join points in the code to which a pointcut applies. In this chapter we presented two groups of work focused on supporting the developer in creating and editing pointcut expressions. T h e first set of works presented language-based features geared toward allowing the developer to match join points based on their properties rather than on their patterns. T h e first group developed an environment with support for editing Soul pointcutexpressions  by example.  The second group provided support that allowed the developer  to annotate and match join point shadows with Java annotations. The second group of works presented tool support for managing pointcut expressions. T h e first work we looked at was the A J D T tool suite. T h e tools in this suite were designed to illustrate the relationship between AspectJ aspects and the base code. This involved gutter annotations at join point locations, and a cross-references  view  that provided an outline of information regarding local join points. T h e second tool,  PCDiff,  was focused on alerting the developer of any impact on the set of local join  points that a current refactoring or editing of the code was having.  14  Chapter 3 The Tool T h e Pointcut Wizard is unique because it allows the developer to edit a pointcut expression from the location of the join point shadows. This support is made possible through the use of  effective  gutter annotations. The operations supported by the Pointcut W i z -  ard include adding or removing shadows in the code from the set o f shadows matched by a pointcut expression. A s the developer explores the base code, shadows matched by the pointcut are shown with annotations in the gutter of the editor next to the line where the shadow exists. A s shadows are added or removed through either interaction with the gutter annotation or direct manipulation of the pointcut expression, the gutter annotations are refreshed to reflect each change. This chapter will begin with a more formal description of the AspectJ pointcut language and an explanation of the features the Pointcut Wizard supports. Following that, we will give a detailed explanation of how to use the Pointcut Wizard to edit a pointcut while browsing Java code. Additionally, we will explain the transformation effected on the pointcut expression through operations performed by the Pointcut Wizard.  3.1  The AspectJ Pointcut Language  T h e Pointcut Wizard is able to parse and annotate shadows for lexical-structure based pointcuts, binding pointcuts and a subset of kinded pointcuts. In this section we will 1  explain each of these categories and which members of each category are supported by the tool. Kinded pointcuts: are pointcuts that each match a corresponding category of join points. F o r example, the e x e c u t i o n pointcut matches method executions and the c a l l pointcut matches method calls. Table 3.1 is a listing of all kinded pointcuts in AspectJ version 1.1. The Pointcut Wizard supports a subset of kinded pointcuts. In the table, the right-most column states whether the pointcut for that row is supported or not. We believe that the subset of kinded pointcuts we implemented for the prototype of the Pointcut Wizard is enough for a developer to use the tool effectively. We plan to add support for the rest of this set in production versions of the tool. We describe our plans to do so in the  Future Work section  of Chapter 5.  Lexical-structure based pointcuts: are pointcuts that capture all join points occurring inside the lexical scope of specified classes, aspects or methods. The Pointcut Wizard supports each of the two lexical-structure based pointcuts of the AspectJ pointcut language - shown in Table 3.2. 'This categorization of pointcut expressions was used in [14]  15  '  Table 3.1: Kinded Pointcuts Join Point Category  Pointcut Syntax  Method execution Method call  execution(MethodSignature) call(MethodSignature)  Supported by PW yes yes  Constructor execution Constructor call  execution(ConstructorSignature) call(ConstructorSignature)  yes yes  Class initialization Field read access Field write access  staticinitializatiion(TypeSignature) get(FieldSignature) set(FieldSignature)  no • yes . yes  Exception handler execution Object initialization Object pre-initialization Advice execution  handler(TypeSignature) initialization(ConstructorSignature) preinitialization(ConstructorSignature) adviceexecutionQ  no no no no  Table 3.2: Lexical-Structure based pointcuts Pointcut Syntax  Join Point Category  within(TypePattern)  Any join point occurring within a class or aspect  withincode(MethodSignature)  Any join point occurring within a method body  withincode(ConstructorSignature)  Any join point occurring within a constructor body.  Binding pointcuts:  can be used in two ways.  First, if the developer wishes to  access an object's state at run-time, he can edit the pointcut expression by hand to take an object of that type as an argument. H e can then use a binding pointcut to bind the argument to run-time objects during program execution. Second, the developer can pass a type name to a binding expression. A n y run-time object that matches a binding pointcut in both category and signature will be matched by the pointcut. F o r example, in Table 3.3 below, there is a binding pointcut o f type this.  If a developer were to use this pointcut and pass to it as an argument a type  F o o , the pointcut would match every join point in the code where t h i s is of type Foo. Table 3.3 presents a list of all binding pointcut types: To support binding pointcuts, the Pointcut Wizard performs a static analysis on the code to determine (and annotate) all join point shadows where the run-time object is possibly of the type passed to a binding pointcut as an argument. However, it does not allow the developer to create pointcut designators of this type while browsing the code. To make such a feature useful, the P W would need to also support the developer in selecting variables and fields in the code that he wishes to bind. We do believe each of these features is useful though - a topic we discuss in the Future Work section of Chapter 5.  Control-flow and conditional pointcuts,  shown in Table 3.4, are dynamic point-  cuts and do not have a direct representation in the source code. The conditional check pointcut if also depends on run-time information to determine a shadow and was therefore not included. A developer using A J D T is alerted to the dynamic nature o f a join point shadow by  16  Table 3.3: Binding pointcuts Pointcut Syntax  Join Point Category  thisfTypePattern or Object Identifier)  A l l join points where t h i s is an object of the type passed as an argument to the pointcut.  target(TypePattern or Object Identifier)  A l l join points where the object on which a method call is performed is of the type passed as an argument to the pointcut.  args(List of TypePattern or Object Identifier)  A l l join points where the method or constructor signature matches the list o f types passed in as an argument to the pointcut.  Table 3.4: Control-flow and conditional pointcuts Pointcut Syntax  Join Point Category  cflow(pointcut)  A l l join points in the control flow of any join point  cflowbelow(pointcut)  A l l join points within the control from of any join  matched by the pointcut passed as an argument. point matched by the pointcut, excluding the actual join points themselves. if(boolean expression)  Does not match any join points, only evaluates to a boolean value.  17  tool-tips that state a run-time check is performed at that location. The Pointcut Wizard prototype does not support these types of pointcuts. In order to support them, the tool would require a more expressive user interface. also need a  resolver  It would  component capable of resolving c f l o w pointcuts. Our thoughts  on design features to address these issues are discussed in the  Future Work  section of  Chapter 5 .  3.1.1  W i l d - c a r d symbols  The Pointcut Wizard's support for wild-card symbols can be best explained broken down into two categories: support for finding all shadows that match a pointcut expression, and support for building pointcut expressions with wild-card symbols based on examples from the code. We will discuss the extent of support for each category here. The three wild-card symbols that AspectJ supports are " * " , "+", and " . . " . The following list presents an explanation of the meaning of each type of wild-card, as well as the extent to which each is supported by the Pointcut Wizard. The  star pattern, " * " ,  denotes any number of characters except the period. Using  this pattern the AspectJ developer is able to form regular expressions to match patterns in the code. For example, he can match all method names that contain the word log with the following expression:  *log*.  Using AspectJ, the star can be used at the  middle, beginning, end or both sides of a set of characters. The Pointcut Wizard supports the star pattern only for the case where the star is not combined with any other characters. A developer can therefore either use a star to capture  all  names or he can use the actual name. In our  Future Work  section in Chapter  5 we present our plans for providing full support for the star pattern in a future version of the Pointcut Wizard. The  plus pattern, "+"  denotes all  sub-types  of any type name it follows. For ex-  ample, the following pointcut:  pointcut starPatExO: c a l l ( *  Foo+.*(..));  will match any method call where the receiver class is of type F o o or any of its subtypes. This operator can be used on any type name, in any type of pointcut designator AspectJ supports. The Pointcut Wizard does not currently support this operator. The  dot-dot operator " .  . " denotes any number of characters including any num-  ber of periods. Using this pattern the developer is able to match fully qualified path names and lists of arguments. Consider the following example:  pointcut dotDotPatEx(): c a l l ( * j a v a . u t i l . . * . * ( . . , Bar)) The receiver of this method call can be any type contained j a v a . u t i l or any of its sub-packages. T h e arguments list can match any arguments list as long as it ends in type B a r - including the case where B a r is the only argument. The Pointcut Wizard prototype supports the use of this pattern in place of an arguments list to match signatures with any number of arguments.  18  3.2  A User Interface for Shadow Browsing  In this section we will present the user interface for exploring the set of shadows matched by a pointcut expression. T h e developer can begin using the Pointcut Wizard view by opening an Aspect. The view organizes information about the Aspect as a tree hierarchy, with the Aspect as the root node, pointcut expressions as child nodes of each Aspect, and shadows as the children of each pointcut. T h e view on the left-hand side of Figure 3.1 shows an example of an Aspect open for editing in the Pointcut Wizard view. In the view the top level node, named  Pointcut Shadows,  notes the selection made by the developer  to reveal all shadows matched by a pointcut expression in any of the Aspects with which the developer is working. Selecting any of the nodes in this view will open the associated program element in the code editor. In this example, the developer has opened the node for a pointcut named  callsWithinFire.  all join point shadows in the code that match  SoundEffects Aspect and selected  the  The node has expanded to reveal a list of  callsWithinFire.  T h e expression for the  pointcut is shown bellow. It was written to capture all method calls made from within the method f i r e in class S h i p .  pointcut callsWithinFire(): (call(* *.*(..)) && withincode(void S h i p . f i r e ( ) ) ) ; To view shadows in the Java code editor, the developer must select an A c t i v e Pointcut.  In order to reduce the complexity involved in navigating context menus at the  shadow sites, only the shadows for an active pointcut are shown in the code editor. When a pointcut is  active, context menus  at join point shadow sites pertain only to that  particular pointcut. To make a pointcut active, the developer must select that option from a context menu at the pointcut node in the Pointcut Wizard view. Once the developer has chosen an active pointcut, lines in the code editor that contain a shadow matched by the pointcut are marked by a pointcut gutter annotation. In Figure 3.2, the developer has selected  callsWithinFire  as his active pointcut. T h e  lightning bolt gutter annotations along the left-hand side of the code editor each signify that at least one matched shadow exists on that line.  19  '©-JQuery sf\  ~  ~  $  1 7 °  B  21  iTree 1:SpaceWar 1 /*.?• create a b u l l e t and f i r e i t void fire')  i Tree | Console |  V  (  I E © fttntcut Shadows'  / / • f i r i n g a shot takes energy  |  if  SouidEffects  ; lexper.dEr.ergy (SSLLfT_£K£RC?Y)): return;  acceleratecaDsWithifire —:?S1 fire calls experidEnergy  //create  --tej fire calls getGame  double xV = getXVelO + EULLET_S?EE2  a b u l l e t object so i t doesn't h i t the ship t h a t ' s f i r i n g  - - t e l fire calls.getSze  double yV =. getTVel() +' BULLET SPEED * (Hath.sin(orientation) ];  * (Hath, cos (orientation) j ;  ~ t e j fire cals get5ze - f e i fire cab.geOTos  //  it  n  create the actual b u l l e t  - t e j fire caDs getXVel - f e j fire cafe.gecYPqs --fejfirecals.getyVel gurfte maiiMethod planesCdfcfc playerDead  hew B u l l e t ( getGame 0 , (getXPpsO +  [getSize()/2 + 2)  (Hathi-cos (orientation)')')'  + xV),  (getYPosO +  (getSize()/2 +. 2)  (Hath.sin(orientation)))  +. yV),  xV, yV) ; ;  Figure 3.1: The Pointcut Wizard  1  1  — v,  ;  1  :[|J|5liip.java-^\n SodncEffects.aj  '•  -  1 Tree 1: SpaceWar |  '  li  -  Tree | Console | ,'  .  "  ••  '  - • "  :  L  B~®- Pointcut Shadows: ' B 0  if  accelerate  ESEG23 h-tED fire calls expendEnergy j~~?53| fire calls getSanie •h'Jt fire calls getSze  void f i r e ( )  '—~  ^  ;  °'D  d  i t . */ •  •,  •  {  <.j j  (  //• f i r i n g a s h o t - t a k e s energy  SouridEffects  B-9  /**• c r e a t e a b u l l e t and f i r e ... • -•>-•  ; .  Jgf^  (IexpendEnergy(BULLET__ENERGYi ) :  j  return;  m  1  1  //create'--a b u l l e t - o b j e c t :30 i t - d o e s n ' t , h i t - t h e ' s r i i p - t h a t ' s f i r i n g  it  doable xV = getXVei() +.BULLET SPEED * ( H a t h . c o s ( o r i e n t a t i o n | ) ; double yV = getYVelt) •+. BULLET_SPEED  * (Hath; sin (orientation));  g^,  • t=D fire calls getSize //  j-- fcp fire calls getXPos' !~ t s | fire calls getXVei' l--fel fire calls getYPos" j-^'fire'cailsgetvyei a-?  gunfire  3 9  iriainMethod  % 9  planesColtde  B-9  playerOead  1 if  If  create t h e . a c t u a l b u l l e t  &  ''  ^%'-  ' '  '  .new B u l l e t f getGameilv  :  |t§« ,  . . . . . . . .  (get-XPosfj + ((getSize (]/2.+.:2) * (Hath-, cos (orientation)')) + xV), Multiple markers at this line; .. ,'\. . . . . .... n) | ) . + ' y V ) , - Method Cai: "int sj^war.Ship.getSzeO" shadowVeated by pointcut'calsW - Method Cai; "doublespacewar'.Sp^eObject.qetYPosO" shadow created by pointcut caUWithiriFire  Figure 3.2: Pointcut callsWithinFire is now an Active Pointcut  CJi ||t Sf§&  Since more than one join point shadow may exist on a particular line, the developer can hover over an annotation to view a tool tip listing the pointcut, the shadow, and the type o f shadow for each shadow in mat line of code. In Figure 3.2, he has prompted a tool tip which reveals the two shadows on a line of the f i r e method: a method call to S h i p . g e t S i z e () and a method call to S p a c e O b j e c t . g e t Y P o s ( ) . We will now explain how the developer can interact with a menu structure at these shadow sites to effect changes in the active pointcut.  3.3 The UI for Editing Pointcuts In this section we will illustrate the process a developer can use to edit a pointcut while browsing code with the Pointcut Wizard. There are a range of possibilities for implementing a system where the developer can edit a pointcut by selecting examples from the code. The most popular o f these is by applying inductive logic. In Chapter 2 we presented an example of such work [4] where a pointcut editing environment used inductive logic to reason about the examples using information based on the current structure of the pointcut expression combined with information from a database containing all structural relationships of the program. However, in order to build this tool, the authors used a logic language called Soul to express and edit pointcut expressions. T h e Pointcut Wizard was designed to work with AspectJ pointcut expressions, which are written in a less expressive language than Soul. Therefore, the information used in performing an edit operation on a pointcut comes only from the join point shadow chosen as an  example  by the developer.  Because it is unclear what the developer is interested in when selecting a shadow as an example, the Pointcut Wizard uses what we call a  most-specific  description to  identify it. This description identifies a shadows type, its signature, and the lexical context within which it exists. This set of properties regarding a shadow make up what we call the  Shadow Model component  of the Pointcut Wizard. A further explanation of  the model will be presented in Chapter 4. In the remainder of this section we will present the user interface for a d d i n g and removing shadows matched by a pointcut expression. Following the description of each operation, we will also present the impact for each type of operation on the pointcut expression.  3.3.1  A d d i n g Shadows  Using the Pointcut Wizard to add a shadow is a very simple process. To illustrate the steps involved, we will continue with the same example from Figures 3.1 and 3.2. In the previous examples, the pointcut expression  callsWithinFire  ture all method calls made from within S h i p . f i r e ( ) . had written a  tracing  was used to cap-  Suppose that the developer  advice with the intention that it trace  all outgoing  calls from  f i r e . If this were the case, the developer would soon realize that the constructor call to B u l l e t was not being included in the trace. The reason is that a  call pointcut  can  use a method signature or a constructor signature, but one signature type can not match  22  both types of join points. In the remainder of this section we will highlight the steps involved in using the Pointcut Wizard to change  callsWithinFire  so that it captures the  constructor call. A s a first step, the developer navigates to the f i r e method in the class S h i p . H e then opens the Pointcut Wizard view and selects  callsWithinFire  as his active pointcut.  Once the shadows have been marked with a gutter annotation (as shown in Figure 3.2), the developer notices that there is no gutter annotation next to the constructor call to Bullet. To add the constructor call to the set of shadows captured by  callsWithinFire,  the  developer opens a context menu at the shadow site, as shown in Figure 3.3 on page 24. Under the  Joinpoint Shadow Operations sub-menu, he  selects the option:  add Constructor C a l l : spacewar.Bullet.new(Game, double, double, double, double)'' to pointcut callsWithinFire 11  A s shown in the figure, the Pointcut Wizard includes the structor call), the full double,  inFire).  double,  signature double,  type of  the shadow (con-  of the shadow ( s p a c e w a r . B u l l e t . n e w ( G a m e , d o u b l e ) and the active pointcuts name  {callsWith-  Once the section has been made, both the Pointcut Wizard view and the code  editor are refreshed to show the new shadow being captured by  callsWithinFire.  developer runs the trace program and finds that the fix was successful.  23  The  •  /**  SoundEffects.aj  create a b u l l e t  void  fire()  and f i r e  it  */  {  //  firing  if  (i e x p e n d E  a shot  takes, energy  riergy(BULLET_ENERGY)  t  )  return; //create  a bullet  object  doesn't  hit  the  ship  that's  firing  xV. -  + BULLET_SPEED  *  ( H a t h , cos ( o r l e n t a t i o n ) ) ;  double  yV = g e t Y V e l ( ) ' ; + BULLET_SPEED  *  (Hath, s i n ( o r i e n t a t i o n ) ) ;  //  create  getXVel()  the  it  :  actiial'.bullet  ze()/2 + 2), * ze()V2 + 2f *  Breakpoint Ptoperhes  4^  so i t  double  ( H a t h , cos ( o r i e n t a t i o n )  )) + xVJ>  ( H a t h . s i n ( b r i e n t a t i o n ) )')  + yV) ,.  :Go;to.'Afjnotatfqn_.^ !Run As .Debug As. -.Team •  \. ,  •Compare With Replace With Add Bookmark,.. MddTask!.. Shew Quick Dfffy  Gtri+SNft+Qr  ' ^Show Une Numbers" Folding - Preferences., r Joinpoint Shadow Oper-atior  add Constnjctor Call "spacewar.Bullet.new(<jarne, double, double, double, double/ to pointcut callswithmFire  Figure 3.3: Adding a Constructor C a l l to the Active Pointcut  Impact o n the Pointcut Expression The Pointcut Wizard uses detailed information about a shadow when forming the pointcut to append to the current pointcut expression. In the above example, before the developer had used the tool to change the pointcut expression, it had appeared as follows:  pointcut callsWithinFire(): (call(* *.*(..)) && withincode(void Ship.fire() ) ) ; When the selection was made, the Pointcut Wizard queried the site for the full signature of the Bullet constructor and the method from within which it was made. A l l of this information was used in creating the  most-specific pcd, as  follows:  call(spacewar.Bullet.new(Game, double, double, double, && withincode(void Ship.fire())  double))  T h e current implementation of the Pointcut Expression uses detailed information to describe the join point shadow so that no false positives are formed when the active pointcut expression is edited to match the new join point. Following the a d d operation, the pointcut expression will look as follows:  pointcut callsWithinFire(): ((call(* *.*(..)) && withincode(void Ship.fire 0 ) ) | | (call(spacewar.Bullet.new(Game, double, double, double, double)) && withincode(void Ship.fire()))) A side effect of this method, however, is that the pointcut expression grows considerably longer with each newly added shadow. O u r methods for dealing with this issue are presented in the following chapter, where we explain the tool's implementation.  3.3.2  Removing Shadows  To illustrate the process of removing shadows from the set of shadows matching a pointcut, we will continue with our  callsWithinFire example.  Suppose that while the developer was inspecting the shadows within the method S h i p . f i r e ( ) , he realized that the call to S h i p . e x p e n d E n e r g y should not be captured by the pointcut. To remove this shadow, the developer must open the context menu, as shown in 3.4, and select the following option:  remove Method C a l l : 'boolean spacewar.Ship.expendEnergy(double)'' from pointcut callsWithinFire 1  Once the selection has been made, the Pointcut Wizard gathers a set of detailed information about the shadow and generates the following pcd:  call(boolean spacewar.Ship.expendEnergy(double)) && withincode(void Ship.fire ())  25  Because the selection was to remove the shadow from the set o f shadows matching the pointcut expression, the pcd is negated and then appended to the pointcut with a logical A N D . Having used the Pointcut Wizard to add a shadow and remove a shadow, the developer has fixed the incorrect pointcut expression without ever leaving the code where the shadows exist. Additionally, the pointcut expression callsWithinFire, shown below, has been edited in a methodical manner, so that it can be read and edited directly if necessary: (  ((call(* *.*(..)) && withincode(void Ship.fire())) && !(call(boolean spacewar.Ship.expendEnergy(double))))  I I (call(spacewar.Bullet.new(Game, double, double, double, double)) && withincode(void Ship.fire 0)) )  T h e resulting pointcut expresses the same semantic meaning, but has been normalized. T h e technique used is described in Chapter 4.  26  •  SouridEffects.aj •  create a b u l l e t void  fire() //  !  Toggle Breakpoint  :  and f i r e  i t *•/  {  firing  a shot  takes energy  '==^;^ . . , ^ = ^ T t j r :  ENERGY)  j;  'A ect *'Go to Annotation Run As-:  .-ctwi  + +  so i t doesn.' B ULLET_  SPEED  BULLET_SPEED  hit  the ship  that's  firing  (Hath.,cos ( o r d e n t a t i o n ) )  •,  (Hathvsi'22 (or i e n t a t ion) ) ;  Debug As bullet  Team Compare-With  ,  %1 <i  Replace .With" Add Bookmark... Add Task!:. yjShowQuick ' Show Line'Numbers Folding- • . Preferences":.', Joinpoint Shadow Operations  yCJtVl+SHiffc+'Q"  t  ze()/2  + 2)  ze'()••/2 + 2)  J  * (Hath; cos ( o r i e n t a t i o n ) ) ) + xV) , * (Hath, sin  (orientation);)')- +. yV) ,  31111  -  J  1  1  remove Method Call "boolean spacewar.Ship.expendEnergy(double)" from pointcut callsWithinFire  add Reld Get_"int Ship.BULLETJENERGY" to pointcut callsWithinFire  Figure 3.4: Removing a Method C a l l from the Active Pointcut  3.3.3  Evaluating the Resulting Expression  The original intention of the c a l l s W i t h i n F i r e pointcut expression was to capture all calls made from within the method S h i p . f i r e ( ) . T h e original version of the pointcut appeared as follows:  pointcut callsWithinFire(): (call(* *.*(..)) && withincode(void Ship.fire() ) ) ; T h e developer then edited the pointcut twice. T h e first edit was necessary because the pointcut did not capture constructor calls made from within S h i p . f i r e ( ) . The add operation he performed with the Pointcut Wizard resulted in the following expression:  ((call(* *.*(..)) && withincode(void  Ship.fire()))  I I (call(spacewar.Bullet.new(Game, double, double, double, double)) && withincode(void Ship.fire()))) T h e developer then performed a r e m o v e operation using the Pointcut Wizard to express his new intention to capture all method and constructor calls  except  the one to  S h i p . e x p e n d E n e r g y . The edit resulted in a pointcut of the following form:  ( ((call(* *.*(..)) && withincode(void Ship.fire())) && !(call(boolean spacewar.Ship.expendEnergy(double)))) II  (call(spacewar.Bullet.new(Game, double, double, double, double)) && withincode(void Ship.fire()))  ) We compare this to the following  best case form o f  the pointcut expression.  ((call(* *.*(..)) | | call(*.new(..)) && withincode(void Ship.fire()) E a c h version of the pointcut expression c a l l s W i t h i n F i r e correctly matches all intended join points.  However, the use of wild-card symbols in the second version  creates a pointcut expression that matches not only the constructor call to B u l l e t , but also any other constructor calls that may exist in a future version of the method. In future versions of the Pointcut Wizard we plan to increase support in the user interface for allowing the developer more freedom in creating a pointcut expression that best reflects his intentions. One possible option is presented in the  Future Work  section o f Chapter 5. The Figure 5.1 on page 45 presents a mock-up of a possible user interface that provides the developer with check-box options for specifying which properties of a signature should be used to match join points.  28  3.4  Conclusion  This chapter covered two aspects of the Pointcut Wizard design. The first half of the chapter provided an explanation of the types of AspectJ pointcut expressions the tool currently supports. Following that explanation we provided an overview of the user interface presented to the developer for the adding and removing of shadows from the set matched by a pointcut expression. We felt it was important to provide a brief explanation of the types of changes a developer using the P W will see in a pointcut expression after performing a d d or remove operations. This explanation was provided as an overview of the tool's functionality, rather than as an explanation of how the tool is implemented. In Chapter 4 we take a more detailed approach to describing the implementation of the Pointcut Wizard.  29  Chapter 4  Implementation 4.1  Introduction  In this chapter we will present the design of the Pointcut Wizard. First we will begin with an overview of the tool's architecture. T h e Pointcut Wizard tool consists of four components: the  shadow model,  the  disambiguator,  the  normalizer  and the  resolver.  T h e shadow model was built to model all join point shadows in the code. T h e other three components share information pertaining to a shadow based on this model. T h e disambiguator is responsible for deciding the meaning of an operation performed at a join point shadow and then mapping the information found at the join point site to a poincut designator that will match it. T h e normalizer is responsible for reducing the pointcut to normal form. D o i n g so allows the Pointcut wizard to remove redundancies that may appear in the pointcut expression following successive  add  and remove  operations. The resolver is responsible for identifying the set of shadows in the code which match the pointcut expression. This information is sent to the user-interface so that each shadow can be identified with a gutter annotation. The data flow between these components is illustrated in Figure 4.1. To understand the diagram, imagine that a developer has selected an  active pointcut  and opened the  Pointcut Wizard menu for a particular line of code. Before the menu is opened, the disambiguator queries the shadow model for the set of shadows that exist on that line. If the shadows are currently matched by the pointcut expression, the tool presents the shadows information with a  remove option, and  if a shadow is not currently matched  by the expression, the tool will present an add operation. T h e tool then waits for a developer to make a selection from the menu. Once a selection has been made, the disambiguator creates a pointcut expression PCD' matches the selected shadow.  that  Then, depending on the operation selected, the tool  acts one of two ways. If the add  operation has been selected, the tool forms a new  pointcut PCD' by O R i n g the active pointcut PCD with the pointcut that matches the selected shadow PCD'.  If a  remove operation  is chosen, the tool creates PCD' by  A N D - N O T i n g PCD with PCD'. The outcome PCD' of whichever operation has been chosen is then taken by the normalizer component which reduces it to normal form. The newly formed pointcut expression is then written to the aspect as a replacement for the active pointcut. The resolver component then annotates all join point shadows that match the new version of the pointcut expression. The remainder of this chapter will provide a more detailed description of the implementation of each of these four components.  30  [•  ..  . . . . . . . . .  %  User .Selects ADD or REMOyE.at shadow .site. ;  JResolver !  NF Adeniify Shadows that match PCD"  Figure 4.1: Data F l o w Between Components  31  4.2 The Shadow Model T h e shadow model is used by the Pointcut Wizard to model all shadows in the code. It is used by the other components of the tool as a mechanism for sharing information regarding shadows. In this section we will illustrate the design and implementation of the model. The shadow model was built on top of a source code browser called JQuery [10]. JQuery uses a declarative database as a back-end to query on properties of elements of a code base. When the Pointcut Wizard is being used, the properties of each shadow in the code can be modeled using this same database. T h e class diagram in Figure 4.3 on page 34 is a representation for all of the properties stored in the database for each shadow in the code. The diagram shows that all shadows contain a S o u r c e L o c a t i o n field which represents their location in the source code. Each SourceLocation  object in the database is unique. Therefore, the  shadow model can extract information about a shadow from the database based on a location in the source code. A s an example of how the shadow model is used, suppose the developer wishes to perform an add operation for a shadow on a particular line of code. The  disambiguator  component first creates a query that returns all shadows whose location in the source code lies within that line. Then, another query is performed to find the types o f shadows that exist on that line. The possible shadow types are represented by the third layer of the hierarchy in Figure 4.3. When the shadow types for the shadows that exist on a line of code are known, the signature properties for those shadows can be found through another set of queries. The shadow types must be known before these queries can be created because different shadow types are parameterized by different signature properties. T h e second layer of the hierarchy in Figure 4.3 represents the three categories of shadows that the Pointcut Wizard supports. The difference between the categories of shadows are the signatures by which they are parameterized. The C a l l S h a d o w and F i e l d A c c e s s S h a d o w shadow types each contain a thisSignature field which is of type S i g n a t u r e P a t t e r n . A class diagram representation of signature types is shown in Figure 4.2. T h e diagram shows that an object of type S i g n a t u r e P a t t e r n will either be a constructor signature or a method signature. This is logical, because a field access or call site will be made either from within a constructor or a method call. Each of the shadow types expressed as the third layer of the shadow model hierarchy is parameterized by a targetSignature.  This signature represents the signature  properties of the shadow itself, so each type of shadow contains a targetSignature of the appropriate type. In the next three sections we will describe the implementations of the components illustrated in Figure 4.1.  32  Signature:  TypeSlgnature' -type ^;ExaclNarnePattem"  SignaturePattern  FlejdSlgnature -type: Exac'NaciiePaltem -name;: E x a c t N a m e ^ U e r r t ; TClassNaine.: E x ^ t N a m e P a i W n  MathodSlgnature ^a^t^'^B«(K^rri<^tt.«m'. insturnTypeJ ExacWirrKrfatterri':. :riarne;:: watlNameRanefh'". •aips^ExactNam^  ConstructorSignature dareNama. : :ExacttoiTiePattern args •: ExactNamePat.ern ;  Figure 4.2: Shadow Signatures  33  Shadow ^sourceliocation: SourceLocatiocv  Cat/Shadow  ExecutionShadow  ReldAccessShadow  thisSignature: SignaturePattem  HhisSignature: SignaturePattern  ConstructorCallShadow  •targBtSjghature: CdnstrucmrSigfiatura  ConstructorExecutionShadow  FieldGetShadow  •targetSignature.: Cor.structocSignature  [•targetSignature,:.Fie[dSigiiature  MetHodCallShadow  MethodExocutionShadow  targetSignature: MethodSignature  targetSignature: MethadS^natuie  s h a d o w types Figure 4.3: The Shadow M o d e l  FloldSotShadow :  targetSlgnatur6":. FialdStgnature.  4.3  The Disambiguator  The disambiguator is responsible for deciding the meaning of an operation performed at a join point shadow and then mapping relevant information from the shadow site to a pointcut designator.  In this section we will describe the implementation of the  component. When the developer selects an active pointcut, the resolver component of the Pointcut Wizard creates a representation for each shadow in the code that it matches. T h e U I of the tool then creates menu options at each site where a shadow exists. When the developer selects an option, the disambiguator builds a new pointcut designator based on the type of operations selected  (add or remove) and information based  on the shadow  model's representation for that shadow. In the current version of the disambigutor,  add and remove operations  translate to  logical operations on pointcut expressions. Figure 4.1 on page 31 provides an overview of each operation. The diagram shows that when the developer selects an add opera-  OR of the active pointcut remove oppointcut from the active pointcut  tion, the disambiguator forms a new pointcut from the logical and the  most specific  pointcut which matches the selected shadow. If a  eration is selected, the disambiguator forms a new  AND-NOT the selected shadow's most specific pointcut. The most specific pointcut is the pointcut that matches  the smallest set of join points  that includes the shadow. This may at times include more shadows than the developer has selected. F o r example, if two call sites with the same signature exist within the same method, there is no way for the developer to specify one and not the other using AspectJ - and therefore the Pointcut Wizard. If new versions of the AspectJ language grow to support such cases, the shadow model of the Pointcut Wizard will be adapted to fit the new semantics. T h e properties of a join point that the Pointcut Wizard uses to specify a most specific pointcut are based on AspectJ's join point model. T h e AspectJ join' point model can be divided into two areas: dynamic join points and statically determined join points. Statically determined join points are the join points which have a direct representation, or  shadow  in the code.  Dynamically determined join points are unknown until the  program is running. T h e prototype version of the disambiguator only supports statically determined join points, although the  Future Work  section of Chapter 5 presents our  plans for extending the tool's support to cover dynamically determined join points as well. A statically determined join point can be expressed in AspectJ using two types of pointcut designators:  kinded  pointcuts and  lexical-structure  pointcuts.  A s noted  in Chapter 3, kinded pointcuts each match a type of action that may occur during the execution of the program, such as a method call or execution. Lexical-structure pointcuts match join points based on where they exist in the source code. To create a most specific pointcut to match a shadow, the Pointcut Wizard creates a pointcut AND'mg the kinded pointcut and the lexical-structure pointcut for that shadow. There are other possibilities for disambiguating an operation performed at a join point shadow. For example, in Chapter 2 we presented inductive logic as a means of interpreting operations on join point shadows [4]. T h e pointcut editing environment presented in this work uses information from the current state of the pointcut as well  35  by  as from the shadow site to make a best guess of the intentions behind the developers'  add or remove operations. We believe that there would be benefits to providing the developer with more control in specifying the properties of a join point shadow he is interested in matching with the pointcut. A l s o , we believe that support for dynamic pointcut designators such as c f l o w and i f is possible. Each of these ideas are discussed in the  Future work  section of Chapter 5.  4.4 The  The Normalizer normalizer  is responsible for maintaining the active pointcut in normalized form  while the developer edits it through effective representations of the shadows it matches. B y maintaining the pointcut expression in a  normalized form,  the Pointcut Wizard  is able to reduce the occurance of pointcut expressions which either conflict with each other or imply one another. Both of these situations make the pointcut unnecessarily difficult to understand and edit. For example, the following pointcut expression specifies method execution join points with two sets of disjunct properties. (execution(* Bar.foo(..))  && e x e c u t i o n ( v o i d *  *(Zed)))  A normalized pointcut with the same semantic meaning would appear as follows: execution(void  Bar.foo(Zed))  In this section we describe how the normalizer is constructed. First we illustrate how each AspectJ pointcut expression is broken down into a more primitive but equivalent logic expression for testing properties of the join points. Following that, we describe the normal form of the logic expression, which the normalizer uses as an internal representation of the pointcut expression. Last, we explain how this internal representation is converted into an equivalent AspectJ pointcut expression which matches the selected join point shadows.  4.4.1  Rules for Converting an AspectJ pointcut to an Expression on Join Points  In this section we present the set of rules the normalizer uses to convert AspectJ pointcuts to a more primitive expression over join point properties. The language in which this internal representation of pointcuts is expressed can be thought of as of the Aspec J pointcut language with three additional expressions: TRUE :  This expression trivially matches any pinpoint This expression doesn't match any joinpoints.  FALSE :  <property_name>  ==  <property_Value>  This expression matches if the join point property denoted by propertyName is of the value propertyValue. The following is a list of transformations the normalizer uses to convert k i n d e d and l e x i c a l pointcuts supported by the Pointcut Wizard. For each type of pointcut,  36  a breakdown of the property tests-performed implicitly by the pointcut is followed by the semantically equivalent expression used by the normalizer.  method call: c a l l ( <return_type> <class_name>.<name> (<args>) )  converted to: actionType==call && target.signatureType==method && target.returnType==<return_type> && target.className==<class_name> && target.methodName==<name> && target.args==<args> constructor call: c a l l ( <class_name>."new" (<args>) )  converted to: actionType==call && target.signatureType==constructor && target.className==<class_name> && target.name=="" target.returnType=="" && target.args==<args> method execution: execution) <return_type> <class_name>.<name> (<args>) )  converted to: actionType==execution && this.signatureType==method && this.returnType==<return_type> && this.className==<class_name> && this.methodName==<name> && this.args==<args> constructor execution: execution( <class_name>."new" (<args>) )  converted to: actionType==execution && this . signatureType==construc.tor && . this.className==<class_name> && this.name=="" && this . returnType= = " && this.args==<args> 11  37  field get: get( <field_type>  <container_class>.<field_name>)  converted to: actionType==<fieldGet> && target.returnType==<field_type> && target.className==<container_class> && target.name==<field_name> field set: set( <field_type> <container_class>.<field_name> )  converted to: actionType==<fieldSet> && target.returnType==<field_type> && target.className==<container_class> && target.name==<field_name> within method code: withincode( <return_type>  <class_name>.<name>(<args>  converted to: actionType==withinCode && this.signatureType==method && this.returnType==<return_type> && this.className==<class_name> && this.methodName==<name> && this.args==<args> within constructor code: withincode( <class_name>."new"(<args>)  converted to: actionType==withinCode && this.signatureType==constructor && this.className==<class_name> && this.name=="" && t h i s . returnType== && this.args==<args> 1111  38  )  within: within(<className>)  converted to: actionType==within && this.className==<className> In Chapter 3 the Pointcut Wizard's support for matching join points by using wildcards was discussed. To summarize here: the tool supports the wildcard symbols "*" and ". . " when they are not used in conjunction with other characters to express a join point property. In the normalizer's property expression language, the "*" and " . . " wild-cards are represented by the absence of a property expression of that type. The empty string is used for the name and r e t u r n T y p e properties of constructor signatures for the c o n s t r u c t o r c a l l , c o n s t r u c t o r e x e c u t i o n a n d c o n s t r u c t o r w i t h i n c o d e pointcut types. At the implementation level, this allows the normalizer to treat the arguments for these types of pointcuts similarly to the corresponding method pointcuts.  4.4.2 PCDNF: A Pointcut Expression in Disjunctive Normal Form When all AspectJ primitive pointcut expressions have been broken down into more primitive property tests as described above, it is relatively straight forward to use logic laws such as DeMorgan's law to reduce this expression into a disjunctive normal form. We call this normal form PCDNF. A pointcut expression is in PCDNF if it matches the grammar shown in Figure 4.4.2 and there does not exist any conjunction in the expression that contains two P r o p e r t y E q u a l T e s t s where one implies the other or the negation of the other (such conjunctions can be further reduced). <Disjunction>  := FALSE | <Conjunction> | <Conjunction> | |  <Disjunction>  <Conjunction> := TRUE | <PropertyExpression> | <PropertyExpression> && <Conjunction> <PropertyExpression>  := <PropertyEqualTest>  <PropertyEqualTest> := [<property_name> |  [<property_name>  "==" <property_value>] "!=" <property_value>]  4.4.3 Converting a PCDNF expression to AspectJ Pointcut Syntax PCDNF is not valid AspectJ syntax. Before the pointcut expression can be inserted back into the aspect it must be converted to AspectJ syntax. This means re-grouping 39  target.className==Bullet && target.return== && target.name== && target.sigType==constructor && actionType==call && this.name!=bar  I  target.className==Bullet && target.return== && target.name== && target.sigType==constructor && actionType==call && this.className!=Foo  I target.className==Bullet & target.return== & target.name== & target.sigType==constructor & actionType==call & this.sigType!=method  I this.className==Ship && this.name==fire && this.sigType==method && actionType==execution Figure 4.4: P C D N F representation  primitive property test expressions back into AspectJ pointcut expressions. The process is somewhat complicated because AspecfJ's primitive pointcut expressions provide somewhat adhoc combinations of tests on different properties o f a join point. To perform this converstion we have implemented an adhoc solution that searches for property test expressions in the disjunctive normal form that can be grouped together into meaningful AspectJ expressions. These expressions are then used to build up an AspectJ pointcut - and are then removed from the disjunctive normal form. This process repeats until all property test expressions have been consumed. Rather than explain the details o f this process we will show an example o f the kinds o f results that it produces. The example is based on the following pointcut expression, which was sent as input to the normalizer component.  (call(Bullet.new(..)) | | execution(Ship.fire(..))) && !withincode.(* Foo.barf..)) The resulting P C D N F representation of this expression is shown in Figure 4.4.3. F r o m this P C D N F representation, the following AspectJ pointcut expression is formed:  c a l l (Bullet .new( ..) ) && ! withincode (* F o o . b a r ( . J ) | | execution)* S h i p . f i r e ( . . ) ) Note that the ! w i t h i n c o d e (* F o o . b a r (. . ) ) expression has been omitted from the e x e c u t i o n (* S h i p . f i r e ( . . ) ) )  conjunct o f the resulting P C D . This  is because during the conversion to P C D N F it was determined that it is implied by the conditions o f e x e c u t i o n (*  Ship. fire  40  (..)).  4.5 The Resolver T h e resolver is responsible for identifying the set of shadows in the code that match the pointcut expression. This information is sent to the user interface so that a gutter annotation can be placed at each shadow matched by the active pointcut. In this section we will describe the implementation of this component. To identify the location o f each shadow in the code, the resolver relies on information from the shadow model. When a pointcut expression is received from the normalizer, the resolver creates a semantically equivalent query that can be executed by the shadow model. The results of this query are objects of type S o u r c e L o c a t i o n . A s was stated in the  shadow model  section, each S o u r c e L o c a t i o n object maintained  in the shadow model is unique - so the results of this query each represent a shadow matched by the pointcut expression. For each S o u r c e L o c a t i o n object returned, the resolver queries the shadow model for the type of shadow that exists at that location. The results of this query must be one of the types specified in the diagram shown in Figure 4.3 on page 34. T h e figure also reflects the information pertinant to each shadow type. F o r example, a C o n s t r u c t o r C a l l S h a d o w contains two sets of signature properties: one for the method or constructor from which it is called, and the signature o f the constructor call itself. A l l of this information is gathered from the shadow model through a series of shadow type specific queries. Once each shadow has been resolved, the resolver component sends information to the user interface of the Pointcut Wizard. The U I places a gutter annotation at each shadow location, along with the type specific properties of the shadow and the pointcut by which it was matched. Once this process has finished, the developer is able to perform operations at any of the shadow sites.  If a remove operation is selected, the disambiguator uses the  shadow properties saved at the annotation site to begin the process of disambiguating the meaning of the operation, and the process shown in Figure 4.1 on page 31 begins again.  4.6 Conclusion In this chapter we presented the design of the Pointcut Wizard. T h e tools architechure consists of the following four components: •  Shadow Model: T h e role of this component is to model all shadows in the code. The prototype implementation of the shadow model is as a database built on top of JQuery. [10]  •  Disambiguator: The disambiguator is responsible for deciding the meaning of an operation performed at a join point shadow and then mapping the information found at the join point site to a pointcut designator that will match it.  •  Normalizer: The normalizer is responsible for reducing the occurance of certain redundancies that may appear in the pointcut expression following successive add and remove operations. 41  • Resolver:  The resolver is responsible for identifying the set of shadows in the  code which match the pointcut expression. This information is sent to the userinterface so that each shadow can be identified with a gutter annotation. The thesis of this dissertation is that it is possible to construct IDE-based tools that allow editing of AspectJ pointcut expressions through direct manipulation of effective representations of joinpoints in the code to which a pointcut applies. In this chapter we have presented the architecture of the Pointcut Wizard - a constructive proof of the thesis.  42  Chapter 5  Conclusion T h e thesis o f this dissertation is that it is possible to c o n s t r u c t I D E - b a s e d tools that a l l o w e d i t i n g o f A s p e c t J p o i n t c u t expressions t h r o u g h d i r e c t m a n i p u l a t i o n o f e f f e c t i v e representations o f j o i n points i n the code t o w h i c h a p o i n t c u t applies. W e presented  Pointcut by Example  as a m e t h o d f o r a c c o m p l i s h i n g this g o a l . T o  create a p o i n t c u t b y e x a m p l e the developer can s p e c i f y j o i n p o i n t shadows i n the code as e x a m p l e s o f the k i n d s o f j o i n points he wishes f o r a p o i n t c u t expression t o m a t c h o r not to match. A s a c o n s t r u c t i v e p r o o f that a p o i n t c u t can b e created i n this m a n n e r w e presented the P o i n t c u t W i z a r d . T h e P o i n t c u t W i z a r d is t o o l support f o r e d i t i n g a p o i n t c u t t h r o u g h e f f e c t i v e annotations at locations w h e r e j o i n p o i n t shadows exist. B y selecting an add or  remove o p e r a t i o n  at a j o i n p o i n t shadow site, the developer can e d i t the p o i n t c u t  expression so that it either captures o r n o l o n g e r captures the j o i n p o i n t . I n this chapter w e w i l l reiterate the c o n t r i b u t i o n s made i n this dissertation. F o l l o w i n g that, w e w i l l present o u r plans f o r f u t u r e w o r k i n this area. T h e dissertation w i l l c o n c l u d e w i t h a b r i e f discussion about w h e r e a t o o l f o r e d i t i n g p o i n t c u t s b y e x a m p l e fits i n t o the w o r l d o f A s p e c t O r i e n t e d S o f t w a r e D e v e l o p m e n t .  5.1 Contributions T h e central c o n t r i b u t i o n made b y this dissertation is the P o i n t c u t W i z a r d : a c o n s t r u c t i v e p r o o f o f p o i n t c u t b y e x a m p l e f o r A s p e c t J . O u r d e s c r i p t i o n o f the t o o l w a s d i v i d e d i n t o t w o areas: the user interface ( C h a p t e r 3) a n d the u n d e r l y i n g i m p l e m e n t a t i o n ( C h a p t e r 4). W e b e l i e v e that each presents a layer o f a n o v e l architecture f o r m o d e l i n g shadows a n d e d i t i n g p o i n t c u t s . I n this section w e w i l l s u m m a r i z e the i m p o r t a n t aspects o f each area.  5.1.1  A U I for Effective Views of Join Point Shadows  T h e P o i n t c u t W i z a r d p r o v i d e s e f f e c t i v e representations f o r j o i n p o i n t shadows i n the code. T o i n f o r m the developer o f w h i c h j o i n p o i n t shadows i n the code are m a t c h e d b y a p o i n t c u t e x p r e s s i o n , w e d e c i d e d to use g u t t e r annotations next t o each l i n e that c o n t a i n i n g a m a t c h e d shadow. T h i s t e c h n i q u e is s i m i l a r t o that used b y A J D T to m a r k locations w h e r e an a d v i c e w i l l apply. B y h o v e r i n g o v e r an a n n o t a t i o n , the d e v e l o p e r can access an E c l i p s e t o o l - t i p c o n t a i n i n g i n f o r m a t i o n about the shadow i t s e l f a n d the p o i n t c u t b y w h i c h it is m a t c h e d . T h e t o o l p r o v i d e s an  effective v i e w  o f j o i n p o i n t shad-  o w s because the developer is able t o access c o n t e x t m e n u s at a n y j o i n p o i n t l o c a t i o n  43  and perform an  add or remove operation.  If the shadow is already matched by the pointcut expression, the developer is provided with the option of removing it. Selecting the  remove shadow option  edits the  pointcut expression so that it no longer captures the selected shadow. T h e tool provides immediate feedback as to the result of the operation. T h e Pointcut Wizard also allows the developer to add shadows in the code that are not yet matched by the pointcut. If the developer wishes to capture a potential join point shadow, he can access the  add shadow menu selection  from the line the shadow  exists on and the pointcut expression will be edited to capture that shadow. Because the tool is implemented on top of a query engine, finding the results of a change operation on a pointcut is as simple as re-running a query. Therefore, all changes to the pointcut have an immediate impact on the annotations shown in the code editors.  5.1.2  An Architecture to Support Effective Views of Join Point Shadows  T h e Pointcut Wizard was implemented as four components: the  disambiguator, the normalizer and the resolver.  shadow model,  the  In this section we will summarize the  role of each. • T h e shadow model was built to model all shadows in the code.  This was a  necessary means for each of the other three components to share information about a shadow. • The  disambiguator is  responsible for deciding the  meaning of  an operation per-  formed at a join point shadow, and then mapping relevant information from the shadow site to a pointcut designator. • The  normalizer was  built to maintain the pointcut expression in normalized form  while the developer performs operations on it. This was necessary because of the additive nature of the operations performed on the pointcut following an add or  remove operation. • The  resolver  is responsible for identifying the set of shadows in the code which  together represent the pointcut expression. This information is sent to the userinterface so that each shadow can be annotated.  5.2  Future Work  In this section we will present what we see as future work for this tool. We divide the work into two areas: improvements to current features and validation o f the tool's usefulness and usability. In this section we will present our ideas for each area.  44  ' Delete j6inp6ihts:.method>xecution ,K3 class:  spacewar.Ship  IXI public ' KI name:  K  returns:  KI args:  void i0  • |  fire  OK  Figure 5.1: A U I for Editing Pointcut Properties  5.2.1  Usability and Usefulness  This dissertation has shown that it is possible to construct IDE-based tools that allow editing of pointcut expressions through direct manipulation of effective representations of join points in the code to which a pointcut applies. However, for future work we would like to validate the usefulness and usability of our technique to actual AspectJ developers. We believe that the prototype o f the Pointcut Wizard provides enough functionality to be able to determine its value to developers. Therefore, these experiments will occur prior to any of the following feature updates.  5.2.2  Improvements to Current Features  In this section we will present our plans for improving features that the Pointcut Wizard currently supports. Our first challenge will be to support the full AspectJ language. This will include full support for wild-card symbols, binding pointcuts, and cflow and conditional pointcuts. Additionally, we wish to provide support for editing join point shadows that occur within aspects. Each of these new language features brings with it new challenges for  effective  editing from the join point shadow location.  In the  following subsections we will describe our ideas for how to adapt the Pointcut Wizard to meet these challenges.  Support for Wildcards We believe that it may be useful for a developer to specify a pointcut designator that matches only certain properties of a shadow he has selected. Through a menu selection, we plan to give the developer access to the dialog box with check-box options for specifying which properties of a signature by which to match join points. A mock-up of the dialog box is shown in Figure 5.1. U p o n opening this dialog box, each box would initially contain values specific to the shadow of interest. T h e developer would have the options of either un-checking a box to use a wild-card symbol in place of the value, or filling in a value. If he wishes to fill in the value by hand, we plan to support using regular expressions to match join points.  45  To implement this feature, we plan to update the  resolver component  cut Wizard to include full support for wild-card symbols.  of the Point-  U s i n g the new interface,  the developer should be able to create a pcd such a s c a l l ( *  * . s e t * (. .) ) that  matches all methods where the method name starts with set. The developer would also have access to the " . . " operator, allowing him to match argument lists by a certain type contained at the beginning, end, or both of an operator list. For instance, the following pointcut designator could be used to capture all calls to a method s e t where the first argument is i n t and the last is b o o l - and any number of arguments appear between them: call(*  *.set(int,  . . ,  bool)).  If the developer un-checks a box in the new interface, the value for that property will be either a star pattern or a dot-dot pattern, depending on the property.  Support for Binding PCDs In the next version of the Pointcut Wizard we also plan to increase support for binding pointcuts. A s explained in Chapter 3, the Pointcut Wizard does not fully support the binding pointcuts t h i s , t a r g e t  or a r g s .  Using the prototype, a developer can  specify a type name as an argument to these pcds and match any join point where an object takes on that role. However, the binding pcds are most useful when the developer needs to access an object's state at run-time. We therefore plan to add a feature to the Pointcut Wizard that will allow the developer to specify variables or fields located at a join point shadow that should be bound in the active pointcut expression. Designing this feature should not be difficult, because the role the developer may wish to bind an object to (i.e. whether to use t h i s , t a r g e t or a r g s ) can be determined by the role it takes at the join point shadow. A s an example, suppose the developer selects an add operation on a method call f o o . f i r e () ; . We plan to add U I support that would allow the developer to select a bind operation on the variable (or field) f o o .  Because f o o is the  target  at this  location, the Pointcut Wizard could automatically use that type of binding operation. T h e type of the variable f o o could then be determined by JQuery, and added to the pointcut's signature as a parameter.  Support for Cflow and If PCDs Supporting c f l o w and i f pointcut designators will require a change to the  model and the disambiguator of  shadow  the Pointcut Wizard.  Currently, the disambiguator attempts to form a one-to-one correspondence between the shadow of interest and the pcd that matches it. Therefore, the shadow model was designed to capture the shadow's signature and its lexical context. However, if the Pointcut Wizard were updated to support dynamic pcds such as c f l o w and i f pcds, the model could no longer identify shadows based only upon signature and lexical context. The next version of the Pointcut Wizard will create a new shadow model that contains a shadow's signature, its lexical context, and information pertaining to any run-time checks associated with it.  46  T h e disambiguator wouldSlso need to be updated to handle the dynamic quality of such shadows. A J D T [5] addresses this issue with tool-tips that alert the developer to the possibility that the shadow may or may not be matched by the pointcut designator at run time. O u r case is rather more complex however because the annotations must also be  effective.  To illustrate this point, take for example the following pointcut expression:  pointcut foot): c a l l ( * *.foo()) && cflow(call((*  *.bar)))  Suppose the developer is at a call site for a method f o o . A l o n g with the add and remove operations that the tool currently supports, the developer may also wish to have the option of adding, removing or changing the c f l o w pcd. T h e problem is that the context on which the cflow is based (i.e. the pointcut taken as an argument by the cflow pcd), may exist outside the context of the f o o call site. Since a central design goal of the Pointcut Wizard was to allow the developer to edit a pointcut expression without facing the disorientation involved with leaving the context where the shadow exists, we believe this new feature could require fundamental change to the design of the Pointcut Wizard. Currently, this issue remains unresolved.  Editing Join Point Shadows in Aspects According to AspectJ semantics, join point shadows can occur in aspects as well as classes. The prototype of the Pointcut Wizard supports the latter. In order to support the editing of join point shadows in to support the  kinded pcd type  aspects with  effective views, the tool would need  a d v i c e e x e c u t i o n , shown in Table 3.1 on page 16.  In order to support this feature we would need to update the  shadow model  to  account for a new shadow type that exists within an advice. Additionally, the tool only supports the parsing of Java code in classes, and pointcut expressions in aspects. To fully support this new feature, the tool would also need to parse both  introductions and  advice.  5.3 Concluding Remarks This dissertation applied the notion of creating  Pointcuts by Example to  AspectJ's join  point model. We argued that AspectJ pointcut expressions are particularly difficult to edit because the pointcut language is based on patterns in the code, rather than the properties the patterns are meant to represent. Editing pointcuts by example allows the developer to gather more information about the property of a join point based on the context in which it exists. The goal of this dissertation was to prove that tool support which was capable of allowing the developer to edit pointcuts by example was possible. We have provided proof in the form of the Pointcut Wizard that such support is indeed possible.  47  Bibliography [1] Aspectj documentation. [2] AspectJ home page, http://eclipse.org/aspectj/. [3] AspectWerkz home page, http://aspectwerkz.codehaus.org/. [4] T o m Tourwe Centrum. Inductively generated pointcuts to support refactoring to aspects. [5] A n d y Clement, Adrian Colyer, and M i k Kersten. Aspect-oriented programming with ajdt. In Analysis  of Aspect-Oriented Software (AAOS), 2003.  [6] Bart D e W i n , Wouter Joosen, and Frank Piessens.  A o s d & security: a practical  Workshop on Software engineering Properties of Languages for Aspect Technologies (SPLAT, AOSD), Boston, Masachussets, March 2003. assessment. In  [7] Stephen G . E i c k , Joseph L . Steffen, and Jr. Eric E . Sumner. Seesoft-a tool for visualizing line oriented software statistics.  IEEE Trans. Softw. Eng.,  18(11):957-  968, 1992. [8] Enterprise Java Beans 3.0 spec.  http://www.jcp.org/en/jsr/detail?id=220.  [9] Geoff Hulten, Karl Lieberherr, Josh Marshall, D o u g Orleans, and Binoy Samuel.  DemeterJ User Manual. http://www.ccs.neu.edu/research/demeter/. [10] D o u g Janzen and Kris D e Voider. Navigating and querying code without getting lost, pages 178-187. [11] D o u g Janzen and Kris D e Voider. Programming with crosscutting effective views. In  ECOOP,  pages 195-218, Washington, D C , U S A , 2004.  [12] Bugdel home page, http://jboss.com. [13] Gregor Kiczales, Erik Hilsdale, Jim Hugunin, M i k Kersten, Jeffrey Palm, and W i l l i a m G . Griswold. A n overview of AspectJ.  Lecture Notes in Computer Sci-  ence, 2072:327-355,2001. [14] Ramnivas Laddad.  AspectJ in Action: Practical Aspect-Oriented Programming.  Manning Publications C o . , Greenwich, C T , U S A , 2003.  48  [15] K a r l Lieberherr, D a v i d H . Lorenz, and Johan Ovlinger. Aspectual collaborations for collaboration-oriented concerns.  Technical Report N U - C C S - 0 1 - 0 8 , College  of Computer Science, Northeastern University, Boston, M A 02115, November 2001. [16]  S. Muggleton and C . Feng. Efficient induction of logic programs, 1990.  [17]  Klaus Ostermann and M i r a Mezini. Conquering aspects with Caesar, pages 9 0 99.  [18] M Strzer and C Koppen.  Pcdiff: Attacking the fragile pointcut problem.  Interactive Workshop on Aspects in Software (EIWAS), [19]  Klaas van den Berg and Jose Maria Conejero. crosscutting in aosd. In  In  September 2004.  A conceptual formalization of  DSOA'2005 Iberian Workshop on Aspect Oriented Soft-  ware Development, Technical Report TR-24/05,  pages 46-52. University of E x -  tremadura, 2005. I S B N 84-7723-670-4. [20] T o m Tourw Vrije. O n the existence of the aosd-evolution paradox. [21] R. Wuyts. Declarative reasoning about the structure of object-oriented systems.  In TOOLS '98: Proceedings of the Technology of Object-Oriented Languages and Systems, page 112, Washington, D C , U S A , 1998. I E E E Computer Society.  49  

Cite

Citation Scheme:

        

Citations by CSL (citeproc-js)

Usage Statistics

Share

Embed

Customize your widget with the following options, then copy and paste the code below into the HTML of your page to embed this item in your website.
                        
                            <div id="ubcOpenCollectionsWidgetDisplay">
                            <script id="ubcOpenCollectionsWidget"
                            src="{[{embed.src}]}"
                            data-item="{[{embed.item}]}"
                            data-collection="{[{embed.collection}]}"
                            data-metadata="{[{embed.showMetadata}]}"
                            data-width="{[{embed.width}]}"
                            async >
                            </script>
                            </div>
                        
                    
IIIF logo Our image viewer uses the IIIF 2.0 standard. To load this item in other compatible viewers, use this url:
http://iiif.library.ubc.ca/presentation/dsp.831.1-0051502/manifest

Comment

Related Items