A Text Editor

The contour package is a simple text editor based on one of the tutorials that comes with the JBuilder Java development environment. The tutorial was designed to exercise JBuilder's graphical UI development tools, and is not a particularly good example of object-oriented design: almost all of the code is contained in a single class TextEditFrame.

Nevertheless, the step-by step development process that is described in the tutorial notes provides a good illustration of how conventional OOP fails to achieve code locality---in other words, code related to a single function is spread through a number of methods or classes.

Change Monitoring as an Aspect

Good locality is maintained until Step 10, when the String that serves as the model for the Text Pane is connected to a file by two methods, openFile and saveFile, which are in turn connected to the appropriate menu commands. Here the tutorial code also introduces a "dirty bit" to record whether the file has changed since it was last read from or written to disk, and in Step 11 this Boolean is used to change the behavior of some of the other methods. Our aspect-oriented version of the program maintains all of this as the ChangeMonitor aspect. (Click here to see it in a separate browser window.)

Line 17 introduces a new instance variable changed into all objects of class TextEditFrame. (Why into the Frame and not into the Model? Because the tutorial example has no real model; it is all interface. The closest it comes to a model of the file is a Java String.)

Lines 19 through 26 take care of resetting changed when necessary: immediately after a successful openFile, saveFile or menuItem1_actionPerformed (corresponding to the File > New event), changed is assigned false. Because opening or saving a file might fail, the weave checks the result of the method (thisResult, line 24) before assigning to changed.

Lines 28 to 37 set changed whenever the textValueChanged event handling method is invoked. The body of this method is:

void textArea1_textValueChanged(TextEvent e)
{
statusBar.setText("Editing " + currentFileString());

}

Since there is no need to set the text in the status bar more than once, if the before weave finds that changed is already true, it returns immediately. However, if changed was false, it sets changed to true and then falls through to the ordinary method body, which will update the status bar as expected.

Lines 39 to 49 optimize away the saveFile action when the file has not changed; in this case the before advice simply beeps and returns.

Lines 51 to 79 introduce a new method okToAbandon into TextEditFrame objects; it returns true if it is permissible to abandon a currently active editor buffer. The final two advise weaves (lines 81 to 89 and lines 91 to 98) use this method to ensure that the contents of a changed editor buffer are not abandoned in error when a file is opened, or when the buffer is cleared, or when the user quits the editor.

The Window Caption as an Aspect

The second aspect (in file Caption.java) contains all of the code related to updating the caption at the top of the window. First we introduce into TextEditFrame a method updateCaption(...), and a variable currentCaption that maintains a cached copy of the current caption, and which is used to avoid unnecessary calls to the windowing system. Five pieces of advice are then offered: after advice to the TextEditFrame constructor, and the methods for openFile, saveFile and the New menu event. and before advice on the method that handles the textValueChanged event.

Some care is necessary to ensure that the two aspects and the original code interact correctly. For example, updateCaption(...) takes a Boolean argument that tells it whether the buffer is "dirty", and which is rendered as an asterisk in the caption. This is much cleaner than relying on the changed variable, which is part of another aspect, because changes to that aspect could introduce subtle bugs. Similarly, the advise weaves that reset the caption when a new buffer is opened must be after advise, because the okToAbandon method called from the before advise on the same method might have prematurely terminated that method's execution.

The Source Code

The Generated Code

The aspect weaver generates Java files that can be compiled and run in any Java programming environment. Although not intended for human consumption, the generated code is quite readable, and viewing it offers an interesting perspective on the weaving process.