UQ Students should read the Disclaimer & Warning
Note: This page dates from 2005, and is kept for historical purposes.
COMP2801 – Assignment Two – Software Documentation
I achieved eighteen out of a possible twenty marks.
Software Documentation Project
Project Team
Stephen Gordon
Stephen Jenks
Ned Martin
Lachlan Smith
Tuesday 8am Group A
Table of Contents
|
|
1.0 Introduction
This document is a compilation intended to provide an overview of the basic design of the main control elements of the UMLet program and some of the implications of its design. Also provided herein is an explanation of the build process for UMLet which produces the final program from source. A plan for future documentation and design pertaining to UMLet as well as journals detailing the documentation and learning process have been included to provide readers with an insight into both the creation of this piece and future works that may be undertaken.
UMLet is an open source program that can be used to create UML diagrams; it uses a graphical user interface which while at first confusing is quite easy to use once learnt. There is no existing user documentation for the tool, but experimentation and perseverance allow the determined user to make efficient use of it.
Figure 1.1
As shown in figure 1.1 the program once started displays a series of panels, each with its own individual purpose. The three panels provide a drawing space, a palette of common UML objects and a space for editing component properties and text.
The program UMLet has no technical or even user level documentation, and the source code itself is very sparsely documented. For this reason this report is not built upon pre-existing specifications or designs commentaries, rather from knowledge gained through the investigative process.
2.0 Structure Overview
2.1 Package layout
The source code is divided up into several packages each with an individual task or group of tasks. The packages in UMLet are divided into three (3) main streams, those being control, element and plug in. For the purposes of this project the Plugin package was not examined at all as it is not required to demonstrate the standalone program. Also note that while the Element package will at times be mentioned herein it is not documented in this report as classes within it simply define new objects for the UMLet drawing panel.
2.2 Class listing
A full list of all classes in the UMLet source code package can be found below, classified by package, and including those classes that are not further documented in this report.
- com.umlet.control
- AddEntity
- ChangeState
- Clip
- Command
- Connector
- ConnectorHandler
- Constants
- Controller
- CreateInterface
- InsertLinePoint
- Macro
- Move
- MoveLinePoint
- RemoveElement
- RemoveLinePoint
- Resize
- Role
- Selector
- SelectorFrame
- Umlet
- UniversalListener
- XMLContentHandler
- com.umlet.control.io
- FileOp
- GenEps
- GenPdf
- GenSvg
- IntHashtable
- UmletPluginHandler
- com.umlet.element.base
- Actor
- Class
- Entity
- Interface
- Note
- Package
- Relation
- UseCase
- com.umlet.element.custom
- TemplateClass
- com.umlet.plugin
- UmletPlugin
- com.umlet.plugin.editors
- UmletEditor
- com.umlet.plugin.wizards
- NewWizard
2.3 External libraries
UMLet makes use of a reasonably large set of libraries produced by third party developers which are not included in the standard Java package from Sun. These libraries and a very brief description of their function are listed below:
- Avalon
Homepage: http://avalon.apache.org/
The Avalon project from the Apache Software Foundation (ASF) is “a component-orientated programming project” (http://jakarta.apache.org/#avalon) and provides a platform for development which concentrates on best design practices in software development.
- Batik
Homepage: http://xml.apache.org/batik/
The Batik library from the ASF provides UMLet with the functionality required to generate files in the Scalable Vector Graphics (SVG) format.
- Crimson
Homepage: http://xml.apache.org/crimson/
Also from the ASF, Crimson is an XML parser which provides access to data stored in XML files in a way that is independent of the actual parsing engine itself.
- EpsGraphics
Homepage: http://www.jibble.org/javadocs/epsgraphics/org/jibble/epsgraphics/EpsGraphics2D.html
The EPS Graphics library provides UMLet with the ability to save to the Encapsulated PostScript format.
- FOP
Homepage: http://xml.apache.org/#fop
This is another library from the ASF and provides a way to convert data from both XML and DOM structured formats to Adobe’s Portable Document Format (PDF).
- Xalan
Homepage: http://xml.apache.org/xalan-j/
The Xalan library from the ASF is able to transform XML documents into HyperText Markup Language (HTML), text or XML formats. The xml-apis and xercesImpl libraries, while included in separate archives, are used to facilitate much of the functionality of the Xalan library and as such are included in this entry.
- JDOM
Homepage: http://www.jdom.org/
The JDOM library and what it can provide to UMLet is probably best described by the mission goal stated on the project webpage:
“To build a complete, Java-based solution for accessing, manipulating, and outputting XML data from Java code.”
3.0 Class Documentation
3.1 com.umlet.control Package
This package provides the vast majority of UMLet’s actual functionality including most, if not all, of the Graphical User Interface (GUI) classes and methods. Each class in the package is documented herein with an appropriate description and UML diagrams as appropriate.
3.1.1 AddEntity
NB: See Appendix B for UML diagram.
The AddEntity class, which also extends the Command class, simply adds or removes an Entity (created by the CreateInterface class above), via its execute or undo methods respectively, to or from an instance of UMLet.
3.1.2 ChangeState
NB: See Appendix B for UML diagram.
The ChangeState class – another class that extends the Command class, changes the state of an Entity or Command within an UMLet panel. ChangeState’s execute and undo methods set the state of an Entity to a new or old state, respectively, and provide getter methods to return this Entity and its new and old states.
3.1.3 Clip
Figure 2
The Singleton Clip class provides self-explanatory methods for copying and pasting data from a system clipboard, which we won’t go into further.
3.1.4 Command & Controller
Figure 3
NB: See Appendix B for broader UML diagram.
The Controller class, another Singleton class, executes Commands, via the abstract Command class. Two methods are provided for executing Commands, one of which allows for undo (and subsequent redo) operations, and one that doesn’t. When using the former, the Commands are stored in a Vector as they are executed, which the undo and redo methods iterate through, executing or undoing the Commands as required – while the latter simply executes its Command without storing it. These two methods are called whenever a large variety of actions are to be performed in UMLet.
The abstract Command class defines the methods execute and undo, which are called by the Controller class, along with a mergeTo method (and its corresponding isMergeableTo method), which we will get to in a moment.
3.1.5 Connector
Figure 4
The class Connector, as its name suggests, handles the connectors between UML entities. An instance of this class is created by ConnectorHandler and represents a connector between two entities, storing references to the two entities it connects. It contains two methods, which respectively return the entities at either end of the connector.
3.1.6 ConnectorHandler
The class ConnectorHandler, which is a Singleton class, contains methods that add, remove, and manipulate connectors between entities. Most of the methods are self-explanatory, accepting two entities and removing, adding, or returning the connector between the two. One slightly more complex method, getConnectorsByConnectedToEntity, returns a Vector containing all connectors connected to a given entity.
3.1.7 Constants
Figure 5
The Constants class handles most of the drawing and writing methods used to actually render the various Entity’s and Connectors in the UMLet panel.
3.1.8 CreateInterface
NB: See Appendix B for UML diagram.
The CreateInterface class extends Command and, not surprisingly, creates an UMLet Interface. Its constructor creates this new Interface, which inturn creates its super-type Entity, defined using various constants from the Constants class, depending on the type of Interface being created.
CreateInterface then overrides the execute and undo methods in its parent Command class, adding and removing an interface from an UMLet instance, or panel, as required.
3.1.9 InsertLinePoint.java & RemoveLinePoint.java
NB: See Appendix B for UML diagram.
The two classes InsertLinePoint and RemoveLinePoint are almost identical. These two classes are concerned with the insertion and removal of points into a Relation object, defined in the package com.umlet.element.base, which contains a list of points, and this relation of points, make up a line. Each point is made up of an x coordinate and a y coordinate and is defined in the class Point of the java.awt package, the point objects are represented in these classes by integer variables _x, and _y respectively, the points are contained in a vector which is defined in the Vector class of the java.util package, and accessed by the int variable _where that represents the index in the vector of a particular line point. The difference between the two classes being that they are used for opposing functions, both of the classes extend the abstract class Command, and in particular both override the execute and undo methods of their parent class. The InsertLinePoint’s execute method inserts a line point into the Relation’s vector of line points and the undo method removes the line point, whereas RemoveLinePoint’s execute method removes a point from a given relation and undo reinserts the point.
3.1.10 Macro
NB: See Appendix B for UML diagram.
The Macro class is a specialization of the Command class and overrides the execute, undo, isMergableTo and the mergeTo methods. A Macro object has only one variable and that is a Vector object defined in the java.util package, and the vector contains Command objects. When the execute method is called a loop runs through and calls each command separately, the undo method does the same but in reverse. The isMergableTo method takes as an argument of a Command object and compares it to the current object, if both are the same size and both contain the same type of commands then the method returns true. The mergeTo method unites the current object with the Macro object included as the arguments of the mergeTo method by placing in a new Macro object all of the combined Command objects one by one.
3.1.11 Move
NB: See Appendix B for UML diagram.
The Move class is almost identical to the MoveLinePoint class in functionality, it inherits from the Command class and overrides the methods execute, undo, isMergableTo and mergeTo. The main difference is that instead of moving a line point an object of the Entity class from the com.umlet.element.base is moved. When a Move objects execute method is called an int value _x and _y are passed to the current Entity object as parameters to the Entity object’s changeLocation method. Move’s undo method is the same as its’ execute method except that the values passed are the negations of _x and _y. The isMergableTo is used to determine if a command is an instance of a Move object and that it references the same Entity object. The mergeTo method takes a Move object as an argument and adds the current Move object’s x and y values to the argument’s x and y values and combines these and returns them as one move on the current Move object’s Entity object.
3.1.12 MoveLinePoint
NB: See Appendix B for UML diagram.
The class MoveLinePoint is a subclass of the Command class and overrides the methods execute, undo, isMergableTo and mergeTo. The method execute gets a point which is defined in the class Point from the java.awt package, from a relation object containing line points which is defined in the com.umlet.element.base package, and adds to the x and y values of the point object _diffx and _diffy, the values of _diffx and _diffy which are both integer values and are how far the line point is to move from its original position. The method undo does the same thing as execute but instead of adding _diffx and _diffy it subtracts these values from a point’s x and y coordinates. The isMergableTo method returns if a command is a MoveLinePoint instance and if it is it returns true. The mergeTo method adds one instance of a MoveLinePoint command to another MoveLinePoint command, it does this by adding the current objects _diffx and _diffy values with the merging MoveLinePoints _diffx and _diffy values, once the values are added together a single Command object is returned.
3.1.13 RemoveElement
NB: See Appendix B for UML diagram.
The RemoveElement class extends the Command class and overrides the execute and undo methods. When a RemoveElement object is created it is passed as a parameter an object of the Vector class, the Vector class is defined in the java.util package. The vector contains a set of Entity objects defined in com.umlet.element.base package, when the execute method is called all Entity objects in the Vector _entities are removed from the UMLet panel and a call is then made to the Selector class to deselect all the Entity objects that were selected to be removed. The undo method places the Entity objects back into the UMLet panel and updates the panel with its repaint method.
3.1.14 Resize
NB: See Appendix B for UML diagram.
The Resize class extends the Command class, and it overrides the execute, undo, isMergableTo and mergeTo methods. The method execute takes an integer that is represented by the value _where, depending on this value different corners or sides of the current Entity object are moved by changing the Entity’s size and/or location, this causes resizing of the object. The undo method does the opposite of the execute method. The isMergableTo method returns true if its given parameter is a Resize object. The mergeTo method takes as its argument a Resize object and adds its _diffx and _diffy values to the current objects _diffx and _diffy values, this is then returned as one Resize object.
3.1.15 Role
Figure 6
The Role class extends the Rectangle class defined in the java.awt package, a Role object is initialized with dimensions for creating a Rectangle object and the String a.
3.1.16 Selector
Figure 7
The Selector class facilitates the use of a tool which is common to many image manipulation programs and allows the selection of objects on the drawing canvas. The provided methods allow the selection of single or multiple entities and even the automatic selection of all entities on the panel. Also provided are methods for de-selection of entities and the selection of all relationships on the panel (as opposed to the all entities selection method which includes everything). Interestingly a lot of this functionality is not actually utilized by the UMLet interface or program at this time. The final thing to note is that like many of the classes in the package, Selector is called/created by an instance.
3.1.17 SelectorFrame
Figure 8
The SelectorFrame is an extremely basic class which extends the JComponent class found in the standard Java libraries. Its’ only method is paint which accepts a Graphics object as it’s only argument and draws a black box around the selection area.
3.1.18 Universal Listener
Whenever the user makes some form of input into the UMLet program, the UniversalListener class interprets the input and executes the appropriate action. The defining aspect of UniversalListener is that it implements a number of listener interfaces; as such, it is positioned to know about key events, mouse events, and window-related events.
For instance, when a double-click occurs, the mousePressed method will determine whether the double-click occurred upon an Entity, and if so, it will do what UMLet does when the user double-clicks upon an Entity - create a duplicate of it.
This event-driven system also includes menu selections, such that when the user selects the "Undo" menu, the method actionPerformed is invoked; this method determines from its parameter that the chosen menu option was "Undo", and thus undertakes the process for undoing a user’s previous action.
This class is clearly envisioned to be a “clearing house” for input, where any kind of user interaction relevant to UMLet can be handled appropriately. All methods are implemented, albeit sometimes without adding any code, and it is easy to understand what each of the methods are for, and roughly what that method is doing, without the benefit of comments. There are a relatively large number of intra-package class dependencies, which is not surprising, considering the range of duties this class is asked to perform.
3.1.19 Umlet
NB: See Appendix B for UML diagram.
The Umlet class is the main class for the UMLet application. It contains the main method, which initializes the application and creates a new document to which the user may begin to add UML.
The defining aspect of Umlet is that it is a singleton, meaning only one instance of it may be created; once created, that instance can be readily obtained from other classes. What this means is that, after the initialization process, Umlet can sit back and wait for instructions from other classes that are not necessarily subclasses of Umlet. Those classes obtain the instance by calling getInstance, and then chain methods onto the end of that: for example, Umlet.getInstance().doSave() can be called from any class, and it will cause Umlet to save the current document.
Umlet is in charge of a lot of methods that need to be accessible from elsewhere in the application, generally methods at the application scope: in particular, file and windowing–related methods. Smaller-scoped methods have been consigned to other singleton classes like Controller and Selector, whose scope is more specific. Looking through the code, it is clear that there was a methodology used to decide ‘which method goes in what singleton class’, but this is not always clear, and a total lack of useful comments in the code makes comprehension somewhat of a challenge.
3.2 com.umlet.control.io Package
The com.umlet.control.io package provides UMLet with the ability to save to the file system of the machine on which it is running along with some other functionality. Classes in this package allow saving to any of several different file types including Portable Document Format (PDF) and Scalable Vector Graphics (SVG). The package also provides a special data structure for use in other parts of the UMLet software and a common interface for plug-in developers to work from. Most of the code in the package is concise and well written but there is little or no commenting to be found. Documentation for all classes and interfaces in the package is provided below to alleviate this situation.
3.2.1 FileOp
Figure 9
When a user selects any of the save options available in the UMLet menu structure the program uses an instance of the FileOp class to generate the appropriate dialog box. The FileOp class makes use of the Java filechooser dialog box as provided by the javax.swing.filechooser package. The instance of FileOp then simply returns the filename selected by the user to the calling class or null, it is then up to the calling class to call the actual save routine to write data to disk.
As can be seen from the above diagram the class provides methods for the selection and generation of filenames for use when saving JPG, SVG, PDF and EPS documents. The other save and open filename methods are related to UMLet’s own file format. Finally the setSaveMenuItem() method is used to toggle the state of the ‘Save’ item in the UMLet menus to indicate to the user whether the option is presently available or not.
The tasks accomplished by the FileOp class are all relatively simple and as such the code is reasonably clear and concise. Unfortunately, like most of the UMLet source package, there is little if any code commenting or documentation to be found and that which does exist is relatively cryptic.
3.2.2 IntHashTable, IntHashTableEntry, IntHashTableEnumerator
Figure 10
This set of classes is used to provide UMLet with the use of an advanced data structure called a hash table. To summarize the diagram above an IntHashTable stores any number of IntHashTableEntrys, each of these entries stores an integer and a Boolean flag. The software’s main visible use of this data structure is to store rendering flags.
When a programmer is using one of these structures to store data they can use an IntHashTableEnumerator to move through the entries in the table in much the same way they would normally use an iterator to move through a linked list or other data structure. It is however worth noting that this construct only allows movement in one direction and therefore is slightly harder to reverse than a doubly linked list, though it still retains most functionality.
The IntHashTable class itself provides functions to perform all of the operations that are normally expected of an advanced data structure. This includes methods for adding, removing, cloning and checking for entries as well as methods to perform operations on the overall set such as checking the size and whether or not certain keys exist. Using this set of classes makes storing of integer hashes quite simple.
Unlike most of the code found in the UMLet packages the hash tables classes are well commented and include appropriate information for the JavaDoc utility to build documentation from. If it was necessary to extend or modify the classes this would prove extremely helpful. As it stands however the hash table classes appear to be fully functional, even though UMLet does not actually use most of this functionality, and as such are unlikely to require modification for further use in UMLet or any other Java program.
3.2.3 GenEps, GenPdf, GenSvg
Figure 11
Figure 12
Figure 13
When a user chooses to save to any format apart from UMLet’s own XUF files an instance of one of these classes is created. UMLet then calls the appropriate createAndOutput*ToFile() member function which is expected to handle all tasks associated with building the data displayed on the screen into the correct format and saving it to the file system. If any errors are generated by these classes they are simply sent to standard output rather than the standard error stream or a dialog box or other piece of GUI functionality.
Interestingly, although the three classes share a number of common member functions, the functionality is not grouped together under a common interface or other object orientated programming construct. For the most part these classes are relatively short with the exception of GenPdf which is required to take more steps to generate data for storing in its associated file format. All of these classes provide some source code documentation in the form of appropriate commenting but in many cases it is still somewhat sketchy.
3.2.4 UmletPluginHandler
Figure 14
The UMLet plug-in functionality is beyond the scope of this document as the intention here is to examine UMLet as a standalone program, not as a plug-in for the eclipse IDE. Despite this it is worth noting that an interface for a plug-in handler is included in the com.umlet.control.io package and that this allows the creation of custom plug-in handlers in a common way so that the main UMLet program can access them without modification. This allows plug in developers to build small re-distributable plug-in packages rather than being forced to release a modified build of the entire UMLet package.
4.0 Build Evidence
The UMLet source code is included in the same archive as the compiled byte code; a build file however is not included and as such has been created from scratch. The following text is intended to provide a brief documentation of the build file and its’ invocation. Further information is available by reading the commented build.xml file which is provided as an appendix to this document.
The provided build file for use with the ant build utility provides the following targets:
- init
Creates the required directory structure in the ${build} directory (defaults to ’./build’, although generally the compilation process would do this anyway in some situations it might be useful to only create the structure without doing a full compile. Note that when this build target is called a ’clean’ will automatically be performed. - clean
Removes all files in the ${build} directory, this is done to purge old class files and also to ensure that no attempt is made to include an existing archive from an old build into that of a fresh build. - compile
When invoked with this target ant will to a complete build process which will include first running the clean and init targets, compilation of all java source files and the creation of an archive from which the complete program may be run. Once the archive has been created the class and manifest files are then deleted from the ${build} tree. The process also copies across all required external libraries that aren’t included with the Java Software Development Kit.
The output produced by running a compile should be similar to the following:
s4054252@lichen:~/cvstest/new/Umlet3$ ant Buildfile: build.xml clean: init: [mkdir] Created dir: /students/11/s4054252/cvstest/new/Umlet3/build [mkdir] Created dir: /students/11/s4054252/cvstest/new/Umlet3/build/com [mkdir] Created dir: /students/11/s4054252/cvstest/new/Umlet3/build/com/umlet/control [mkdir] Created dir: /students/11/s4054252/cvstest/new/Umlet3/build/com/umlet/elemet compile: [javac] Compiling 30 source files to /students/11/s4054252/cvstest/new/Umlet3/build [javac] Compiling 16 source files to /students/11/s4054252/cvstest/new/Umlet3/build [copy] Copying 1 file to /students/11/s4054252/cvstest/new/Umlet3/build/META-INF [copy] Copying 1 file to /students/11/s4054252/cvstest/new/Umlet3/build [jar] Building jar: /students/11/s4054252/cvstest/new/Umlet3/build/Umlet3.jar [copy] Copying 9 files to /students/11/s4054252/cvstest/new/Umlet3/build/lib [copy] Copying 3 files to /students/11/s4054252/cvstest/new/Umlet3/build [delete] Deleting directory /students/11/s4054252/cvstest/new/Umlet3/build/com [delete] Deleting directory /students/11/s4054252/cvstest/new/Umlet3/build/META-INF BUILD SUCCESSFUL Total time: 20 seconds s4054252@lichen:~/cvstest/new/Umlet3$
The directory structure in ${build} after ant completes a full compile should be similar to that shown in the following listing:
-rwx------ 1 s4054252 students 21 Aug 20 22:49 Umlet.sh -rw------- 1 s4054252 students 70848 Aug 20 22:49 Umlet3.jar drwx------ 2 s4054252 students 96 Aug 20 22:49 icons drwx------ 2 s4054252 students 8192 Aug 20 22:49 lib -rw------- 1 s4054252 students 6447 Aug 20 22:49 palette.uxf -rw------- 1 s4054252 students 1685 Aug 20 22:49 plugin.xml
All of the listed build targets can created by simply changing to the directory the build.xml file is in and running ant with the following syntax:
ant [target]
When no target is supplied the build script defaults to a full compilation of UMLet. Once UMLet is compiled all that is required to execute the program is to change to the ${build} directory and run the included shell script:
./Umlet.sh
5.0 Team Learning Journal
5.1 Stephen Gordon
[Removed for privacy]
5.2 Stephen Jenks
[Removed for privacy]
5.3 Ned Martin
Apparently, I’m supposed to have been keeping a “team learning journal”, but I haven’t been so I’m currently in the same situation as the proverbial. To rectify this situation, I have decided to paraphrase various parts of another journal I have been keeping, interspersed with my own (occasionally accurate) recollections, and attempt to formulate from this something that vaguely matches the description of what a team journal should be.
First, a little about myself – I am Ned. Hear me roar. That done, I guess I may as well begin at the beginning, way back in July – Thursday, 15th July, to be precise.
Thursday 15 July – Sign On
I woke up at a horribly early hour, to sign on for my COMP2801. I’ve gone from having an all but perfect timetable, to a pretty average timetable, to a rather bad timetable with two eight o’clock starts and a five o’clock finish on Friday – due to tutoring. Hopefully it’s worth it, and everything works out ok.
Monday 26 July – First Lecture
The next COMP2801 thing of any import was the first lecture, which I attended quite too bright and early one Monday morning. I believe I’ve dutifully attended all lectures since, and found them instrumental in helping me understand UML, along with the tutorials. This has been particularly handy, as I don’t have any UML textbooks.
Tuesday 27 July – Practical 1
I woke up when my alarm went off, at six o’clock, and again eight minutes later. Eight o’clock starts aren’t my favorite things. Nevertheless, I managed to get to uni on time, and it wasn’t even that cold. I found the right room for my practical, and formed a group with the three people sitting nearest me – all of whom I happened to know, vaguely. I had been a little worried that I’d end up being automatically assigned a group of dumb people – less intellectually endowed people, I should say, or people who wouldn’t do any work, couldn’t speak English, were intolerable, had multiple open wounds, etc. I just wasn’t quite sure what people would go to an 8 AM practical, because, by my logic, no sane person would intentionally sign up for something that early. Fortunately, though, I think the group I’ve managed to get are reasonably intelligent, willing and able to try, well versed in basic English and other associated communication skills, including, but not limited to, the ability to write and talk in an understandable manner, and so on, and so forth. In other words, I’m hopeful that I’m in a good group.
We then proceeded to “bond”, by attempting to survive a plane crash in snowy, sub-zero northern Canada, in a wooded area crisscrossed with creeks and roughly 20 miles from the nearest town. Luckily, we had some vital survival equipment, such as a lighter with no fluid, a ball of steel wool, and two dead pilots. We had to individually rank these (and several other) items in order of importance to our survival, and then do the same again but as a group. We then compared our results to that of an “expert”, who, I suspect, would accidentally kill himself (and several innocent bystanders) while trying to survive a trip to the local supermarket. Nevertheless, we bonded, and, apart from one member who took the whisky and headed towards town and certain death, and another member who didn’t place enough importance on the lighter and froze to death, and myself and another member who left the steel wool behind and not only froze to death but were also unable to signal for help due to the unreflective properties of Crisco shortening, we all survived.
Tuesday 3 August – Practical 2
Today, at the ungodly time of 8 AM, I learnt how to use ANT – which beats learning how to use make files. I also learnt that I should follow instructions exactly as given – as I had several problems and had to ask for help a few times, and each time it was because I’d failed to read the instructions properly, or had missed a step. So, I guess you could say today has been a productive day.
Tuesday 10 August – Practical 3
I had to tutor for another subject, and attend my eight o’clock group practical, so didn’t want to be late. I had also stayed up most of the night, as usual, so had to use my patent-pending psychological trick to wake up – setting the computer’s alarm to play something loud five minutes after my alarm, so when mine goes off, I have to get up to turn the computer’s one off before it goes off and wakes everyone else, who will then kill me. It was very cold – one of the coldest mornings so far, but I managed to attend my prac, and probably learnt something there, although I can’t remember what it was.
Tuesday 17 August – Practical 4
We had a group meeting during our prac, which went quite well. We managed to delegate tasks to ourselves in a way that seems to make everyone happy, without really meaning to, while telling lots of doubtful jokes and stuff. It seems Flash (Steve Gordon) is Mr. CVS, Stephen (Jenks) is Mr. PowerPoint Designer, and Lachlan (Smith) and I are your presenters – with Lachlan being more comfortable talking, and me being less comfortable talking, so I’m Mr. Click Things and he’s the inimitable Dr Voice. It’s all going good.
Friday 20 August – Group Meeting
We had a group meeting today. I almost forgot about it, and because my tutoring ran overtime, I was late. The meeting went for all of three minutes, during which time we unanimously decided to have another group meeting at a later date, due to lack of motivation and a dire lack of a lack of assignments in other subjects.
I am so busy right now - it’s not good. I have an assignment due before 2 PM Monday, this one due during my two-hour eight o’clock practical on Tuesday and another due on Friday. I also have a fourth assignment that I should be doing, but I haven’t even looked at it so don’t know when it’s due. Then, on top of that, there’s a few things relating to my tutoring that I have to do, several little things around here I need to do, paperwork and computer stuff, and I need to go shopping and do some washing.
Tuesday 24 August – Practical 5
I headed down to the labs, via the refectory where I bought a terrible pretending pizza thing that was so bad I had to throw it out. After three quarters of our group finished not preparing in the labs, we went up to the other lab and, after the fourth quarter arrived we presented our program – “UMLet”, a Java based UML drawing program, which I insist is pronounced as “omelet”. It was a ten-minute presentation, during which Lachlan spoke and I cleverly manipulated our PowerPoint slides and the actual program. This was followed by rapturous applause (or so I insist on remembering), and then Stephen (the Gordon one) took a break from losing sleep over Slashdot to demonstrate his immeasurable CVS skills – and that was that. The rest of the groups ran through their presentations ranging from one who had a simple script and read it out without any computer involvement to one who had a fully scripted presentation with all four participating. We were the only group who ran to time (or at least the only group who had a two-minute warning given), and successfully covered all points on the criteria sheet with a live demonstration of the program, so I’m hoping for marks. We might even get an excellence and innovation mark for Stephen’s installation and run script.
Tuesday 31 August – Practical 6
Today’s practical was supposed to teach us how to use Rational Rose, but after a quick perusal of that program, I’ve decided that “use” is not the appropriate word – performing even the most basic tasks requires immense effort, although perhaps it wouldn’t be so bad if I actually understood what I was trying to do – something I must aim for. I did, however, learn how to create complex-looking (and sometimes meaningful) UML diagrams from Java without expending too much effort – something that’s very useful considering that’s part of what I have to do for the next assignment. My only other exposure to UML had been through Visio, while attempting to draw ER diagrams for an INFS assignment, I came across some UML templates and had a bit of a play around, but I didn’t realize the full depth and breadth, and the rich variety of diagrammatical styles possible. Now I do. The tutorials on UML have been instrumental in aiding my understanding as well, as I’ve found some aspects of UML, particularly the way it’s only semi-formal and a lot of discretion is required to determine precisely how to model something, quite confusing.
Tuesday 7 September – Practical 7
I pretended the world was round and that today was just another day, and headed into university. I attended my prac, during which we planned how we are going to try to do our assignment, and after that, I repressed all thoughts of assignments for as long as possible.
Tuesday 14 September – Practical 8
Our original plan had us all completing our individual parts of assignment two by today, and beginning the group parts. What actually happened, though, was that I went to Sydney over the weekend and didn’t complete my part on time, and we realized that some aspects of the individual work we’d assigned ourselves is better done in a group environment. Basically, we each found that we had to read half of the java files assigned to other group members in order to be able to figure out what the code in our files did – so we’ve modified our schedule a little. It is now more realistic and goes something like “finish everything as fast as possible – definitely before the due date”.
Wednesday 15 September
So here am I, sitting down in the lab typing all this. Now that I’ve given what is, I hope, an accurate overview of my experiences with COMP2801 so far, I would like to reflect on what I’ve actually learnt so far, and how I’ve gone about it.
UML – I had a vague idea about it, mostly garnered from using Visio to draw diagrams during a previous INFS course. I’ve now learnt quite a lot about UML, and can actually use Rational Rose – in a way.
Teamwork – This is the third teamwork-based assessment I’ve done here at UQ, but the first where I’ve really learnt how to cooperate and trust others. I’ve had to, as I haven’t had enough time to check work others are doing to see if it matches my “standards”.
Java – I don’t really think I’ve learnt anything I didn’t already know about Java and programming itself, everything has been straightforward code so far and I believe I’m becoming adept at spotting situations that could benefit from re-factoring. I have, however, had to struggle to understand and identify design patterns, as I don’t find their discovery intuitive.
CVS – This course is the first time I’ve used CVS. I’d heard about it a lot from various open-source places, but never actually had to use it myself. I can’t say I’m overly impressed, it doesn’t seem to be much more than a glorified versioning archive to me – but it’s handy to know how to use it should I ever need to.
ANT – Having only used make files before, ANT came as a nice surprise. It’s quite powerful, relatively easy to learn, and uses XML for that up-to-the-minute effect. I didn’t have much input into the ANT build file used by our team, but the ANT practical helped.
5.4 Lachlan Smith
[Removed for privacy]
6.0 Extended Project Planning
6.1 Further Documentation
As part of the creation of this document a large section of the UMLet program code has been documented, namely both the com.umlet.control and com.umlet.control.io packages which contain the core program functionality. For future extension of the program’s capabilities it is quite likely that further code examination and documentation will be required.
Although the com.umlet.plugin package was considered beyond the scope of this document it may be necessary to examine its use to provide an extended feature set and/or added functionality to the UMLet program. More likely to be required is an examination of the single class in the com.umlet.element.custom package. The reason for this is that extension of this class can allow the addition of extra object representations to the UMLet palette which can be placed on the drawing window. Using this functionality is possibly one of the better areas to improve the program in as it provides immediate and obvious extra functionality to the user.
Based on these facts the list of packages that are intended to be investigated during the next stage of this project is as follows:
com.umlet.plugin |
UmletPlugin |
com.umlet.plugin.editors |
UmletEditor |
com.umlet.plugin.wizards |
NewWizard |
com.umlet.element.custom |
TemplateClass |
6.2 Program Improvement
As part of the code documentation process undertaken by the team for this section of the project an effort was made to attempt to find areas in which UMLet could be improved either in terms of functionality or code structure. It is planned that at least some of these improvements will be added to the program via the code base currently stored in the Con-current Versioning System (CVS) during the next stage of this project. The areas which the team has selected to be candidates for improvement are listed below with a brief description of the suggestions.
- Extending save & open functionality:
Currently UMLet has the ability to save to the JPG, SVG, PDF and EPS file formats as well as its own UXF format which it also has the ability to load from. To extend this functionality it has been suggested that adding the ability to save to additional formats might be necessary. Possible formats include BMP and a HTML/MATHML combination format. It has also been suggested that adding the ability to load from the SVG format would be of some benefit. - Additional UML objects & improvement of the palette:
As part of the extension process it may prove possible and even in some cases necessary to extend the UMLet palette to include more objects for using in diagrams. Examples may include adding further UML representations or pre-created ‘templates’ that represent common class grouping structures. Even if such extension of the palette is not undertaken it is highly probable that some cleaning up of the palette layout and the overall UMLet window will be necessary. - Code re-factoring
During the documentation process there were several instances where it was found that code layout for a given class and/or package was rather poor. An example of this would be the com.umlet.control.io package where several of the classes for file output (GenEps, GenPdf and GenSvg) share a very common structure. This however is not reflected in the code base as all three (3) of the classes are completely separate and share neither a common interface nor an abstract parent class. As such it has been decided that in this and several other instances an attempt will be made to create a common interface or parent class which can group code together in a way more conducive to efficient programming. - On-line help
Currently UMLet provides little or no user help system and as such the user is very much left up to their own devices when they first come to use the program. The proposed way to improve this situation is to add at the very least a help item in the menus to go to an external documentation file. Additional possibilities in this area include adding features like ‘tip of the day’ and help pop-ups on certain mouse actions. - Code documentation
As part of any or all of the listed extensions it is hoped that it might be possible to provide full code commenting and documentation for the classes which have been modified. It is also planned to write full and appropriate JavaDoc comments for the changed classes and to generate online source documentation using the appropriate tool from Sun. - Additional User Interface (UI) functionality
The UMLet user interface is quite basic and as such it has been decided that some improvements need to be made in this area. This may include additions such as including a right click menu and/or additional main menu functionality to reflect other added features.
6.3 Testing Guidelines
As the team has now documented a large section of the UMLet program source code and selected appropriate goals for extension it is now necessary to outline a basic test strategy so that actual implementation of suggested features can begin. The test plan outlined in this section of the document will be relatively general as it is yet to be seen which features will actually be chosen for full implementation and as such it is difficult to say exactly which classes will require testing.
The tool used for the majority of the testing will be JUnit as it is better suited to the testing of UMLet than a solution like roast. This is in large part because roast for the most part is geared towards simple value and exception checks whereas JUnit provides the ability to write more robust and extensive tests. Also important is the fact that roast adds an extra step between writing of a test driver and actual running of the test(s), this is due to the fact that roast is a Perl program and as such must first parse its test scripts and create appropriate drivers before they any tests are able to be run. This is in contrast to JUnit test scripts/drivers which are written entirely in Java and require no further pre-processing before being sent to the compiler.
Unfortunately, due to the Graphical User Interface (GUI) nature of the software being tested, there are more than likely going to be large areas of the program which will prove quite difficult to test using automated tests. When this occurs it is planned to use the automated testing procedures as much as is possible with integration testing methods, once this is complete it is then intended that system testing will be applied. This will be done to attempt to catch errors which may only occur when the program is run as a full GUI application.
For the reasons previously outlined it is difficult to confirm exactly which classes are to require testing. As such areas which are candidates for extension are listed below with short descriptions of the classes that are expected to be tested if said feature is implemented and how this may be accomplished.
- Extending save & open functionality:
If any alterations are made to the program’s functionality in this area then it is likely that the FileOp class and any class responsible for input/output of data to the file system. This may include classes like GenSvg if they are modified. As the FileOp class and all of its methods accept input only through the GUI interface it will be necessary to test this class manually. Luckily it performs only relatively basic options relating to the selection of filenames for data output. Building a test driver for the classes which actually build the data files while possible will be challenging. The challenge in this instance is mainly provided by the fact that an actual object representing the graphics to be drawn is required as a parameter to some class methods. Once this is overcome however an appropriate test driver can be built to test the methods as most of them make reasonable use of exceptions to provide feedback to a testing program. - Additional UML objects & improvement of the palette:
Extensions to the palette will revolve around extending TemplateClass, as such any new classes created on this base will require testing. Due to the small nature of the class(es) involved and the amount of common code they will share it should be quite feasible to build an automated testing mechanism for this section of the code base, should it be necessary. Like those testing scenarios mentioned above however this will require the creation or ‘faking’ of a graphics object with which to work. In this case however it is less of a problem as the object can just be loaded straight from file. - Code re-factoring
Currently the only code tagged for major re-factoring is that in the com.umlet.control.io class, the possible testing of which has already been discussed above. If re-factoring is successful the major change to this procedure will hopefully be that it will be possible to test all of the output classes with a common test driver or suite. - On-line help
The most likely feature of the on-line help concept to be implemented is ‘tip of the day’ functionality. It is most likely that this will involve some file I/O and at the very least a class to control tip loading and display. This class will be designed in such a way as to make writing test scripts with JUnit relatively easy. It is intended that this will be done by both using exceptions correctly and providing methods to monitor the class’ status. Thanks to this it should be possible to use a unit testing methodology for this class as it should be able to be created in a manner separate to all other program functionality. - Code documentation
For obvious reasons this is not something that will be tested with an automated tool. Rather the updated classes will simply be run through the JavaDoc program to generate code documentation in Hyper-Text Markup Language (HTML) format. - Additional User Interface (UI) functionality
As this is possibly the broadest area of possible feature expansion it is also the hardest to predict testing strategies for. For the most part extensions in this area will be tested via a system wide test plan as almost all feature addition will be through code that is intrinsically tied to GUI input and output functionality. Despite this an effort will be made to implement integration testing, possibly through the creation of a ‘fake’ GUI application to provide all of the required functionality to test the class(es).
7.0 References
- The Apache Software Foundation:
- Avalon (http://avalon.apache.org/, http://jakarta.apache.org/#avalon) 15-09-2004
- Batik (http://xml.apache.org/batik/) 15-09-2004
- Crimson (http://xml.apache.org/crimson/) 15-09-2004
- FOP (http://xml.apache.org/#fop) 15-09-2004
- Xalan (http://xml.apache.org/xalan-j/) 15-09-2004
- EPSGraphics (http://www.jibble.org/javadocs/epsgraphics/) 15-09-2004
- JDOM (http://www.jdom.org/) 15-09-2004
8.0 Appendix A – UML Diagram for the Command class
9.0 Appendix B – UML Diagram for the Umlet class
10.0 Appendix C – build.xml
<?xml version="1.0"?> <project name="test" default="compile" basedir="."> <property name="src" value="." /> <property name="build" value="build" /> <!— Make sure the compiler knows where to find all classes this depends on --> <property name="libpath" value=".:lib/crimson.jar:lib/fop.jar: lib/xalan-2.3.1.jar:lib/xml-apis.jar:lib/batik.jar: lib/epsgraphics.jar:lib/jdom.jar:lib/xercesImpl-2.0.1.jar: lib/avalon-framework-cvs-20020315" /> <!— Prepare the build directory structure for compilation, note the use of clean, this has to be used to prevent un-necessary files ending up in the jar file. --> <target name="init" depends="clean"> <mkdir dir="${build}" /> <mkdir dir="${build}/com" /> <mkdir dir="${build}/com/umlet/control" /> <mkdir dir="${build}/com/umlet/element" /> </target> <target name="compile" depends="init"> <!— Compile the UMLet Java code, we list these two directories seperately rather than just using ${src}/com so that we don’t inadvertantly try to build the plugin classes. --> <javac srcdir="${src}/com/umlet/control" destdir="${build}" classpath="${libpath}" /> <javac srcdir="${src}/com/umlet/element" destdir="${build}" classpath="${libpath}" /> <!— Put the manifest file for Umlet3.jar into the build directory --> <copy file="META-INF/MANIFEST.MF" tofile="${build}/META-INF/MANIFEST.MF" /> <!-- Copy across the script for running UMLet3 --> <copy file="shell/Umlet.sh" tofile="${build}/Umlet.sh" /> <chmod file="${build}/Umlet.sh" perm="u+x" /> <!-- Build the jar file using the newly compiled program --> <jar manifest="${build}/META-INF/MANIFEST.MF" destfile="${build}/Umlet3.jar" basedir="${build}" /> <!— Copy across the libraries which are distributed with UMLet. --> <copy todir="${build}/lib"> <fileset dir="./lib"> <filename name="**/*.jar" /> </fileset> </copy> <!— Copy across the files which Umlet will run without, but not very well, basically the icons and a few other minor things. --> <copy todir="${build}"> <fileset dir="./base"> <filename name="**/*" /> </fileset> </copy> <!— Delete the class files as they are now in the JAR archive. --> <delete dir="${build}/com" /> <delete dir="${build}/META-INF" /> </target> <target name="clean"> <!— Simply delete the build directory and all it’s contents. --> <delete dir="${build}" /> </target> </project>
26-Oct-2004