Concern Manipulation Environment


The CME[7] provides a set of open, extensible components and a set of tools that promote aspect-oriented software development throughout the software lifecycle. It has two main goals. The first goal is to provide an open, integrated development environment (IDE) for those using AOSD across the lifecycle and to allow developers to use different AOSD approaches in an integrated manner. The second goal is to promote the rapid development of new tools supporting AOSD at any stage of the software lifecycle.

[7] http://www.eclipse.org/cme.

For our purposes in this section, we are interested in the first goalthat which includes support for an applications programmer in the separation of the code for different pieces of functionality and the specification of how to compose them. The CME's open framework provides support for both the asymmetric and symmetric schools of AOSD. In this section, we look at mapping Theme/UML to the CME's symmetric AOSD model. Theme/UML was based on the origins of the CME, and so it is no surprise that mapping to the CME is very straightforward.

For all themes, whether they are base or aspect, you implement the structure and behavior defined in the theme in standard Java. You then specify the composition requirements in a separate file that captures the specifications in the Theme/UML composition relationships. We look first at composing base themes and then at composing aspect themes.

Base Themes

Figure 7-3 illustrates the CME mappings for base themes. As with both base and aspect themes, the structure and behavior of each theme is captured separately. In our implementation of these examples, we used the Eclipse[8] IDE, and put each theme in a different Eclipse project. Each project contains classes to support the design. The CME composition specification file cap tures the composition relationships from Theme/UML, with merge and override keywords capturing the integration possibilities.[9]

[8] http://www.eclipse.org/.

[9] CME can work with themes separated into either packages or projects. Projects provide a stronger separation, making it easier for CME to identify composition namespaces.

Figure 7-3. The CME and base themes.


Figure 7-3 uses the Theme composition design from Chapter 6. We also use this Theme composition design to illustrate the CME in more detail with a subset of the code.

Standard Java for Base Themes

In the composition design represented in Figure 7-3, three game themes are composedstart, enter-location, and duel. Each design theme should be implemented in a different Java namespace. In general, the process of moving from designs to code in the CME is no different than how you would move to any Java implementation from a standard UML design. Here, we illustrate the structure of the Player class for each of the themes.[10] Note that you can call all the classes Player, since they are in their own namespaces. Listing 7-12 shows the structure of the Player class from the Start project, Listing 7-13 shows the structure of the Player class from the EnterLocation project, and Listing 7-14 shows the structure of the Player class from the Duel project.

[10] You will have similar class implementations for all the classes in the theme designs contained within the theme namespaces.

Listing 7-12. Project Start Game.Player
 public class Player {   private String name;   private String ipAddress;   private Location location;   private Game game;   public Player (String name) { ... }   public String getName() { ... }   public Game getGame() { ... }   public Location getLocation() { ... }   public void joinGame(Game game) { ... } } 

Listing 7-13. Project Enter-Location Game.Player
 public class Player {   private GPSComponent gpsComponent;   private Game game;   private Location location;   private Collection magicItems;   private MagicItem magicItem;   public void setLocation(Location location)  { ... }   public Collection checkOtherPlayers()  { ... }   public void duel() {      throw new ImplementationNotProvidedError(); }   public void takeCrystals()  { ... }   public void takeMagicItems()  { ... }   public void setMagicItem(MagicItem item)  { ... }   public void setMagicItems(Collection magicItems)  { ... }   public void newLocation(Location location) { ... } } 

Listing 7-14. Project Duel Game.Player
 public class Player {   private int crystals;   private boolean crystalsOffered;   private boolean wagerAccepted;   private boolean wagerAgreed;   private boolean finishedRecieved;   private String rockPaperScissors;   private Collection magicItems = new LinkedList();   public void getMagicItems() { ... }   public String getRockPaperScissors() { ... }   public int getCrystals() { ... }   public void duel() { ... }   public void duelLoser() { ... }   public void addCrystals(int numberOfCrystals) { ... }   public void decrementCrystals() { ... }   public void incrementCrystals() { ... }   public void addMagicItem(MagicItem magicItem) { ... }   public void deleteMagicItem(MagicItem magicItem) { ... }   public void updateRPS(String rockPaperScissors) { ... }   public void magicSelected(MagicItem magicItem) { ... }   public void wagerTwoCrystals() { ... }   public void wagerMagicItem(MagicItem magicItem) { ... }   public void wagerTwoMagicItems(MagicItem firstMagicItem,     MagicItem secondMagicItem) { ... }   public Wager Player.wagerCrystal() { ... }   public boolean Player.wagerAccepted(Wager wager) { ... }   public String Player.duelRevealRPS (Player player,                                       String rpsSelection) { ... } } 

There is one interesting point to note when implementing base themes separately. There may have been some operations in the Theme/UML designs whose structures were included to allow the individual theme designer to reason about them without actually providing a detailed design for such operations. The designer of the theme would have known that the operation was to be provided in a separate theme. The duel() operation in the enter-location theme is a good example of this. As we discussed in Chapter 5, the enter-location theme provides a design for knowing when a player is in a game location. This is important for knowing whether a player can pick up crystals and also whether a player should get involved in a duel. We decided in Chapter 5 that it made sense for the enter-location theme to "mark" when dueling should happen, but not provide a design for the actual dueling, since it appears in the duel theme. This results in a method signature for duel() in the Player class in the EnterLocation project.

This leaves us with a question of how you can work with the EnterLocation project separately. The CME treats a method whose body begins with throwing an ImplementationNotProvidedError as indicating that the real implementation will be provided by another concern (see Listing 7-13).

Composition Specification

Now that the base themes are implemented, each in its own Eclipse project, we address how to compose them. The two composition relationships in the Theme/UML design illustrated in Figure 7-3 indicate that

  • the three themes should be merged into a theme called "game," and matching is by name.

  • the duel() operation in enter-location's Player class should be overridden by the duel() operation in duel's Player class

The CME provides a merge concerns construct that can be used to specify merging themes. For our example, this results in:

 merge concerns StartTheme, EnterLocationTheme, DuelTheme => Game; 

The default for this specification is to match code elements by name. Notice that you can name the composed result using =>.

Override integration is similarly directly supported by the CME with its override method with construct. For the duel() operation, the integration specification looks like this:

 override method     EnterLocationTheme:Player.duel(Player) with     DuelTheme:Player.duel(Player); 

The full CME composition specification for the Theme/UML design is illustrated in Listing 7-15.

Listing 7-15. Merge Start, Enter-Location, and Duel Themes
 1 merge concerns StartTheme, EnterLocationTheme, DuelTheme => Game; 2 3 override method 4      EnterLocationTheme:Player.duel(Player) 5 with 6      DuelTheme:Player.duel(Player); 

Aspect Themes

Aspect themes are different than base themes from a composition perspective because some subset of their behavior is triggered by behavior in a different theme. The CME provides additional constructs that allow you to specify the methods in a base theme that trigger the methods in an aspect theme. Figure 7-4 illustrates the mappings from a Theme/UML aspect theme to the CME's composition specification.

Figure 7-4. The CME and aspect themes.


Standard Java for Aspect Themes

In the game, we identified two aspect themestrack-energy and P2PCommunication. As with base themes, these themes should be implemented with standard Java in their own namespaces, using the standard process of moving to any Java implementation from a standard UML design. Listing 7-16 illustrates the code for the Energy class from the TRackEnergy project. As you can see from the first line, Energy is implemented as an abstract class because it is expected that it will be composed with a class in a base theme that triggers behavior here. It also implements the Runnable interface to handle the energy tracking thread. The remainder of the code provides implementations for the rest of the design.

Listing 7-16. Track-Energy Theme Energy Class
 public abstract class Energy implements Runnable {   // methods expected in base theme   public abstract Game getGame();   // attributes   int duration = 5;   int energyUnit = 10;   int changeAmount = 1;   public void setChangeAmount(int a)   { changeAmount = a; }   public void changeEnergy(int e)   { energyUnit += e; }   public void loseEnergy()   { energyUnit -= changeAmount; }   public void run()   {        Game game = getGame();        while(game.isActive()) {           try {                        loseEnergy(); Thread.sleep(5000);           } catch (InterruptedException e) {           // Log or notify exception occurred           }        } } // advice methods public void setChangeAmountForLocation() {   Game game = (Game)getGame();   if(game.isPlayerInLocation())   { setChangeAmount(2); }   else   { setChangeAmount(1); } } private void changeEnergyForIncrementCrystalsAction() { changeEnergy(1); } private void changeEnergyForAddCrystalsAction() { changeEnergy(2); } private void changeEnergyForCompleteWizardErrandAction() { changeEnergy(4); } private void changeEnergyForCompleteWarriorTestAction() { changeEnergy(3);} private void joinGame() {   // Starting new energy loss thread   Thread energyLossThread = new Thread(this);   energyLossThread.start(); } } 

Listing 7-17 illustrates some of the structure of the code for the P2PCommunication theme. The theme contains implementations (not illustrated) for each class used in the theme.

Listing 7-17. P2PCommunicationTheme.Game
 public class Game {   private GameComms Game.gameComms = new GameComms();   public GameComms getGameComms(Game game) { ... }   public GameComms getGameComms() { ... }   public void Game.fullGameState(GameState gameState) { ... }   public void Game.fullGameStateRequest() { ... }   public void update(State state) { ... }   public void unmarshallGame() { ... }   public GameState marshallGame() { ... } } public class Player {   public void playerJoinGame(Game) { ... }   public void stateChange() { ... }   public void update(State) { ... }   public void unmarshallPlayer() { ... }   public PlayerState marshallPlayer() { ... } } public class Location {   public void stateChange() { ... }   public void update(State) { ... }   public void unmarshallLocation() { ... }   public LocationState marshallLocation() { ... } } public class GameAdmin implements Runnable {   public void run() { ... }   public void checkAvailableGames() { ... }   public void newGameAdmin() { ... } } 

Composition Specification

Again, now that the aspect themes are implemented, each in its own Eclipse project, we address how to compose them with the base themes. The composition relationship with bind[] attachment, illustrated in Figure 7-4, indicates that the game theme should be composed with the track-energy theme. This is captured with the CME construct extend concern with as follows:

 extend concern Game with TrackEnergyTheme; 

The difference between the extend concern with construct and the merge construct (used for the base themes earlier) is equivalent to the difference between composing template classes with classes that contain triggers and merging nontemplate classes. In the former, the template class is merged with each triggering class separately, while in the latter, there is one merged class in the result (see Chapter 6). In the CME, the extend concern with construct provides for extending many different triggering classes with behavior, while the merge construct composes classes to a single result.

There is behavior in the Energy class that is triggered by behavior outside the track-energy theme as indicated by the templates in the template box. The bind[] attachment to the composition relationship lists the Player class in the game theme as containing all the triggers for the templates. In the CME, Energy is therefore seen as an extension to the base theme's class (i.e., game's Player class) which is captured with its extend type with construct, as follows:

 extend type    Game:Player with    TrackEnergyTheme:Energy 

You would add more of these constructs if there were other classes in the bind[] attachment that contained triggers for the templates in the template box.

Finally, we need to specify the methods that trigger the aspect's behavior, and indicate when that behavior should be executed. Again, we find a direct correlation to Theme/UML in the CME's constructs. The CME provides an advise method construct that you can use to capture the concrete method in the base theme that should replace the template, as specified in the bind[] attachment.

The first example for track-energy is specifying that the setLocation() method (first in the bind[] attachment) should trigger the moveLocation template implementation. From the implementation of the track-energy theme, the method that implements the actual behavior to be executed was named appropriately for that implementation and called setChangeAmountForLocation(). This naming is reasonable in the implementation, as there is no need to indicate a generic intent for appropriate kinds of triggers, as was the case in naming the moveLocation template in the design. The resulting CME specification is as follows:

 advise method           Game:Player.setLocation(Location) with after::TrackEnergyTheme:Energy.setChangeAmountForLocation(); 

Notice that the with part of the advise method construct indicates that the crosscutting behavior should be executed after the trigger method. This is as specified in the Theme/UML sequence diagram.

trackEnergy defines two more template parameters: energyAction() and joinGame(), both of whose concrete bindings can be specified in a similar manner. For example, mapping to energyAction() is as follows:

 advise method         (Game:Player.incrementCrystals(..) ||         Game:Player.addCrystals(..) ||         Game:Player.completeWarriorTest(..) ||         Game:Player.completeWizardErrand(..)) with after::TrackEnergyTheme:Energy.changeEnergyForAction         (String = $methodName); 

There are two interesting points to note here. First, you can list multiple triggers to be advised, separated with || notation. Second, the CME allows you to reason about the metaproperties of an executing methodfor example, a method's name with $methodName.

Listing 7-18 illustrates the full composition specification for the TrackEnergy theme.

Listing 7-18. Track-Energy Theme Composition Specification
 extend concern Game with TrackEnergyTheme; extend type     Game:Player with     TrackEnergyTheme:Energy; advise method     Game:Player.setLocation(Location) with after::TrackEnergyTheme:Energy.setChangeAmountForLocation(); advise method     (Game:Player.incrementCrystals(..) ||     Game:Player.addCrystals(..) ||     Game:Player.completeWarriorTest(..) ||     Game:Player.completeWizardErrand(..)) with after::TrackEnergyTheme:Energy.changeEnergyForAction      (String = $methodName); advise method     Game:Player.joinGame(Game) with after::TrackEnergyTheme:Energy.joinGame(); 

For your interest, Listing 7-19 illustrates the CME composition specification for the P2PCommunication theme. To remind you, the bind[] specification from Chapter 6 is as follows:

 bind[ < Player.joinGame()>       < Player.{incrementCrystals(), addCrystals(),                 decrementCrystals(), addMagicItem(),                 deleteMagicItem() } >       < Location.{ setCrystals(), takeCrystals() } >       < GameAdmin.GameAdmin()> ] 

In this example, there are three different classes in the base theme that have triggers for the crosscutting behaviorPlayer, Location, and GameAdmin. Lines 3 to 6 illustrate an extend type with construct for the Game concern level. Each of the three lower level extensions required for Player, Location, and GameAdmin are implied by this concern-level one because the class names are the same in both concerns. This is equivalent to intertype declarations for these classes. Lines 8 to 26 list the advise method specifications that indicate when the crosscutting behavior should be executed, as specified by their respective sequence diagrams (see Chapter 5).

Listing 7-19. P2PCommunication Theme Composition Specification
 1    extend concern Game with P2PCommunicationTheme; 2 3    extend type 4       Game:Game 5    with 6       P2PCommunicationTheme:Game; 7 8    advise method 9       Game:GameAdmin.new(..) 10   with after::P2PCommunicationTheme:GameAdmin.newGameAdmin(); 11 12   advise method 13      Game:Player.joinGame(Game) 14   with after::P2PCommunicationTheme: Player.playerJoinGame(); 15 16   advise method 17      Game:Location.setCrystals(..) 18   with after::P2PCommunicationTheme: Location.stateChange(); 19 20   advise method 21      (Game:Player.incrementCrystals(..)) || 22      Game:Player.decrementCrystals || 23      Game:Player.addCrystals(..) || 24      Game:Player.addMagicItem(..)) || 25      Game:Player.deleteMagicItem(..))) 26   with after::P2PCommunicationTheme: Player.stateChange(); 



Aspect-Oriented Analysis and Design(c) The Theme Approach
Aspect-Oriented Analysis and Design: The Theme Approach
ISBN: 0321246748
EAN: 2147483647
Year: 2006
Pages: 109

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net