Edge Weight Changes (2)

Page header 1





Title page

Memo

Introduction
In this memorandum, I want to discuss the changes we must make to make edge weight commands available through the MST GUI. I describe the MST tree view changes, the block view changes, the dialogs, and the interactions with the TCL files.

We want users to be able to define weights without directly editing the combine sections, and we want them to see the weights on the tree views.

Changes to the Tree View
In MST, five types of nodes can be assigned weights: Anomaly file, Closure, Octet range, Option, and Selection. The nodes other than selection nodes still implicitly provide selections from a set of alternatives:

Internally, each node implements the AbstractWeightedNode interface, and each therefore has a method with signature

public AbstractWeight [] getWeights

How do we display these?

Displaying Weights
Instances of the DotFileView class are in charge of displaying the node trees. They construct a GraphViz dot file, send it to the dot process, and read the output which gives positions. The view instance then paints the node polygons and edges onto the screen using methods in the Java Graphics2D framework when Swing asks for a refresh. We need to modify it to draw text at the appropriate places. We traverse the tree by starting at the root node, and following each node with its children. For each node, we do these tasks:


 * If node is a leaf node, skip it and go to the next one.
 * If the node cannot accept weights, skip it and go to the next one, whether child, sibling, or parent ’ s sibling.
 * If the node has no weights assigned, skip it and go to the next one.
 * The node has weighted children. Draw the node with a colored background to indicate the weighting, and display the fact in the tooltip as a reminder. The color will be white by default, but we will make this a user GUI preference. See Figure 1 Displaying a weighted node.
 * If the node is explicitly a selection node and some of its visible children have weights, annotate the edges to those children. Let n be the number of its children.
 * For i going from 0 to n-1,
 * If child i is invisible, skip to the next child.
 * Find the weight of child i.
 * If the weight is null, skip to the next child.
 * Find the edge form the node to child i.
 * Find a suitable place near the tail of the arrow from the node to child i, and display the weight.
 * If the sums of the weights exceed 1 by more than the tolerance, display the weighted node in red.
 * If the sums of the weight are smaller than 1 by more than the tolerance, and the node does not have the remainder property, display the weighted node in red.
 * Go to the node ’ s first child, or its next sibling, etc.



Figure 1 Displaying a weighted node

Drawing weights is not as complicated as I thought. The default dot output tells where it will show labels in an lp attribute:



Figure 2 Dot output with labeled edge

We will capture the label ’ s lp attribute and print the label on the screen at the place specified by this attribute. The GraphVizFilter communicates with the dot process, and parses the output. When it reads an output line that corresponds to a graph edge, it constructs a GraphEdge object. We could determine which nodes are weighted, but since few will actually be weighted, we will find it more efficient to parse the output line not only to get the path from the pos attribute, but also to get a label from the label attribute and its position from the lp attribute. We will add label and position attributes to the GraphEdge class, and we will use them when we draw the edge. We should replace the tokenization with regular expressions.

We do need to worry about rounding. If we are not careful, we will get weights like 0.0328430. We do not want this on the screen. Percentages would be appropriate. We will make the label format a user GUI preference; we may also make positioning a user preference too.

Allowing User Selections
Currently when the user left-clicks on the view, the system tries to select the node he is on. It does nothing if he selects an edge. When the user right clicks on the view, the system tries to find the node he ’ s on. It creates a menu; the top half contains basic commands suitable anywhere on the graph, while the bottom half has commands suitable for nodes. Commands will be enabled or disabled depending on what, if anything is selected and where the mouse is.

Two alternatives for allowing a user to add or modify weight commands through the GUI are: allow the user to select an edge, and add a command menu for edges; or we can add weight-based commands to the node menus.

Edge Selection
We have rejected the idea of allowing users to select edges directly. For us to allow this, we would have to have MST try to determine whether the user was selecting a node or an edge when he clicks upon the graph. It is easy to see whether the user has selected a node; the Java Graphics2D package supports that directly. However, the package cannot directly tell whether the user has selected an edge; the appropriate method on the Line2D class always returns false. Instead, MST would need to iterate over the entire tree to find the nearest edge, and it would need to decide whether the edge was near enough.

Because this is time-consuming, we reject this idea and place the commands upon the nodes only.

Node Selection
For this alternative, we simply add weight based commands to the menus shown when a user selects a node (right clicks on a node). If a node is weighted with respect to its parent, we can activate the "add weight", "modify weight", and "remove weight" commands. If a node is a weighted node, we can add commands that weight its children.

Dialog Boxes
The dialog boxes would pre-populate selections from controller classes that know how to interpret commands from the TCL combine sections; the interactions will come later.

A dialog box for selecting a single weight might look like:



Figure 3 Weight Dialog

A dialog for weighting the children of a selection node might look like:



Figure 4 Weight Children Dialog

A dialog for weighting an optional node might look like:



Figure 5 Weight Optional Node Dialog

We will restrict these commands so the user can choose to weight a more easily managed number of alternatives. Theoretically a user can choose to put weights on the 256 individual octets of the < OCTET > production, but that is very unlikely. We will use a configurable limit to the number of children we will allow a user to weight.

Changes to the Block View
We shall need to add the right menu items to blocks. To do this, we will need to attach to the routine in the BlockView class that tells what node block a user has clicked on, selectNodeForMenu.

We will also need to display weights and the fact of weighting in our blocks. Blocks are combinations of JDK Graphics2D rectangle objects together with text. The text is derived from the node text, but it does not need to be the same. The text is also drawn as an attributed string. We can change fonts, font weights, and colors. Accordingly, we shall:


 * Use a light-yellow or white fill for the block of any node with weighted children.
 * Change the tooltip for a node with weighted children.
 * Append the weight to the text of a weighted child of a weighted node.
 * Append the weight to its tooltip.

Changes to the Stereotype Command
Currently, activating a stereotype on a type production replaces it with the types associated with that stereotype. Essentially, these two lines are equivalent given appropriate anomaly definitions:

stereotype {< month-name >}{ monthName }

For now, however, the contents of the anomalies are used, not the anomalies themselves. We want to change this so the substitution only happens part of the time

stereotype {< month-name >}{ month-name } { 0.20 }

The above stereotype command should be equivalent to:

To do this, we need to do four things:

Modify the stereotype TCL command
The stereotype command now can be invoked in three ways:

stereotype stereotype { path } stereotype { path }  { stereotype list }

Each corresponds to a constructor of the Stereotype class; the first turns on all stereotypes everywhere, the second turns on all stereotypes below a path, and the third turns on the stereotypes in the list below a path. To add a weight argument, we would want commands like

stereotype  { weight } stereotype { path }  { weight }  stereotype { path }  { stereotype list }  { weight }

Unfortunately, all TCL commands send their arguments to Java as strings, and so the first two of these alternatives conflict with the last two of the original three. Fortunately, no one ever uses the bare stereotype command, and so no one will ever use the stereotype  { weight } command. We will permit weighting only in a new three-argument stereotype command. The equivalent of the three commands given above will be:

Modify the Java Stereotype action
After we have created the new constructor of stereotype, we need to modify the code of its void replaceStereotypedNodes (MSTNode) method. This uses the NodeFactory class to construct the new selection node; we just need to have it keep the old version when requested, and to apply the weights correctly.

Change the stereotype GUI
Currently, when the user invokes the Activate Stereotype command, he first gets a confirmation dialog asking if he really wants to activate the stereotype. After he confirms, he gets the Generate Tests dialog. I propose that we change the confirmation dialog to be a more full-fledged dialog similar to Figure 3 Weight Dialog. We can have a slider and a text box, and we would have a Continue/Cancel pair of buttons. We will edit the ActivateStereotypeAction.processAction(ActionEvent) method; it currently raises a standard confirm dialog, and we will replace that.



Figure 6 Sample Activate Stereotype Dialog

Have the GUI action modify the combine section
When the user activates a stereotype, we need to modify the combine section by adding the appropriate stereotype command. We can take the code from the Generate Stereotype Test Cases action. We will want to replace old stereotype commands when the user asks for a new one at the same path. Currently, a user who selects a stereotyped node and activates its stereotype twice will end up with two stereotype commands in the combine section. This has led to baffling errors; we should help the user by deleting the old version when we create the new one.

Replacing Type Productions
Currently the MST software replaces productions with the contents of Stereotypes and anomalies. We would like to alter this functionality such that MST replaces the node with the anomaly name or names and not the contents. Some examples in the GUI are: the Replace with Anomaly command, the Insert Anomaly command, the Activate Stereotype command, and the Generate Test Group command.  stereotype  { weight }. A thorough code search will be necessary to ensure all occurrences of this behavior have been altered.