2005.Jun.04 at 15:38 I'm finished editing the readme index file, ready to upload that and previous log ... done. Needed to wash laundry. It's now 19:35 as I resume work, starting with fixing some minor issues. First, re-thrown exception needs newline in middle so line doesn't get too long ... done in source at 19:37. Next, protect against apostrophe and newlines in message text ... code added and debugged in BeanShell, then file compiled for NULL-mode test, whereupon it worked too, and also I got to exercise the earlier fix to insert newline in middle of re-thrown error to avoid long line, also verified working, at 20:25 now. Time for a nap etc. ... Back to working at 23:20, starting with writing a comparison method for trio (CabID# CabName #msgs) per number of messages ... what a pain the Comparator interface requires an instance method even though it's used in a totally static way. Anyway, done, and code to use that with TreeSet done too, next to modify the per-cab-message report to look for an additional key of "sortby" with value of "nmsgs" to trigger this sorting action before showing the report ... all done given that the form submitted says task=showrep&sortby=nmsgs, and of course the form looks good in Netscape. Bedtime now at 01:40, but tomorrow I'll make the column headers of the report be one-button forms with those hidden values. Now 2005.Jun.05 at 12:06 and I've decided to convert my servlet toplevel to keep all servlet-state information in a single object which can be passed around and updated. This includes the original and wrapped request and response objects, the decoded form contents or query string (via the HashMap within the request object, queried via getParameter), the session ID (computed from best of 3 sources), and any application-specific info computed from these such as the taxicab dispatcher user ID#. Whenever the servlet asks for a particular item of information, it'll be computed from previous items if this is the first time it was asked, otherwise it'll just retrieve the value it already computed. This will make the code much easier to invoke from BeanShell, as well as making the actual code easier to write because I'll just pass a single parameter of type MyServletState from method to method instead of having to pass several separate parameters which are different from method to method and a pain to keep track of. Starting conversion at 12:15 ... got to the point where I'd like to know, for future info, if there's any way to recover the session object given its session ID, went online to consult the API, didn't find any such, composed a query and posted to newsgroup comp.lang.java.programmer, now 13:32 as I get back to actual work ... finished writing and testing the basic part of the new class MyServletState, i.e. the two constructors, one for test rig where I pass it the encoded form contents string and it calls the wrappers, and one for live session where it gets called after wrapped request/response objects have already been created and gets passed those as parameters. Also finished writing and testing the rather lengthy code (formerly inline inside doGetMain in DispatcherServlet) which checks three sources of info about session ID against database to see which is correct and caches the winner in the servlet-state object, at 15:49. Next to remove all that inline code from DispatcherServlet and replace it with one constructor-call and one method call ... done, no compiler diagnostics so I must not have trashed the edit, quick NULL-mode test ... still working, at 16:08. Resuming work at 20:04, programming the last part of use case #4, namely setting up column header which is button to sort by column, and encapsulate sections of inline code within MyServletState object as needed as I go along ... finished writing one new method for MyServletState and needed to know if there's any way to compile it from within BeanShell and add it to the already-loaded class, so I went online to look at the documentation, found there's no way, but I can put the new method into the actual java file and javac it the come back into BeanShell and reload that one class and re-instantiate any instances of it that I happen to have around. While online I looked at other BeanShell info that I might need to use later. It's now 21:25 as I actually try compiling and re-loading and re-instantiating ... gee, once I get started cleaning up my code it's hard to stop, spent a lot of time doing that, which is good in the long, but now at 23:14 I really need to get back to main task of installing column head that invokes sort by column task ... hmm, CloudScape has gotten in that confused state again, so I'm stopping it and restarting it, and also exiting and restarting my BeanShell session ... done, and it's back to working so the method call that bombed before has worked this time. Proceeding with work ... have most of code written and working to make a regular link button, going to bed Jun.06 at 00:36. 2005.Jun.06 at 08:26, resuming work ... done writing code to make multi-UI structure for sort-by-#msgs button and fitting it into headers which is part of overall structure generated, all unit-tested in BeanShell, and all files compiling without diagnostics, as of 09:18. Next to write code to convert that to HTML ... done, unit-tested in BeanShell, file compiles, re-tested, all working at 09:51. Next to run a full NULL-mode test ... done, worked first time, lynx verifies link correct, waited long time for Netscape to start up, finally it's up and shows form layout still looks good, at 09:59. Next to shut down cloudscape and Linux and re-start everything including J2EE server for live test ... OK everything down and class files copied to system area and Linux&J2EE back up at 10:10, now CloudScape up, starting live test with lynx ... still waiting for J2EE server to respond with first Web page at 10:17 ... cookie at 10:18, got login form, filled it out, waiting for login to be confirmed ... at 10:25 got main menu and clicked to get report, at 10:27 got report and clicked to sort by msg count, at 10:32 got report sorted but not exactly correctly sorted, sequence is 2 4 4 8 4 8 but should be 2 4 4 4 8 8, strange!! I went back to the unsorted screen, printed to file, then upon returning to that screen I see the counts are 4 8 8 2 8 4, which means the sorted version should be 2 4 4 8 8 8, maybe my program is working correctly but lynx is doing VT100 update incorrectly? So now moving forward again to the sorted screen, sequence shows as 2 4 4 8 4 8, but if I go to print screen then come back, or if I just do a ctrl-L to fully refresh screen without attempting any VT100 optimizations, I get the sequence 2 4 4 8 8 8 which is correct! So it was lynx's broken idea of VT100 optimizations and/or X term's incorrect VT100 emulation that was messing the screen. (I've noticed in the past that when dialed from this laptop into Unix shell and running lynx there, the screen gets trashed badly much of the time, requiring frequent ctrl-L full-refreshes, and likewise on campus using MicroSoft Windows TELNET to Unix shell running lynx there trashing is very very common.) My program actually worked 100% correctly the first time! It's now 10:43. Clicked on button to return to main menu, waiting for J2EE server response ... at 10:47 I have main menu and clicked on send message (just to be sure that other use case is still working), waiting for response ... at 10:52 I have send-message form and filled it out and clicked to send message now, waiting for response ... 10:56 got confirmation and list of N most recent messages, clicked to go to main menu ... at 10:58 I have main menu already, clicked logout ... at 11:01 I have logout confirmed and login form. End of this demo of Bob and Ray's S. T. O. A. (Slow Talkers Of America). Shutting down J2EE.