It's now May.28. Today I finished the code to translate from multi-UI structured representation to swing components, specifically: converting button to translate from struct, implementing flowpane and stackofpanes. Then I put all the pieces together to actually show such a converted object on screen. Next I put more pieces together to yield an instance method within ClientWriter (the output stream within each WrappedHtmlServletResponse object) which produces a swing object from the current contents of the ClientWriter. Next I updated the toplevel test rig so that after it runs the servlet and shows the result converted to s-expression and HTML it also displays it in swing. So then I ran the first part of the first use case, where the initial connection is made to the servlet and it returns the login form, and it works! Before continuing, I finalized yesterday's log and wrote this text so-far in today's, now 15:10, and next I'll update the 1-README.html file ... done, and upload both to the JavaClass WebSite ... done at 15:55. After break, resumed work at 19:23. Upgrading DispatcherServlet as follows: If invalid login, have response include the login form again (after the explanation of failed first attempt at login) ... but first I need to delete some of the logged in users so they can log back in, but my tool for auditing the ActiveUsers table is giving trouble, says the DB update failed, aha I had '' around the numeric contents, will fix that to use number instead of quoted string number, done, but it's still complaining that the update failed, recompiling with trace on, tried again, Cloudscape is giving me this error: DELETE FROM ActiveUsers WHERE UserID=5; ERROR 25502: An SQL data change is not permitted for a read-only connection, user or database. That's not supposed to happen. It never happened before. This was working fine just before I was having trouble with the J2EE server so badly that neither Cloudscape nor J2EE could shut down normally so I had to shut down the whole Linux system and restart it. So maybe Cloudscape is in some wedged state? I'm desperate! I shut down Cloudscape, then restarted it, then re-tried the same operation, and now this happens: DELETE FROM ActiveUsers WHERE UserID=5; 1 row inserted/updated/deleted Phew! If it hadn't gotten working, I'd be unable to make any progress on the whole Lab#3 project until I get help next Tuesday or maybe never. Anyway, that was manually issuing the command from cloudscape -isql. Now let's get back to my ActiveUsers audit program and see if that is back to working too, at 20:08 ... yes, that works too, phew! Also I needed to fix my Users audit program and the shell script for calling it, because toSexpr was moved from Lab3Props to Sexpr1, and that file was moved from the DL3 directory to another. Anyway, all fixed at 20:50, ready to get back to work on DispatcherServlet ... much cleanup done before bedtime. May.29 08:41 looking at my original use cases document for first time in weeks, to see what to do next: I see that I've implemented the logic wrong. The program is supposed to check for login-session token first, before checking for program-task mode. In that way, if user is already logged in, even if no program-task mode given, the user gets a main menu instead of a login form. So first order of business is to reorganize the main logic of DispatcherServlet to look at both jsessionid in the request properties (from hidden field or url) and the ID of the session object, to see whether either is valid (matches current record in ActiveUsers), installed new method in wrapped request to pass through requested ID, put code in DispatcherServlet to look at three sources of ID (session object, requested ID, and hidden field in form), writing code to validate any that are non-null, but first need to upgrade MyInput to support default values ... done and revived&upgraded test suite for MyInput, done at 10:58. Now back to test rig for upgraded audit of ActiveUsers to support lookup by session ID ... Had to stop for a while to run other urgent errands, back at 15:07, back to working on new code and test in Lab3Props ... all done at 15:46. Now back to writing code in ActiveUsers to lookup session ID and return record number, which uses that Lab3Props code, and which is used by ActiveUsers audit where I'm testing it ... finished and working at 15:57. Now back to code in DispatcherServlet which needs to look up a session ID in order to validate it to determine whether the current user is already logged in ... taking nap at 17:20 ... After nap and some other necessary tasks, back to this at 19:50 ... almost done May.30 at 00:44, all parts of use case #1 (check session and possibly log in) done except where session ID was lost and user tries to log in when already logged in. In cases where user is already logged in and passes correct session ID token, or where user newly logs in, user gets toplevel menu. Cleaned up some stuff, now at 00:59 I'm starting up the J2EE server for the first time all day, to see if a live run of everything so-far actually works ... while it's starting up I remembered to copy all the recently-changed class files to the system directory. Now starting up lynx ... done, at 01:09 still waiting for J2EE server to be finish getting up ... server finally up at 01:13, clicked on link ... at 01:17 I'm still waiting for JSP to compile and server to offer me a cookie ... at 01:21 I decided to check the system log to see what's going on: Program is running, doing database query to see whether session ID from live J2EE servlet container matches any session ID of logged in taxicab-message user ... at 01:26 still no cookie, so going to check system log again ... it seems to still be in that SQL query, no more trace output since it showed me the SQL command ... finally at 01:31 it finished the SQL query and moved on with the rest of the program and offered a cookie, and I accepted, and it put up login form, and I filled it out, and at 01:33 I'm waiting for the login verification to finish. Going to check system log now at 01:35 ... as I suspected, it's sitting in the SQL query for session ID again ... at 01:41 it finished that SQL query and moved ahead to start checking the contents of the login form that I had submitted ... at 01:45 it's finally finished with those database checks, and before I can switch back to the lynx window it's already put up the main menu. I clicked on the button to send a message, which feature is not yet implemented, so it should bomb out as soon as it gets to that point in the program. Bottom line: My method of developing program in NULL test rig, augmented with conversion of output to swing, never having to do anything with J2EE server until I have it all working, is a big win! OK, at 01:50, server error: Unknown case of sTaskval [sendmsg], as expected. Let me press back button on browser and make it die at logout likewise ... did that, now 01:52 ... at 01:56 the expected server error: Unknown case of sTaskval [logout]. Now 2005.May.30 at 08:16. Adding third button (show report of messages per cab) to main menu ... done. Fixing login logic so that if user tries to log in when already logged in, the old session ID will be retrieved and used instead of rejecting the login ... done. I ran some other errands during that time. It's now 11:10 at the time I claim that use case #1 is fully implmented, and tested in NULL test rig, including swing display. (I don't feel like spending two hours just to verify it also works in live J2EE session.) Next to start working on use case #2, send message ... took nap etc., back to work at 13:01 ... made a nifty demo of the locking mechanism whereby a program tries to get a lock, keeps trying until it gets it, then holds onto it for 30 seconds before releasing, and when I start two of them nearly simultaneously one of them gets the lock and holds onto it while the other keeps trying, then as soon as the first one releases it the other gets it promptly. Now working on code to actually look up the largest existing message number and add one and write a new message with that unique message number while holding onto the lock ... done and tested at 15:38 but with one problem: When I ran two simultaneous programs, after the first program got the lock and posted a message and released the lock, the second was still unable to get the lock. cloudscape -isql confirms the lock is no longer present, so why can't the second program get the lock?? I changed the program to show what's happening at the SQL level when trying to set a lock, and in one case it got a truncation error because Locks allows only 10 characters in a user name and I happened to specify a longer name during that test. Maybe that is what happened the other time it could never get a lock, but that's rolled off-screen so there's no way to see if that was the case. All this is because I originally created the Locks table manually in cloudscape -isql. I've added code in Locks.java to create the table with 20 characters allowed in a username, same as in the Users table. So now I need to call that code from somewhere. I think it's time to write a 'Setup' module which makes sure all the tables are present and creates them if not. I'll do that after nap&shower. It's now 16:23. Resuming now at 17:30. Starting to write Setup.java ... got the first part all done where it checks system configuration against properties file to verify it's running on the correct system, and then verifies it can open the database connection. Next it checks each of the tables to make sure it exists and has initial data if any is available, which requires calling mayMakeTable() within each specific class dealing with the corresponding table. I needed to upgrade Users.java, add code to Locks.java to create the table if it didn't already exist, which it didn't because I had to delete it earlier tonight because the manually-generated version I'd been using was bad as described above, create Msgs.java from scratch, including code to create the table if it didn't exist and put one dummy message in it, create Cabs.java from scratch, including code to create the table if it didn't exist, and set up initial data in properties file and software to load that initial data. It's already 22:19, more than two hours past the deadline I had set for myself to finish this lab assignment and upload it in case I don't have time tomorrow, and I still need to create MCRelat.java like the other table-specific classes already done, and at the moment DispatcherServlet is in the middle of an edit so it can't be compiled, and I still haven't implemented logout in the servlet, and I haven't implemented either of the "interesting" use cases (send message, show table of per-cab message counts), so I can't stop work now and upload what I have so-far. I need more time after Tuesday!!