Fandom

Scratchpad

Edge Weight Changes (2)

215,965pages on
this wiki
Add New Page
Discuss this page0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.



Page header 1


File:Edge Weight Changes (2) 01.jpg

Title page


Memo

To: Kevin Yeich
From: Eric Jablow
CC: Bill Graf, Josue Perez, and Jacob Stokes
Date: March 16, 2007


Re:Edge Weight Changes: Plans and Estimates

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:

anomalyFile("…") ::= line 1 | line 2 | … | line n
3..5x
{<A>}   ::= <A><A><A> |
      <A><A><A><A> |
      <A><A><A><A><A>
0x01-0x03
  ::= 0x01 | 0x02 | 0x03
[ <A> ]
  ::= () | <A>

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.[1]
  • 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.
File:Edge Weight Changes (2) 02.png

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:

Input Output of dot –Tdot.
digraph G {
a;
b;
a -> b
[style="bold",label="3"];
}
digraph G {
node [label="\N"];
graph [bb="0,0,54,140"];
a [pos="27,114", width="0.75",
height="0.50"];
b [pos="27,26", width="0.75",
height="0.50"];
a -> b [style=bold, label=3,
pos="e,27,44 27,96 27,84
27,68 27,54", lp="30,70"];
}
File:Edge Weight Changes (2) 03.png

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.

protected static void parseDotLine(Graph graph, String line) {
if (…) {
  // Skipped…
} else if (line.indexOf("->") >= 0) {
  try {
    node = Long.parseLong(next);
    next = token.nextToken();
    next = token.nextToken();
    long c_node = Long.parseLong(next);
    if (line.indexOf("pos=") >= 0) {
      getNodeEdges(graph, node, c_node,
      line.substring(line.indexOf("pos=")+5));
    }
  } catch (NumberFormatException e) {
}
}
private static void getNodeEdges( Graph graph, long node_num,
          long child_num, String str) {
Node p_node, c_node;
GeneralPath curve = updateLine(
  str.substring(0,str.indexOf("\"")));
p_node = (Node) m_map.get(new Long(node_num));
c_node = (Node) m_map.get(new Long(child_num));
GraphEdge edge = new GraphEdge(p_node,c_node,curve);
// Code to set labels and their positions
//should be put here.
if (p_node != null)
  if (!p_node.addEdge(edge)) {
    //Skip error handling.
}
}

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:

File:Edge Weight Changes (2) 04.png

Figure 3 Weight Dialog

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

File:Edge Weight Changes (2) 05.png

Figure 4 Weight Children Dialog

A dialog for weighting an optional node might look like:

File:Edge Weight Changes (2) 06.png

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}

replace{<month-name>} { <month-abbreviation-anomaly> |
      <month-name-anomaly>}

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:

replace{<month-name>} { <_OLD>
        | <month-abbreviation-anomaly>
        | <month-name-anomaly>}
weight {*.:monthName.0} {0.80}
weight {*.:monthName} {remainder}

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:

stereotype {root} {*} {weight}
stereotype {path}
{*} {weight}
stereotype {path}
{stereotype list} {weight}

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.

File:Edge Weight Changes (2) 07.png

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.

Estimated Work Schedule

Task Activity File Method(s) Hours
Display weighted nodes. Choose a color based on weighting and weighting errors. DotFileView drawNode 4
  Draw the node with selected color. DotFileView drawNode 1
  Change the tooltip for weighted nodes. Node and its subclasses New getToolTip method 8
  Apply tooltip. DotFileView getToolTipText 1
Display weights on the tree view. Put the weights into the file sent to the dot process. GraphVizFilter writeNode 1
  Add attributes to store edge weight information. GraphEdge Constructor and new get and set methods. 2
  Interpret the edge labels from the dot process output. GraphVizFilter parseDotLine 8
  Save the edge labels and positions. GraphVizFilter getNodeEdges 2
  Draw the weights. GraphVizFilter updateLine 4
Weight a node’s children Install a non-working action. DotFileView registerContextMenu, new action inner class 1
  Enable the action only when a single node is selected and that node may take weights. DotFileView registerContextMenu 4
  Create dialog class. New dialog or panel subclass.   8
  Create data model for table. New table model class   4
  Initialize table model from node data. DotFileView action inner class   4
  Write weight commands to the TCL sections. New Context…Command subclass.   8
  Remove or edit old weight commands. New Context…Command subclass   12
  Create variant dialogs for optional nodes and closures.     8
Show parents with weights in the block view. Choose a color based on weighting and weighting errors. BlockView setNodeGraphicsStyle 2
  Draw colored background.   paintGraph 2
  Draw tooltips.   getToolTipText 2
Add weighting of children to the block view. Add action to the block viewer. BlockView inner class registerContextMenu 4
Modify stereotype command to take weights. Modify stereotype constructor Stereotype Constructors 4
  Include old production in replacement of stereotyped nodes.   replaceStereotypedNodes 8
  Apply weight to the old data production. Give parent the remainder attribute.   replaceStereotypedNodes 4
Modify command class to create new stereotypes Update uses of Stereotype. StereotypeCommand   2
Add a probability to the Activate Stereotype action Modify the dialog box. ActivateStereotypeAction processAction 8
Modify anomaly replacements and inserts to use the anomaly names instead of their contents. Change how the stereotype command replaces data productions Stereotype createConcatenated
StereotypeProduction
8
Ensure consistent behavior with other anomaly replacements. Test how other commands replace nodes.     4
Unit testing Create new JUnit tests and modify old invalid ones     80
      Total (hours) 208
      Total (days) 26.00

  1. This and the next bullet are unnecessary, but nice.

Also on Fandom

Random wikia