Tutorial using JHotDraw as an example
Installation
The tutorial relies on the code base of JHotDraw.
Before you attempt the tutorial, you must create a project for JHotDraw:
- Download this version of
JHotDraw.
- Create a new JHotDraw project. From the Workbench menu, select File | New |
Project.... This will display a dialog box with two lists.
- In the left-hand list, select Java, and in the right-hand list, select Java Project.
Then click on the Next button. A wizard will be displayed.
- In the wizard page, in the Project name field, enter JHotDraw5.3. Make sure
the Use default check box is checked, and click on the Finish button. This will
create a new, empty project named JHotDraw5.3. This project should appear in the package explorer.
- In the package explorer, right-click on the JHotDraw5.3 project and select New |
Source Folder. Name the folder src and click Finish.
- Right-click on the src folder in the JHotDraw5.3 project and select Import....
In the dialog box, select Zip file, and click on the Next button.
- Select the JHotDraw5.3.zip file you have previously downloaded. You can use the Browse
button if you want. A directory hierarchy will appear in the wizard page.
- Make sure the top-level of the hierarchy is checked, and click the Finish button. This will
import the JHotDraw code base into your project and compile it.
In the source folder for your project, you should see 11 packages and 3 other source folders. No compilation
errors should be present. At this point, you are ready to begin the FEAT tutorial.
Context
When investigating source code before making a change to a
program, you typically need to find the code related to your
change, and find out how it works. In most cases, it is not feasible
nor desirable to read the entire source code. Instead, it is
necessary to search for
code related to some specific aspect, or
concern, of your change. For example, the answers to
the following questions would typically represent
implementation concerns:
- How is this data structure used?
- Where is this menu created?
- What are all the methods involved in IO operations on this buffer?
FEAT allows you to search the source code by performing
queries of the relations between different elements (such as
fields or methods), and to keep track of elements and relations that
are of importance to you. These elements and relations are
saved in containers called concerns. Each concern
represents a subset of the program addressing a specific
functionality or aspect of the program involved in a change,
like the examples above.
The idea of FEAT is to allow you to investigate and document
small, focused subsets of the code,
using structural relations. A collection of concerns related
to a specific system is called a Concern Graph.
In this tutorial, we will consider a change to jHotDraw.
jHotDraw is a drawing application, allowing users to draw
various shapes on a canvas. To run JHotDraw:
- In the package explorer, select the file JavaDrawApp.java, in package
CH.ifa.draw.samples.javadraw. Then, with this file selected, select
Run | Run As | Java Application from the Workbench menu. jHotDraw will start up.
Try out jHotDraw:
- In jHotDraw, select File | New. This will create
a canvas.
- Select the rectangle figure in the menu (
)
- Draw a rectangle on the canvas.
- Select the rectangle. Handles should appear around it.
We can then change the attributes for the rectangle:
- In the jHotDraw menu, select Attributes | Fill Color |
Black. The rectangle turns black.
- Now select Attributes | Arrow | at Start.
Nothing happens
In the jHotDraw Attributes menu, options are displayed to
set attribute types that are irrelevant for a specific figure.
As you have seen, it is possible to set the type of arrow end
on a rectangle. This is not a desirable aspect of the user
interface. The user should only have the option to set
attributes that are relevant to a figure. In this tutorial,
we will use the FEAT Tool to capture the concern "setting
figure attributes" in the jHotDraw code base, in order to
improve this aspect of the code.
- Close jHotDraw.
Creating a Concern Graph
Involves initializing the tool and
opening a file in which to store the results of your program
investigation.
The first step to analyze a code base with FEAT is to create a
Concern Graph. A Concern Graph is a collection of
concerns relevant to a particular task. Specifically, a
Concern Graph stores the classes relevant to one or more
concerns, and the concerns themselves. This idea will become
clearer shortly. Let's create a Concern Graph:
- Right-click on the jHotDraw5.3 project in the package Explorer.
- Select New | Other | Concern Graphs | Concern Graph (note that you can customize your
Java perspective to have Concern Graphs appear directly in the new menu. See the Eclipse
Documentation). A dialog box will appear.
- In the Concern Graph Name field,
enter Tutorial.
- In the Include... field, you will see
all the packages of the JHotDraw5.3 project.
Click Finish. The tool will load the classes in the
selected packages so that they can be analyzed by the tool.
A Concern Graph is now created. To view this Concern Graph,
it is necessary to open the FEAT Perspective.
- In the Workbench menu, select Window | Open
Perspective. If the FEAT Perspective is visible, select
it. Otherwise, select Other... and then FEAT. This
will open and show the FEAT Perspective. By default, the FEAT
Perspective contains 4 views. All these views are currently empty,
except the Concern Graphs View, which contains an icon
describing the Concern Graph.
At any time, it is possible to switch between the Java and the
FEAT perspective using the buttons on the left Eclipse
toolbar. When switching to the Java perspective, the state
of a Concern Graph will not be lost. Try switching to the
Java perspective, and then back to the FEAT perspective.
We will now save our Concern Graph as a resource:
- In the FEAT Perspective, right-click on the
Tutorial icon. Select Save As.
- In the browser, select JHotDraw5.3.
- In the File name field, enter
Tutorial.crn. Note that it is very important that
Concern Graphs be saved in files with the .crn extension.
Otherwise, it will not be possible to open them again without
renaming them.
- Click OK.
A message will confirm that the Concern Graph was saved. A resource corresponding to the
Concern Graph will appear in the Package Explorer. To open a previously saved
Concern Graph, right-click on a the corresponding .crn file in the package explorer, and
select FEAT View from the pop-up menu.
You are now ready to investigate the code of JHotDraw in the
context of a Concern Graph, and discover how you can improve
the code to set the attributes of a figure.
Seeding a Concern
Involves choosing Java elements
relevant to a change task and moving them to FEAT.
The next logical step is to find out how attributes are set on
figure objects in jHotDraw.
To do this, you could probably find and understand all the
code you need using the Eclipse search features. However,
FEAT gives you something more, and that's the ability to
capture your knowledge of the code you investigate, and to
organize it in little compartments, or concerns.
A good way to proceed with FEAT is to find a seed (or code
element relevant to a task), add this element to a FEAT
concern, and then grow a concern description based on
this element.
To start, let's search the workspace for all type declarations
containing the string Attribute, and build a concern
based on this seed:
- If you aren't already in the Java perspective, switch to it.
- In the Package Explorer, select the src folder
of the jHotDraw project.
- In the Workbench menu, select Search | Search....
The Eclipse search dialog will appear.
- Click on the Java Search tab.
- In the Scope box, select Selected
Resources.
- For the search string enter *Attribute*
- In the search options box, select Type and
Declarations.
- Click Search. The results will appear in the Search
Result View, at the bottom of the Workbench. You see that three
classes contain the string Attribute: AttributeFigure,
FigureAttributes, and
ChangeAttributeCommand. To display a result,
right-click on it and select Open. This will display
the type in the editor and select the corresponding file in
the package explorer. Briefly look at the three classes
found.
Just from looking at the comments in each of these classes,
you can guess that you have found 2 classes dealing with the
storing of attribute values in figures
(AttributeFigure and FigureAttributes), and
one class dealing with a command to change the value of
attributes on a figure (ChangeAttributeCommand). One
of the major benefits of using FEAT is that it allows you to
deal with the different concerns separately. In our case, we
will create two different concerns to deal with the two
aspects of attribute handling we have uncovered.
- Open or switch to the FEAT Perspective.
- Right-click on the Tutorial Icon. Select New
Concern. In the dialog box, enter the name Attribute
Figure. A new concern appears as the child of
Tutorial.
- Proceeding as above, create a concern named
Command.
This procedure gives us two concerns, or containers for
elements relevant to changing figure attributes in JHotDraw.
Separating our knowledge of the code in different concerns
helps staying focused on the task.
The important concept here, is that it is possible to break
our task in different concerns. Moreover, in the current
version of FEAT, it is better to create child concerns as early
as possible, since it's not possible to move elements from one
concern to another.
This bring us to the question: what goes into a concern? A
concern consists in elements, such as classes, fields,
and methods, and relations between these elements.
Let us add our newly discovered classes to the concerns. There
are two ways of adding an element to FEAT. One way is to put
it directly in a concern. Another way is to put it in the
Projection View, and then moving it to a concern. The
Projection View (top right window) is a sort of scratch pad
for code investigation. It lets you investigate the
relationships between different elements in the code, so that
you can add the interesting ones to a concern.
- In the FEAT Perspective, select the Command
concern. It's important to always remember which concern is
selected. It is the active concern: the concern we are
operating on. Its name appear in the title of the
Participants View (top middle window).
- Switch to the Java perspective.
- In the package explorer, expand the node representing the
file ChangeAttributeCommand.java in the
...standard package.
- Right-click on the class node, and click Add To FEAT
Concern. Nothing visible happens, but the class was
added to the active concern.
- Switch to the FEAT Perspective. In the middle view (the
Participants View), the class ChangeAttributeCommand
is now displayed. The Participants View shows all the
elements participating in the active concern.
- Select the Attribute Figure concern. The
Participants View will now be empty. This is because the
class was added to the Command concern, and the
Attribute Figure concern is still empty. Note that
parent concerns are the union of all child concerns.
- Select the Tutorial concern. The Participants
view will display the ChangeAttributeCommand class.
This way, in FEAT, even though it is possible (and desirable)
to break a concern into small, easy to understand chunks, it's
always possible to see the complete concern, too.
- Select the Attribute Figure concern.
- Switch to the Java perspective.
- Add the AttributeFigure class to the concern as done before.
For the last class considered, FigureAttribute,
we will first add the class to the Projection View before
adding it to any concern.
- In the package explorer, right-click on the
FigureAttributes class node (not the .java file, but
the actual class). Select Fan-out | declaring.
This will show all of FigureAttribute's members in the Projection
View. Elements
in the Projection View are not necessarily in any concern.
The projection view allows you to perform queries on the
various relations between elements in a program, and to record
some of the relations as part of a concern. These functions
will be covered in a later part of the tutorial. For now, we will
simply add the FigureAttributes class and all its
members to the Attribute Figure.
- Swich back to the FEAT Perspective. Make sure that the Projection
View is visible by selecting the Projection table in the top
right folder.
- Make sure the Attribute Figure concern is
selected in the Concern Graphs View.
- On the toolbar of the Projection View, click on the black
triangle to bring up the View menu.
- Select Add Relation to Concern. The class and
all its members are added to the concern, and appear in the
Participants View.
You now have a seed to start your investigation in FEAT. Now
is also a good time to save your Concern Graph.
- Right-click on the Tutorial concern in the Concern Graphs View, and save your concern
as Tutorial.crn. Note that the Save As option is only available on the root node
in the Concern Graphs View.
Building a Concern Graph
Involves searching the
program to understand the code and storing interesting results
in a concern.
You now have a Concern Graph layed out to capture the functionality in JHotDraw to
manage figure attributes. This Concern Graph is broken up into two different concerns:
Command, and Attribute Figure. Finally, classes in jHotDraw which are potentially
involved in the implementation of each concern have been identified.
There remains the task of completing the concern description
to represent a useful amount of code implementing the two
concerns (here a useful amount would mean enough code to
understand how the attribute management in jHotDraw can be
improved).
The intended way to build concerns in FEAT is entirely within
the FEAT Perspective, using the Projection View. You perform
a search by right-clicking on any element either in the
Participants View or the Projection View, and then choosing a
query. Queries are organized into two groups: fan-out, and
fan-in. Fan-out groups outgoing relations (or relations
from the selected element to other elements),
whereas Fan-in groups incoming relations, (or
relation from other elements to the selected
element). Results of the
queries appear in the Projection View, in a tree that
represent the relations resulting from the query. From the
Projection view, it is then possible to add interesting
results to a concern. Let's see how this work. We will fist
complete the Command concern.
- In the FEAT Perspective, select the Command
concern. The class ChangeAttributeCommand should
appear in the Participants view.
- Right-click on the ChangeAttributeCommand class
in the Participants View. A Pop-up menu appears.
- From the pop-up menu, select Fan-out |
declaring. All the members declared by
the class ChangeAttributeCommand will appear in the
Projection View, on the right. The combo-box at the top of
the view will display the name of the current query, in this case: all of
ChangeAttributeCommand.
- In the Projection View, we see that
ChangeAttributeCommand declares a method
execute(). Double-click on execute().
This will display the code
of execute() in the Editor.
- From this, we see that the execute() method is the
one that actually changes the attribute on a figure. We will
add it to the concern.
- Right-click on the execute method. Select
Add Element to Concern. The execute()
method will appear in the Participants View, under the class
ChangeAttributeCommand.
- In the Participants View,
expand the ChangeAttributeCommand node to reveal its
child and click on it. You will notice this also replaces the
Projection View with a Relation View. The Relation View
should be empty now. Click on the Projection tab at the
bottom of the view to bring back the Projection View.
Now we will investigate where the command object is
created.
- In the Projection View, right-click on the constructor of the class
ChangeAttributeCommand (labeled
<init>(...). Select Fan-in |
called-by. This will display all the callers of the
ChangeAttributeCommand constructor in the Projection
View. If you expand the called by node, you will see that the
constructor is called by methods in classes
DrawApplet and DrawApplication. Clicking on
any of the methods calling the constructor will display, in
the editor, the location of the call:
- Click on method createFontMenu() of class
DrawApplication. The call will be highlighted in the
editor.
- Say we decide that this call is important knowledge for
our concern (e.g., because we need to remember where the
command is created). We can store the actual method
call as part of the concern.
Some of the elements you select in the Projection View are the
results of a query. In our case, createFontMenu() is
in the Projection View because it is called by the constructor
of ChangeAttributeCommand. We can actually store the
entire relation as part of a concern. The advantage of
storing a relation in a concern (as opposed to only storing
a single element) is that both elements in the relation are
stored in the concern at once. Furthermore, the relation is
visible in the Relations View. Typically, you would normally
add an element to a concern with its relation, except in the
cases where you have found an element through a query you know
has nothing to do with the concern.
- Right-click on the method createFontMenu().
- Select Add Relation to Concern. You
will notice that both the createFontMenu() method and
the constructor get added to the Participant
View.
- In the Participants View, select the method
createFontMenu in class DrawApplication.
You will notice two relations in the Relation View.
The Relations View appears whenever a participant is selected
from the Participants View. The Relations View presents a
summary of relations between the different elements in a
concern. Relations tagged with a blue dot have been
explicitly added by you, when adding an element to a concern
from the Projection View. Relations tagged with a question
mark are relations that currently exist between the participants
of your concern that have been automatically detected by FEAT.
In brief, relations with blue dots are there
to remind you of what you have inspected and added to a
concern. Other relations are presented to indicate potential
links in the code you might want to look at. Clicking on any
relation in the relations view displays the corresponding
code, if applicable.
- Always in the Participants View, select the constructor of
class ChangeAttributeCommand. In the Relations View,
you will see that this constructor is called by method
createFontMenu().
- Click on the relation in the Relations View. The editor will display the location in the source code related to
the relation.
- Now select createFontMenu again in the
Participants View. You will notice that there is another
relation in the Relations View: creating
ChangeAttributeCommand. This relation is displayed next
to a question mark, meaning that it links two participants of
the concern (createFontMenu() and
ChangeAttributeCommand). This relation indicates that
createFontMenu() creates an object of class
ChangeAttributeCommand (which is somewhat equivalent
to the constructor call, in our case).
We can flag this relation as part of the concern, too:
- Right-click on the creating... relation. Select
Add Relation to Concern. The relation will now be
part of the concern. The relation will be marked as part of
the concern with a blue dot.
In FEAT, the Projection View is your main tool of
investigation. Let's return to it to cover a few more
features. First, you can recall previous queries.
- Return to the Projection View by clicking on the
Projection tab.
- Using the combo box, select the query: All of
ChangeAttributeCommand. This will display the class and
all its members.
- Now return to the callers of the
ChangeAttributeCommand constructor by
selecting ChangeAttributeCommand.<init>...called by
ALL. This will display the callers of the constructor we
looked at previously.
Sometimes, you will realize that all the results of a query
should be part of a concern. For example, if you are
investigating the use of a method, all the callers might be
part of a concern. The Projection View allows you to save an
entire query as part of a concern.
For example, let's say you decide that all the callers of the
ChangeAttributeCommand constructor should be part of
the Command concern.
- In the tool
bar of the Projection View, click on the black triangle. This
brings up a menu of actions that apply to the entire view.
- From this menu, select Add Relation to Concern. All
the participants and relations will be added to the concern.
You can also perform queries on all the target elements in
the Projection View. For example, to get all the callers of
any method in ChangeAttributeCommand:
- Bring up the result All of ChangeAttributecommand from the
history.
- Then use the View's menu (black triangle) to select Fan-in |
called by. This will list all the methods of
ChangeAttributeCommand which are called somewhere in
the code, with their caller.
- For the purpose of this tutorial, we will leave these out.
- Save the Concern Graph.
Analyzing a Concern Graph
Involves comparing two concerns to discover any interactions
between them.
The main idea behind Concern Graphs is to use them to record
your knowledge as you investigate various concerns of interest
in a program. Once concerns are available in FEAT, they can
be compared to see if they are inter-dependent.
The main idea of comparing two concern is two see how they
interrelate without having to understand the entire
concern. FEAT will point out directly the related parts.
In this part of the tutorial, we will partially complete the Attribute
Figure concern and compare it with the Command
concern.
- In the FEAT Perspective, select the Attribute
Figure concern from the Concern Graphs View.
- In the Participants View, select the
AttributeFigure class.
- Right-click, and select Fan-out | declaring.
- Add the entire relation to the concern using the View menu
(black triangle on the View's tool bar).
You now have two partial concerns: Command, and
Attribute Figure. If you are wondering whether (and
how) these two concerns interact, you can compare them.
Compare is a simple operation that shows the two concerns side
by side and flags any relations between them.
- In the Concern Graphs View, hold down the Ctrl
key and select both the Command and the Attribute
Figure concern. Then, right-click and select
Compare.
The Interactions View will replace the Participants View. As
the title indicates, the view displays the Command
concern on the left and the Attribute Figure concern
on the right (or vice-versa). Clicking on any element will
bring up the Relations View, as usual. However, when
activated through the Interactions View, the Relation View
shows only the relations between the selected element and
any element in the other concern. The two concerns
views are completely symmetrical: it does not matter which one
is on the left and which one is on the right. Elements which
are present in both concerns are flagged with a red diamond.
Elements which have relations to any element in the other
concern are flagged with a yellow diamond. Let's see what
this means in our case.
First, we see that no class exists in both concerns. However,
this does not mean that there are not interactions between the
two concerns. If we expand ChangeAttributeCommand in
the Command concern, we see that the
execute() method is flagged with a yellow diamond.
- Click on the execute() method. You see in the
Relations View that the execute() method calls
AttributeFigure.setAttribute(String,Object), a method
in the Attribute Figure concern.
We can add this relation to the concern:
- In the Relations View,
right-click on the relation and select Add Relation to
Concern. AttributeFigure.setAttribute is added to the command
concern and flagged with a red diamond.
- Remove the relation: in the Command concern, select the
execute() method of class
ChangeAttributeCommand again.
- In the Relations
View, right-click on the relation and select Remove.
Observe how AttributeFigure.setAttribute is also
removed from the command concern, and the corresponding red
diamond disappears in the AttributeFigure concern.
To see how the two concerns in the Interactions View are
symmetrical, we can discover the same call, but from the
perspective of the Attribute Figure concern:
- In the Attribute Figure concern, expand class
AttributeFigure. Observe that the method
setAttributes is flagged with a yellow diamond. This
means it is involved in a relation with an element in the
Command concern.
- Click on the
setAttribute method. The Relations View will list
the call by ChangeAttributeCommand.execute(), the
same as we uncovered above.
This short example was intended to demonstrate that concern
description need not sprawl all over the code. They can be
kept short and focused on as specific a task as possible. In
our case, we did not initially capture how commands are
relayed to the figures. This relations was uncovered at a
later stage, using the compare feature.