TAVI technical companion 0 Introduction Here we say a few words about the TAVI project and state the purpose of this document. 0.1 Overview This is the technical documentation of TAVI, a visual analyzer tool, with which transaction based systems can be planned. TAVI was a software engineering lab project group 1, spring 2002, at University of Helsinki department of computer science (www.cs.helsinki.fi). 0.2 Purpose of this document The process model used in the project was XP (eXtreme Programming, see www.extremeprogramming.org), a model oriented towards prototyping and coding, with minimal documentation. There was no definition or design phase in the project, and thus no documentation relating to these phases exist. In XP the only documentation is the code itself, the extended comments in the code (see www.cs.helsinki.fi/group/ohtu1k02/javadoc/index.html for the latest javadoc documentation), the unit tests and the user stories. However, a technical documentation is necessary to enable a future project group to carry on development and maintenance on TAVI. Thus, this document will try to serve as a definition, design and implementation document, with emphasis on implementation. This document will focus on the interactive construction of models and the displaying (drawing) of those models on the drawing area. We will not go deep into implementation details, but rather will try serve as a top level introduction to implementation of TAVI. Implementation details should be found in the generated javadoc documentation and the extended comments in the code. Before reading further, it is suggested that developers read the TAVI user manual and try the software out to make sure that they understand WHAT it is that TAVI does, as it is then easier to understand this document which tries do describe HOW TAVI does it. 1 Overview of TAVI Here we take a look at the current state of TAVI, say a few words about XP specific testing and state the class hierachy of TAVI. 1.1 Current state TAVI was originally intended to be a visual analyzer tool. However, during the project it became clear that there would not be enough time to implement the analysis functionality as making the basic user interface and creating functionality that would enable users to construct models was perceived to take a lot of time. Thus TAVI is currently really not much more than a tool that enables users to construct and store graphs. Also, the concept of variables is most likely a bit misrepresented as this was implemented late in the project with perhaps too little customer consultation. 1.2 About testing In XP, unit testing is tightly integrated with development, and testsuites are used to conduct testing. The project used JUnit 3.7 (see www.junit.org). The test classes reside in the same package as the classes which they test. Testing was further automated by including execution of tests in the default Makefile target. Thus you need JUnit3.7 or later installed to compile with target "make". Use "make tavi" to compile without JUnit. 1.3 Class hierachy An UML-diagram of TAVI can be found in the files taviClasses.ps and taviClasses.pdf (the pictures) or TaviClasses.mdl (a Rational Rose file)which reside in the same directory as this document. TAVI consists of twelve (12) (program) classes plus six (6) test classes in two packages for a total of eighteen (18) classes. The packages are tavi and tavi.graph. In package tavi we have the classes StateHandler, Tavi, TaviCanvas, TaviDialogs, Timer and test-classes AllTests and TimerTest. The classes in package tavi implement the user interface of TAVI. In package tavi.graph we the classes Graph, Server, TFlow, Variable, Identifier, Transaction, TransactionManager and test-classes GraphTest, ServerTest, TFlowTest, VariableTest and IdentifierTest. The classes in package tavi.graph implement the data structures and algorithms used to represent and draw the models. 2 User interface TAVI user interface consists of a main window and secondary popup windows. The main window contains a standard menubar (top, north), toolbar (left, west), textfield displaying current transaction (under toolbar) and a drawing area (center). Composition of the popup-windows varies from info-windows with single non-editable textfields to query-windows with several editable components. 2.1 Main window The main window is implemented entirely in class Tavi, excluding the drawing area which is implemented in TaviCanvas and event handling associated with the drawing area and the toolbar which are implemented in StateHandler. Saving and loading models is also implemented in class Tavi. 2.2 Popup-windows Popup-windows are implemented in class TaviDialogs. It handles window creation, destruction and event handling. Some info windows (such as those indicating that some action was succesfull) automatically close after a few seconds. Timer class is used to implement this automatic closing. 2.3 More about TaviDialogs class (Note that this goes deeper into details than most of this document.) In TaviDialogs, the dialog managing is made in a way it would be inside Tavi. There are some JDialogs, where requested dialog components are inserted as needed. If no dialogs are open, the currentWindow variable has value -1. Otherwise the variable has a value corresponding to some constant value defined in the class. When using JList, it should be noted that method valueChanged (that is required in ListSelectionListener interface) changes specific window components whenever JList component is accessed. Current functionality in the method is necessary for the consistency of the Transaction and Variable modifications. There are three Vector instances in the TaviDialogs class. Purpose of these instances is to keep code understandable and they aren't necessary. Instance of global variable vector doesn't cause any side effects in any case, because global variables are accessible anywhere from the current model. However, the Transaction's local variables need to be changed every time the transaction is changed somehow (even clear and some other functions) and it is necessary to keep this in mind. Transaction vector instance is only changed when transactions are changed completely (and this doesn't occur too often). 3 Model representation In this chapter we review the data structures used to represent models of transaction based systems in TAVI. Also, in the second paragraph of chapter 3.2 we define the concept of model. 3.1 The basics Since the queue models of transaction-based systems are essentially directed graphs, adjacency list was selected as the data structure to represent them in TAVI. The adjacency list is implemented using Graph, Server and TFlow classes. The Server class represents a vertex or a service point in the graph and TFlow (Transation Flow) represents an edge or a transaction's transition from one service point to another. 3.2 Representing multiple transactions The situation is not quite as simple as depicted above since for a system of service points, we may have several different transactions, each with different characteristics, that may enter the system. The transacations are implemented in the class Transaction and TransactionManager class acts as a manager for them. In TAVI, a model is a collection of Server objects representing service points of some system, a collection of Transaction objects representing transactions that may enter the system and a collection of TFlows each representing a transactions transition from one service point to another. For a model to be consistent two of the servers must be special: there must be a source of transactions through which all transactions enter the system and there must be a sink of transactions through which all transactions exit the the system. The source is named B and the sink is named E. The source must not be the destination of any TFLow and sink must not be the source of any TFlow (this is enforced in.) Each TFlow is associated with one and only one Transaction and the TFlows associated with a specific Transaction form a graph with all paths from source to sink representing the possible migration paths of the Transaction through the system of Servers. In a consistent model all the TFLows will be part of a path from source to sink (this is not enforced.) Thus, we actually have multiple graphs, one for each Transaction. The collection of Server objects is maintained in a linked list in a Graph object and the collection of Transactions is maintained in a Vector in a TransactionManager object. The representation differs from an ordinary linked list in that the Server class has two linked lists. One list contains the TFlows of a single Transaction, the active transaction, and the second list contains the TFlows af all the other transactions. The active transaction can be changed simply by first appending all the TFlows from the first list to the second list and then moving the TFlows associated with the new active Transaction from the second list to the first list. 3.3 A word about variables The concept of variables was introduced into TAVI but it is most likely not exactly what is needed to do analysis with the graph. The variables itself implemented in class Variable are probably not incorrect, but rather how they are integrated into the graphs. At present, there are two kinds of variables: global and local. Global variables are universal and belong to the TransactionManager. Local variables are Transaction specific and each belongs to one and only one Transaction. There is no direct connection between Variables and TFlows or Servers. Thus the connection between Varables and Graphs is indirect via the Transactions. 4 TAVI in action Here we describe the runtime behaviour of TAVI with respect to constructing models and displaying the graphs on the drawing area. 4.1 Constructing a model 4.1.1 TAVI as a virtual blackboard TAVI can be thought of as a virtual blackboard on which users can draw models. The blackboard is the drawing area represented by the TaviCanvas object, on which the model is drawn, with circles representing Servers and arrows representing the TFlows of the active Transaction. In TAVI, each Server contains a Point object which represents its location on the TaviCanvas. A user can add Servers by clicking on the Server icon in the toolbar, and then clicking on the drawing area. The coordinates of the click on the drawing area is extracted by TAVI from the MouseEvent that the click created and a Server with these coordinates as its location is added to the Graph. The event handling is not simple, as different functionality needs to be invoked based on what is currently selected (eg. nothing, objects from the toolbar or Servers or TFlows from the Graph), which button is clicked (LMB or RMB) and where the mouse cursor is positioned (eg. what is under the cursor: a toolbar button, an empty region of the draw area or a region occupied by a Server or a segment of a TFlow.) 4.1.2 Handling the events A deterministic finite state automaton was selected to handle the resolution of users' actions when constructing the model (ie. mouse presses on drawing area or toolbar or DEL-key presses). The states of the machine represent which object is currently selected (eg. if user had selected the server from the toolbar the state would be ADD_SERVER as pressing LMB on the drawing area would now result in the addition of a Server into the Graph) or some more complex situation (eg. adding TFlows and source Server is selected and adding a routed TFLow, in which case the state would be ROUTING_TFLOW). The transitions of the machine represent the actions of the user (eg. pressing LMB when the cursor is on a Server in drawing area, in which case the transition or action would be LMB_ON_SERVER_IN_DRAW_AREA.) The state machine is implemented in class StateHandler. The state transition matrix and a matrix depicting functionality associated with each transition are available in two formats in the same directory as this document: as a csv-file in StatesHandler.csv and as a StarOffice-file in StateHandler.sdc. Note that a adding Servers and TFlows is a particularly tricky part of StateHandler since TAVI checks that the added objects won't overlap existing objects. Since we have curved and recursive TFlows this gets quite complex and the checks involved encompasses about a dozen methods and hundreds of lines of code. 4.2 Drawing the graph 4.2.1 Abstract view On abstract level, drawing the graph is fairly simple as each Server in the graph knows how to draw itself and when asked to do so (via the drawSelf-method) it will, in addition to drawing itself, ask all the TFlows originating from it to draw themselves selves (again, via the drawSelf-method). The Graph itself has a drawSelf-method as well which will simply ask each of the Servers in it to draw themselves. Thus, drawing the graph is accomplished by calling the drawSelf-method of the Graph object. 4.2.2 Drawing TFlows Drawing the TFlows is quite complicated since there are four different types: straight flows, curved flows recursive flows and routed flows. Straight and routed flows are simplest since they are just a collection of line segments with arrowheads. Recursive and curved flows are complex since they have to be drawn "by hand" as the precision af awt's drawArc-method is not good enough to draw arcs that are required in TAVI. Also, as TAVI does not use control points on Servers to which TFlows would be connected, the end points of the TFlows have to be calculated using eg. trigonometric functions. The actual drawing of the TFlows requires about two dozen different methods and around thousand lines of code. The mathematical background of drawing curved TFlows can be found in tavi_math_declaration.html which resides in the same directory as this document.