Scooby2beDue Design Document
Contents
Project Description of Target System
The Scooby2beDue To-Do List will support far more than the most basic to-do
list functionality. In addition to adding and removing reminders of tasks
that the user
may need to accomplish, it will also allow the inclusion of the date that
each item is due, and setting a priority for each one. The list may then be
sorted and diplayed based on priority (the default), due date or creation
date. The applet will also support the concept of "groups", where list items
may be separated into logical subsets or groups and then displayed sorted
based on group. List items may be edited at any time to correct typos or
to reflect changes in circumstances.
Click here to see the full Project Description.
High-level architecture
The Scooby2BeDue system is divided up into 5 major
components, as depicted in the following diagram. This high-level
architecture depiction represents a decomposition of the system
into components or subsystems:
- Interface - handles all user interaction.
- Items - temporary data storage and management for items
on the users To-Do List.
- Groups - temporary data storage and management for
the user-defined item groups.
- Files - permanent storage and retrieval of all To-Do
List data.
- Telnet Server - provides link to file system for data
storage.
The Web Server (based on rossem during development), WWW Client,
and Java Interpreter communicate via control and data calls that
do not concern us here. The details of the interaction between the
Telnet Server and the file system are similarly unimportant. For
this reason, these components and their interactions will be
mostly ignored in the remainder of this document. However, it is
important to note that the Telnet Server and Web Server
must both reside on the same UNIX-based host.
Data and control among the four components of the Applet are
further described in the Design Specification section of this
document below.
The fifth significant component depicted below is the Telnet
Server through which all interaction with the File System occurs.
The Files component handles all file read/write interaction from
the ToDo Applet to the Telnet Server.
The following is a high-level architecture depiction of the
Scooby2BeDue system:
Figure 1: High-Level Architecture Design
Since the Scooby2beDue To-Do List Manager is divided up into 4
sections, the internal wokings of each section will be described
seperately, and the interactions will be described throughout.
Interface
Everything that happens inside the List Manager is driven by the
main applet class, ToDo. The rest of the Interface objects
are all dialog boxes. The majority of the data processing and
interface management is done by ToDo's handleEvent method. This
method is called every time the user clicks on anything in the main
screen (shown below). This method then does
any required processing in response to the user's input.
The way dialog boxes are handled in the Scooby2beDue To-Do List
Manager is somewhat unusual. All of the dialog box classes have
constructors that display the dialog window and shift the input
focus to that dialog box. All of these dialog boxes are modal,
so, the user cannot interact with the main screen while the
dialog is displayed. Also, while displayed, the dialog's
handleEvent method recieves any user events, rather than the
main applet handleEvent. This method does any processing for
user interactions with the dialog box. When the user dismisses
a dialog box (by pressing OK, Cancel, etc.), an event is generated
in the main applet event handler that notifies the applet that the
dialog box has been closed and returns any data collected. The
dialog boxes remove themselves from the screen.
The handleEvent methods of the applet and the dialog boxes do all
of the high level processing and call methods in the other objects.
Items
The Item component manages a doubly linked list and is responsible
for interpreting and converting the data to be read from and written to
the data file. The ItemList class is the main class in this subsystem.
The ItemList class provides several self-explanatory methods to add
an item, delete an item, and sort the data in memory. It also
provides a unique method of access to the data in that it maintains
an internal pointer to the most recently accessed node in the list
to improve access time when each item will be accessed sequentially.
WARNING: Care must be used if this class is ever used in a
mutli-threaded environment, since different threads might leave the
list on different nodes.
This class does not use the built-in Vector class for maintaining
lists of objects. Instead it uses a series of node objects to build
the doubly linked list, with each node having a reference to one
Item object. This is done to facilitate using the quicksort algorithm
for sorting the item list.
Also unusual to this class is the fact that it partially manages the
main GroupList in that it loads the GroupList with the data from the
file, and writes the data from the GroupList to the file.
The ItemList also provides methods for explicitly reading the file
into memory and writing the current data to the file.
Groups
The Groups component of the Scooby2beDue applet is by far the
simplest. It merely maintains a singly linked list of group names
and makes those names available to other portions of the system.
The GroupList class performs all of the actual work of this
component. Insertion sort is used to alphabetically sort the
group names as they are inserted. This class also maintains the
same "most recently used" state information to keep the interface
similar to the ItemList class.
Files
The Files subsystem uses a Telnet connection to the Web Server
to maintain files on the server. The Connection class manages the
telnet protocol and all escape-character processing, etc. However,
the interface that it provides is very rough: it only allows for
transmission and reciept of raw byte arrays. The wrapper class,
RemoteFile, actually performs the functions of interacting with the
Telnet Server on the remote machine.
When the ToDo event handler calls the login function of RemoteFile,
it establishes the connection to the host, and sends the given
username and password to the Telnet Server as if the user was
actually logging in personally. It then verifies that the
login was successful (i.e. valid username/password, no network
errors), and if so, configures the user's shell for its use.
Read operations are performed using the UNIX utility cat to display
the file (cat filename). The user's prompt is temporarily
set to a very uncommon sequence of characters to help the system
detect when the file has ended. Write operations are also
performed using cat (cat - >| filename). Control-D is used
to indicate the end of the file in this case. This method of
file transfer limits the types of files that can be stored using
this class to those consisting only of printable characters and
whitespace - no control characters or 8-bit ASCII characters.
The RemoteFile class never explicitly logs out of the Telnet
session, instead the connection is broken when the RemoteFile
object is destroyed and the socket is no longer allocated to the
applet. The Telnet Server will detect this a a "hangup",
terminate all running processes (there shouldn't be any), and
log the user out automatically.
Design Specification
Here is a Coad and Nicola style Object-Oriented Design diagram of our applet:
Figure 2: Object-Oriented Design of Scooby2BeDue Applet
Detailed Class Interface Specification
ToDo Class Specification (Interface)
public class ToDo extends java.applet.Applet {
public final static int FILENAME = ".todolist";
protected List mainList;
protected Choice primarySort;
protected Choice secondarySort;
protected TextField description;
protected TextField dueMonth;
protected TextField dueDay;
protected TextField dueYear;
protected TextField startMonth;
protected TextField startDay;
protected TextField startYear;
protected Choice priority;
protected Choice group;
protected ItemList itemList;
protected GroupList groupList;
protected boolean initDone;
public void init();
public void start();
public void stop();
public boolean handleEvent( Event evt );
}
ToDo Class Notes
- ToDo::FILENAME - filename to use in user's directory
- ToDo::init - sets up main screen and presents login dialog
- ToDo::start - ensures we are still logged in on restart
- ToDo::stop - saves ToDo List
- ToDo::handleEvent - main message loop of applet. handles all
events caused by screen components and all Close Dialog events
(see below)
LoginDlg Class Specification (Interface)
public class LoginDlg extends java.awt.Dialog {
protected TextField userName;
protected TextField password;
protected Applet app;
public LoginDlg( Applet app );
public boolean handleEvent( Event evt );
}
GroupsDlg Class Specification (Interface)
public class GroupsDlg extends java.awt.Dialog {
protected TextField groupName;
protected Choice groupList;
protected Applet app;
protected GroupList groups;
public GroupsDlg( Applet app, GroupList tGroups );
public boolean handleEvent( Event evt );
}
NewDlg Class Specification (Interface)
public class NewDlg extends java.awt.Dialog {
protected TextField description;
protected TextField dueMonth;
protected TextField dueDay;
protected TextField dueYear;
protected TextField startMonth;
protected TextField startDay;
protected TextField startYear;
protected Choice priority;
protected Choice group;
protected Applet app;
protected GroupList groups;
public NewDlg( Applet app, GroupList tGroups );
public boolean handleEvent( Event evt );
}
MsgDlg Class Specification (Interface)
public class MsgDlg extends java.awt.Dialog {
protected Applet app;
public MsgDlg( Applet app, String str );
public boolean handleEvent( Event evt );
}
YesNoDlg Class Specification (Interface)
public class YesNoDlg extends java.awt.Dialog {
protected Applet app;
public YesNoDlg( Applet tApp, String str );
public boolean handleEvent( Event evt );
}
Dialog Class Notes
- All *Dlg constructors: create own Frame, resize it as necessary,
call Dialog's constructor, adds dialog components, and shows
the dialog box.
- GroupsDlg, NewDlg constructors: also stores GroupList pointer into
groups.
- MsgDlg and YesNoDlg constructors: also sets message label to str.
- *Dlg::handleEvent - handle events on the dialog screen. When it
is time to hide the dialog, also constructs an Event object
with itself as the target and any data it collected as the
arg ( id / type left at 0 ) and passes it to app.handleEvent()
ItemList Class Specification (Items)
public class ItemList {
public final static int SORT_PRIORITY = 0;
public final static int SORT_ENDDATE = 1;
public final static int SORT_GROUP = 2;
public final static int SORT_STARTDATE = 3;
protected final static int SORT_DONE = 4;
protected int sort1;
protected int sort2;
protected ItemRec head;
protected ItemRec tail;
protected ItemRec mru;
protected RemoteFile file;
protected GroupList groups;
public ItemList( RemoteFile tFile );
public void readFile() throws IOException;
public void saveFile() throws IOException;
public GroupList getGroups();
public int getNumItems();
public Item getItem()
throws IndexOutOfBoundsException;
public Item getNextItem()
throws IndexOutOfBoundsException;
public void addItem( Item newItem );
public void deleteItem( int pos )
throws IndexOutOfBoundsException;
public void sort( int tSort1, int tSort2 );
protected void sort( ItemRec head, ItemRec tail,
int sort1, int sort2 );
}
ItemList Class Notes
- ItemList::ItemList - stores the RemoteFile but does not read it,
initializes sort1 and sort2 to defaults.
- ItemList::ReadFile - reads the remotefile into the list, passes
IOException ( if recieved ) on to caller
- ItemList::SaveFile - writes to the remotefile, passes IOException
( if recieved ) on to caller
- ItemList::getGroups - returns the GroupList groups
- ItemList::getNumItems - returns the number of items in the list
- ItemList::getItem - returns the first Item in the list and
stores the position in mru. throws exception if the list
is empty
- ItemList::getNextItem - returns the Item immediately after the
position stored in mru, then increments mru. throws exception
if the next position would be out of bounds
- ItemList::addItem - inserts a new Item into the list
- ItemList::deleteItem - removes an item from the list. throws an
exception if the requested item does not exist.
- ItemList::sort - changes the sort parameters. if the new
parameters are different from the old values, re-sorts the
list.
- ItemList::SORT_* - constants used to indicate different types of
sorts
Item Class Specification (Items)
public class Item {
public String description;
public Date startDate;
public Date endDate;
public byte priority;
public String group;
public Item( String tDescription, Date tStartDate,
Date tEndDate, byte tPriority,
String tGroup );
}
Item Class Notes
- Item::Item - initializes all member variables.
ItemRec Class Specification (Items)
class ItemRec {
public ItemRec next;
public ItemRec prev;
public Item item;
public ItemRec( Item tItem );
}
ItemRec Class Notes
- ItemRec::ItemRec - Initializes item
GroupList Class Specification (Groups)
public class GroupList {
protected GroupRec head;
protected GroupRec mru;
public int getNumGroups();
public String getGroup( int pos )
throws IndexOutOfBoundsException;
public String getNextGroup()
throws IndexOutOfBoundsException;
public void addGroup( String tStr );
public void deleteGroup( String tStr )
throws IndexOutOfBoundsException;
}
GroupList Class Notes
- GroupList::getNumGroups - returns number of groups in the list
- GroupList::getGroup - returns the first Group name in the list and
stores the position in mru. throws exception if the list
is empty
- GroupList::getNextGroup - returns the Group immediately after the
position stored in mru, then increments mru. throws exception
if the next position would be out of bounds
- GroupList::addGroup - inserts a new Group into the list
- GroupList::deleteGroup - removes an item from the list. throws an
exception if the requested item does not exist.
GroupRec Class Specification (Groups)
class GroupRec {
public GroupRec next;
public String name;
public GroupRec( String tName );
}
GroupRec Class Notes
- GroupRec::GroupRec - Initializes name
Connection Class Specification (Files)
public class Connection {
protected Socket sock;
protected InputStream in;
protected OutputStream out;
public Connection( String host, int port )
throws UnknownHostException,
IOException;
public int available()
throws IOException;
public int receive( byte[] data )
throws IOException;
public void send( byte[] data )
throws IOException;
protected int getchar()
throws IOException;
}
Connection Class Notes
- Connection::Connection - constructor, establishes connection
- Connection::available - returns the number of bytes available
for reciept (includes control char's stripped out by recieve)
- Connection::recieve - recieves bytes from the connection up to
the length of the given byte array. returns actual number of
bytes recieved
- Connection::send - sends a byte array of data to the host
RemoteFile Class Specification (Files)
public class RemoteFile {
protected Connection conn;
public RemoteFile( String host );
public boolean login( String userName, String password );
public void openRead( String filename )
throws IOException;
public void closeRead()
throws IOException;
public void openWrite( String filename )
throws IOException;
public void closeWrite()
throws IOException;
public int available();
public int read( byte[] data )
throws IOException;
public void write( byte[] data )
throws IOException;
}
RemoteFile Class Notes
- RemoteFile::RemoteFile - constructor based on connection
- RemoteFile::openRead - opens the file for reading
- RemoteFile::closeRead - closes the file after reading
- RemoteFile::openWrite - deletes the file and opens it for writing
- RemoteFile::closeWrite - closes the file after writing
- RemoteFile::available - returns the number of bytes available
for reading
- RemoteFile::read - reads the specified number of bytes
- RemoteFile::write - writes the specified number of bytes
- RemoteFile methods will throw IOException on any error.
User Interface
When the user opens the URL for the To-Do List Manager, the
Scooby2beDue List Manager will load, then immediately present the
following login screen:
Once the user logs in, they will be left on the main screen for
the application:
If the user presses the Add... button, they will be presented with
the following screen to add a new item:
Or, if the user presses the Groups... button from the main screen,
they will see this screen:
The following two screens come up in a variety of situations. This
is displayed when Yes/No input is needed:
Finally, the following screen is used to notify the user of error
conditions, etc.:
Link to Scooby2beDue Project Notebook
Last Modified 5/7/96 -- Jon A. Preston (Technical Writer)