Consulting Agency Information System
This is a complete rewrite of the Applet version (which is just the front-end) and is a complete system with XML data and server-side HTML dialogs for maintaining the data and SVG (server-side line drawing) generated diagrams for displaying the data.
XML is stored on the database in CLOBs (Character Large Object), each CLOB containing a group of agencies. All the CLOBs are in one database record. The servlet uses Java to read and parse a particular CLOB, constructing XAGProject and XAGConsultant objects representing the projects and consultants at that group of agencies.
The data is normally presented graphically as a bar graph which is drawn with SVG (Scalable Vector Graphics, or line drawing) on the server.
Here's a sample screen of SVG output. But you won't see anything interesting unless you have your browser configured appropriately.
Alternatively, in maintenance mode, HTML dialogs containing the data are constructed, again in Java. This HTML is transmitted to the user as a normal function of the servlet technology and they can make changes to it and submit them as with a normal HTML page.
Here are the javaDocs
Technical Aspects
JDK
I've used JDK for the first time on my own project here partly because so many workplace environments use it. All the gurus say this is a bad thing, but if you're a small company which will hire contractors to write the code, does it make sense to lock into a complicated IDE that only a quarter of the programmers out there will be really familiar with? It's also easier to get started with JDK -- and it's free. Of course an IDE can do a lot for you, but if you have a good designer who's thought out all the problems, then the coding should be relatively pain free -- and whose going to trust a contractor with tricky stuff anyway?
Development Tools
I'm using the Textpad editor which goes a long way toward making up for an IDE. I use a different Textpad instance for each of my packages of which there seven (plus one for test code) for a total of about 80 modules. In addition there are three Textpads for documentation and one for looking at generated files on the server. To top it off I keep a separate Textpad just for the JServ log file which sometimes gets very large, slowing down page switching, so that it can't share with other files.
Incidentally I'm using the Jikes compiler -- it's way faster than Sun's.
Two other tools I use are Jident for code formatting and Javadoc for documenting.
Debug Control
The main reason to use an IDE, as far as I'm concerned, is for its debugger. There is a JDK debugger, called JDB, but I was under the impression that it wouldn't work work on a servlet. After saying as much on this page, I decided to look into it and, with the help of the Sun Java Technology Forums (not any news groups by the way, one guy there said I should be logging!) I've just found out how to use the JDB on a servlet,
(see this link).
To control the generation of logged debug messages, I have a high-level flag: if it's off the message isn't even created, let alone sent to the debug method.
For special cases, there's a dialog which enables you to set debugging at run-time on individual classes.
Inheritance and Polymorphism
My program uses XAGProject and XAGConsultant objects in very similar ways so they share a base class, XAGObject, which contains most of the functionality. Thus getName() is a base class function that returns the name of a project or of a consultant bacause name is a common variable, in the base class. Polymorphism however, is concerned with methods that belong to children of the base class that behave in different ways, a classic example being that birds fly quite differently than aircraft though both could be represented as sub-classes of flying objects and having the same method name: 'fly'. Polymorphism is about calling a method on an object where you don't know what kind of object it is.
A good example of the value of this occurs when I'm processing the XML using SAX.
First you create a blank object, then update it each time you get more information from the SAX parsing process. There are two ways of doing this: the old structured way, or using P/M; the type of object you create determining the process you are using:
Structured
Initially SAX tells you know what kind of object you are processing, so you create one of them, a Project say:
Project aProject = new Project;
When you get a name field you call the setName() method on that Project. This sounds very straightforward, but there is a certain amount of overhead in keeping track of the different kinds of objects. Java is a type sensitive language and you can't just reserve some space for a not-yet-defined object. Other languages get around this aspect, but there's still overhead. For example, if you want to modify the program by adding another sub-class, you have to change the code.
Polymorphism
You create a Project object but refer to as being of the parent class,
Object anObject = new Project();
You would update this with anObject.setName(); and you don't have to modify the code if you need to add a new sub-class.
Polymorphism Extended
This behaviour extends to other processes, such as XAGObjectList which is a base class for XAGProjectList and XAGConsultantList. Thus when I want to create a list of projects, I create a XAGProjectList object and call makeObjectList() on it. Since this method only exists in the base class that's where we go. makeObjectList() does a lot of generic processing, but occasionally needs to do some Project specific stuff. This is done by defining separate functions in the sub-classes, but with the same name.
Thus if you need to show what kind of object you're processing, you could have a method called 'getType()' which in XAGProjectList returns "Project" and in XAGConsultantList returns "Consultant". At the appropriate time in XAGObjectList.makeObjectList() you call getType() but since it doesn't exist in the base class and does exist in the sub-class and since you originally called makeObjectList() from the XAGProjectList object, it calls the method in XAGProjectList, returning the String "Project".
'Class' class and Reflection
The Class class is very interesting and somewhat unique to Java. At run-time there is a Class object for every class in use by the program and they are used by the Java Virtual Machine to create new objects. As far as the user (programmer!) is concerned, these can be used to produce new classes, or, more usually, to provide access to the properties of the class; the latter is known as reflection, or introspection, and is used a lot with Java Beans.
After the user selects a class name from a menu, my program creates an instance of that class and calls its 'doCommand' method with this code:
Class cmdClass = Class.forName( "xag.command." + nameOfClass );
Object cmdObject = cmdClass.newInstance();
((XAGBaseCommand)cmdObject).doCommand();
From another screen you have the option of setting the static debug flag in a class with:
Class targetClass = Class.forName( inClassName );
Object targetObject = targetClass.newInstance();
Field targetField = targetClass.getField( "debug" );
targetField.setBoolean( null, inStatus );