Ganymede Release 1.0.7
October 11, 2001
CHANGES
---------------------------------------------

-------------------- Changes from 1.0.6 to 1.0.7 -------------------

RELEASE DATE: October 11, 2001

1. [SERVER] Deleted objects now have all of their fields logged

The Ganymede server has not been logging the status of objects when
they are deleted, which has made it in some cases impossible to
determine what was in an object when it was deleted.  In theory,
today, all objects created in the server will be logged with their
initial state as well as all changes made, but at ARL we had a great
deal of objects that were imported using the old 'directLoader' hack,
without any logging done.

The real advantage to this for other users will not so much be
for scanning the log file as it will be to make the object deletion
email more informative.

2. [SERVER] Better error message on field creation failure

The server now gives a better error message if a user tries to link an
object to a (previously undefined) field that the user does not have
permission to create.

3. [SERVER] Made sessions smarter about refusing to edit objects during commit

The DBSession class has been modified to disallow editing of new
objects during a transaction's commit or abort process.  This is to
help make sure that any code during the commitPhase1() and
commitPhase2() DBEditObject customization methods that seeks to bring
new objects into the transaction after the commit has already started
will trigger a runtimeException, rather than silently confusing the
commit logic.

This change shouldn't have any effect on any code provided with the
Ganymede distribution or the userKit, but might force an error in
custom code if the customizers were doing some sort of dangerous
activities during the commit process.

4. [SERVER] Amended wizard shutdown process

The GanymediatorWizard class had a loophole that would cause wizards
to not be unregistered from a GanymedeSession if the wizard's state
had been forced to DONE outside of the GanymediatorWizard.unregister()
method.  This has been fixed so that any time a wizard goes through
returns a success() or fail() result it will be unregistered.

This fix took care of a bug in the laboratory's GASHARL schema kit
operations, but is very unlikely to be affecting anyone out there
unless you've done just the right (wrong) kind of custom schema
coding.

5. [SERVER] Put loopback binding check into server startup

The server now checks to make sure that it is not being bound
to a loopback address on startup, which would prevent clients from
being able to communicate with the server from remote systems.

The server will now generate a message of the form

 ** Error **

  Both the system hostname (hostname) and the ganymede.serverhost
  definition (hostname) resolve to the 127.0.0.1 loopback address

  The Ganymede server must have an externally accessible IP address or
  else clients will not be able to communicate with the Ganymede server
  from other than localhost.

  If you really want to be only usable for localhost, edit the runServer
  script to use the -forcelocalhost option.

if the server is not able to figure out a hostname that will resolve
to a network-accessible IP address.

RedHat Linux 7 systems are particularly prone to this, as the default
configuration for such systems includes the system's hostname in
/etc/hosts as mapping to 127.0.0.1, and the system 'hostname' function
returns by default a non-fully-qualified hostname.  The combination
of these two conditions resulted in the Ganymede server registering
itself with the rmiregistry process as being on IP address 127.0.0.1.

This change was in response to a problem report from Steve Lemons
(steve.lemons@arrisi.com).

6. [SERVER] Objects in the process of being deleted may not be linked to

The server's object binding logic had a bug which would allow an
object which was being deleted to be improperly linked into an Invid
field in another object.

This occurred in a bit of custom code in the GASHARL schema kit where
unlinking a remote object in a given context resulted in the object
being deleted by the custom server-side code.  The client, however,
showed the unlinked object as a valid choice to be added back into the
link field.  If the user tried to put the (now deleted) object back
into the field, the link was made, even though the object was marked
for deletion when the transaction committed.

This resulted in an Invid field containing an Invid pointer to an
object which no longer existed, which is a bug.

The server's InvidDBField logic is now smart enough to forbid linking
to an object which has been marked for deletion by the transaction.

This was a very obscure integrity violation vulnerability.  The server
and client have always cooperated in other ways to prevent this
condition from arising.  It was only due to some odd custom coding
in the GASHARL schema kit that this vulnerability was revealed.

7. [CLIENT] Optimized out redundant network calls in the GUI client

The Ganymede GUI client has been optimized to remove a great many
redundant RMI calls when viewing objects on the server.  The client
can now display objects with only about half the RMI calls that the
client used previously.  This will speed up the client noticeably on
slow network links, and will reduce loading on the server slightly.

-------------------- Changes from 1.0.5 to 1.0.6 -------------------

RELEASE DATE: August 15, 2001

1. [SERVER, ADMIN CONSOLE] Fixed delayed memory release for schema editing

The Ganymede server wasn't properly clearing references to a bunch of
temporary data structures when a schema edit was cancelled by the
admin console.  This had the effect of increasing our server's memory
footprint by a couple hundred kilobytes or so until such time as the
admin console was stopped and restarted.

2. [WEBACCESS] Fixed ganypass.pl to allow < and > chars in passwords

The ganypass.pl script, which provides a CGI interface to the
xmlclient for changing users' passwords, was improperly failing to
convert < and > to the XML entity escapes &lt; and &gt;, which could
cause the server's XML parser to reject password changes that involved
those characters.

3. [SERVER] Fixed several journal processing bugs

Yowtch.  Several nasty bugs that were lurking here.  None of these
bugs caused any problems if the server was shut down cleanly and
restarted, but if the server was abnormally terminated, the following
bugs caused problems during transaction recovery on startup.

Firstly, the server had a bug that prevented successful startup if the
server was killed without getting a chance to consolidate the database
into a new ganymede.db file, and if one of the transactions in the
journal file involved an deleted object that had one or more
namespace-constrained database fields.

This was due to an attempt to use Ganymede.internalSession before that
variable was defined.  This has been fixed by making the
DBNameSpaceHandle.getField() method look up objects directly out of
the DBStore tables without using a GanymedeSession, if needed.

Thanks to Gaurav Bhargava at Villanova University for reporting
this first bug.

Secondly, there was a bad bug that caused transaction processing in
the journal handling code to repeatedly process object records in the
journal.  The journal processing code was not clearing the entry
vector at the end of each transaction's processing, which caused the
server to do a lot of repetitive work and to generate misleading
warnings about 'objects already deleted' in the object deletion case.
Ugh.

Thirdly, there was a bug, subtle in causation but HUMONGOUSLY AWFUL in
effect, which caused the server to *eat* changed scalar fields when
processing journal entries.  This bug has been in Ganymede since
1.0pre1, when I moved field storage in DBObject to a packed hash as a
memory optimization.  The replaceField() code that edited the packed
hash to replace fields with the versions noted in the journal
transaction entries silently failed if it could not find the field it
was looking for, causing the changed fields to be simply dropped on
the floor.  That's what I get for recklessly optimizing my data
structures.

Data loss bugs in Ganymede have been rare, thankfully, but this was an
ugly one, and it bit me when I was testing the fixes to the first two
journal bugs.  My apologies if it bit anyone else out there.

The good news is that I've cleaned up the journal loading code a fair
bit, and that I have significantly improved the debug instrumentation
in this section of the code.

-------------------- Changes from 1.04 to 1.0.5 -------------------

RELEASE DATE: July 27, 2001

1. [DISTRIB] Fixed a number of bugs for JDK 1.4 compatibility

Fixed a few places that assumed SimpleTimeZone.getDefault()
would return an object of class SimpleTimeZone.

Fixed the jar packaging to satisfy Java 1.4's slightly pickier
serialization logic.

Because of these changes, the Ganymede 1.0.5 server will not be
compatible with clients from 1.04 or earlier.

2. [DISTRIB] Added support for using Java Web Start to launch clients

Sun's excellent Java Web Start provides the best way yet to launch the
Ganymede clients on Windows.  I have made changes to installWeb to
support the Java Web Start option in the Ganymede launcher.

3. [CLIENT] Fixed java.security.AccessControlException in client

On some versions of the JDK, the client, when running as an applet,
was refusing to allow changes to the animated build status icon in
response to RMI callbacks from the server.  This robbed the user of
valuable feedback and resulted in java.security.AccessControlException
messages being thrown on the server in response to the client
notification call.

I have added a new 'SecurityLaunderThread' to the client, which waits
for build status messages from the server and updates the build status
icon.  Since the SecurityLaunderThread was started by the client and
not by the RMI system, it has proper permissions to play with the
Swing Event Queue, and everything works properly.

4. [SERVER, CLIENT] Reworked permissions handling for built-in fields

The Ganymede server previously did not separately track permission to
edit the "built-in" fields.  That is, the permissions editor in the
client did not allow per-field permissions to be set for the standard
fields that are automatically present in every object, including the
Owner List, Expiration Date, Removal Date, and Notes fields.  Instead
of allowing access controls for these fields to be set in the standard
permission matrices in the Role objects, all of these fields were
accessible with the same permission as the containing object itself.
If a user had permission to edit an object, that user automatically
had permission to edit these four system fields.

This turned out to be a security hole, because there are many cases in
which it is desirable to allow an object to be minimally editable by
non-privileged users (so that end users can change their own
passwords, for instance), where such users may not be trusted to edit
the owner list, notes, expiration date, and removal date fields.

The client's permissions editor and the server now allow explicit
setting of permissions for the Owner List, Notes, Removal, and
Expiration Fields.  The four 'historical' fields used to track object
creation and modification timestamps and admins are never allowed to
be edited by the user, and so are still left out of the permissions
editor.

In the process of doing this work, a few potential vulnerabilities
that might have been exploitable by a rewritten Ganymede client were
closed.  The Ganymede philosophy is that the server should not trust
the client for anything, and a few security assumptions have now been
made explicit.

The server now makes several checks and forbids the granting of
privileges that would be liable to break the Ganymede security
model.  For instance, non-privileged end users will never be allowed
to edit the owner list field for objects, regardless of whatever
permission for the Owner List field might be granted in the server's
Default role.

5. [CLIENT] Improved GUI cleanup

Miklos Muller reported that the client was leaving the permissions
editor up if the server forced a client disconnect due to a timeout.

I looked into things, and the code for handling resource cleanup on
window close in the client was still very messy, despite Bug fix #11
for release 1.0, below.

Things are a good bit cleaner in the client, now, and all popup
permission editor windows should now be put away properly when the
window that the permission editor was launched from is closed.

6. [DISTRIB] Changed numbering scheme

I realized that if I have more than 6 more 1.0x releases, I'll
suddenly be at 1.1, which I don't want to do by accident.  So, we're
going from 1.04 to 1.0.5.

7. [DOCUMENTATION] Added an upgrade guide, improved XML docs

I've written a short upgrade guide that explains how to go about
upgrading the server, schema kit, and clients when a new version of
Ganymede comes out.

I've also done a fair amount of rework of the xmlclient documentation.

8. [SERVER] Made the server use a default address for email if necessary

The Ganymede server typically sends mail out for actions taken by
admins on behalf of the admin's email address.  That is, Admin Persona
objects have an 'email address' field, and when the Ganymede server
sends out mail in response to that admin's actions, mail from Ganymede
is sent with the admin's address used as the 'From:' header.

Previously, if Ganymede could not determine an email address to use
for an admin, it would try to send mail out with a null return
address, which caused the mail attempt to fail.

Martin Vogt <vogt@itwm.uni-kl.de> reported this bug, and the proper
fix for it, back in March of 2000, but I didn't realize how likely
this problem was to affect new users until I did some testing
of a fresh install on a new system.

9. [SERVER] Fixed field/object permission interaction

Previously, the GanymedeSession.getPerm() method filtered per-field
permission bits against the permission bits for the object as a whole.

This makes sense for the view and edit bits, as you can't view or edit
a field if you can't view or edit the object it is contained in, but
it does not make sense for the create bit, as it might well be
appropriate to be able to create a new field in a pre-existing object
that you can edit, even if you don't have the right to create a new
object of the type.

The server is now smart enough to avoid filtering the create bit
for a field against the create bit for its object.

-------------------- Changes from 1.03 to 1.04 -------------------

RELEASE DATE: July 9, 2001

1. [SERVER] Fixed NullPointerException thrown in XML Login path

The Ganymede server's xmlLogin() method was throwing a
NullPointerException if a user submitted an XML file through the XML
client with an invalid username and/or password.  The server now
avoids having that exception thrown by explicitly checking the success
of the username/password login before trying to construct a
GanymedeXMLSession.

2. [CLIENT] Fixed date reversion in the pop-up calendar GUI component

I fixed the pop-up calendar's reversion handling for when the user
attempts to change the date/time in a date field and chooses a date
that is out of range.

3. [CLIENT] Enhanced list GUI boxes in the client

The client's JstringListBox and StringSelector components have
had their behavior enhanced, with a 'select all' button added
at the top of the StringSelector, and with the JstringListBox
keeping all items added selected, to allow easy undo of
item moves.

The JstringListBox is now capable of supporting item dragging
in the list.

4. [CLIENT] Enhanced query box

The query box now uses a pair of StringSelectors to represent
the list of field choices rather than a bunch of checkboxes.

5. [SERVER] Fixed namespace constraint handling during schema editing

Previously, it was possible during schema editing to set a namespace
constraint on a field that contained data in violation of that
constraint.  Now the schema editor will not allow any schema edits to
be made that would allow a namespace constraint to be placed on a
field that contains data in violation of such a uniqueness constraint.

With this change, it should now be impossible to put the server into a
state where fields hold data in contradiction to an expressed
uniqueness constraint.

Thanks to Gaurav Bhargava at Villanova University for reporting
this bug.

-------------------- Changes from 1.02 to 1.03 -------------------

RELEASE DATE: June 22, 2001

1. [SERVER] Fixed non-event related mail sending in DBLog

The DBLog class had an error, effectively, that prevented 'mailout'
class mail from being sent, although it was logged.

Added a 'sendMail' method to DBLog to simplify the sending
of mail by plug-in code and custom tasks.

2. [SERVER] Fixed startup default permissions for non-supergash users

Miklos Muller, mmuller@lbcons.net, reported a bug that caused Ganymede
to not allow non-supergash users to login to a freshly initialized
Ganymede server.  Editing the Default Role object's Default Access
Bits field, works around the problem, but unless this is done, an
exception will be thrown in GanymedeSession.resetDefaultPerms().

I have corrected the GanymedeSession resaultDefaultPerms() method so
that it will not freak out when it doesn't find any definition for the
Default Access Bits field in the Default Role object.

This bug was avoided by users who used the userKit's loader.pl script
to initialize the Ganymede database.

3. [SERVER] Fixed infinite loop bug in XML parser

The XML parsing code had a bug that would leave it looping infinitely
if the XML stream was closed before completion of parsing, either due
to an incomplete XML file being fed to the xmlclient, or through the
xmlclient dying suddenly.  This didn't break the server, but it did
take up a lot of processor time, and kept all of the memory associated
with an XML session pinned in the server's heap.

4. [SERVER] Fixed default label field for persona objects

The persona object schema definition was improperly defaulted to use
the older 'name' field as the label, rather than the composite 'label'
field.  This could cause errors when trying to login with a newly
created persona.

This bug was reported by Miklos Muller as well.

-------------------- Changes from 1.01 to 1.02 -------------------

RELEASE DATE: June 7, 2001

1. [SERVER] Fixed an incompatibility with JDK 1.1 on the server

The server code included a use of a generic 'add()' method
on the java.util.Vector class that didn't get added until Java
1.2.  Replaced it with addElement().

I'm going to have to put up some sort of nightly build directory until
I can get network CVS access going, putting out new releases like this
is silly. ;-)

-------------------- Changes from 1.0 to 1.01 -------------------

RELEASE DATE: June 7, 2001

1. [SERVER] Fixed an IllegalArgumentException with empty namespaces

Michael Jung (mikej@confluenttech.com) reported an exception thrown
during startup.  It turned out to be due to some of the checkpoint
code trying to deal with an empty namespace.  Easily fixed, so
I did.

-------------------- Changes from 1.0pre1 to 1.0 -------------------

RELEASE DATE: May 31, 2001

1.[SERVER] Made server do better server-side cleanup for stuck clients

The RMI system has the ability to get into a state where a TCP/IP
handling thread waits indefinitely for communication from a client.
Prior to this fix, the server would wait forever for a dedicated
thread to try and notify the client that it is being forced off before
handling the server-side client logout housekeeping.

Now, the forceOff() method in GanymedeSession will expunge the client
from the server on the server-side before notifying the client that it
has been disconnected.

Note that this fix may still leave those dedicated background threads
stuck in the JVM trying to finish reading from a socket from the
(presumably dead) client.  I can't do much about this other than wait
for Sun to fix their RMI implementation so that RMI reads on a socket
will eventually time out.  In my experience, threads hanging due to a
partial socket read is reasonably rare, so I'm not overly worried
about hanging disconnect threads clogging up the server.

2. [SERVER, ADMIN CONSOLE] Added support for memory status tracking

The server and admin console now collaborate to display the amount of
free memory and the total amount of memory taken up by the server, to
be updated once a minute by a new Memory Status Updater task.

3. [SERVER] Added the garbage collection task back in

I added back in the on-demand garbage collection task, which is an
interesting thing to play with now that the admin console shows memory
usage on the server.  It looks like System.gc() doesn't do much of
anything under the HotSpot server VM.  Not too surprising, as the
HotSpot server VM is already optimized for continual, incremental
garbage collection, but having the ability to launch a garbage
collection task from the admin console's task monitor may be helpful
on some VM's.

4. [SERVER] Cleaned up setLastEvent() usage in GanymedeSession

I cleaned up usage of the diagnostic setLastEvent() stuff in
GanymedeSession.  Viewing or editing objects that contain embedded
objects will no longer cause notification for the embedded stuff to be
sent to the client.  In addition, all setLastEvent()-style
notification for non-interactive sessions has been turned off, to
reduce the overhead during XML bulk-loading.

5. [CLIENT] Informative dialogs are no longer modal

The Ganymede GUI client was occasionally freezing up on start-up if
the user attempted to bring up a toolbar dialog at the same time the
client was working in the background to bring up the MOTD dialog.

This was a result of the HTML messageDialog class used for the MOTD,
Credits, and 'About Ganymede' dialogs being configured to lock out any
other GUI interactions until those dialogs were released.  

I don't think there was ever any compelling reason to make these
dialogs modal, so I have made them not be so.  There's now a small
risk that a user might ignore the MOTD dialog without dismissing it,
but that's a far less serious outcome than having the client lock up.

Thanks to Tom Embleton for bringing this back to my attention.

6. [SERVER] Memory leaks fixed

Once I had the admin console tracking memory usage, I quickly saw that
the Ganymede server was leaking memory over time.  At ARL, our
server's heap was starting out at about 10 megs, and after 8-9 days,
the heap had nearly doubled in size.  I ran the Ganymede server
through a profiler for a couple of weeks and identified several places
where bits of code were holding on to references to things that were
no longer needed.  Some of these were really obscure.. things I would
*never* have found were it not for the assistance of the profiler.

After a month or so of analysis and code work, the Ganymede server's
memory usage has been brought under far better control.  I've not yet
had a chance to run the newly updated server for long enough to judge
whether the heap usage is truly stable over the space of weeks and
months, but I can say that the server's memory growth rate appears to
have dropped to less than a tenth of what it was before, at worst.

7. [SERVER] File descriptor leak fixed

The arlut.csd.ganymede.util.zipIt class was neglecting to close files
that were being read in for adding to a zip file.  This caused the
Ganymede server to run out of file descriptors during nightly
archives.  Apparently this problem was masked on earlier versions of
the JVM by the FileInputStream's finalize() method doing clean-up.
Since finalize() is not guaranteed to ever be called, moving the
Ganymede server to a new JVM made file descriptor starvation start
appearing.

I have now fixed the code so that finalization is no longer required
for proper resource release, and everything is working well.

8. [SERVER] Added cryptographic hash support for Samba

The server now includes classes to support both forms of password
hashing used in Samba's encrypted password file.  This will simplify
support of Samba in userKit 1.0, as the NTSambaBuilderTask will now be
able to emit a file with all of the plaintext passwords pre-hashed,
rather than depending on a hard-to-install Expect script to drive
smbpasswd to insert updates into the Samba password file.

9. [SERVER/ADMIN CONSOLE] Added a 'force rebuild' menu item to admin console

The admin console now has the ability to force a mandatory rebuild of
all external data.  Previously, it was possible to manually run a builder
task from the task monitor table through the right-click popup menu, but
that builder task would typically not actually write out data if the
object bases in Ganymede that contained the data had not been changed
since the last run of that builder task.

Now the admin console has a 'force build' option under its Control
menu which forces the running of all builder tasks registered in the
system, and that forces those builder tasks to treat all object bases
as having been dirtied since the last run of the builder tasks.  This
allows an admin to force a dump of all external data files generated
by the builder tasks, and the consequent execution of all external
update scripts.

10. [ADMIN CONSOLE] Improved network error handling

The admin console would previously force a disconnect from the
server in the event that any network operation returned a RemoteException.

Unfortunately, a RemoteException may be returned even if the network
connection remains good.  Any exception that occurs on the server
in response to an RMI call results in a RemoteException.  Having
the admin console do a force disconnect on any error was a bit harsh.

Now, the admin console will append the stack trace information for
any RMI remote exception to the console's log area, where it may be
seen.

11. [CLIENT] Cleaned up resource retention on the Ganymede GUI client

The Ganymede client was doing very little in the way of cleaning up
allocated structures.  So little, in fact, that it was retaining
references to remotely exported fields from the server, even if the
client had been logged out.

The client has now had some extensive work done to disassemble object
structures when appropriate.  This will very significantly reduce
memory loading on the client.

12. [CLIENT] Made the client's query window non-modal

The client's query window's modality was causing the JpopUpCalendar to
lock up when someone tried to edit the date and time of a time field
search.  Making the query window non-modal takes care of this.

In addition, I reworked the way that threading is handled for the
'waiting for query' animation and table window display to make sure
rendering operations for them are handled on the GUI thread, which
should help avoid some exception traces that were occasionally
being thrown on the client.

13. [GUI, SCHEMA EDITOR] Fixed a race condition in the tree node drag code

The schema editor provides support for re-ordering fields within an
object, or objects within an object category folder.  The tree GUI
component had a race condition, however.  Depending on the rate at
which the Java GUI thread produced mouse motion events and the rate at
which the user moved the mouse, node dragging could result in the
wrong node being moved.

This of course, made the schema editor amazingly frustrating to try
and use if conditions allowed this bug to be expressed.  This bug has
been around for years, transiently appearing and disappearing
according to the speed of GUI thread processing on the JVM on which
the schema editor was run.  I am *very* happy to have it fixed at
last.

14. [SERVER] Fixed transient logic errors in permission editing

There were a few places in the Ganymede server where the Ganymede
logic was invalidly depending on the post-serialization initialization
of transient fields in objects passed over RMI.  This is not in
keeping with the way that Java serialization actually works, and in
one instance this logic flaw resulted in changes made to permission
matrices by editing Role objects not taking effect until the server
was stopped and restarted.

Nasty, nasty bug, and a pain to track down.

I've fixed this, and audited all of the server code to insure that
there are no remaining attempted dependencies on post-serialization
initialization of transient fields.

15. [SERVER XML] Fixed missing attribute error reporting in XML parser

The Ganymede server's XML parsing code is designed to report to the
xmlclient a record of the last 30 XML elements parsed prior to
encountering an XML validity error (such as an invalid character,
say).  Unfortunately, the class that represents XML entities (such as
'<object type="I.P._Network" id="CSD - No Inet Access">') had a bug in
it's toString() method that caused every other attribute to be skipped
over when regenerating a string representation for the node.

This was a small bug, but made it maddeningly difficult to track down
syntax errors in XML files created for use with Ganymede, if the odd
numbered attributes in the nodes were not unique enough to identify
position in the XML input file.

16. [CLIENT] Tweaked the Ganymede client's GUI

I have tweaked a number of aspects of the Ganymede client's GUI to
make using the Ganymede client a bit more convenient, mostly in the
way of reducing the default length of fields in the object
viewing and editing windows.

17. [SERVER] Fixed DBNameSpace rollback()/unmark()/commit() bug

The server had a vulnerability in the DBNameSpace class that would
cause the commit() method to fail in circumstances where a namespace
rollback() operation had been followed by an unmark() operation on a
value previously allocated in that namespace.  The
DBNameSpace.commit() method could in this circumstance throw a
NullPointerException at a point in the transaction commit process that
would leave the transaction in an unfinished state, causing confusion
and mayhem all around.

This bug only manifested one time in the year and a half that Ganymede
has been in production here at ARL:UT, and appears to have manifested
at a time of heavy contention for resources in the namespace, such
that multiple transactions were trying to allocate namespace-guarded
unique values concurrently.

In response to this, the DBNameSpace.java code was largely rewritten.
The rewrite fixed this problem, and also significantly reduced the
memory requirements for unique value namespace handling.

18. [CLIENT, ADMIN CONSOLE] GUI tweaks for 1.0

Added 'About Ganymede' dialog to Admin Console.  Added keyboard
accelerators to Admin Console menus.  Tweaked menu names in Admin
Console to allow unique and intuitive accelerators.

Tweaked the messageDialog class so the client's MOTD can be dismissed
by hitting spacebar.  Tweaked the menus in object windows in the client,
added keyboard accelerators to menus.

Did some more cleanup work on the tree GUI component.  When you drag a
node in the schema editor, the node you are dragging will now be
highlighted in blue during the drag operation, in addition to the icon
drag that the tree has had.  Made right-clicking on nodes select the
node before popping up the pop-up menu, as a visual reference point.

19. [SERVER] Fixed DBObject synchronization

The server ran into a deadlock race condition where logins could not
be processed while a database dump was in progress at a certain point.

This arose out of the conversion to a packed array hash structure
for field storage in the DBObject class within the last year.  There
were a number of places in which I was sloppy with nested monitor
synchronization.

I have thoroughly reworked the DBObject synchronization logic
to avoid all such problems.

-------------------- Changes from 0.99.9 to 1.0pre1 -------------------

RELEASE DATE: January 30, 2001

1. [SERVER] Reworked server synchronization logic

The GanymedeServer.login() method was vulnerable to a nested monitor
deadlock due to a section being synchronized on both the server's
GanymedeServer object and its DBStore object.

Basically, I was getting way too fancy in synchronizing on various
server objects instead of defining a proper semaphore class and using
that.

I added the loginSemaphore class, which takes care of everything
without my having to worry about n^2 different possible code paths.

I modified the admin console to report the login semaphore count for
each log entry.. this makes it easy to see at a glance how many users
are logged on for each log entry, and to insure that the semaphore
count is incremented and decremented properly under all circumstances.

In the process of all this, I realized that I was unnecessarily doing
a notifyAll() every time I did a synchronized operation on the
server's DBStore object.. I had misunderstood when it was necessary to
do a notify when I originally wrote a lot of this code.

The sweepInvids() and checkInvids() methods have been fixed so that
they are no longer synchronized on GanymedeServer but they do now
establish a dump lock on the server's database, to insure that the
object walk is done safely.

2. [SERVER] Added getBackLinks() method to the DBObject class

Martin Schneider <martin@ira.uka.de> reported that he needed to be
able to get the Vector of Invid's pointing to a given object through
asymmetric links, in the same way that was possible by using the old
backlinks field.  To support this, I added a getBackLinks() method to
the DBObject class that directly consults the DBStore's backPointers
hash tree.

3. [ADMIN CONSOLE] Fixed admin console confusion with multiple logins

The admin console had a bug that would cause the console user table to
become confused if more than one user with the same persona name was
logged in at the same time on the Ganymede server.

This problem only happened when an admin logged into the server with
admin privileges more than one at a time.  Logging in without admin
privileges did not cause this problem, because the server assigns
unique usernames to logins, but the server does not guarantee unique
persona names.

The server now reports to the admin console each login's unique user
name, which the admin console uses for login tracking, but the admin
console will continue to display the user's (possibly non-unique)
persona name.

This one has bugged me for awhile, it's good to have this fixed.

This change (and change 5 below) change some of the semantics of the
admin console's operations, so you should not use an older version of
the Ganymede admin console with a 1.0pre1 server.

4. [CLIENT] Right clicking on a selected JTable row no longer de-selects the row

This one has bothered me for a long time, too.  I changed the
baseTable, rowTable, and tableCanvas classes in src/JTable so that
right-clicks on a table row won't ever deselect that row if already
selected.  Left-clicking on a selected row in the rowTable will still
deselect the row.

5. [ADMIN CONSOLE] Threaded out server-to-console communications

The Ganymede server has always communicated synchronously with any
attached admin consoles, which made the server effectively block if
the admin console became non-responsive without explicitly throwing a
RemoteException.  I noticed today that the admin console was blocking
the server from processing logins/logouts while my window manager on X
was waiting for me to place a new window, which of course is not
acceptable.

The Ganymede server now queues up notification events for the admin
console, and uses a separate thread for each admin console for
actually handling the server-to-console communications, using the new
serverAdminProxy class.  The Ganymede server will no longer sit around
waiting for the admin console when something happens, with the obvious
benefits resulting in speed and reliability on the server.

As a side benefit of the event queueing model, I've implemented event
coalescing and event replacement, so that if the Ganymede server is
generating admin console events faster than the console update thread
is getting them to the admin console, the server will combine and/or
drop old events, so that the server won't waste time sending events to
the console that are already out of date.

The admin console was changed a very little bit to support event
coalescing; the changeStatus() method in arlut.csd.ganymede.iAdmin now
depends on the server prefixing each status line with a time stamp,
rather than trying to time stamp each event from the server itself.

Good stuff, and very clean on the server.

6. [ADMIN CONSOLE] Fixed admin console shutdown process

I fixed some code in the server's GanymedeAdmin class so that an admin
console will stay open if a shutdown attempt by it was refused for
some reason.  Also fixed a bug in the admin console that made it fail
to really attempt to shutdown the server if it tried once and failed.

7. [SERVER] Cleaned up some locking and transaction logic

I went through and did a code review of all of the server's
transaction and locking classes, and removed a few bits of extraneous
stuff, fixed a couple of mistakes that could conceivably cause
problems on edge cases, and extensively commented code that I hadn't
really touched for a couple of years so that if I dive into it in 2002
I won't have to figure it all out from scratch again.

These changes probably won't be noticeable in operation unless I broke
something.

The DBLock code itself has been reworked a fair bit.  The DBLock code
no longer synchronizes directly on the Ganymede server's DBStore
object, but instead uses a DBLockSync object held in the DBStore
object.  This as well will help prevent deadlock problems, by limiting
the scope of synchronization on the DBStore object even further.

8. [SERVER] Made the database dumper task less timid

Due in part to the increased confidence I have in the server's thread
safety with the new login semaphore and my code review, I made the
database dumper task go ahead and do a database consolidation even if
users are logged into the server.

Previously, the database consolidation task could be postponed
indefinitely if users were logged in each time the dump task fired,
leading to a bigger journal file and longer startup times if the
server machine was rebooted.  Now the database dumper task will go
ahead and do the dump, even if it has to wait for transaction commits
to finish so it can assert a DBDumpLock on the database.

9. [SERVER/CLIENT] Added bulk add/remove methods to DBField

The Ganymede client has long supported moving large blocks of choices
from the unselected panel to the selected panel in vector invid and
string fields, using shift-click to do multiple selection.
Unfortunately, actually doing this with large blocks has been
*excruciatingly* slow to perform, as each item moved was a separate
round trip network call.  For Invid fields, things were even worse, as
each single item moved involved a separate transaction checkpoint to
make sure that all bind and unbind operations for the element
add/delete were done with transactional consistency.

The db_field interface now has explicit addElements() and
deleteElements() methods that support bulk adds or deletes.  The
DBField and InvidDBField classes have had these methods added as well.
For InvidDBField particularly, the speed up from using the bulk
add/delete methods is dramatic.

In the process of adding addElements() and deleteElements() on the
server, I wound up significantly increasing the efficiency of even
non-bulk vector adds where there is an enumerated list of choices that
any adds have to be chosen from.

In the process of supporting such bulk transfers, I modified a good
bit of the client and the client's StringSelector GUI component.
Everywhere the client uses the StringSelector can now handle bulk
moves in one operation.

Making this change has the potential to complicate custom DBEditObject
subclasses, which now have to be able to respond in wizardHook() to
both singleton and bulk adds and deletes, and which have to provide
separate finalizeAddElements() and finalizeDeleteElements() in
addition to the old finalizeAddElement() and finalizeDeleteElement()
methods if the customizer wishes to take special action when items are
added to or removed from a vector field.

10. [CLIENT] Cleaned up the Objects Owned panel in the Owner Group window

Despite the fact that the 'Objects Owned' panel in the Owner Group
window uses the same GUI component that the normal 'General' panel
uses, it was not possible to right-click on entries in order to view
or edit objects listed.

This has been fixed, and it should now be possible to right-click on
any object listing in the client and get at least a view/edit menu.

The object type listing pulldown menu in the Objects Owned panel will
now be sorted in the client.

Turned debugging off in the Objects Owned panel.

11. [CLIENT] Added threading to adminHistory panel

When I added a thread-out to the generic history panel in the client
(change 0.99.9#10), I neglected to do the same for the admin history
panel that is present when viewing and/or editing an admin persona
object.

The admin history panel is now threaded so that it won't block the GUI
refresh during long waits for a history summary from the server.

12. [SERVER] Fixed journal handling on start up

The DBStore load() method failed to consolidate the journal into a
clean ganymede.db dump if the journal was not in a fully consistent
state.  It would print an error message and then skip the normal
start-up dump.

Now, the error message is still printed, but since the journal loading
code will properly cope with incomplete or malformed transaction
records in the journal, the normal startup process is followed
thereafter.

13. [SERVER/CLIENT] The client now displays whether the server is doing a build

The server will now notify the client when it starts and stops
performing a build.  The client displays this information in the panel
in the very bottom left corner, where the 'Status: ' text used to be.

This is an asynchronous message sent by the server using a new
serverClientProxy class that has its own background thread for
queueing and sending asynchronous RMI calls to the client.  The
mechanism used to send this message is generic; it will be easy to
extend this mechanism if I want to add more generic server
notification features to the client.

This involved a change to several server classes, including the
GanymedeBuilderTask base class.  Any task not subclassed from
GanymedeBuilderTask will not trigger this status update.

14. [SERVER] Took out deprecated thread stop() operations

The Ganymede Server's background scheduler used the deprecated
java.lang.Thread.stop() method call to shut down running tasks when
the server is shut down.  The stop() method is deprecated in 1.2 as
unsafe, however, so the scheduler now uses the interrupted() method
instead.  The scheduler and all tasks included with Ganymede 1.0pre1
are responsive to the interrupted() call, but custom background tasks
written for use with the Ganymede scheduler may need to be reworked to
respond to the interrupt call.

The GanymedeBuilderTask base class will check for an interrupt between
phase1 and phase2 of a build, but it will be up to a builder task
writer to check java.lang.Thread.currentThread.isInterrupted() during
the two phases if they want to be able to quickly interrupt their
builder task.

With this change and a couple of unrelated deprecation fixes in the
JDataComponent and JTree packages, the Ganymede server and client
should now build with no deprecation warnings under Java 1.2 and
later.

15. [SERVER/CLIENT] Added regexp support for IP fields in Query mechanism

The Ganymede server and client did not previously support regexp
matching for IP fields.  The client now provides a 'matching' option
in the query box for performing regexp searches on IP address fields.

Gil Kloepfer (gil@arlut.utexas.edu) pointed this out.

16. [SERVER] Did a basic reworking of ganymede.db and DBStore structures

I've been laying the groundwork for support for XML database
export/import, and towards this end, I have evolved the ganymede.db
database format and the server's DBStore data structures in a
direction that may make it easier in the future to load data from an
XML file, and to make the server code simpler.

The ganymede.db file no longer includes definitions for the mandatory
fields in the schema section.  The server now implicitly creates these
field definitions whenever an object type definition is read from the
ganymede.db file or created with the schema editor.

This not only makes the schema editor simpler, but it also will lessen
bulk and possibility for error when schema importation from an XML
file is supported, as the XML file would only need to specify custom
object and field types.

And while I was mucking around with the file format, I modified server
code and the ganymede.db file format to make keeping track of the
order of fields within an object and object types within a category
simpler, and more robust.

There were also a good number of RMI interface changes to simplify
schema editing logic.  Signficant changes were made to Base,
BaseField, Category, FieldTemplate, and SchemaEdit, and the classes
that implement these interfaces.  A number of effects of these changes
are discussed in change 1.0pre1#17, below.

These changes in the server are wrapped in file version checks, so
Ganymede 1.0pre1 should work fine with ganymede.db files from older
versions of the Ganymede server.  When 1.0pre1 dumps out the
ganymede.db file, however, it will be dumped in its new form.

17. [SERVER/ADMIN CONSOLE] Made schema editing more robust

The server now supports schema editing better.  Schema changes that
would break the database are prevented (at least, much more than
before).  The server now provides feedback to the admin console (with
error dialogs, and the like) if an attempted change would cause
problems.

A lot of the interface between the graphical schema editor and the
server has been simplified and regularized, to depend less on
serialization of server-specific data structures.  The schema editing
system now uses String labels to identify objects to be manipulated in
many cases.  A number of operations during schema editing that were
performed as an interaction between the graphical schema editor and
the server are now done locally on the server, to reduce performance
problems.

18. [SERVER] The server now resolves client ip addresses to host names

When a user or admin console logs into the Ganymede server, the server
will now do a reverse DNS lookup to get the fully qualified name of
the system that the user is logging in from.  

The admin console will show the fully qualified domain name for
attached clients.

19. [SERVER] Transaction email can be turned off with the starttransaction event

Formerly, the server would always send a transaction log to the admin
who commited a transaction, as well as sending email to all owner
groups that own any objects affected by the transaction.

Now, this email can be turned on or off by editing the
'starttransaction' system event object.  If the 'Event Mail' checkbox
in the starttransaction object is not checked, no transaction logs
will ever be mailed.  If it is checked, then the 'Cc: Admin' and 'Cc:
Owner Groups' checkboxes are consulted to determine whether the admin
and the owner groups of any affected objects should be notified.  In
addition, any email addresses added to the 'Mail List' vector field
will receive a complete copy of any transaction logs generated during
the server's operation.

By default, all three checkboxes are turned on and mail will be sent
out in the same fashion that it was in 0.99.9 and earlier.  Users with
pre-existing Ganymede databases will have to edit this system event
object in order to restore the previous mail behavior.

20. [SERVER] Fixed QueryResult.append()

The arlut.csd.ganymede.QueryResult class's append() method did not
properly update its invidHash and labelHash tables when multiple
QueryResult objects were coalesced.  This caused the appended
QueryResult object on the server to act as if it did not contain
Invid's that it did, which could result in a permissions violation
report when an InvidDBField tried to verify an Invid in an addElement
operation.

This only had an affect when the DBEditObject.obtainChoiceList()
method used the QueryResult.append() method to concatenate query
results, which the gasharl schema kit's emailListCustom class did for
its Internal Members field.

Thanks to Andrew Helyer (helyer@arlut.utexas.edu) for reporting this.

21. [CLIENT,SERVER] Fixed object description mail from the client

Fixed the client's object mail feature.  Added getSummaryDescription()
to the DBObject class and the db_object interface, which is now used
for sending an email description of an object from the client.

This feature is activated by using the 'Mail To...' menu item under
the 'File' menu in the client's object view/edit windows.

22. [SERVER] Fixed role cloning

The PermissionMatrixDBField class had a slight error in its
copyFieldTo() method which broke role cloning.  This was supposed to
work, but it didn't.

Thanks to Pug Bainter (pug@pug.net) for reporting this.

23. [SERVER] Changed client naming for concurrent use

Previously, if a user logged into the Ganymede server with more than
one client at a time but the same username, the Ganymede server would
report the second account as user2 in the logs and the admin console.

This can be confusing for situations where both user and user2
actually exist as valid user accounts, so the Ganymede server logic
has been changed so that if 'user' is logged in twice at the same
time, the second login will be reported as 'user[2]' rather than
'user2'.

Thanks to Pug for complaining about this.

24. [SCHEMA] Fixed gash/gasharl schema system interface deletion bug

Pug caught a bug in the gash/gasharl schema kit, by doing
something I would never have been able to make myself do.  He created
a system, set the room to a room with a single network, edited the
system's single interface, set the network, then deleted the
interface.

In doing so, he discovered that the gasharl schema kit didn't keep
track of things properly on interface deletion, and that the network
that was chosen became unavailable as a choice for that system when an
interface was created again with the 'add interface' button.

I've fixed this, so now you can delete and add interfaces all you want
without losing the ability to choose a previously chosen network.

25. [CLIENT] Fixed default owner dialog logic

Previously, the ganymede client could get confused about the proper
settings for the default owner dialog (the dialog that pops up to ask
you what owner group you want to put a soon-to-be created object into)
if you change personas.

It would be too painful right now to explain the precise situation in
which the ganymede client wouldn't do the right thing, but it doesn't
anymore.  It does the right thing.

This is another one of those things that's been bugging me for a long
time, and I'm glad to see it fixed.

26. [SERVER] Fixed case-sensitive login handling

The GanymedeServer login process was mishandling login authentication,
by canonicalizing user login to lower case, but using a case-sensitive
comparison to find matching admin privileges.

GanymedeServer.login() now uses a case-insensitive query to look up a
user's login privileges.

This is another thing that Pug caught.

27. [SERVER] Fixed mail handling for persona names

Another fix for a Pug bug.  Pug reported that attempting to log into a
server with a fully qualified persona name, like 'pug:admin', and
messing up on the password would cause the server to attempt to send
mail to 'pug:admin@mailserver.com', which his mail system ultimately
resolved to be equivalent to 'admin@mailserver.com'.

The DBLog code that handles system event mail will now truncate at the
colon, so a bad login for 'pug:admin' will be sent to
'pug@mailserver.com', as it should.

28. [PASSWORD CLIENT] Fixed PasswordClient compatibility for 1.2

The PasswordClient class used by the changePassword program attempted
to set an RMISecurityManager, which is not allowed under Java 1.2.  As
a result, running changePassword on a 1.2 JVM would cause a security
exception to be thrown.

Sun really makes it hard to be both 1.1 and 1.2 compatible, some
times.  Fortunately, the Ganymede clients work acceptably well with
the default security manager, since we package all of the RMI stub
classes with the client and password jar files.

This was yet another fine bug report by Pug.

29. [NIS PASSWORD CLIENT] Fixed rpcpass non-termination errors

There were certain conditions in which the rpcpass client proxy would
not properly exit the JVM, but would instead linger until manually
killed.

Now, the client will always terminate if something goes wrong, rather
than sticking around.

This time, for real.

30. [SERVER] The dump task now reports how many transactions it is dumping

The dump task, which typically runs every couple of hours to
consolidate the transaction journal into the ganymede.db file, will
now announce the number of transactions in the journal to the log and
admin console when it runs.

31. [SERVER] Fixed supergash admin persona renaming in DBStore.initializeObjects().

The Ganymede server wasn't properly renaming the supergash admin
persona on startup if the ganymede.properties file specified an
alternate name for the supergash persona.

I've fixed this.. the server will now always reset the supergash
persona name to that specified in the server's ganymede.properties
file.

Thanks to Alex Robinson (Alex_robinson@bigfoot.com) for reporting
this.

32. [SERVER] Improved object cloning with partial failure on vector copy

I happened to notice that when I attempted to clone a user who
belonged to one or more groups that I did not have permission to put
into a new user, Ganymede did not react well.  That is, I got a dialog
saying that certain items could not be cloned, and when I looked at my
newly cloned object, several of the fields were just totally blank.

I've now modified DBField.addElements() and InvidDBField.addElements()
so that they are able to handle partial copies, and so that the
DBField.copyFieldTo() method takes advantage of this to make object
cloning more robust.

33. [CLIENT] Added a fabulous new XML client

When installing the client, a new text-mode client program called
xmlclient is installed.  xmlclient is able to bulk load data into the
Ganymede server from an XML file.  Loading data through the xmlclient
is less efficient than the old custom runDirectLoader hacks that data
loaded depended on before, but it is far more versatile and lets you
load in any kind of data that you can specify in your Ganymede schema
definition with nothing more than a Perl script and this client.

Ultimately, I want to make the xmlclient able to not only load
arbitrary Ganymede data from an XML file, but for it also to be able
to connect to an empty Ganymede server and establish a custom schema
from an XML file.  Supporting this and converting all of the existing
schema kits to this method of server initialization is the big goal
left for Ganymede 1.0.

34. [SERVER] Made the server less picky about setting owner groups ahead of time

The Ganymede server now allows non-interactive clients (clients that
have turned wizards off) to create objects without having previously
selected one or more owner groups to be the default owners for newly
created groups.

This was only an issue if the user that was creating objects belonged
to more than one owner group, such as supergash.

Now, if supergash creates objects through a non-interactive client,
the objects will be created with null (supergash) ownership.  If a
non-supergash user that belongs to multiple owner groups creates
objects through a non-interactive client, the objects will be owned by
the first owner group found by the server.

All of this was done to simplify things for XML bulk loading.

35. [SERVER] Made the server not complain about redundant invid loading

I'm finding that I need to make a number of tweaks to the server so
that it behaves in a reasonable way in the XML client context.  In
many ways, the server was designed around interactive usage, and a
number of issues are coming up with the batch mode XML client.

In this case, the server previously complained if an object reference
(invid) was added to an vector object reference field that already
contained that object reference.

Now, the server silently discards redundant invid additions.  This
allows the XML client to have a symmetric invid relationship in which
both sides of the relationship show the link without having the server
reject the second object's invid links as redundant.

36. [SERVER] Improved error reporting on object editing contention

The Ganymede server previously returned a misleading error message if
during editing the user attempted to cause an object to be linked to
an object that was already checked out for editing by another user on
the Ganymede server.

Now, if a link to an object cannot be established because the object
is already checked out for editing by another user, the server will
report the error properly, and will identify the user that has the
object checked out for editing.

37. [SERVER, CLIENT] Fixed the deferred shutdown option

The 'shutdown the server when all users log off' mechanism was broken,
and didn't actually shutdown the server even when all active users
logged off.  This has been fixed.

Additionally, the Ganymede ClientBase class has been reworked slightly
so that if the server is in deferred shutdown mode, the login failure
message will explain this, rather than the generic 'bad
username/password?' message.

38. [SERVER] Added deleteAllElements() to the db_field interface

I added the deleteAllElements() method to the server's DBField class
and db_field interface, to allow the new XML client to remove all
values in a Vector DBField without having to do an additional
roundtrip to the server to get the list of elements currently in the
field.

39. [SERVER] InvidDBField.createNewEmbedded() now includes a db_object ref

Another change to support the XML client efficiently.  The
InvidDBField createNewEmbedded() method now includes a db_object
reference as well as a serialized Invid.  This removes the need for
the XML client to make an additional round trip request to the server
in order to get an editing handle on a newly created object.

40. [SERVER] Added support for high speed log scanning

The Ganymede server has always had support for scanning its own log
file to produce an object summary report for the Ganymede client.
Unfortunately, Java is rather inefficient at text file parsing, and
the log scanning code converts each line of the log file scanned into
a DBLogEvent object.  This conversion made coding convenient, but made
scanning a very large log file much much slower than a simple grep
would be.

The Ganymede server now supports an external Perl script which
prefilters the log file on request, so the Ganymede server only needs
to process those lines that match the object being reported on.  This
makes the object history feature much much faster, as the server
doesn't have to process unrelated log entries.

If an object (such as an owner group) actually does have a very large
number of lines in the log file, parsing and reporting on what might
be megabytes of log data will still be very slow, however.  At some
point, the log scanning code should probably be written to avoid the
object conversion step in favor of simply identifying matching lines
through textual means and appending the text of such lines to the
object history report.

The external helper program is an optional acceleration.. if the
'ganymede.loghelper' property isn't defined in the server's
ganymede.properties file, then log scanning will be performed in the
old-fashioned style.

41. [CLIENT] Fixed persona creation in user object panel

The Ganymede client allows new admin personae to be created in two
different ways.  In 0.99.9, however, creating a new admin persona from
within the user editing window threw an exception.

It is now possible to create new admin personae either directly
through the client's tree by creating a new 'Admin Persona' object, or
by editing a user object and using the Personae tab to create a new
persona.

42. [SERVER] Optimized critical database lookup code.

This one's embarassing.  A long time ago I heavily tuned and optimized
the Ganymede server's database hash structures.  A job well done, I
said to myself.  Unfortunately, the DBSession.viewDBObject() method
which everything in the server actually uses to pull objects out of
the server was doing some extremely dumb things.  

In particular, before ever looking in the highly optimized database
structures, viewDBObject() looked to see if the object being sought
was already checked out for editing by the session's transaction.

Unfortunately, the DBEditSet transaction class tracked objects checked
out for editing in a linear Vector rather than a hashing structure, so
as more and more objects got checked out by a session, *all* database
access operations on behalf of that session got slower and slower and
slower.  This turns out to be the reason why the Ganymede server's
bulk loading was so very slow.

Now this transactional data structure has been converted to a
Hashtable, and viewDBObject() has been extensively optimized so that
it will only attempt to find an object in the transaction's hashtable
if an object has not yet been committed into the main database
structures.  All transactional object view, edit, delete, inactivate,
and clone operations will involve *much* less work as transactions get
bigger.

I knew there was a reason I hadn't called it 1.0 yet..

43. [SERVER] Schema Editor dumps database after making schema changes

A number of people, including Christoph Litauer
(litauer@uni-koblenz.de), reported problems resulting from the server
not consolidating its on-disk database after schema changes were
committed.  The problems arose whenever changes were made to the
server's schema in the schema editor after which transactions were
committed to the journal file before the server was abnormally
terminated, leaving a mix of object data in the journal file from
after the schema change, which is not itself recorded in the journal
file.

The server will now dump its database to disk and consolidate the
journal file when schema changes are committed, so there is no
opportunity for a mismatch between the schema in the ganymede.db file
and the object change records recorded in the server's journal file.

44. [SERVER] Object Event Mail Is Now Coalesced

Another change in response to bulk loading with the XML client.  It
used to be that people who requested mail notification when certain
operations happened to certain kinds of events (such as when a user
was created or deleted, say) will now get a single message with a
summary of all events of that type during a transaction rather than a
single message for each event.

We had a user who was subscribed to system creation objects and was
getting hundreds of messages all at once every time I ran my bulk
loader test.  Now he'll just get an easily deleted summary.

In addition, when these events do happen one at a time, the message
subject in the mail sent out by Ganymede will now include the name of
the object operated on.

45. [SERVER] Expiration/Removal dates may not be set to times past

Jeff Sims (jsims@arlut.utexas.edu) reported that Ganymede erroneously
allowed a user's Expiration date to be set to an already passed date.
The admin intended to set the Expiration some months in the future,
across a year boundary, but neglected to change the year, causing
Ganymede to expire the object at the next run of the Expiration Task.

Ganymede will now forbid any changes to an object's Expiration or
Removal date that would set either date to a time earlier than the
Ganymede server's notion of current time, as a safeguard against this
sort of mishap.

46. [SERVER/CLIENT] Server now has soft timeout option

The Ganymede server has always had the ability to time out users that
were idle in the Ganymede client.  Tom Embleton
(embleton@arlut.utexas.edu) expressed dissatisfaction with this, for
the reason that having to login again from scratch forced him to
readjust his windows and was a pain in general.

In response, I implemented a soft timeout option that can be turned on
by activating the 'ganymede.softtimeout' property in the server's
ganymede.properties file.  If this option is chosen, the server will
send a time out message to the client, which will respond by
downshifting from any admin persona to the base user login and
presenting a mandatory persona selection dialog which will insist on
being given a proper password in order to let the user continue work.

A soft timeout will still close any transactions open at the time of
the server timeout, but it will be faster to enter the user's password
into the persona dialog and get back to work than to login from
scratch again.

In addition, the server's two time limits (for idle sessions with no
objects checked out and for idle sessions with objects checked out for
editing) are now configurable in the server's ganymede.properties
file.

47. [SERVER] Added shutdown semaphore to keep shutdown from breaking builds

I have added an additional semaphore to the server so that when an
admin initiates a shutdown of the server from the admin console, the
server will wait for any builder tasks waiting on phase 2 (execution
of external scripts for NIS/DNS/etc. builds) to complete before
shutting down.

This is to insure that a builder task in phase 2 won't interrupt an
external build script or program, leaving a network service in an
inconsistent state.

48. [SERVER] Fixed namespace-optimized lookups on IP fields

The server has special logic in GanymedeSession for optimizing query
lookups on namespace-indexed data fields.  That logic was not properly
handling IP address fields when given an IP address in string form
rather than in byte array form.

Now, the query logic will properly convert IP strings to byte array
form for optimized namespace lookups.

49. [SERVER] Fixed queries on embedded objects

The GanymedeSession queryDispatch() method will now properly perform a
search on an embedded object if a Query is submitted whose requested
returnType is equal to the searched-for type.

My initial decision to include embedded objects in the Ganymede design
has made *so* many things painfully complex in the whole system.
Sigh.

This is another bug that showed up in development and testing of the
XML client.

50. [SERVER] Optimized transaction commit

The server code had a potentially quite expensive checkpoint()
operation in the DBEditSet.commit() method.  This checkpoint operation
was there to allow the server to set the historical fields (creation
and/or modification date and user identity) before the commitPhase1()
methods were called while still being able to do a rollback() if a
commitPhase1() method rejected the transaction commit.

This checkpoint and rollback pair could be enormously expensive if the
transaction gets real big, as it can with the xmlclient.

The commit() method now forces the new date and user identity
information into the transaction's edited objects in a manner that
bypasses the object value freeze put in place during an early point in
transaction commit.

This change will make committing large transactions a good deal
faster, and will make failed commit attempts even faster than that.

51. [SERVER] Improved startup sequence

The server now intelligently checks to make sure that no server is
already running at the same host and port, rather than simply ignoring
the warning from the RMI rebind process.  The server will now decline
to start up if another server is answering the phone at the same
address.

52. [SERVER] Fixed PermissionMatrixDBField loading

The server had a bug that would prevent the database from loading
if a role had a permission matrix defined with no entries defined
in it.

53. [INSTALL] Install scripts now check to make sure jars were built

All of the install scripts now double check to make sure the
jar files were made during the system build.

54. [SERVER] Reworked checkpoint handling for non-interactive transactions

I have simplified how non-interactive transactions handle
checkpoints..  basically, the DBEditSet class now automatically
ignores checkpoint activity for non-interactive transactions.  Any
rollback request made during a non-interactive transaction will result
in the transaction committing hari-kari at commit time.

By putting all the logic for this in DBEditSet, I've simplified a fair
bit of code in InvidDBField, DBEditObject, and DBSession.

I should have done this before.

55. [CLIENT] Added count indicator to StringSelector

The vector field GUI component now includes a count number, to make it
easy to see how many items are in the field.

56. [CLIENT] Windows now kept within bounds

It turns out that the default Swing window resize/move logic made it
possible to resize/pull windows above the top of the inner desktop,
such that the title bar was no longer accessible.  Richard Mach here
at ARL:UT graciously pointed out this problem, and it turned out to be
pretty easy to fix.

The Ganymede client will now block attempts to resize or pull a window
out of the visibility area to the top and left.

57. [CLIENT] Fixed owner panel on view windows

The right-menu popup menus weren't enabled on view object windows in
the owner panel.  Now, you can view any object and be able to
right-click on the items in the owner list to directly view or edit
the owner groups that own that object.

58. [SERVER] Fixed object cloning in previously broken case

The object cloning logic was not previously excluding object linkage
(invid) fields that were involved in a one-to-one or many-to-one
relationship.  The upshot of this was that when a user here cloned an
I.P. network, the cloned network had duplicated not only a list of
rooms for the network to be present in, but also the systems, thereby
unlinking those systems from the original in the process.  This caused
much confusion until the cause was detected.

Thanks again to Gil Kloepfer for pointing this out.

59. [SERVER] Fixed rollback for object deletes

This was a really critical bug.  The result of this bug was that if an
object deletion was attempted, but was refused due to consistency
problems, the system would rollback everything *except* the object's
to-be-deleted status.  This meant that if the user went on to commit a
transaction after unsuccessfully deleting an object, that object would
be deleted anyway.  Worse, all the objects that should have had their
links to the object undone as part of the deletion operation will
retain their links to the deleted object, ruining the symmetrical
pointer integrity constraint of the Ganymede database.

This bug and #58 above manifested as part of the same incident, so
thanks must go again to Gil Kloepfer for demonstrating a really ugly
problem.  This bug has been in Ganymede since 0.99.8, lurking quietly
for over 10 months.

The fix was to move one line of code in DBSession up about three
lines.  Amazing how these little touches matter.

60. [SERVER] Serialized checkpoint logic, removed client access to checkpoint()

In examining the checkpoint and rollback code, I realized that there
was nothing in the system that would prevent multiple threads from
attempting to assert and rollback checkpoints on the same transaction.
This meant that it was in principle possible for the server to
interleave checkpoint operations, leading to unpredictable and
incorrect results if multiple threads simultaneously attempted to do
things like object creation, deletion, and linking within a single
session's transaction.  I don't believe this does ever happen, in
practice, but if it ever did it would be confusing and a pain to
debug.

To avoid this, I put in a system whereby only one thread at a time is
allowed to have a checkpoint on any given transaction.  If another
thread attempts to checkpoint a transaction while it is already
checkpointed by a thread, the thread that is attempting to checkpoint
will block until the earlier checkpoint is popped or rolled back.

This scheme will guarantee safety of checkpoint operations at the cost
of an mildly increased risk of deadlock.  To mitigate the deadlock
risk, I removed the ability for remote clients to access the
checkpoint() and rollback() methods in the GanymedeSession class, and
I put a deadlock timeout on the checkpoint block, so if a checkpoint()
attempt blocks for more than 60 seconds, an exception will be thrown
and the checkpointing thread will let go.

The loss of client access to checkpoint and rollback doesn't seem to
be an unreasonable thing to do, as no client code that I have yet seen
has done anything with the intra-transactional checkpoints.  If
someone convinces me that it is critical that remote clients be able
to access intra-transactional checkpoints, I'll need to rework the
anti-interleaving code to deal with the fact that subsequent RMI calls
from a single client are not guaranteed to be handled by the same
thread on the server.

61. [SERVER] Fixed deadlock vulnerabilities

Previously, the GanymedeServer object used Ganymede.internalSession to
process database queries for user and admin console logins.  The
problem was that this was prone to deadlock with some other uses of
Ganymede.internalSession in the Ganymede server.  In particular, if
anyone ever attempted to login at the same precise moment that a
transaction was being committed, the whole server locked up.

Now, the Ganymede server uses a distinct GanymedeSession object to
handle logins.  Since GanymedeServer has its own synchronization at a
higher level, it is no longer possible to get nested monitor deadlocks
from logins.

In addition, since the Ganymede.internalSession object is often used
by random Ganymede server code to look up things in the database, I
partially de-synchronized DBSession.viewDBObject() so that a DBSession
that does not have an open transaction asssociated with it will not
incur a synchronization penalty/deadlock opportunity merely to
retrieve a reference to an object from the database.

62. [SERVER, CLIENT] Added -dump{schema|data} to the xmlclient, removed decodeDB

The xmlclient is now able to emit a copy of the server's schema
definition in xml format, using xmlclient -dumpschema, and to dump the
server's database in its entirety in xml format, using xmlclient
-dumpdata..  Due to this, I have removed the old hackish decodeDB and
permdecodeDB front ends to the Ganymede server.

63. [SERVER, ADMIN CONSOLE] Added runEmbeddedTest, runEmbeddedSweep

Bug 59 above, the deletion rollback bug, allowed some inconsistencies
into our database, wherein embedded objects were left in the database
when their owners had been deleted.  I added test features to the
server and the admin console to detect and repair this condition.

64. [CLIENT] Made Client check for MOTD message in background

The client now runs its check for a new MOTD in a background thread,
so as not to lock up the GUI thread initially.  This will get rid of
the ugly lack of refresh that was visible when the user dismissed
the select persona dialog.

65. [CLIENT, ADMIN CONSOLE] Cleaned up login boxes, console shutdown dialog

I finally went back and got the admin console and gui client to put
the focus on the username box, so people can just start typing their name
when the clients come up.  I reworked the admin console shutdown dialog
so it just uses one dialog box for the various shutdown modes.

66. [INSTALL] Removed installClient2, made installServer autodetect java version

A bunch of changes to the installation process. installClient2 is now
gone, installClient is now smart enough to autodetect what version of
Java is being used and to configure the client install appropriately.

Ditto the installServer script.

I cleaned up the gasharl schema kit's ganymede.schema file to take
care of some inconsistencies that have been in that file for a long
while.

67. [CLIENT] Tweaked right-menu clicks in StringSelector to select and popup

Mike Mulvaney (ex-Ganymede GUI guy) filed a bug report indicating that
clicking the right mouse button should select the item that the pop-up
menu is being applied to.

He was right, and I so fixed it.

68. [SERVER SECURITY] Fixed a loophole in the object permission system

The Ganymede system allows admins and users to be given editing
privileges to objects that are not considered to be owned by the admin
or user.  This is an unusual circumstance, usually only done when the
customizer wants objects to appear in the client's object tree but
doesn't want to allow certain (or even any) fields to be modified.

The problem was that the built-in fields, including the owner list
field, do not typically have their own access permissions tracked,
independently from the object's access permissions.  This allowed
any user who could edit an object to grant themselves ownership
of the object, which is bad.

The server now refuses to grant edit privilege to an object's owner
list field unless the user already owns the object, or is running with
supergash-level privileges.

69. [SERVER, XMLCLIENT] Added XML-based schema editing through the xmlclient

The xmlclient can now be used to perform schema edits on a running
Ganymede server (so long as no users are logged in, and as long as the
schema edits do not result in an incompatibility that will break
loaded data).  This makes is possible to get rid of the old
directLoader crud in the schema kits.

70. [SERVER, ADMIN CONSOLE] Fixed exceptions on drag/drop in schema editor

Fixed bug #13 in bugzilla.

71. [SERVER] Added TaskOptionStrings to Task definition

The built-in object type, 'Task' now supports an optional vector
string field, which will be used in 1.0 to represesnt builder task
options for schema kits that support more than one transaction-time
builder task.

72. [CLIENT, SCHEMA EDITOR] Fixed tree's pop-up menus on Linux

The GUI tree component was still using old-style AWT pop-up menus,
which wasn't working properly on Linux using Java 1.3.  Since almost
everything in the Ganymede client and admin console are based on Swing,
switching the pop-ups to Swing should keep things consistent and
working on various platforms.

73. [ADMIN CONSOLE] Fixed console deadlocks on Linux

I was being sloppy with my GUI thread handling in the admin console..
updates from the server were not being painted on the GUI thread,
which was leading to swift lockups when running the admin console on
the Linux 1.3 JDK.  I fixed this, the admin console should run fine
in any Java environment now.

74. [SERVER] Reworked query engine to increase concurrency

The Ganymede server no longer has to block threads from doing most
queries on the server while a transaction has portions of the database
locked for updates.  The server now makes an interal snapshot vector
of the objects in an objectbase when transactions are committed, and
most queries are run against these snapshots.

The Ganymede server will still lock the database on a standard
GanymedeSession query if the query spans more than one object type.
In practice, this means that unless you or your code attempts to do a
query that involves embedded object values (as in searching for a
system using a give i.p. address held in an embedded interface
object), the query will never block.  For this reason, it is now safe
to take advantage of the Ganymede query mechanisms during all stages
of transaction commit in DBEditObject subclasses.

The main tradeoffs for doing this are a slight increase in memory
usage (4 bytes per object in the database), to maintain a second copy
of references to all objects in the database, and a slight increase in
transaction commit time, as the new snapshot is constructed.

Another, more subtle trade-off is that support for this level of
concurrency in the server might be hard to maintain if the Ganymede
server is ever reworked to move away from its in-memory database.

75. [XML] Simplified the XML schema for integer and boolean fields

The XML file format used to require boolean field values to be
expressed as <boolean val="true"/> or <boolean val="false"/>, and
integer numeric values as <int val="123"/> and the like, which seemed
unnecessarily wordy, since boolean and numeric fields are always
scalar.

Now you can do things like

<uid>1005</uid> and <option>true</option>

rather than

<uid><int val="1005"/></uid> and <option><boolean val="true"/></option>

The Ganymede XML loader will continue to recognize the older style
for backwards compatibility..

76. [SERVER] Memory optimizations

I made a number of optimizations to memory usage in the server, which
should cut the amount of per-field overhead roughly in half.  Heap
required for objects in the database has been reduced by at least
10-20 bytes plus 10 bytes per field in each object.  Fields in the
database now have only 14 bytes of overhead each, plus whatever
overhead your Java VM needs to track garbage collection for two
objects.

To accomplish this, I reduced the number of variables held in the
DBField class to an absolute minimum and restructured DBObject so it
uses a simple array with packed hashtable access logic rather than a
separate hashtable.

Custom DBEditObject subclasses that directly manipulate the old fields
FieldTable variable will need to be reworked in order to work with the
new field storage structure.

In addition, the server will now create a lot fewer temporary
Enumeration objects during runtime, and a lot fewer PermEntry objects,
both of which will have some impact on reducing memory usage.

Schema edit commits will be faster, but otherwise the overall speed
of the server will probably not be much changed.

77. [SERVER, CLIENT] More Memory Optimizations, History Panel revisions

I reduced the size of the creator info and modifier info strings so
that they will only include the name of the user/admin and the name of
the client used to create/modify the object.  This will save about 100
bytes from each object created right off.  In addition, since the time
is no longer included in these fields, the automatic interning that
the server does to eliminate redundant strings will reduce the
overhead for these data elements by a very, very large percentage.

To compensate for the creation and modification time no longer being
included in the history string fields, I have modified the client
to display the history date fields with hour, minute, and second
as well as date.

78. [SERVER] Memory, security fix

The new system for handling DBField/DBObjectBaseField association
revealed a longstanding bug in DBObject that prevented Ganymede from
properly de-linking fields from their previous DBEditObject when a
transaction was committed.  This had the effect of preventing the last
DBEditObject constructed for a particular database object from
being garbage collected unless and until the object was actually
deleted from the database.  A small memory leak.

This bug also allowed clients the possibility of at least attempting
to continue to perform edit operations on fields after a transaction
was committed and the editing objects were checked back into the
server's database hashes.

Both conditions have been solved, which will reduce the server's
active working set somewhat during runtime and which will protect the
server against malicious clients.

79. [SERVER] Fixed logging of newly created Role objects

The PermissionMatrixDBField wasn't properly reporting the value
of a newly created Permission Matrix in the log file.

80. [SERVER] Fixed permissions xml parsing

Fixed the xml parser's handling of permission matrix field objects.

81. [SERVER] Redfined DBEditObject.canRemove() to allow dialog return

Modified the canRemove() method in the DBEditObject class to allow
a complete ReturnVal to be returned rather than the old boolean.

-------------------- Changes from 0.99.8 to 0.99.9 -------------------

RELEASE DATE: January 13, 2000

1. [SCHEMA] Fixed gasharl schema errors

a. The gasharl schema kit had a bug which made it impossible to edit a
system if that system was connected to a room that had no networks
listed.

b. The gasharl GASHBuilderTask code is designed to handle netgroups that
overflow the 1024 byte NIS line length limit, but the code that
handled netgroup folding did so very inefficiently, putting only one
netgroup entry per line after the first.

2. [SERVER] Fixed race condition in Qstmp stopThreaded() method

The Qstmp shutdown process could throw a NullPointerException in
stopThreaded() if thread timing worked out just wrong.  This has been
caught, and this race condition will no longer be able to prevent
clean server shut-down.

3. [SERVER] Fixed various deadlock possibilities in server

a. The 3 DBLock subclasses (DBReadLock, DBWriteLock, DBDumpLock) did not
properly call notifyAll() on the DBStore object if they threw an
exception in their establish() method.  Now, all synchronized blocks
in the DBLock subclasses use try..finally to guarantee that other
threads waiting on DBStore will be woken up, even if something
unexpected happens.

The DBReadLock.establish() code had code to throw an exception if a
session that possessed a write or dump lock tried to obtain a readlock
at the same time.  Unfortunately, the internal sessions used for the
Ganymede builder tasks, expiration task, and warning task were given
the same identifier as the standard 'internal' session used to process
queries in the login process, so if a login was attempted during a
builder task's phase1 execution, or during portions of the expire or
warning task, an exception could be thrown, possibly causing
threadlock if other threads had wait()'ed at that point.  All this
should be fixed now.

b. There are several ways a user can be forced off of the Ganymede
server..  the idle timer, the admin console, and the RMI unreferenced
object mechanism.  Previously, various essential objects in the server
could get locked if the client refused to respond to the server's
disconnect command.  Now the client force-disconnect code is better
coordinated so only one thread in the server will ever attempt to
force the user to disconnect, and that thread will itself spawn a
background thread to force the user to disconnect.  As a result,
although the server may wind up with a single dangling thread per
client if the RMI system blocks trying to call the client, nothing
in the server will deadlock because of it.

As a result of this change, knocking a user off the system by the
admin console is no longer a synchronous operation, so it may take a
few seconds before the admin console updates to show the results of a
user kill operation.

c. The admin console code in the server had a number of problems that
could lead to a deadlock that blocked any admin console operations
(including the stopServer script).

The server code that handles communications to/from the admin consoles
have been significantly reworked so as to not be vulnerable to a
threadlock condition, and some redundant operations have been pruned
to reduce overhead.  A number of possible race conditions have been
closed.

This will make the server faster and safer when admin consoles are
attached, but the admin console updating is still generally
synchronous.  Every admin console connected to the Ganymede server
will slow the server down a bit.

4. [SERVER/CLIENT] Added support for 'browse' mode in client

John Knutson pointed out that the Ganymede client wasn't an adequate
directory browser because it always hid things that couldn't be
edited, when in fact the user had a perfect right to see everything
for which he is granted view access.  This was intended to be a
feature of the client, that it could present a simplified tree to the
user to avoid confusion, but it needlessly restricts advanced users.

The server and client have now been modified so that the client can
display all objects and object types viewable by the user, even if
the user does not have editing permission.

This is toggled by a 'Hide non-editable objects' checkbox menu item
under the client's 'File' menu.  I expect I may move this someplace
else in the client's GUI eventually.

This involved changes to GanymedeSession.java, Session.java, and
CategoryTransport.java on the server, and gclient.java on the client,
so a 0.99.9 server will now require a 0.99.9 client.

As before, the server is really responsible for deciding what object
types are reported to the client.. the client can't choose to show
object types in the tree if the server doesn't report them, but the
client can now ask to have all visible object types reported, which it
couldn't do before.

5. [CLIENT] Reworked object folder pop-up menus in client tree display

The client's object folder pop-up menus in the tree display has been
reworked to be less ambiguous.  The old 'List editable' and 'List all'
have been changed to 'Report editable' and 'Report all', and the old
'Show All Objects' has been changed to 'Show Non-Editables', and moved
to the top of the pop-up menu.

Hopefully this should be less confusing for folks.

6. [SERVER] Fixed custom schema migration bug from 0.99.8

Change 0.99.8, #17, listed below, which modified how the server
handles non-symmetrically linked InvidDBFields, didn't properly handle
InvidDBField definitions that explicitly listed the backlinks field as
the field to be linked to.  Apparently, in 0.99.7 and before, the
schema editor presented the backlinks field as a valid symmetric field
target.

Martin Schneider reported that Ganymede 0.99.8 was complaining when it
came across such a field in his ganymede.db file from 0.99.7.  I had
the server handling invid fields with target fields set to 'none', but
I hadn't handled the equivalence case of the 'backlinks' target.

The Ganymede server will now treat an invid field with a target field
set to field 8 (the obsolete backlinks field) in precisely the same
way that it treats invid fields with no target field specified.  This
should make Martin's ganymede.db file from 0.99.7 work properly in
0.99.9.

7. [SERVER] Made bad login user notification optional

Previously, the Ganymede server would always attempt to send
notification of a bad password/login attempt to the name of the user
entered at the login attempt, regardless of the configuration of the
'badpass' system event object.

Now the Ganymede server will not do this unless the 'badpass' system
event object in the ganymede.db database has the 'Cc: Admin' flag set.

8. [SERVER] Took out unnecessary fields in DBField.java

The DBField base class had a number of redundant or unnecessary
fields, including both a scalar and vector field, even though no field
is both a scalar and a vector.

I've removed the Vector values holding field and replaced it with
accessors which will treat the single value field as a Vector as
appropriate.

I also took out the 'fieldID' short, which was redundant, since the
DBField.getFieldDef() method already calculated that information from
the field definition reference.

I also took out the 'newValue' field, which was only used in one very
specialized case in the userCustom plug-in, and which was better
handled by putting an extra field in that custom DBEditObject subclass.

This will save 10 bytes per field in the database while in memory,
with probably around 40 bytes of per-field overhead remaining for
scalar fields, rather more for Vector fields.  Not a very big deal,
but it does amount to 80-300 bytes of RAM per object in the
database. For our current database, this probably saves us a megabyte
of in-memory space, or around 3% of the total resident memory usage.
That percentage could probably get quite a bit higher when the initial
size of the server itself is amortized over larger and larger
databases.

This change doesn't affect the on-disk database file at all.

9. [STOPSERVER] Modified the stopServer code to prompt for supergash password

Previously, if the Ganymede server's supergash ("root") password was
not kept in the server's ganymede.properties file, the stopServer
client would simply fail.

Now, if it can't load the supergash password from the
ganymede.properties file, stopServer will prompt the user for the
supergash password.

10. [CLIENT] Threaded out the client's history panel to avoid locking GUI

Here at ARL, our server log is getting quite large, and the round trip
time for reporting on the history of changes to an object is getting
large.  Because of this, the client's GUI has been locked for a longer
and longer time as the client's GUI thread blocks waiting for the
server to report the object history.

Because of this, the Ganymede client has been modified to thread out
history reporting.  The client's GUI will no longer lock up while the
client is waiting to get a report on an object's history back.

-------------------- Changes from 0.99.7 to 0.99.8 -------------------

RELEASE DATE: November 23 , 1999

1. [SERVER] Included regexp info in schema html dump

The html/text schema dump facilities in DBObjectBaseField.java now
include regexp information for string fields, if defined.

2. [SERVER, CLIENT] Made it possible to do a more limited log search

Previously, the history panel in the client's "show history" function
showed the complete transaction in which the object was modified.
There is now support for showing only changes directly affecting the
object in question.

Added a new version of viewObjectHistory to the Session RMI interface.

Added explanatory tool tips to the show history buttons in the
client's history panel.

Cleaned up the historyPanel generally.

3. [CLIENT] Cleaned up object report mail/save dialog

The Ganymede client allows the user to mail and/or save a status
summary for single objects in the Ganymede database (from the File
menu in the object view/edit window), but the dialog that came up was
really lousy, and hadn't been touched for over a year.  I restructured
the dialog and made it more usable.

4. [SERVER] Made server start-up less fragile

A user here got a ganymede.db file into a state where a field had a
namespace listed, but that namespace wasn't declared in the .db file.
The server was not able to recover from this because the
DBObjectBaseField class was throwing an illegal argument exception.

I modified DBObjectBaseField so that a warning message is displayed
instead.

Hopefully I'll be able to find how the system got into that state and
prevent it, but the server can deal with that inconsistency now.

5. [SERVER] Improved Qsmtp mail-out code

Previously, the Qsmtp mailer code would abort sending a message if any
of the recipients were rejected by the mailhost.  Now the Qsmtp code
will go ahead and complete the message if any of the recipient
addresses were accepted.

This was causing the 'bad login' mail for an invalid user login
attempt not to be sent.

6. [CLIENT] Made rpcpass exit cleanly

The rpcpass client (used in conjunction with the Linux NISkit's
rpc.yppasswdd to pass NIS password changes into Ganymede) wasn't
properly terminating after execution a transaction in Ganymede,
resulting in lots of lingering rpcpass processes hanging around.

This is a result of the JVM's policy of not closing down an
application until all of its non-daemon threads terminate.  Since the
rpcpass code is an RMI server, this never happened.  I added a
System.exit(0) to take care of this.

7. [SCHEMA] Minor fix to the nisonly schema

Fixed the nisonly schema's userCustom.java's fieldRequired() method to
not attempt to call isInactivated() on the non-value-containing
objectHook instance of userCustom.java.

John Knutson here at ARL was developing a schema based on the nisonly
schema kit, and it turns out that I haven't done much in the way of
upkeep on that schema kit for awhile now.

8. [SERVER] Made GanymedeBuilderTask.backupFiles handle an empty dir ok

The backupFiles() method in the GanymedeBuilderTask class is intended
to produce a zip archive of all files in the out directory when a
builder task is run.  Unfortunately, it caused an exception to be
thrown if there are no files in the out directory, as is the case the
very first time the builder task is run after installing Ganymede.

This has been fixed.  Thanks to John Knutson for reporting this.

9. [SCHEMA] Fixes to the gasharl schema

a) The server used to throw an exception if an admin created a user
and hit 'commit' without filling in the home group field, because
some of the custom logic wasn't checking to make sure that the
field was there before trying to do calculations based on it.

b) Moving a system from a room to another which was not connected
to the network that the system had been allocated on was broken..
a 'can't free network' error was being reported.  This case is
now properly handled.

10. [CLIENT] Miscellaneous Client Improvements and Fixes

a) You can now right-click on a row in the query result table and
inactivate or delete objects shown, rather than having to do a query
to find the object you want to delete and then use the tree to find
and delete it.

b) Related to this change, the 'are you sure you want to delete this'
dialog will now appear whenever an object is deleted, whether from
the delete object dialog, the table, or the tree (which used to
not prompt for verification).  The object deletion verification dialog
is now more friendly and descriptive.

c) The client now resets its 'default owner chosen' flag when the user
changes personae. *** STILL NEED MORE HERE ***

d) The GUI component for scalar invid fields has been very
significantly revised to make it possible to enter a choice by using
the keyboard instead of having to mouse through a possibly huge list.
This was done using a custom JComboBox editing component that monitors
keystrokes to do 'choice completion' during the course of text
editing.  I'm sort of pushing the Swing JComboBox to the limit here..
hopefully with Kestrel/1.3 Swing will be more useful for real world
stuff.

e) Reworked StringSelector to put the add box on the left, and to
enable typed choice completion if the only valid choices are listed

f) Changed the layout algorithm for window placement within the client.
No more client windows being placed partially outside the client's
display area.

11. [SERVER] Implemented support for object cloning

Since the beginning, I've planned on having a clone_db_object() method
on the server that would create a new object by copying values from an
existing one, but somehow I never had gotten around to implementing
it.  The work John Knutson is doing with Ganymede would benefit from
this feature particularly, so I went ahead and got it done today.

This involved lots of changes to the server, including DBField and all
its subclasses, DBEditObject, DBObject, GanymedeSession, and possibly
other classes.

These changes included making the server's code differentiate between
inhibiting wizards for the sake of an automated field copy and
inhibiting oversight for the purpose of loading the database on server
start, etc.

I still need to document all of this in the DBEditObject subclassing
guide.

12. [SERVER] Added support for floating point fields

All of the code for this came from John Knutson
(johnk@arlut.utexas.edu) here at the laboratory.

This change bumps the DBStore revision numbers to

	major: 1
	minor: 15

13. [CLIENT] Improved speed for object editing

The client was inefficiently and redundantly sorting large choice
lists, slowing object editing down a great deal.  Now all QueryResult
objects from the server are automatically sorted one time only, on
receipt, using an efficient binary insertion sort.

14. [SERVER] Reworked Password fields to support FreeBSD-style MD5 hashing

The Ganymede has supported 'MD5 passwords' since August, but this was
actually just a simple MD5 hash of the plaintext.  FreeBSD, OpenBSD,
Linux PAM, and possibly other operating systems use a much more
involved process of generating 'MD5' passwords, including a salt field
and a thousand round trip through MD5 to make dictionary cracks much
more time-consuming.

Ganymede's PasswordDBField class now supports these fancy MD5
passwords, and the old support for a simple MD5 password hash has been
removed.

This change bumps the DBStore revision numbers to

	major: 1
	minor: 16

15. [CLIENT] Fixed tree filtering

The Ganymede client had a bug in gclient.recurseDownCategories which
could cause categories to be erroneously omitted from the client's
tree display in a specific situation.  This was detected by John
Knutson in regard to a custom schema that he did.

16. [SERVER] Took unnecessary fields out of the DBObject class

I took the 'int id' and 'DBEditSet editset' variables out of the
DBObject class.  This will save 8 bytes per object in the database in
memory.  Not a major deal, but every little bit helps, I suppose.

Added methods to compensate for the lack of the redundant, but
directly accessible variables.

17. [SERVER] Major reworking of object linking

I spent a week and did major surgery on the Ganymede server's handling
of non-symmetric object linking.  Previously, if an invid field did
not point to an explicit field in a remote object, the server would
automatically maintain the symmetric back pointer in the target
object's back links field, field 8.

This meant that whenever an object's field was set to point to an
object, that object had to be exclusively checked out by the server to
handle the association.  Only one transaction at a time could
establish such a linking, which could make for a really big and
unnecessary bottleneck in the server.

Now the server maintains at all time a separate, in-memory hash
structure for back pointers.  This hash structure is designed to allow
any number of objects to 'anonymously' link to a given object
concurrently.  The server maintains a separate system to track
deletion locking for objects, allowing anyone to forge or remove an
asymmetric link to a common object, and to allow the common object
itself to be edited, as long as no one tries to delete that common
object.

This change can drastically increase performance in cloning objects
which point to a lot of non-symmetrically linked objects, since those
targetted objects no longer need to be pulled out of the database for
editing in order to establish the link.

This change bumps the DBStore revision numbers to

	major: 1
	minor: 17

18. [SERVER] Server object accounting fix

There was an opportunity for the server's objects checked-out
accounting to get out of sync if an object creation operation was not
able to proceed to completion as a result of a failure to perform
the custom object initialization.

Now the server's object accounting should be reliable under
all circumstances.

19. [SCHEMA] Updated BSD and Linux schema kits to support MD5 hashed passwords

I have put preliminary (but functional) support into the Linux and BSD
kits for MD5-hashed passwords.

Someone will have to let me know how well this works.

-------------------- Changes from 0.99.6 to 0.99.7 -------------------

RELEASE DATE: October 13, 1999

1. [SERVER] Fixed the Ganymede server's registry binding for localhost

Michael McEniry (mmceniry@itsc.uah.edu) provided a patch to
Ganymede.java which corrects the problem on Linux systems with the
server failing on startup with a localhost RMI registry binding
permissions failure.

2. [SERVER] Fixed object deletion for multi-level nested objects

Martin Schneider (martin@ira.uka.de) wrote to report that deleting
objects which contained embedded objects which contain embedded
objects fails on transaction commit.. the problem was that the
GanymedeSession.getContainingObj() method couldn't walk the embedding
stack to find the top-level parent to determine object ownership for
logging purposes.

GanymedeSession.getContainingObj() will now check to see if it is
trying to find the parent of an embedded object which has been
processed for deletion, in which case it will check the original
version of the object in order to find the original parent.

3. [SERVER] Added support for regexp matching in StringDBField

Added support for specifying a regular expression pattern in string
fields.  Modified the server and schema editor to support regular
expression binding to string fields.

The older 'OkChars' and 'BadChars' string field parameters are still
maintained.. any change to a string field must satisfy any regular
expression specified in addition to the OkChars and BadChars
parameters.

This change bumps the DBStore revision numbers to

	major: 1
	minor: 14

Martin Schneider (martin@ira.uka.de) asked for this change, it seemed
like a good idea to me.

4. [SERVER] Fixed server-loading bug from 0.99.6.6

Change 6 to Ganymede.java in release 0.99.6 broke loading data from a
freshly dumped schema.  Fixed the server initialization so that it can
properly reset passwords if the password field is undefined in the
supergash persona object.

5. [SERVER] Fixed schema dump bugs in DBObject.partialEmit()

Since July there has been a bug in DBObject.partialEmit() which makes
it impossible to successfully dump a modified schema to disk and then
turn around and use it to load a new database.  The problem was that
when the server was dumping a ganymede.schema file, the supergash
persona was being written to disk without the link to the supergash
owner group (owner group 0) that gave it supergash privileges.

Actually, there were a cluster of bugs in the schema dump logic.  All
of them have been fixed, so schema dumping should produce a clean and
usable ganymede.schema file now.  I knew the code for schema dumping
was poorly architected, but I somehow missed the fact that it was so
thoroughly broken.

6. [SERVER] Added code to protect the essential server data structures

It used to be possible to manually delete the supergash owner group,
which would put the ganymede.db file in an unusable state.
GanymedeSession.remove_db_object() now refuses attempts to do this.

In addition, the Ganymede server now checks the database schema on
start-up to make sure that all of the essential database objects are
defined, including the supergash persona object, the supergash owner
group, the default role, and the system event objects.  If any of
these objects are undefined in the database on server startup, the
server will now recreate them.

The server still doesn't do a schema sanity check on startup, though.
Still lots more work to do to clean up schema editing as a whole.

7. [SERVER] Fixed logging for IP address changes

The IPDBField.getDiffString() method had an error that caused it to
report the old value for a changed IP address when it was meant to be
showing the new.

8. [SERVER] Added a background task to disconnect idle users

The Ganymede server now has a built-in task which runs every minute to
disconnect users that have been idle for a certain period of time.

Currently, users with no objects checked out of the database will be
disconnected after 15 minutes of idle time, and users who are in the
middle of a transaction but have not done anything for a long time
will be disconnected after 20 minutes of idle time.

9. [CLIENT, SERVER] Made client able to re-acquire server without restarting

The Ganymede client is now able to attempt to re-acquire the Ganymede
server if the server goes down while the client is running.

That is, if the server goes down cleanly while the client is running,
the client will close the main window, leaving the login box.  The
login box will now be able to attempt to bind to a new instantiation
of the Ganymede server if the server has been brought back up.

In order to do this properly, I had to add a new method to the
RMI Server interface (Server.up()), so you'll need to install
the client from Ganymede 0.99.7 for use with the 0.99.7 server,
and vice-versa.

Also modified the client to be more responsive to a server shut-down
message, even if the user was sitting on the persona selection dialog.

10. [SERVER] Server now associates embedded objects with container in log

Previously, if changes were made to an embedded object that did not
result in a modification to the state of the container, the log for
that change did not record that the container was involved in the
transaction, making such changes invisible to the history panel of the
containing object.

Now, whenever an embedded object is changed, the log record for the
change will be associated its container and the change will show up
properly in the container's history view.

11. [SERVER,SCHEMA,DISTRIBUTION] Changes to handle descriptor starvation

We put Ganymede in production at the laboratory on October 10th and
quickly discovered that the Ganymede server was running into file
descriptor exhaustion when builds are done at a high rate of speed.

It turns out that one of the problems was that the GASHBuilderTask
class in the gasharl schema kit wasn't explicitly closing the file
descriptors for the Process object used to do the external build.
Looking on the Java BugParade, I found bug item #4025386, which
describes the problem and how to fix it.

I went through all the BuilderTask classes in all the schema kits
included with Ganymede and added a finally {} clause to close the
Process file descriptors once the external build was done.

Even after this change, I still saw the server run out of descriptors,
so I put a 'ulimit -n 128' in the runServer script (64 is the default
on Solaris.. the ulimit command is commented out so that people on
Linux, etc., don't get an artificially low descriptor limit), and I
fixed a few other places in the code where the system was
unnecessarily waiting for garbage collection to close resources.

File descriptor depletion is still a big issue with Ganymede, as a
user with the client login window open is taking up a descriptor on
the server for the RMI connection, even though the user isn't doing
anything.  I'm not sure how much I can do about this, since I believe
the only way to force an RMI break is by allowing the remote object to
be garbage collected on the client.

In any case, the problem isn't so much that the Ganymede server itself
is keeping an excessive number of descriptors open, but that the
extensive Ganymede/GASH build process we initiate on transaction
commit opens dozens of files, taking up lots of the server's
descriptors along the way.  Java doesn't provide any good way to
manage this, but it may be a good idea to put another ulimit
invocation in the script run by Ganymede?

12. [SERVER] Fixed really stupid DBEditSet rollback mistake

Ugh. Ugh. Ugh.

I had broken the DBEditSet rollback code with change #0.99.6.9 below.

There was no way it could have ever worked.  It didn't come close to
working.  Not even remotely plausible code.  I am dum.

I fixed it.. it is now both efficient and correct.

13. [SERVER] Optimized DBEditSet.commit()

I reworked DBEditSet.commit() so that it doesn't need to use
rollback() to handle an incompletely filled-out object at transaction
commit time.  Basically streamlined commit() so that it does the
minimum amount of work required to check things out, without doing an
unnecessary checkpoint()/rollback() pair when one or more objects in a
transaction aren't completely filled out.

And I checked my work, and I tested the code, this time.

14. [SERVER, ADMIN CONSOLE] Added a deferred shutdown option

The server can now be told to disable logins and to shutdown the server
when all users log out of the system.  This is very useful for shutting
the server down cleanly in a production environment.

If you use the 'stopServer' script, you can now say 'stopServer
-delay' to have the server do a user-friendly shutdown.  If you do do
'stopServer -delay', the stopServer script will not wait for the
server to shut down before exiting.

If you shut the server down through the admin console, a dialog will
pop up asking if you want to make the shut down deferred or not.

This change involves an incompatible change to the
arlut.csd.ganymede.adminSession RMI remote interface used by the
server, admin console, and stopServer script.

15. [SCHEMA] Several tweaks to gasharl schema

Lots of minor fix-ups to the gasharl schema code, which we are actually
using in production at ARL now.

-------------------- Changes from 0.99.5 to 0.99.6 -------------------

RELEASE DATE: August 27, 1999

1. [SERVER DISTRIB] Fixed decodeDB

decodeDB was failing because the properties weren't being loaded and
the db load routine was attempting to find the Ganymede.journal
property.

2. [SCHEMA] More improvements to gasharl schema.

Fixed ARL maildirect file generation to only emit entries for
normal category user records, made it possible to clear the
primary user field for systems.  Fixed a minor infidelity in
hosts_info generation.

3. [CLIENT] Fixed problems with string area gui object

I fixed a couple of problems with the JstringArea class used in
the Ganymede client to display and edit multi-line string fields.

I had to make some changes to the code so that it really didn't try to
do editing when the field was not editable, and so that when errors
are returned when the JstringArea is edited, the focus-loss update
trigger won't get into an infinite loop, popping an error dialog up
over and over and over and over again.

The JstringArea is one of the least used GUI components in the client,
which is why this wasn't detected and fixed a long time ago.

4. [CLIENT] Fixed error in handling fixable transaction failure

The change I made in 0.99.5 to the client's handling of catastrophic
transaction commit failure broke proper handling of non-catastrophic,
correctable commit failure.. if such a transaction failed to commit,
gclient would reset its state, even though the transaction was still
open and repairable.

gclient.commitTransaction() now handles both circumstances properly.

5. [SERVER] Added support for MD5-hashed passwords.

Added MD5 support to PasswordDBField.java.  Bumped DBStore.minor_version
to 13 for MD5 support.

The server can now store and authenticate using MD5-hashed passwords.
Schema kits can be written to input MD5-hashed passwords into the
system as well as UNIX crypt()'ed passwords.

Neither the Linux nor the BSD schemas have yet been modified to
support MD5 passwords, but the PasswordDBField code now supports MD5.

6. [SERVER] Improved the server's password reset logic

Previously, if the -resetadmin parameter was given on the command
line, the server would always open a new transaction and reset the
supergash password.  Now the server checks to see if the password has
changed before doing the edit.  This cuts down on the redundant 'hey,
i set the supergash password!' mail that Ganymede was sending out.

7. [SERVER] Fixed adminPersonaCustom.convertAdminInvidToString()

The new DBLog transaction logic for finding an email address to mail
to was broken when the change was made by an end-user and not by an
admin persona.  I fixed adminPersonaCustom.convertAdminInvidToString()
so that it can gracefully deal with the possibility that the 'admin
invid' in an DBLogEvent produced by the DBEditSet commit() routine is
actually an end-user Invid.

8. [SERVER] Reworked DBSession.createDBObject()

The old createDBObject() call in DBSession had problems if a user
in an owner group tried to create a new object at the same time that
another user had the owner group checked out for editing.. the object
create would fail in an ungraceful manner, resulting in the server
thinking that the user had a negative number of objects checked out,
and getting very confused.

The DBSession createDBObject() code now does a transaction checkpoint 
before attempting to place the newly created object in the proper
owner groups.  If one of the owner groups turns out to be unavailable,
the object create will fail and the transaction will be rolled back.

I also modified createDBObject() to return a ReturnVal so that
detailed failure information can be returned to the user if object
creation fails.

This is continuing a trend.. I've been finding the need to go through
the code and make some of the server's internal paths better about
returning detailed error information.

9. [SERVER] Improved DBEditSet.rollback() code

Minor changes to the transaction rollback code, to take advantage of
the optimized vector compare operations in arlut.csd.Util.VectorUtils.
Should make rollbacks in very large transactions noticeably faster.

10. [DISTRIBUTION] Added template schema directory, fixed installServer

In 0.99.5 and for awhile before, the installServer script would break
if you tried to install the Ganymede server without choosing a schema
kit, which caused installServer to break with a complaint about

'Couldn't write schema build config'.

installServer now goes ahead and installs an empty schema directory
with all of the build scaffolding required to develop your own schema
kit.

I am planning on significantly revising the way that schema kits are
packaged and distributed to make it easier to distribute schema kits
independently, but that is something for a future revision, I think.

Thanks to Glen Joseph <gjoseph@us.ibm.com> for reporting this.

11. [SERVER] Reworked embedded object initialization

In 0.99.5 and before, embedded objects had their custom
initializeNewObject() methods called before the embedded object
was linked into its container, making it hard for custom code
to make initialization decisions based on the container's state.

This has been fixed; initializeNewObject() for embedded object types
is now called after the object has been linked into its parent.

In addition, initializeNewObject() now returns a ReturnVal rather than
a boolean, to allow detailed error messages to be returned to the
user.  All custom DBEditObject subclasses included in the Ganymede
distribution have been brought up to date with the new
initializeNewObject() method signature.

Thanks to Martin Schneider <martin@ira.uka.de> for bringing this to my
attention.

12. [SERVER] DBEditObject.createNewEmbeddedObject() now returns ReturnVal

Another change made to provide better feedback paths for server
errors.

This method wasn't one that was ever overridden in the schema kits
provided with Ganymede, but adopters who did override this method
will need to modify their custom code to return a ReturnVal rather
than a boolean.

13. [CLIENT] Fixed string field GUI component.. now limits size properly

Way back in dev6a, I modified the arlut.csd.JDataComponent.JentryField
class so that it would employ a custom DocumentModel to make sure bad
characters couldn't be entered into a string/number/ip field in the
Ganyemde client.

Looks like I had somehow missed testing the code which was supposed to
prevent entry of characters after the size limitation on the field had
been met.  There was code there for that function, but it wasn't
correctly functional.

Modified the arlut.csd.JDataComponent.JentryDocument class to check
for the number of characters currently in the JentryField versus the
stated limit (if any) on the number of characters allowed in the
field.

14. [SERVER] Moved GanymedeServer creation, binding to end of server start

Previously there was a remote chance that a user or admin console
could attach to the server before all startup housekeeping was taken
care of.  The GanymedeServer RMI binding is now the very last thing
done by Ganymede.main().

15. [CLIENT] Fixed client behavior for Java 1.3 beta (Kestrel)

In the new Java 1.3 beta, code-named Kestrel, a lot of JInternalFrame
code has been changed.  Several things in the Ganymede client had to
be tweaked to insure internal windows in the Ganymede client work
acceptably well with all existing versions of Swing.

-------------------- Changes from 0.99.4 to 0.99.5 -------------------

RELEASE DATE: July 28, 1999

1. [SCHEMA] Several gasharl schema mods

The commitPhase2() method in userCustom for the gasharl schema now
calls out to 'directory_namer' and 'directory_maker' to handle
external actions when users are renamed or created.

Added support for generation of the ARL maildirect file, which will be
of absolutely no interest to anyone outside of ARL.

2. [CLIENT] Fixed client behavior on catastrophic transaction commit failure

The client wasn't properly getting rid of any edit windows if a
transaction commit failed catastophically.  This was occuring during
development and test of changes in 1.) above.. a NullPointerException
was causing the transaction to be aborted rather than committed, and
the client wasn't properly resetting its state to reflect this.

3. [DOCUMENTATION] Put a warning about deadlock possibilities into DBEditObject guide

The DBEditObject commitPhase1(), commitPhase2(), and release() methods
are called by the server while portions of the database are locked.
Using the GanymedeSession query mechanism will very likely bring the
server into deadlock, as I discovered.  Documented this in the DBEditObject
subclassing guide, as well as the javadocs for those methods.

4. [SERVER] Revised GanymediatorWizard spec, logic

In 0.99.4 and before, the GanymediatorWizard logic depended on the
custom wizard author writing a getStartDialog() method that had to
be smart enough to unregister() itself if no further interaction
with the user was needed.  It was very, very easy to not do this,
and so leave the client's GanymedeSession with a registered wizard
blocking further activities.

To prevent this problem, I have deprecated getStartDialog() in
favor of a processDialog0() method to start the wizard sequence.  This
has the advantage that the GanymediatorWizard's respond() method
will automatically unregister a wizard that no longer needs to talk
to the user.

This is an incompatible change in the GanymediatorWizard class that
will break existing wizard-using custom code, but fixing this now
will make wizard use far more reliable, and it would only be harder
to fix this later.

I don't expect many (any?) folks outside of ARL have written wizards
for use with custom schemas yet.  For those who are interested, the
GanymediatorWizard javadoc header now has some hopefully usable
documentation on how to do this.  (I've also written a guide on
the whole subject.. see change #18.)

Modified all wizard code in all of the included schema kits (not
counting the not-maintained ganymede.only schema) to use the modern
wizard support code.

5. [SERVER] Made transaction commit, abort clear active wizard

Another fix to help keep wizards from getting stuck.. aborting or
committing a transaction will now clear any wizard from registration
with the GanymedeSession object.

6. [SERVER] Improved lock system to prevent intra-thread deadlock

Modified the DBSession and DBEditSet lock handling code to help insure
that the server can't be deadlocked by a thread attempting to
establish a lock when it already holds one that would cause the new
lock establish() to deadlock the server.

This should only be an issue in terms of deadlock brought about during
transaction commit through errors in custom-plugin development.. the
existing system already prevented deadlocks between threads.  Now the
server will report an intra-thread lock error rather than simply
dead-locking.

Note that this deadlock prevention is in the form of an
InterruptedException being thrown, rather than permissive
lock-sharing.. the reason for this is that the operations that require
a read or dump lock (such as a query) will not be able to provide
transaction-consistent results when called from within a transaction
commit.

This change is entirely for the purpose of making the server more
friendly to customizers, and should not have any significant effect on
normal server operations.

7. [CLIENT] Fixed password handling in dialogs passed to the client

Wizards that asked the client for a new password value (as in the user
reactivation wizard in the gasharl schema) were not able to get a
password back because the password field logic in StringDialog and
JpassField was not working properly.

Wizards can now request a new password from the client properly.

8. [SERVER] Changed dump process to be safer

Previously, the server would dump the database by first renaming the
old on-disk database to ganymede.db.bak, and then write the current
in-memory database to ganymede.db.

This meant that if the server was killed while writing out the
database, there would be an incomplete ganymede.db file in place,
which would require the admin to manually recover from the
ganymede.db.bak file.  Things would always be recoverable, but it
wasn't an automatic process.

Now, the ganymede.db file is not renamed until the server has
completed dumping out its new dump, which is called ganymede.db.new
during the dump.

There are still one very narrow opportunity for stopping the server at
a point in which the server can't recover on its own at restart, but
the odds of this occuring are infinitesimally low now.. only if the
server is killed after it has renamed ganymede.db to ganymede.db.bak
and before it has renamed ganymede.db.new to ganymede.db will the
server be unable to properly recover on start-up.

This change does slightly increase the amount of disk space needed
during operations, as the system needs to have enough disk space for
three versions of ganymede.db at a time during a database dump.

Thanks to Darrell Tippe, <Darrell.Tippe@atcoitek.com>, for reporting
the problem.

9. [SERVER] Made DBObjectBase explicitly record max object id

The Ganymede server in some cases could erroneously re-use an Invid.

This could occur if an object was deleted, and the server was
restarted before another object of that type could be created.  The
server now explicitly records the maximum object id seen for
each object type in the ganymede.db file.

This change bumps the DBStore revision numbers to

	major: 1
	minor: 12

10. [SERVER] Seriously Improved Logging, Mailouts Systems

Reworked lots and lots code in DBLog.java, DBEditObject.java, and
DBEditSet.java to make all of the transaction logging stuff work
right.

--

Mail-related exceptions will no longer cause transactions to fail to
commit.. the server will report the mailer error, but continue with
normal processing.

--

Modified the Qstmp class so that it can queue messages for sending on
a background thread.. the extensive mail-outs in the revised logging
system was noticeably slowing down transaction commits.

All e-mail messages sent out by the DBLog class will be done without
blocking the logging thread.

--

The DBEditSet class now does transactional event logging after a
transaction's objects have had all of their commitPhase2() methods
called.  This change makes it possible for a commitPhase2() method to
send mail out.

--

Added variants of DBSession.viewDBObject() that will automatically
retrieve the original version of a DBObject that is being deleted by
the current transaction.  Useful for getting the original version of
an object during transaction commit from the object's Invid.

--

Added a getLabel() override to DBEditObject.java that will
automatically return the object's pre-deletion label if the
object is being deleted and the DBObject getLabel() routine
returns null.

--

Added standard methods to allow custom objects to identify email
addresses that should be notified when changes are made to them.
Useful for making sure that users get cc:'ed on any changes made to
their account, etc.

These methods are documented in the DBEditObject subclassing guide,
and are used by the logging system.

11. [CLIENT] Added tooltip support to checkboxes, other GUI field types

A number of the GUI field types supported by the clients were not
being added to containerPanel with any registered field comments set
as tooltips.  Fixed.

12. [SERVER] GanymedeScheduler could lose on-demand tasks

If the Ganymede server tried to initiate an on-demand task that was
currently running, the scheduler would 'lose' the task instead of
properly doing back-to-back execution of the task.  Big oops.

13. [SERVER] GanymedeBuilderTask didn't do overlap properly

The GanymedeBuilderTask base class has code that remembers the last
time the builder task was run, so that it can check for changes in
the various object bases that occurred since the last builder task
run.  Unfortunately, the time stamp was being recorded after the
builder task completed, even though changes could be made in the
database after builderPhase1() finishes and before builderPhase2()
completes, which left the possiblity for build tasks to not be
re-issued properly if two transactions affecting the same object
base were committed back-to-back .

The GanymedeBuilderTask base class now properly records the time
before entering builderPhase1(), so that rapid sequences of changes to
the database will always properly trigger subsequent builds.

14. [SERVER, CLIENT, CONSOLE] Cleaned up login sequence

Both the admin console and client will now give a nice dialog if login
fails.  Previously, the admin console showed an exception trace, which
did not make it clear that the problem was a bad username or password.

Made the clients include error.gif in several of their dialogs.

15. [CLIENT] Removed extraneous menu items from object windows

The object view/edit windows had a menu on them that included a number
of options that didn't always apply, as well as a 'print' option which
never worked well enough to be available to the end user.

Now, the object window's "File" menu only includes actions that can't
be done anywhere else.

The File menu will now only present the 'Set Inactivate Date' option
when the object being edited can in fact be inactivated.

16. [SERVER] Cleaned up schema dumping of persona objects

Modified DBObject and DBObjectBase's partialEmit() methods so that
supergash's locally-defined email address is not saved into the
ganymede.schema file.

17. [WEB FILES] Reworked the web access system for the Ganymede clients

Brian O'Mara did a very nice job of making a new set of web pages for
the Ganymede clients.  The new primary web page uses JavaScript to
launch the clients in their own frames, making it possible to run a
client and console simultaneously, and to be able to close the
original launch frame without killing the clients.

18. [DOCUMENTATION] Added a detailed guide to Wizard authoring

Added another long document on customizing the server with plug-in code,
this time on the topic of wizard authoring.

-------------------- Changes from 0.99.3 to 0.99.4 -------------------

RELEASE DATE: July 8, 1999

1. [SERVER] Optimizations to permissions system

The simplifications to GanymedeSession.getPerm(object,field) that
I did for 0.99.3 was in fact doing too much work, and the logic
didn't flow clearly.

GanymedeSession.getPerm(object, field) is now correct, efficient, and
easy to read.

2. [SERVER] Added new versions of anonymousLinkOK/UnlinkOK() to DBEditObject

It was previously impossible to grant anonymous linking privileges to
a field only when the other side of the link was being created in a
particular object type/field.  This posed a problem in the
circumstance where you want to allow a specific field in a given
object type to be linked to another object type's backlinks field
without having general editing permissions for the other object.

I added a couple of new versions of these methods that take additional
parameters identifying the originating object and field, so that
customizers can take the other side of the proposed link into
consideration before granting anonymous linking permissions.

See the DBEditObject.anonymousLinkOK()/anonymousUnlinkOK() javadocs
for details.  Hopefully I'll get around to writing a full-scale
technical manual for Ganymede that will go into when/where you would
use these methods.

Modified InvidDBField.bind() and InvidDBField.unbind() to call the
new versions.

3. [CLIENT] Improved StringSelector used in String and Invid fields

The StringSelector GUI component used in the client to allow editing
of String and/or Invid vector fields has been fixed so that it does
not include the text box for entering custom entries unless the
StringSelector is editable.

Fixed some minor GUI problems with the StringSelector resizing itself
to a minimum size after adding a new entry to an empty
no-choices-provided string selector, made the 'remove' button disable
itself after removing something.

4. [SCHEMA] Improved email list behavior in gasharl schema

An email list owner can now add any user, list, or redirect to his
list without having general editing privileges for that user, list,
or redirect.

This takes advantage of change #2, above.

5. [INSTALL] Various improvements to the install process

Modified installServer so that the custom loading instructions it
writes out at the end is sent to a README.custom file in the installed
server's directory rather than to screen.  No sense spewing a couple
of screen's worth of customized install instructions if the user has
to do cut and paste to save it to a file for reading.

Added an installWeb script to install the web files into a designated
directory, separate from the normal UNIX client install.  This has the
advantage that you can install the web resourcs for Ganymede without
having to have Swing installed locally (which installClient checked
for.)

Added a handy index.html file for the Ganymede web resources, got rid
of the old activator and hotjava directories, added a nice set of web
frames to allow the installer to bring up their browser and directly
visit the directory where they installed the web resources.

6. [WEB FILES] Updated plugin client files for 1.2

The plugin client files were re-generated from the 1.2 htmlconvertor
utility, and now include proper links to the latest version of
Sun's java plug-in for Solaris and Windows.

7. [SCHEMA] Fixed BSD schema master.passwd parser, Linux passwd parser

The old Linux and BSD passwd file parsers would break if they
encountered a user record with a blank password field.

Modified GanymedeServer.login() and GanymedeServer.admin() to make
sure the server won't throw a null pointer exception if the database
contains a user or admin persona with no password during the login
process.

If a Ganymede user record has no password set, that user will not be
able to login to the Ganymede server.  Unlike UNIX, Ganymede never
lets anyone log in without a password.

8. [ADMIN CONSOLE, SERVER] Reworked admin console, server's admin API

Fixed the admin console so that it will properly log itself out when
it is closed through the window system.

In prior versions, the admin console wanted to know the name of the
supergash account on the server, so that it could preemptively refuse
to perform certain operations.. this really makes no sense at all, and
was never needed for security.  The admin console now goes ahead and
attempts such operations, and depends on the server properly refusing
the operations.

The install scripts no longer prompt for the supergash account name
when installing the UNIX and web clients.

Also in previous versions, the server wasn't actually honoring the
console permissions checkboxes in the admin persona objects.. any
admin persona could log into the server via the admin console, but no
one other than supergash could do any control operations.  The admin
persona console permissions checkboxes now properly control the
server's response to admin console operations.

Admins other than supergash and monitor will need to log into the
server via the admin console using their full persona name.. i.e.,
'broccol:GASH Admin'.

9. [DOCUMENTATION] Revised, improved the install guide, added FAQ

Significantly revised and enhanced the install guide, corrected some
mistakes, included information on the use of installWeb.

The text INSTALL file is now a lynx-generated version of the HTML
file.. it was too much work and too error-prone trying to maintain
both independently.

Added a text FAQ file.  Will convert this into a nice web version at
some point.

-------------------- Changes from 0.99.2 to 0.99.3 -------------------

RELEASE DATE: June 23, 1999

1. [SERVER] Fixed value() in StringDBField.java

The value() method in StringDBField.java was improperly forcing
a permissions check, despite the fact that value() was used for
server-side code only.

This was causing a problem at transaction commit-time under certain
conditions, caused by the PermMatrix.union() bug below.

2. [SERVER] Fixed bugs in permissions system

Ugh, I had screwed up PermMatrix.union() in 0.99.2, the object->field
inheritance logic wasn't working properly.

I fixed PermMatrix.union(), simplified GanymedeSession.getPerm(), and
modified both PermEntry.union() and PermEntry.intersection() to optimize
out a lot of new PermEntry creation.

-------------------- Changes from 0.99.1 to 0.99.2 -------------------

RELEASE DATE: June 18, 1999

1. [DOCUMENTATION] Seriously Improved Javadocs

Lots more improvements to the source code javadocs.  Improving the
javadocs is an ongoing project.. I really want to make it possible to
get a very good feel for how the entire system works on a technical
level by simply browsing through the javadocs.  It's an interesting
exercise, and a continuing one.  If you find yourself puzzling about
something in the code, please let me know so I can document it better.

2. [SERVER] Improved DBLock, DBObjectBase classes slightly

Added some more explicit lock status check methods to DBObjectBase.
Modified GanymedeAdmin's schema edit status check to use the
new DBObjectBase.isLocked() method.

Pulled some methods and variables from the DBLock subclasses up to
DBLock.  Added DBLock.isLocked(Vector) to safely test a lock against a
vector of DBObjectBases.  Modified GanymedeSession.queryDispatch() to
use the new method, and to verify that the database remains read
locked at the completion of the query loop.  (the user could have been
knocked off via the admin console, etc.).

Documented all the pieces of the lock system in the Javadocs.

3. [SERVER DISTRIB] Added permdecodeDB command

permdecodeDB will take an existing ganymede.db file and report on
the permissions bits encoded by roles in the database.  Useful
for debugging permissions code problems.  See #4 below.

4. [SERVER] Corrected, simplified server's permissions system

The Ganymede server's permissions system had a complex and (as it
turned out) broken system for inheriting 'default permissions' for
fields in an object.  Previously, an object type could have a default
permissions bitset registered, and any fields in that object for which
permissions had not been explicitly set would take on the default
value.  This was intended to support reasonable behavior for newly
created fields, but the code to implement this had problems in some
odd cases.  The notion of an explicitly recorded default permission
set for fields that differed from the permissions on an object type
itself has been removed.  In keeping with this, the
setDefaultFieldPerms() methods on both PermissionMatrixDBField and
perm_field have been taken away, in favor of setFieldPerms(), which
sets permissions for all existing fields in an object type, but
doesn't involve the complex default logic.  The permissions logic has
been simplified, and better documented in the javadocs.

Now, when new fields are added to object types through the
schema editor, all Role objects will grant the permission for the
object as a whole to the new fields.  If you run the permissions
editor in the client on a Role object's permissions fields, you can
change this default.

Since the Ganymede client's permissions editor dialog had no code for
calling the setDefaultFieldPerms() methods on perm_field, this change
shouldn't affect any custom work people have done.  The gash and
gasharl ganymede.schema files did ship in 0.99.1 with a default
permission set on a few object types.  People using a ganymede.db file
derived from a gash or gasharl ganymede.schema may find that they need
to use the permissions editor to correct problems in the GASH Admin
Role object's permissions bits.

5. [SERVER] Changes to permissions fields now descriptively logged 

If an administrator makes changes to the permission bits in a Role
object, the server's log will now record the precise changes, which
will be visible in the Role object's history panel.  

The history recorded may be a bit deceptive in the case where a field
which previously had no explicit field-level permissions set has them
set..  if the object type has a permission of view/create/edit, and
you edit the field's permission to set it to view/edit only, the log
file will show that the field gained view and edit, when it
effectively lost create, which was previously inherited.

6. [SERVER] Miscellaneous methods added

Added debugging toString() to DBField, PermMatrix classes.
Added getFieldName(short) to DBObject, db_object.

7. [ADMIN CONSOLE] Fixed admin console

The admin console now works properly in a browser, and properly
initializes under all conditions.  

The magic incantation to get the Ganymede Admin console to find the
arlut/csd/ganymede/GanymedeServer_Stub.class file was to include the
arlut/csd/ganymede/Client.class in the ganymedeAdmin.jar file.

Apparently, Sun's RMI classloading logic freaks out if it comes across
a reference to an unavailable RMI remote interface parameter in a RMI
remote method _Stub.class file, even if the freaked-out client in
question never refers to that method call.

I tried *everything* to figure this out, before finally noticing the
blurb in the Java plug-in's console about the Client.class load
attempt.. d'oh.  I wound up having to include
arlut.csd.ganymede.Client and arlut.csd.ganymede.GanymedeScheduler
because both were referenced by RMI methods or serialized objects the
admin console needed.

In addition to fixing the ganymedeAdmin.jar file, the applet code was
revised to be closer to that of the standard client, to improve its
behavior and appearance in a web browser context.

I still need to make a nice 'admin console' logo for the admin console
applet.

Thanks to Charles Adams (charles.adams@central.sun.com) and Andy
Johnson (andyjohnson@engineer.com) for reporting the problem with the
admin console not working properly with the Java plug-in.

8. [SERVER] Fixed login logic

In 0.99.1 and before, the server had an ambiguity that would allow
users to login to the wrong priviliged admin account on occasion, if
there was more than one account with the same persona name.

I.e., if there was persona account 'broccol:supergash' and
'supergash', each with different passwords, the broccol:supergash
password could allow access to the non-user-associated supergash
admin account.  This was true for both normal client login and for
admin console attachment.

9. [SERVER] Fixed DBQueryHandler's field DEFINED logic

The Ganymede server's DBQueryHandler would throw an exception if
attempting to process a "field is defined" QueryDataNode if the field
in fact did not exist.

-------------------- Changes from 0.99 to 0.99.1 -------------------

RELEASE DATE: May 27, 1999

1. [SERVER] Made decodeDB omit built-in field types by default

Did a bit of work to clean up the schema report code generated by
decodeDB.

2. [SERVER] Cleaned up, documented DBEditSet, DBEditObject

Added lots and lots of documentation to the DBEditSet transaction
class, made the commit() operation a bit more robust in terms
of relinquishing a write lock on exceptions and errors.

The DBEditObject class was modified to include a boolean finalAbort
parameter in the release() method.  Javadocs for this method were
improved to clarify and document the different ways this method can be
called.

3. [SERVER DISTRIBUTION] Added a stopServer commandline app

In order to facilitate automatic shutdown of the Ganymede server on
operating system shutdown, I've created a command-line stopServer
application that can shut the server down if you keep the server's
supergash password in its ganymede.properties file.

Yet another thing for production use.. we use this to support
automatic server shutdown when we reboot our Solaris Ganymede server.

4. [SERVER, CLIENT DISTRIBUTION] Made registry port number configurable

The Ganymede server and clients can now be configured to use an RMI
Registry on a non-standard tcp port.  This is necessary if you are
going to run the Ganymede server on the same system as other RMI
servers (such as Sun's SIMS administration console).

The server, client, admin console and password client all now accept a
property/parameter called ganymede.registryPort.  If the
ganymede.registryPort is not set, all Ganymede code will default to
the standard RMI registry port, 1099.

5. [SERVER] Added Session.findLabeledObject()

Added a convenient shortcut method in Session called
findLabeledObject() which allows the client to quickly get an invid
from an object type and name without having to use the full Query()
method.

This method is used by client/rpcpass.java.

6. [CLIENT] Added client/rpcpass.java to support Linux NIS rpc.yppasswdd

Added a program 'rpcpass' to the client distribution.  rpcpass is
designed to be used with the -x/--execute option present in versions
1.3.6.92 and later of the Linux NISkit's rpc.yppasswdd daemon
(included in the ypserv distribution), to allow users to use yppasswd
to change their password in Ganymede.

When run, rpcpass reads a single line from stdin,
which should be of the form

<username> o:<oldpass> p:<new cryptpass> s:<shell> g:<gcos>\n

Where the p:, s:, and g: fields are each optional.

After reading this line from stdin, rpcpass will connect to
the Ganymede server and change the password and/or shell.  If
this operation succeeds, rpcpass will emit a single line
to stdout,

OK\n

which is to be read by rpc.yppasswdd to signal success.  If
there are any problems, these will be described in a 
report to stdout, which rpc.yppasswdd will take as a failure
signal.

Note that while the rpc.yppasswdd daemon may pass gcos information to
rpcpass, the gecos field is formatted differently on different
operating systems, and so rpcpass does not attempt to handle it at
all.

Of course, any program can use the rpcpass program to propagate
password/shell change requests to Ganymede, not just the Linux NIS
kit's rpc.yppasswdd daemon.

7. [SOURCE] Fixed a couple more PATH problems with building sources

A couple of fixes relating to doing source builds with '.' not in
one's PATH.

EXECUTING: src/server/build
  ERROR     :  buildrmi: command not found
  FILE FIXED: src/server/build
  PREV LINE :  buildrmi
  NEW LINE  :  ./buildrmi

EXCECUTING: src/classes/buildJar
  ERROR     :  sync_tree: command not found
  FILE FIXED: src/classes/buildJar
  PREV LINE :  sync_tree 
  NEW LINE  :  ./sync_tree

Reported by Andy Johnson (andyjohnson@engineer.com).

8. [DOCUMENTATION] Significantly Improved Documentation

Fixed all link errors in the javadocs.  Added more javadocs to several
classes.

Reworked doc/index.html.  Added an HTML version of the INSTALL file,
cross-linked to a file glossary.  Added the log file format documentation
to the doc distrib.

-------------------- Changes from 0.98 to 0.99 -------------------

RELEASE DATE: April 16, 1999

1. [SCHEMA] gasharl schema mods

Various kinds of objects listed in an emailList object are now
shown with extra detail so that admins can see what sort of thing
they are dealing with.

Modified interfaceCustom so that the server will now check ethernet
addresses for valid form.

2. [CLIENT] Newly created object windows can now be undone.

Put the close box back on object creation windows.. now if you
close the window, the client will prompt you as to whether you want
to delete the object.  If you do, the server will drop the newly
created object from the server when the transaction commits.

Unfortunately, the code to handle intercepting the internal frame
close request in framePanel.java and windowPanel.java had to be
hacked with the VetoablePropertyChangeListener since Swing 1.1
and 1.1.1-beta1 have JInternalFrame.setDefaultCloseOperation()
totally broken.

If you click the close box on an edited object, you'll also
get a dialog explaining what that does and does not do.

3. [SERVER] Server always allows deleting a newly created object

This provides an exception to change 0.98.5 to allow the client to
always undo an object creation, even if normally they could only
inactivate the object, not delete it.

The server had always had support for DROPPED objects as well
as DELETED objects, the change above just really takes advantage
of this more.

4. [SERVER/CLIENT] Added case-insensitive regexp matching

The server and client now support performing a case-insensitive
regular expression comparison when querying on string and object
reference (invid) fields.

5. [CLIENT] Scalar invid fields are now always sorted

Scalar invid fields would become unsorted when the server instructed
the client to refresh them.  The client will now properly sort
invid lists from the server on field refresh as well as on field
construction.

6. [CLIENT] Client code simplified, documented, improved

Embedded object vector panels were seriously broken, and would break
when you tried to delete entries.  The vectorPanel refresh logic
was totally reworked and should behave properly in all situations now.
Loading embedded object vectors will be more efficient now.

The client's tracking of container panels active loading information
from the server has been simplified and better documented.. the client
does less work now to track container panels, and hitting cancel or
commit while loading a panel should still do the right thing.

Lots and lots of javadocs added and corrected in the client code.

Some of the debug output when running the client in debug mode has
been cleaned up.

7. [CLIENT] Fixed error on loading 'inactivate.gif' on HPUX JVM

The client included code to try to create an inactivate icon from a
file called inactivate.gif.  That file did not exist in the jar file
distributed with Ganymede 0.98, and the JVM on HPUX 10.20 threw an
exception on this, even though Sun's JVM's do not.

Reported by Lewis Muhlenkamp (lewism@tt.comm.mot.com)

8. [DISTRIBUTION] Build scripts, make files no longer require '.' in PATH

The Ganymede install and build scripts required '.' in the user's PATH
during install.  This should no longer be the case.

Reported by Lewis Muhlenkamp (lewism@tt.comm.mot.com)

9. [DISTRIBUTION] configure prompts for Swing jar location

Previously, src/make client would fail because the client's build
script didn't know how to find the Swing swingall.jar file if it
wasn't in the user's CLASSPATH.  Now the initial configure bootstrap
script will ask for the location of the Swing jar files so that the
build scripts in the source tree can be properly configured.

Reported by Lewis Muhlenkamp (lewism@tt.comm.mot.com)

10. [CLIENT] Fixed focus handling for IP address component

The JIPField GUI component class had problems with reentrancy that
could cause problems when dialogs were thrown up in response to
focus loss.

11. [CLIENT] Added toolbar to the Query Results window

The File menu on the Query Results window was really unobtrusive, and
didn't really emphasize to users that they could mail out the query
table.  Brian put in a spiffy mini-toolbar to show people what's up.

12. [CLIENT] JComboBoxes in client are more keyboard friendly

Previously, JComboBoxes in the client used the default
KeySelectionManager, which only allowed you to search for items by
their first letter.  You can now type in a full name of an object and
as long as you don't pause for more than a half-second between
keystrokes, the JComboBox will find the object by its full name.

Actually, this doesn't work as well as it sounds, because Swing's
KeySelectionManager stuff doesn't let you use the keystrokes to choose
an entry in a JComboBox before actually selecting it, and selecting
items in the Ganymede client will tend to be a slow operation due to
the round-trip to the server.

13. [SERVER DISTRIBUTION] Added decodeDB command

Added a new executable in the server's bin directory, decodeDB, which
takes the name of a ganymede.db or ganymede.schema file and generates
a print-out of the file's object and field type information.

This was added mainly to make it easier for me to do quick checks on
the ganymede.db and ganymede.schema files packaged with Ganymede
releases.

14. [DISTRIBUTION] Fixed linux, bsd, nisonly schema kits

In Ganymede 0.98, the linux, bsd, and nisonly schema kits had an
incompatibility that rendered them inoperable.  This had to do with a
field in the admin persona object type that was not defined in these
kits, but which the server had been modified to depend on.

I've modified the kits so that the field is defined, and modified
the server so that the lack of the field won't prevent an existing
ganymede.db file from being usable.

Reported by Nikola Nedeljkovic, nikola@carbonix.iam.tu-clausthal.de

15. [SERVER] Upgraded to gnu.regexp 1.0.8

Updated the gnu.regexp classes used in the server to version 1.0.8.

-------------------- Changes from 0.97 to 0.98 -------------------

RELEASE DATE: March 17, 1999

1. [BUILD] Ganymede build scripts moved out of db/out to db

The Ganymede server now uses a property called
'ganymede.builder.scriptlocation' to locate the builder scripts to be
run by the builder tasks registered in the server.

Previously, the builder tasks ran the build scripts in the out
directory, which wasn't really compatible with the decision in 0.97 to
have the build tasks archive the output files written by the build
tasks.  Now the build scripts are expected to be located by default
in the directory about out, which allows the zip archives to be 
cleanly made.

There is still some confusion here.. in theory, you can have multiple
build tasks registered in the server, each of which will try to zip up
the out directory.  This is not optimal, but what to do about it?

2. [SCHEMA] Added emailListCustom class to gasharl schema kit.

The email list members field is an invid field that can point to
objects of different types.  It is used to allow the email list object
to have members that are users, external email listings, or other
email groups.  Previously, the email list members field couldn't really
be edited after the bulk loading process was complete.

3. [CLIENT] Made windows for newly created objects non-closeable

The client allows the user to close object windows manually as a
convenience, to avoid cluttering up the client when editing lots of
objects.

Unfortunately, if we allow the user to close a newly created object,
there isn't necessarily a good way of getting that window back if it
turns out that the user left some mandatory field unfilled when they
go to click on 'commit'.  Now object creation windows will not be
closeable, so that it's not possible to 'lose' object windows that you
need to do further editing on.

4. [CLIENT] Modified the list editor GUI component

The 'list editor' GUI component used in the client may have a text
field at the bottom to allow the user to simply type in something
to add to the list.  Previously, the 'Add' button connected to the
text field was enabled all the time, confusing users manipulating
the component.  Now the 'Add' button will only be enabled when the
user has entered something into the text button.

5. [SERVER/CLIENT] Modified removal/inactivation handling

The server now by default refuses to allow objects to be removed
that have an inactivation protocol defined.  supergash can go ahead
and remove objects directly, and custom DBEditObject subclasses can
still redefine this behavior by overriding canRemove().

In conjunction with this change, the client has been modified so
that it will always show 'delete' as an option when right-clicking
on an object, even though the object may have an inactivation
protocol defined.  This makes things simpler, since it would be
difficult to handle the delete toolbar icon properly if I just
wanted the client to prevent the user from ever trying to delete
an object that can be inactivated.  And besides, the user might
be operating with supergash privileges.

6. [SCHEMA] Lots of refinements to gasharl schema

Modified the loader code to use BufferedReader, and to take care
of a few deprecation warnings.  Loading files from GASH should
be a good bit faster now.

The GASHARL schema now includes fields in the admin persona and owner
group objects to track information used for more complete GASH
compatibility.  New users and groups will be created with their
uid and gid starting in a numeric range compatible with GASH's
permission model if the owner group has a minimum uid/gid set.

The GASHARL schema now includes support for handling ARL contract
information, which will be of no interest to anyone outside the
lab.

7. [CLIENT] Reworked the persona select handling

The client now prompts users with multiple admin personae with a
persona selection dialog on log-in.

8. [SERVER] Fixed the html schema dump code in DBStore.java

Oops.  DBStore had my home directory path hard-coded when it
should have been using the ganymede.htmldump property.  Fixed.

9. [SERVER] Fixed a bug preventing creating new object types in develop mode

The server's schema editing code had a bug that caused it to reject
the creation of new object types when the server was run with -develop
on the command line, which allowed for the creation of new universal
fields.  Not a bug that anyone else should have run into, but some
aspects of this bug had the server doing some unnecessary extra work.

10. [CLIENT] Changed date representation in the query table

The query table will now use 4 digit years when showing dates.

11. [CLIENT] Fixed Calendar GUI

Previously, viewing an object that had date fields in it was not
handled properly.. the date field in most respects did not act
properly (clear button, calendar popped up in edit mode, etc.).

Fixed bug in JPanelCalendar which caused the calendar's year field not
to be refreshed properly upon rejecting a date as out of range.

12. [CLIENT] Fixed stupid lingering 'working guy' window bug

Fixed the problem with the 'working' internal frame not being properly
disposed of, and with it being hidden behind existing windows when
created.

13. [CLIENT] Redesigned query dialog

The querybox has been redesigned for clarity and user-friendliness.

The querybox now allows the ownerlist field to be searched on.

14. [SERVER] Optimized memory handling for strings

All strings loaded into the database are now interned(), trading
database load time for memory/runtime efficiency.  Not sure that this
makes a noticeable difference, but it will be of some help.

15. [CLIENT] Fixed dialog placement and sizing errors

The JCenterDialog placement code was broken if the dialog was larger
than the frame parenting it.  All Ganymede dialogs should now always
be entirely visible on screen.

The JCenterDialog's pack() method improperly adjusted the size of
centered dialogs, causing the edges of centered dialogs to be too
small.  All dialogs should now be properly sized on NT as well as
UNIX.

16. [SERVER] Empty strings are considered undefined in StringDBField

The server's required fields logic wasn't detecting an empty string (a
string equal to "" rather than null) as an undefined field, which it
should do and now does.

17. [SERVER] Improved error reporting paths in server

Changed the verifyNewValue() methods in DBField and DBEditObject
to return a ReturnVal so that those methods can pass back detailed
error dialogs to the user.

18. [SERVER/ADMIN CONSOLE] Added more information to admin console

Added a column to the active user table to show how many objects each
user is actively editing, to help track actual use.

Added a column to the task table to show when each task was last run.

-------------------- Changes from 0.96 to 0.97 -------------------

RELEASE DATE: February 11, 1999

1. [DISTRIBUTION] Fixes to the distribution set

There was an error in scripts/sync_tree.admin.in.. it didn't include
the NameSpaceEditor class required by the admin console's schema
editor, so editing namespaces in the schema editor was broken in 0.96.

Thanks to frederick.j.dickey@boeing.com for reporting this.

2. [DOCUMENTATION] Fixes to the customization guide

The DBEditObject customization guide has lots of references to javadoc
pages, but the method links weren't properly constructed for use with
the 1.2 javadoc output format.  You should now be able to click on
method names in the customization guide and be taken directly to the
method docs.

Brought the guide's content up to date with recent changes to
DBEditObject.

3. [SERVER] Amended journal loading code for production mode

The journal loading code in the Ganymede server now simply complains
politely to stderr if the journal is truncated inappropriately, rather
than throwing an IOException.  This allows the server to recover
gracefully if the server was killed while in the middle of writing a
transaction to its journal.

The Ganymede server no longer keeps the old journal files around, but
rather just keeps a single back-up.  While it was entertaining doing a
hexdump on old journal files to see what had been done, it cluttered
the db directory more than being of any use.

4. [SERVER] Changed how file backups are handled

Previously, all of the schema kits' builder tasks copied individual
files to file.<date> when the builder task was re-run.  Now any time
a builder task is executed, the existing output files are zipped into
a file named <date>.zip in an 'old' directory in the output directory.

Actually, didn't modify all of the kits.. I didn't bother to modify
the ganymede.old kit, which is really in need of a major overhaul.

The ganymede.db file itself is now archived when the newly created
archive task is run (on command by an admin console currently), or
when the server starts up with a dirty journal.

5. [SERVER] Enhanced Task Management

The server's task scheduling system was basically replaced.  The old
'Builder Task' object type is now a generic 'Task' type, with support
for editing scheduling parameters directly from the Ganymede client.
You can now add, remove, or tweak any task's scheduling parameters
from the Ganymede client.

Previously, of course, all but the builder tasks were configured by
hand in Ganymede.java.  Now it will be possible for Ganymede adopters
to have total control over task registration and scheduling without
having to edit code.

The downside to this is that the server will not have the 'standard'
tasks scheduled unless the ganymede.db file you are using has the
tasks registered.  

Most importantly, the change from Builder Task to Task object types is
an incompatible change from 0.96 and previous releases.  You will need
to start from scratch with the schema files included in the Ganymede
0.97 release in order to get the new Task object definition that the
server now requires.  Or, if you are particularly enthusiastic and
don't want to lose data already in Ganymede, you could use the schema
editor to bring your pre-0.97 datafile into compliance with the 0.97
Task object schema.

Generally, I am not committing to a freeze on the basic schema
definition until 1.0.  I don't expect any more incompatible changes to
the basic schema, but no promises until 1.0.

See doc/server.html for a guide on the new task scheduling system.

6. [CLIENT] Better taskbar icons

Brian reworked the taskbar significantly, with bigger and nicer
taskbar icons.  The dialogs brought up when the toolbar buttons are
clicked have been reworked a bit to be more distinctive.

More work coming to the client's GUI in 0.98.

7. [CLIENT] Fixes to date GUI code

The date selector dialog now properly shows the time of day set in a
date field.  You could set the time of day before, but upon reloading,
it would not be displayed properly.

-------------------- Changes from 0.95 to 0.96 -------------------

RELEASE DATE: January 29, 1999

1. [DISTRIBUTION] Fixes to the distribution set

Added the missing calendar.gif used by JdateField.  Added missing
up.gif and down.gif used by JpanelCalendar.  Added doc/buildjavadoc to
automate building of javadocs.

Added a -develop option to the configure script, to allow doing builds
in a CVS checkout directory, with the results of compiles put in a
location outside the checked out tree.  For use when developing and
maintaining Ganymede.

2. [SERVER] Fixed bug in query engine

Queries that combined embedded and non-embedded fields would cause
the server to throw an IllegalArgument exception, complaining about
a DBObjectBase being locked with an extantLock.

Made the query engine a bit more regular with respect to dump()
vs. query().  Made things a bit safer.  Improved the server's handling
of a forced disconnect of a user who is executing a query.

3. [CLIENT] Fixed bug with open object dialog and inactivated objects

The client displays inactivated objects in the tree with "(inactive)"
added to the end.  The dialog brought up when clicking on the Edit,
Delete, or View buttons on the toolbar were including the "(inactive)"
bit when brought up with a tree node selected.

4. [SERVER] Made GanymedeExpirationTask more robust

Previously, the Ganymede Expiration Task would be unable to commit
its transaction if, by removing objects from the database, other
objects were left with empty fields that are normally mandatory.

Now, the expiration task will commit successfully, possibly leaving
some objects with empty invid fields that would ordinarily not be
permitted.  This is the most straight-forward way of handling things
like systems with required user fields, which would otherwise have to
be automatically removed, a much dicier prospect.

Probably need to add a feature to scan the database for objects which
do not satisfy the required-fields check.  Any time an admin edits
an object that doesn't satisfy the check, the user will be required
to fix the object before that transaction can be committed.

5. [SCHEMA] Fixed the gasharl schema's user inactivation logic

The userCustom object in the gasharl schema was not properly
differentiating between the case of wizard-led inactivation and
automated inactivation in handling checkpointing and rollback.

Note that I'm not really maintaining the 'gash' schema at this point..
I'm concentrating on getting gasharl to the point where we can use it
here in the lab.  At some point someone is going to have to take on
the task of doing a generic DNS schema that lots of people can easily
use, but it's not me right now.

6. [SERVER] Added GanymedeValidationTask

Added GanymedeValidationTask, a task that scans through the entire
database and reports on any objects which are missing ostensibly
required fields.

7. [ADMIN CONSOLE] Added a clear log button

Added a clear log button to the admin console, to allow admins to
reset the log display on the admin console.

8. [CLIENT] Various cosmetic tweaks

Mike did a nice help system, with index and what-not implemented in
HTML, but we never wrote any content for it, so I've taken the help
menu item out of the help menu for the time being.

Put the release info and copyright info in the about.. dialog.

There are a couple of places in the client that were throwing
NullPointer exceptions due to Swing's choice of behaviors.  We were
catching it, but reporting it to stderr.  Now we just stay silent
about it.

Modified the glogin applet so that it gives a better appearance when
invoked in a web browser.

9. [SERVER] Upgraded to gnu regexp 1.06

The gnu regexp classes used in the server have been updated to version
1.06, the 18 November 1998 release.

-------------------- Changes from 0.94 to 0.95 -------------------

RELEASE DATE: January 22, 1999

1. [DISTRIBUTION] Final distribution preparation

Some more tweaks to the build scripts.  Added some more README type
files. Changed COPYRIGHT to a declaration of the GNU General Public
License.  Added GPL boilerplate to all source code.

-------------------- Changes from dev6a to 0.94 -------------------

RELEASE DATE: January 21, 1999 (internal)

1. [CLIENT] QueryBox improvements

The client was broken when it came to submitting requests for a
membership test on vector fields.  This caused the server to always
return empty results when querying on invid vector fields.

Also, the querybox now just prompts for the label of an invid to match
against, rather than forcing the user to scroll through a (possibly
huge) list of possibilities.  The user can actually use any string
comparator on simple scalar invid fields.

Regular expressions can be used on vector string and invid fields
using the 'Contain Matching' operator.

The list of available object types and fields to search on is
now sorted.

2. [SCHEMA] Fixed gasharl schema to expand group ownership privileges

The gasharl schema now allows an administrator who has privilege to
edit a group to place any user in that group, even if the
administrator would not normally be able to edit those users.

3. [CLIENT] Icons shuffled

The tree no longer uses the icons from the toolbar.

4. [CLIENT] Permissions editor now uses a hybrid table/tree GUI.

Brian O'Mara has made the permissions editor much spiffier, by using a
hybrid table/tree Swing GUI component.

5. [DISTRIBUTION] Source included

We've spent the last couple of weeks reworking our build scripts and
getting everything into CVS so that we can release ganymede with
source code and allow people to tweak and build everything themselves.

-------------------- Changes from dev6 to dev6a -------------------

RELEASE DATE: December 4, 1998

1. [CLIENT] Fixed another long-standing table rendering bug

The table code had an obscure bug that would cause the vertical lines
to be misdrawn if the table's vertical height got too big, either
through having a lot of rows, or by having a lot of word-wrapping.

2. [CLIENT] Fixed tooltips on vector panel element wrappers

The 'expand this element' and 'close this element' tooltips were
reversed after an element was first opened.

3. [CLIENT] Made the QueryBox pop down calendars

Basically took care of the problem handled in change dev6.10 in the
query dialog.

4. [SERVER] A number of fixes relating to schema editing

There was an opportunity for field ordering changes to not be kept..
it turned out to be a bug with wider implications, so a fair bit of
code was changed to make things work better.  Turned off some
debugging which should make schema editing go faster.

5. [SERVER] Changed the permissions inheritance system

Previously, the default role's Objects Owned permissions bits were
inherited into all other roles.  This is inappropriate, as it might
be desirable to have an admin who has less power over a broad set
of objects owned by a linked object group than end-users have over
themselves and other implicitly owned objects.

That is, for all admin personae other than supergash, permission to
mess with object types and fields in objects owned must be explicitly
granted by a non-default role.  Default privileges over non-owned
objects are still enjoyed by all, and end-users still get the
'default' objects owned privilege over their implicitly owned objects.

6. [CLIENT, ADMIN CONSOLE] Replaced Homer and Krusty with custom icons

Brian O'Mara has done some really nice work on the icons for Ok,
Error, and Question in the client and admin console.

7. [CLIENT] GUI Calendar fixes

Previously, the GUI Calendar object used in the client was not able to
handle a non-set date.  In addition, the calendar did not properly
reset itself if the user hit a date button that was rejected by the
server.  These have been fixed, and the client's datePanel class now
directly clears the calendar rather than displaying a 'This date will
be cleared when the transaction is committed' message.

8. [SCHEMA] gasharl schema user expiration limitation implemented

The gasharl schema will now properly restrict changes to a user's
expiration date in keeping with the limits set in the user's category.
User's with mandatory expiration dates will not be able to be cleared,
nor set too far in the future, relative to the current date.

9. [ADMIN CONSOLE] Revised console applet to simplify login

You can now hit return in the password field of the admin console
applet to log in.

10. [CLIENT] Changed code for text fields

We now use a custom DocumentModel to filter keystrokes in the client's
text fields, which is more reliable, works properly in JDK 1.2rc2, and
will properly handle cut and paste text entry.

11. [CLIENT] Rewrote permissions editor

The permissions editor is now based on the Swing JTable class,
providing better performance.  The code is much cleaner now.

-------------------- Changes from dev5c to dev6 -------------------

RELEASE DATE: November 9, 1998

1. [CLIENT] Replaced the 'click' menu on the scalar invid chooser fields

Replace the confusing 'click' menu with a pair of buttons to view and/or
create a remote target for a scalar invid field.

2. [CLIENT] Modified the status label handling

The status bar at the bottom of the client will now be automatically
cleared after 5 seconds by default, to make the status label less
confusing.

3. [CLIENT] GUI Tweaks

Some new icons, tweaks to dialogs, fixes to a few graphical glitches.

4. [CLIENT] A few major fixes to table code

The table code had a horrendous bug that made the table rendering
routine take forever with large datasets.  All table operations on
large tables should be very much faster now.

A number of memory and speed optimizations were made along with the
bug fix, probably of minor impact, but maybe not.

Fixed a couple of edge-case rendering problems in both the table and
the tree that could screw things up if the vertical or horizontal
scrollbar was set to max and then the table/tree was grown to a larger
size, but not large enough to get rid of the scrollbars.

5. [CLIENT] Fixed date bug in QueryBox

The JdateField and JpopUpCalendar classes had a problem such that
if the JdateField had no callback set, the JpopUpCalendar would
always complain that the date entered was unacceptable, which broke
things in the QueryBox.

6. [SERVER/CLIENT] Made the DumpResult class more memory efficient

In what is probably at best a fairly minor aid to garbage collection
on the server, the DumpResult class used to pass tabular query results
from the server to the client has gained the ability to self-dissolve,
making GC go quicker if things get tight while handling a query.

7. [CLIENT] Fixed re-entrancy problem with JstringField, JnumberField

The GUI fields used in the client's object editing windows had a
problem wherein they could trigger a callback to the server several
times for a single change, if the focus is taken back and forth from
the GUI field whose changed triggered the callback.  This was a
particular problem with changes to fields that triggered wizards,
because the focus transition between the wizard dialog and the main
client window could cause the callback to be re-issued repeatedly.

The focus/callback handling code in JstringField and JnumberField have
been made safe for re-entrancy.

8. [SERVER] Fixed admin persona rename on user rename

Fixed a bug in the adminPersonaCustom class so that the label for
adminPersona objects are properly refreshed when the attached user
is renamed.

9. [SERVER/CLIENT] Added regexp capability to the server's query engine

The dev6 server takes advantage of the gnu.regexp package to provide
regexp based string match capability in the server's query engine.

10. [CLIENT] Cleaned up auxiliary windows on frame close in client

The client now closes any date field calendar windows when the
containerPanel held in a object editing window is closed.

11. [SCHEMA EDITOR] Made some dialogs more descriptive

For instance, when you go to delete a field in the schema editor,
the confirmation dialog mentions what field it thinks you are trying
to delete.

12. [INSTALL SCRIPTS] Added installClient2.perl for installing the client under 1.2

The installClient2.perl script is provided to install the client on
systems using the 1.2 JDK, which includes the Swing GUI library
required for the operation of the Ganymede client and admin console.

-------------------- Changes from dev5b to dev5c -------------------

RELEASE DATE: November 2, 1998

1. [SERVER] Fixed bug in GanymedeWarningTask

The GanymedeWarningTask class had a bug such that when it went to
report on an object's incipient removal, it would throw a
NullPointerException.  The task scheduler did properly clean up after
itself, but no warnings about incipient removal were sent.  Fixed.

2. [CLIENT] Fixed buttons embedded object wrapper

Previously, the buttons on the blue embedded object wrapper did this
ugly flashing thing when you clicked on them.  No more.  Brian O'Mara
did nice pressed/not-pressed versions of the expand/contract icon, and
figured out how to make them not be surrounded by the brown yuck.

3. [CLIENT] Set menu hot keys for all the menus

Some of the menus in the client had no hot-keys associated with them.
I set hot keys for most of the menus.. the version of Swing in
JDK 1.2 RC 1 has a bug that makes it impossible to give an item in
a menu the same hotkey as the menu itself has, so I didn't set menu
items where it would naturally lead to a conflict.

4. [CLIENT] Improved open/close box handling in tree, rendering

Previously, the tree open/close boxes were handled by the tree when it
received the mouseClicked() signal.  Now the boxes are handled on the
mousePressed() signal, which happens faster.  It seems that the
mouseClicked() and mousePressed() handling were confusing each other
occasionally before.

Also, the tree would only render rows that it could fully display,
leaving a bit of empty space at the bottom of the tree, depending
on where the scrollbar was with respect to the division point between
rows in the tree.  This has been fixed.

5. [CLIENT] Reinstated applet.destroy(), made the client respond to disconnect

Change dev5b.8 turned out not to be practical with the JDK 1.2
plug-in, as it will halt the plug-in if the browser leaves the
applet's page, regardless of whether the destroy() method does
anything or not.  So, I reinstated the destroy() clean-up method to
help insure a clean logout.  This is unfortunate for users with the
1.1 plug-in, but the 1.2 behavior is quite arguably correct, so
we'll just request users running Ganymede in a browser not to leave
the page while they're running it.  At least now they'll get very
clear feedback when they do.

Made the client able to respond properly to disconnect commands from the
server, even when running as an applet.  This change makes the disconnect
works properly under the Java 1.2 security model.

6. [CLIENT] Intercepted client's main window closing

Now, when you click on the window manager (or Windows') close box to
shut down the main client window, it will handle that in the same way
that it handles the logout menu item.

7. [CLIENT] Fixed title for created object panels

This is just a tweak to the dev5b.3 change.

8. [CLIENT] Made the persona combo not show up if the user has no personae

The persona selector combo box will no longer appear if a user logs
into the Ganymede client who has no admin personae attached to his
user account.

9. [CLIENT] Made the cancel button close all windows in the client

Before, clicking on cancel would close just the editing windows in the
client.  This could be potentially misleading to the user, as view
object windows can be left displaying the status of things as they
were during the transaction which was since aborted.  The commit
button will continue to leave up the non-editable windows.

-------------------- Changes from dev5a to dev5b -------------------

RELEASE DATE: October 28, 1998

1. [SCHEMAS] gasharl schema fixes

The gasharl schema included in dev5a did not properly have the custom code
to manage the user category object specified.

The system object's fieldRequired() logic did not check the associated
system type to see if the associated user field was required.

Both fixed.

2. [SERVER] Took out limit variable from GanymedeServer

The arlut.csd.GanymedeServer class had a 'limit' parameter in its
constructor, ostensibly for allocating space for a specific maximum
number of concurrent clients.  In fact, this parameter didn't actually
do anything and so it was removed.

3. [CLIENT] Titlebars in all windows now include type of object

There were a number of cases in which object panels would pop up
without any indication of what type of object was being displayed or
edited.  This has been fixed.

4. [SERVER] Fixed permissions checking for object viewing

In dev5a and before, the server could throw an
IllegalArgumentException if the user tried to view an object that
contained fields that the user did not have permission to see.  This
has been fixed.  The server will now just omit those fields from the
FieldInfoVector passed back to the client.

5. [CLIENT] Added ARL logo

I spent some time playing with gimp, to fancy up the login window,
and to let people know where ganymede came from.

6. [SERVER/CLIENT] Optimized memory usage for query handling

In dev5a and before, the client can take an enormous amount of
memory in processing a set of query results from the server, as
a result of inefficient memory usage in java.lang.StringBuffer().

The code used by the client to process query results now uses a
modified StringBuffer() designed to be far more memory efficient,
so the client should be able to handle much larger queries.  Truly
large result sets may still be a pain to handle in the table, speed-wise,
but the client shouldn't just crap out trying to digest the results
from the server.

In addition, the client now traps any errors in query processing and
will clean up the 'guy at work' window if the query fails for some
reason.

7. [SERVER/SCHEMAS] Fixed embedded object creation logic, pulled it into DBEditObject

Previously, the gash and gasharl schemas included code in the
userCustom and systemCustom objects to handle creating embedded
objects.  That code was broken, as it did not go through the normal
permissions checking to see if the user had permission to create the
object.  Now, in order to create an embedded object of a given type,
the user must be granted privilege to create that kind of object.
Having editing authority over the embedding field is no longer
adequate.  This change makes it possible to grant permission to edit
or delete entries in an embedding field without necessarily granting
privilege to create new entries in the field.

In addition, the code to do the creation of embedded objects was
essentially the same in the gash and gasharl userCustom and
systemCustom classes, so I pulled the code up into
DBEditObject.createNewEmbeddedObject().  Customizers can still
override createNewEmbeddedObject() in their custom DBEditObject
subclasses, but the normally expected behavior will be handled by
DBEditObject if they do not.

8. [CLIENT] Made the client applet not log out when the browser leaves the page

Previously, the client would log out as soon as the browser that it
was running in left the applet page, even though the client's other
windows were left up.  Now the client won't disconnect from the server
until forced to by the browser closing.  This was done by having the
glogin applet ignore both the stop() and destroy() methods in JApplet.
This probably wouldn't be the right thing to do if the client were run
directly out of a browser, but when using the Java plug-in, this lets
us keep going until the browser is shut down.  The server is able to
automatically disconnect clients that go inactive, so it isn't
strictly necessary that the client do a clean logout.

9. [CLIENT] Fixed the StringDialog class

The dialog used for entering a persona password when changing personas
was some broken, in that if you entered your password and hit return
it would fail, and in that on Windows, the dialog would come up with a
big scrollbar across the dialog.  Both of these have been fixed.

This change will also make it possible to hit enter in the last field
in a wizard to progress to the next.

One possible detriment to this change is that the main dialog class
used in the Ganymede client no longer includes a ScrollPane.. this
means that if a wizard dialog is given too much stuff, the dialog
might not be able to fit on the user's screen.. but no wizard dialog
should have that much stuff anyway.

Also made it so that if the StringDialog window is closed without
cancel being hit, the dialog treats that as a cancel request.

10. [SERVER] Fixed embedded object query handling

In dev5a and prior, the server would not return proper results if a
equality test query was made on an namespace-managed field in an
embedded object.  This caused corrupted results if you tried to
search for a system by IP address in the gash and gasharl schemas.

-------------------- Changes from dev5 to dev5a -------------------

RELEASE DATE: October 19, 1998

1. [SERVER/CLIENT] Added support for date, multiline text fields in dialogs

The dialog system used to pass wizards from the server to the client
has been radically simplified, and now depends on the Java
serialization system rather than its own serialization /
de-serialization code.

The server can now pass multiline text fields and date fields to the
client for use in wizards.

The GUI calendar/date field class has been reworked a bit so that
the system is more robust when dates outside of the defined range
are entered.

2. [SERVER] Reworked database field handling

Made the server more robust in the face of changes made with the
schema editor.  Converting fields in use between vector and scalar
will no longer cause the schema/db dump to fail, but changing a
field between scalar and vector will cause any instances of that
field loaded in the database to be dropped.

All of the DBField subclasses now use explicit isDefined() and
setUndefined() methods to handle tracking whether a field is
defined or not, rather than using a defined flag.  This makes
things much more flexible and robust, as the isDefined() method
can check things out at any time and report on the status of the
field, rather than having to try to properly update the defined
flag everytime anything could possibly affect it.  Like changes
to the schema, say.

3. [SERVER] Made DBEditObject.{getSession(), getGSession(), getOriginal()} public

This change allows custom wizard code to have more access to the
Ganymede server for examining state and making changes, etc.

4. [SERVER] Fixed GanymedeWarningTask

The Ganymede warning task had an error in it that caused it to throw a
NullPointerException when it came time to warn about an impending
object removal.

5. [SERVER] Added support for generic transactional mailouts

I added support in the Ganymede transaction class (DBEditSet) for
doing generic mailings associated with a transaction, using the
logMail() methods.  Some changes made to DBLog and DBLogEvent to go
along with it.

This code isn't the cleanest, as the existing event handling code has
been adapted for handling generic mailouts rather than reworking the
logic to use different kinds of events with a base class and
subclasses, but will have to do for now.

6. [CLIENT] Substantially simplified, reworked icon tracking for nodes in tree

Previously, the client maintained an extensive set of hashes to try to
synchronize changes to objects made by the client to the graphical
representation of nodes in the tree.  This has been changed.  Now the
client just asks the server for the status of objects after a transaction
has been committed, rather than trying to track the changes by guesswork.

The point of these changes is to make the client much more robust in its
synchronization with the server, and to make it easier to maintain.

The cost is that whenever an object is manually inactivated or
reactivated, the client will do a round-trip to the server to verify
and update the status of the object, and whenever a transaction is
committed, the client will spend time checking the status of all the
objects touched by the transaction.

All of this was due to the need to have the client be able to
react appropriately if server-side wizards set an expiration date
on a user, etc.

The client still uses a client-side cache to handle reverting the icon
for deleted/created objects on transaction cancel.

7. [SERVER] Added Session.queryInvids()

This provides a high-speed, non-blocking path that the client can use
to get a status update on a specific list of objects.  This is to
support #6, above.

8. [SCHEMAS] Fixed writeUserLine in builder task

In the Linux and BSD schemas, the system would throw a null pointer
exception when it went to build the passwd file if a user had
a home phone number but no office phone number registered.

9. [SERVER] Fixed InvidDBField.unbindAll()

The object binding logic erroneously assumed that all invid fields
potentially targeting a backlinks field were vector fields.  This
could lead to problems when deleting objects with a non-empty
backlinks field.

10. [SCHEMA] Added 'gasharl' schema

This is a variant of the gash schema that includes support for some
of the extended user_info fields we use here at the lab, including
user categories, user expiration dates, and social security number
handling.

-------------------- Changes from dev4f to dev5 -------------------

RELEASE DATE: October 8, 1998

1. [SERVER/SCHEMA EDITOR] Enhanced the password field

Password fields can now be configured in the schema editor to remember
plain text passwords while the server is up.  That is, a password
field can be configured such that when a password is entered into
that password field and, in the case of the password field in the
user account object, whenever a password is authenticated for
Ganymede login, the field will remember the plaintext password in
memory.

This is intended to be used to support NT and UNIX integration.
Currently, ARL is synchronizing our UNIX passwords to our NT primary
domain controller by running a Perl script on NT via RSH.  The Perl
script is fed a list of changes, including the passwords for the NT
users.  Because NT can't use UNIX-crypt()'ed passwords, it is
necessary to include the plaintext of any passwords that have changed.

Since the beginning, the Ganymede server was able to handle passwords
using either UNIX's crypt() password hashing function or plain text
passwords.  Now, a password field can store both in memory (if both
crypted and plain-text are selected for a password field in the schema
editor), but plaintext passwords will never be saved to disk if the
crypted option was also selected.  That is, Ganymede uses crypted
passwords for its own authentication and unless it has NO OTHER
CHOICE, it will only save the encrypted passwords to disk.  In addition,
the Ganymede server provides no means for a client to get access to
the plain text of a password stored in the server.  Only local code
directly linked with the server (built tasks) can get access to the
plain text of the passwords.

The idea is that the NT primary domain controller is perfectly capable
of remembering the NT-hashed passwords once set, and Ganymede need not
risk security by keeping the plaintext passwords around on disk.

By default, all Ganymede passwords are encrypted using the UNIX crypt
function.  An adopter must explicitly configure a password field to
have the server retain plaintext passwords in memory during execution.

2. [EVERYTHING] Updated all code to work with JDK 1.1.7, Swing 1.1b3

Swing 1.1 beta 3 has had all of the Swing classes moved from
com.sun.java.swing to javax.swing.  For compatibility with the future
releases of Swing (beta and otherwise), all of the Ganymede clients
and admin console code has been moved over to the javax.* package
naming.  This means that from this point on, the Ganymede client will
require Swing 1.1 beta 3 or later.

3. [CLIENT] Fixed invid/string vector selector so that pop-up menus work again

At some point the right mouse button stopped selecting items in the
Swing JList class.  This broke the popup menu in the client's
string/invid selector.  The problem was that the lack of selection
caused the right-mouse-button pop up menu to not be able to identify
the item in the list that it needed to pass up to the containerPanel.

4. [CLIENT] Fixed scalar invid chooser refresh

The JInvidChooser GUI component's refresh logic, as changed in dev4f,
wasn't taking into account the possibility that an invid field's
choices() might not include the value currently set in the invid
field.  This left the invid chooser blank after a change was made, as
the server immediately requests a refresh of the field.

5. [CLIENT] Tweaked the open object/create object dialogs

The Swing libraries, up to and including Swing 1.1 beta 3, have some
serious problems with pop-up menus in dialogs.  That is to say, Swing
is currently incapable of displaying a pop-up menu that goes outside
of the dialog.  In dev4f and before, we tried to encourage Swing to
try to do this, with the result being that the pop-up menu just gets
truncated in the dialog.  In dev5, we have modified our dialogs with
pop-down menus so that they don't try to extend the menus past the
bounds of the dialog.

All of which is to say, we've made it look a _little_ bit better now,
but we're going to have to remember to keep an eye on later Swing
releases and try to make this a bit better when we can.

6. [SERVER/CLIENT] Field choice listing improved

Previously, the list of choices provided when one edited an invid
field only listed the set of objects that could be directly edited,
and did not take into account the DBEditObject anonymousLinkOK()
method that can provide for an exception to the normal editability 
determination.  Now, objects that can be linked by virtue of the
remote object type's anonymousLinkOK() method will also be shown
in the client's list of possible choices.

The server and client have been elaborated a bit so that the client's
results caching system won't be confused by this.

7. [SERVER/SCHEMAS] Removed the 'throws RemoteException' from DBEditObject constructors

Part of change dev4b.11 (the big optimization) was to make it so that
the DBObject and DBField classes no longer subclassed from
java.rmi.UnicastRemoteObject, which automatically exported them on
creation.  Since this change, it has not been necessary to have the
'throws RemoteException' any more.  Since the optimization has been
working perfectly for over a month now, I've gone ahead and gone
through the code and removed these vestigal code bits.

I also removed the try..catch.. that was surrounding code in the
server that was responsible for creating instances of DBEditObject,
as well.

The upshot of this is that you'll want to use the new custom jar
file corresponding to whatever schema kit you've been testing with,
and if you've written any custom DBEditObject subclasses, you'll
want to go ahead and lop the 'throws RemoteException' off of your
constructor definitions.

The documentation for DBEditObject customization has been amended to
reflect the dropping of the 'throws RemoteException' from the
constructors.

8. [SERVER] adminPersona custom code modified

The plug-in for the admin persona object has been modified so that the
user field is not presented for editing for the supergash and monitor
personas.

9. [SCHEMA] Fix-ups to the GASH schema

The GASH schema was not correctly updated in dev4f.  The
ganymede.schema file included with the GASH schema kit now has all of
the fields required for the new admin persona schema.

10. [PASSWORD] Brought the password client(s) up to date

The password client has not been up-to-date with changes to the server
over the last several releases.

-------------------- Changes from dev4e to dev4f -------------------

RELEASE DATE: September 28, 1998

1. [SCHEMA EDITOR] Minor fixes

Made it so you can't set a category's title to the empty string.  Made
it so the category name string field will prevent entering a '/'
character.

2. [CLIENT] Client Fixes/Enhancements

The client will now put up the same 'guy working' query progress
window while the client is working on responding to a 'List editable'
or 'List all' command in the tree, to emphasize that listing is using
the same mechanisms as querying, and will result in the same kind of
report window.

3. [SERVER] Fixed Bug In Owner Group Handling

Ugh.  The server code was accidentally messing with the list of owners
in an owner group outside of the normal change process, creating an
improper self-reference in owner group's owner list.  This basically
put an invalid self-reference in a newly created owner group's owner
list.

4. [SERVER/CLIENT] Modified admin Persona object

The admin persona object class now includes a hidden label field which
it uses to maintain uniqueness among persona objects.  The server no
longer requires you to enter <name:descrip> for an admin persona.
Instead, you choose the user with a combo box and type in a brief
description.

The client once again allows personas to be created directly from
the tree and/or toolbar.

5. [CLIENT] Fixed JComboBox Update Logic, Rescan Logic

Previously, if the client ever got it into its head that it needed to
update the contents of a very large JComboBox, it would take a very
long time.  As in, on the order of half an hour for a list of 800
users.  It'll now happen pretty much instantaneously, as it ought.

Removed a couple of redundant client updates that could happen on an
invid chooser. This should speed up by a good margin operations that
required the client to update fields.

6. [SERVER/SCHEMAS] DBEditObject methods changed

The finalizeSetValue(), finalizeSetElement(), finalizeAddElement(),
and finalizeDeleteElement() methods in DBEditObject have been
redefined.  Now, instead of returning a boolean indicating approval
or disapproval of the operation, they return a ReturnVal.

This allows the finalize*() methods to return error dialogs to the
client, and to pass back rescan information from contingent operations
that the finalize methods may perform (for cascading changes, etc.)

All of the custom code included in the schemas distributed with dev4f
have had their finalize methods changed to return the appropriate
return type.

-------------------- Changes from dev4d to dev4e -------------------

RELEASE DATE: September 21, 1998

1. [CLIENT] Tooltips Not Set If Blank

In 4d and prior, the client would set tooltips on all field
components, even if those components did not have comments registered.
This left mysterious little blue boxes floating around the field.  Now,
the client will only set tooltips if the comment for that field is
actually defined.   Thanks to Matt Bush for pointing this out.

2. [CLIENT] Toolbar added, persona menu moved, dialogs added.

The client now has a nifty toolbar, both to facilitate users creating
new objects intuitively, and to allow for easier single-button
operation on Macs and the like.

3. [CLIENT/SERVER] adminPersonae may no longer be created out of context

Previously, it was possible to use the tree in the client to create
new admin Persona objects.  This was an oversight.  Admin Persona
objects should only be created in the context of a user, using the
create button in the Personae panel, which takes care of linking
the persona to the user, behind the scenes.

4. [SCHEMA] Parser, script fixes for linux and bsd schemas

Fixed up the sample builder scripts, and modified the parser for Users
so that trailing commas in the gcos field won't break things.

5. [CLIENT/SERVER] Added support for a message of the day, other messages

We added the property ganymede.messageDirectory to the server.  This
property is set by default to <installdir>/db/text.  Files placed in
this directory can be retrieved by the client using Session.getMessage()
and Session.getMessageHTML().  So far, the client only ever looks for
motd.txt and/or motd.html in this directory.

6. [CLIENT] Pruned Client's Category Tree Display

The client will now omit category nodes in the server's category tree
if the category has no siblings.  That is, the 'Categories' node will
no longer show up in the client, and if the user is logged in without
privileges to see the Admin Level Objects or Configuration categories,
they will just see the user level object subtrees at the top level.

-------------------- Changes from dev4c to dev4d -------------------

RELEASE DATE: September 9, 1998

1. [SCHEMA] Added Linux Schema, Revised BSD Schema

We have added a simple Linux schema, which is designed for basically
managing users and groups on a single system.  The user
inactivation/reactivation logic from the GASH schema has been left
out of the linux schema.  Unlike the BSD schema, the Linux schema
does not currently support the use of shadow passwords.

The linux and bsd schemas both have sample linux/bsd builder scripts
that you can install.  We've tested the linux_builder.sample script on
RedHat Linux 5.1, the bsd_builder.sample has not yet been tested.

Using the linux schema with the linux_builder.sample script installed,
we have got Ganymede actually creating real user accounts on RedHat
5.1.

2. [INSTALL] Made the installServer script smarter.

The installServer.perl script will now refuse to continue if it
couldn't find java where you told it to look.  installServer will now
give you a brief, customized outline of what you need to do to get
your schema up and running when it finishes installing everything.

-------------------- Changes from dev4b to dev4c -------------------

RELEASE DATE: September 2, 1998

1. [SERVER] System Event Records Initialized On Database Bootstrap

More work to get the database bootstrapping complete.  Now, if you
run Ganymede without a database, in addition to everything else, it
will create the system event objects in the database.

2. [CLIENT] Tree Wasn't Handling Fonts Correctly

The arlut.csd.JTree.treeControl GUI component we're using in the
client and the schema editor was consulting the font specification
passed in by the user of the tree in order to calculate the width
of the tree, but it didn't actually bother setting that font to
render with.  This made the tree width calculations not match the
on-screen rendering, confusing things as to when scroll bars were
supposed to appear.

3. [CLIENT] Number Fields were broken

In dev4b and dev4a, Number fields just didn't work.  This broke
things in the Schema editor, mainly, since number fields don't
tend to show up a lot in the schemas we've been working with,
except for uid's/gid's, which are fixed.

4. [CLIENT] Viewing Persona Panel With No Persona Fixed

In dev4b, viewing (not editing) a user who had no persona attached
would cause a NullPointerException to be thrown on the client.

5. [ADMIN CONSOLE] Schema Editor GUI Changes

The Schema Editor's layout has been improved a bit.

6. [SERVER] Invid and String fields sort values for getValueString().

Invid and String fields will now show up sorted when Doing queries or
lists on the server.

7. [CLIENT] Save File Dialog Expects Swing 1.1 beta 2 or better

The query / object list table in the client gives the user the option
of saving the table to disk in ASCII or HTML mode if the client is
run as a command-line application rather than as an applet in a
web browser.  When this option is chosen, the Ganymede client will
bring up the Swing file chooser to select the filename and location
to save to.  We've made the Ganymede client require the 1.1 beta 2
version of Swing to do this function.  If you are running an older
version of Swing, you won't be able to save files to disk from the
Query Result table successfully.

8. [CLIENT] Improvments to the table code

The table now changes the cursor while you are dragging a pole.
Improvements were made to the optimize column logic.

9. [CLIENT] Query Box Can Be Used To List All Objects Of A Type

The Query Box now has a 'view all objects' check box that you can
use to get a full list of objects that you do/do not have editing
authority over, without having to make up a selection criteria
that all objects should match (User uid > 0, etc.).

10. [DISTRIBUTION] base_classes included again

In dev4b, schemas/base_classes was inadvertently omitted.  This
pre-release includes the source to DBEditObject and GanymedeBuilderTask
to help people interested in writing custom subclasses of these
classes.

-------------------- Changes from dev4a to dev4b -------------------

RELEASE DATE: August 27, 1998

1. [CLIENT] View-only StringSelectors are double width

The StringSelector GUI components are now twice as wide as before 
when they are not being edited.  That is, the single StringSelector
panel will expand to take up the space that would have been given
to the list of choices in an editing context.

2. [SERVER] Owner Groups Now Own Themselves, Implicitly

This change allows owner groups to be self-administering, so that
group administrators (possibly with a special role) can edit the mail
delivery options for object event notification for a group.  This
change also prepares the way for group administrators with a special
role to be able to create sub-groups, and to put their administrators
in these subgroups.

The permissions logic in GanymedeSession can now handle recursive
ownership hierarchies.

3. [SERVER] Roles can be created by non-supergash admins

But the roles created cannot exceed the privileges granted to the
admin that creates the role.

4. [SERVER] Permission Bits Cleaning Implemented

The permission bits system (used by PermissionMatrixDBField) is only
loosely bound to the object/field definitions held in the schema.
Previously, the permission matrix fields would not properly drop
permission entries recorded for object or field definitions that had
been removed by the schema editor.  Now, the database-writing code for
the PermissionMatrixDBField will check all entries for validity, and
omit those entries that no longer have any application to the revised
schema. Permission entries that are redundant or pointless are
filtered out as well.

5. [SERVER] CategoryTransport fixed

The CategoryTransport object passed from the server to the client was
supposed to carry only entries for object bases that were editable by
the end user, and the categories containing such objects.  In dev4a
and prior, the CategoryTransport code that was supposed to make this
determination did a Visibility test when choosing to include Category
definitions and an Editability test when choosing to include Base
definitions.  This made for a confusing set of results in the tree for
non-supergash users/admins.

6. [CUSTOM] Miscellaneous GASH Schema Fixes

Fixed network selection error in interface custom class.  This was
preventing users from being able to create more than one interface
in a system.

7. [CLIENT] Miscellaneous Client Fixes

Fixes in some of the GUI components, and their interaction with the
server to present choices, etc.

8. [INSTALL] Changed the install script to support new schema development.

It has always been possible to install the Ganymede server without
specifying one of the schemas that we provide with the Ganymede
distribution.  Now, if the installer does not choose one of bsd,
nisonly, or gash, the installServer.perl script will go ahead and
install the scaffolding upon which custom code for a custom schema can
be built.

9. [DOCUMENTATION] Documentation on DBEditObject subclassing added.

We've added a lengthy guide to the operation of the DBEditObject
class, and how you can subclass it to implement custom logic
on the server.  A book should probably be written on this topic,
but this guide should prove a useful start on things.

10. [SERVER] Important Fixes In Invid Binding Code

The object linking code now handles 'untargeted' object reference
fields properly, both in binding and in unbinding.  The InvidDBField
code will also properly catch ambiguous link operations resulting from
improperly specified link fields in the schema.

11. [SERVER] *** Major Memory/Speed Optimization ***

Previously, all objects and all fields in the server were subclassed
from java.rmi.server.UnicastRemoteObject, which meant that as each
field and object was created, it was registered as a remotely
accessible object through the RMI system.  Now, all objects and fields
in the server are no longer subclasses of UnicastRemoteObject, but
instead are exported through the RMI system only at the time the
object or fields are accessed by the client.  This reduces the size of
the Ganymede server in RAM by a lot.  With the full ARL GASH database
loaded, the server used to take up anywhere from 93 to 105 megabytes.
After this change, it's down to 40.  Likewise, database loading time
for our GASH database is less than half of what it was.

12. [SCHEMA] Recompiled all schema files to take advantage of 11.

You will need to recompile any custom classes you may have authored,
as they are no longer subclasses of UnicastRemoteObject.

-------------------- Changes from dev4 to dev4a -------------------

RELEASE DATE: August 11, 1998

1. [SERVER] Deleting admin personae now works properly

Before, deleting an admin persona object would cause a null pointer
exception to be thrown, as the code that checked to verify the new
name wasn't expecting a null name.

2. [SERVER] Added more rescan info for client.

In many cases, the server would not properly notify the client of
fields that Wizard code had changed on behalf of the client.  Now,
anytime anyone calls setValue(), setElemet(), addElement(), or
deleteElement() on a field, the ReturnVal returned will include an
instruction to the client to rescan that field.  This is primarily
useful for Wizard code that changes fields on the client's behalf.

3. [SERVER] User names forced to lowercase on login

Previously, it was possible to log in with mixed case or all-uppercase
and have Ganymede not recognize that the user was the same as another
login by the same user for the purpose of tracking the client's name.
Now, whenever a user logs in, Ganymede will track that user by an
all-lowercase version of their name.

4. [SERVER/CLIENT] Server tells Client its assigned id

If a user logs into the server more than once concurrently, the server
assigns each instance a unique name.  The client now asks the server
what that name is, so that you can see which instantiation of the
client matches which entry in the admin console's active user list.

5. [SERVER/CLIENT] String Fields can optionally be multi-line

The schema editor and the client now support multiline string fields,
for cases where an object needs more than a simple TextField can
reasonably provide.

6. [SERVER/CLIENT] CategoryTransport, BaseListTransport fixed

CategoryTransport and BaseListTransport are serializable classes that
transport data from the server to the client.  Both of these classes
included transient (non-transported) references to the GanymedeSession
class for use on the server.  Because we are not using the
RMISecurityManager any longer, the JVM is not able to download the
GanymedeSession class definition when the object is deserialized.  To
get around this, these classes now simply hold a generic transient
Object reference, and do a cast whenever the methods intended to be
run on the server are run.  This allows us to defer the class-loading
on the client until a server-side only method is called on these
objects, which should never happen anyway.

7. [CLIENT] Viewing The Ownership Panel Fixed

In dev4, clicking on the 'ownership' tab on a viewed (not edited)
object would throw a null pointer exception.

8. [SERVER/CLIENT] ReturnVal Rescan Information Reworked

In dev4 and before, the ReturnVal object returned by the server to the
client in response to most operations included information on what
fields and objects should be rescanned.  The design was ad hoc and
unwieldy, however, and has been changed. [...]

9. [CLIENT] String, Number Data Fields Limit Entry Properly

For awhile now, the GUI fields that allow String and Number entry
in the client weren't properly restricting keystrokes to enforce
string length and acceptable character restrictions.

In addition, String fields in the GUI will now size themselves to
reflect the size limit for size-limited fields.  Fields with large
sizes will be limited to 40 characters wide.

-------------------- Changes from dev3c to dev4 -------------------

RELEASE DATE: July 30 1998

1. [SERVER] DBEditObject.finalizeInactivate() no longer assumes removal

DBEditObject.finalizeInactivate() used to throw a NullPointerException
if the inactivated object didn't have its removal date set in the
removalField field.  While this is arguably appropriate, I made the
code resistant to that circumstance.  I may want to change it back
to catastrophic failure.

2. [SERVER/CUSTOM] Radically Simplified Wizard Construction

I moved a lot of the wizard bookkeeping from the individual
GanymediatorWizard subclasses up into GanymediatorWizard.  It's much
simpler to make wizards for DBEditObject customization now.

3. [SERVER] Modified DBEditObject.finalizeRemove() to track rescan.

The server should now properly provide field/object rescan to the
client when the client deletes an object.

4. [SERVER] Rescheduled Garbage Collection Task in Ganymede.

The server used to schedule the Garbage Collection task for 5 minutes
after startup, which always hit us right when we were testing whatever
feature we restarted the server for.  Ganymede will now schedule the
Garbage Collection task for 6 hours after server startup.  The server
will initiate garbage collection when it needs it anyway.. I had just
made it a task to have something to test the scheduler with.  I may
take the GC task out entirely.

5. [SERVER] Fixed bugs in Journal file processing

We ran into some problems with the Journal file logic as implemented
in dev3b.  The journal file format has been reworked a bit, both to
fix some vulnerabilities to failure and to further improve file size
and processing time.

6. [SERVER] Server Properly Reports Inactivated Objects

The server wasn't properly reporting the inactivation, expiration,
and removal of objects.  Now whenever the client does a query on
the server (including for the building of the tree), it will get back
the proper status of the objects.

7. [SERVER] DBEditObject now has default reactivation logic

Previously, the DBEditObject reactivate() method would simply refuse
action, forcing this method to be overridden by subclasses if
inactivation was to be supported.  Now DBEditObject.reactivate() will
go ahead and clear the Removal date if called on an inactive object.
Customizers are still encouraged to override this method to provide
intelligent reactivation.

8. [CUSTOM] Various refinements to the GASH schema

You can now rename a user to a name the user previously had as an
email alias.  You can now inactivate a group in good conscience.  The
fields in the user object have been re-ordered to make entering data
for a new user more straightforward.  The mapEntryCustom code checks
to see if it is being deleted before complaining about an
auto.home.default pointer being messed with.

Added preliminary code in userCustom.commitPhase2() to perform
external actions when a user is created, deleted, renamed, or when
their home directory is moved from volume to volume.  Right now, these
are just stubs, but the logic is there.  Turn on the debug flag and
recompile userCustom.java to get messages about when various external
actions would be taken.

9. [SERVER] Set serialVersionUID on serializable classes

This change will allow the server and client to communicate even if
they are using slightly different versions of the data objects used to
pass data back and forth between the client and server.  It will also
make for a (probably very) slight speed-up in server initialization.

10. [CLIENT] The client will now terminate when killed by the server

In recent versions, the client would not get the hint and die when the
admin console knocked a user off.  Instead, it would display a dialog
reporting the boot, but would keep running, getting all kinds of
exceptions from the server.  Now, the dialog will show up, and a timer
is started.  When the timer counts down to zero, the client will
self-destruct.  The user can, of course, acknowledge the dialog to
shut it down sooner.

11. [SERVER] original field in DBEditObject is now protected

This change allows custom DBEditObject subclasses (out of the
arlut.csd.ganymede package) to get easy access to the original state
of a changed object for comparisons.

12. [SERVER] Server now re-sorts fields after the schema is edited

The server will now properly report the correct order of fields after
that order has been changed by the schema editor.  This worked before,
but only if the server was restarted.

13. [SERVER] Object creation and deletion is now logged

Before, only changes to existing objects were explicitly logged.. now
object creation and deletion is also logged, and can be emailed.
Right now, there is no straightforward way to specify that different
users should get mail when different kinds of objects are created, as
all object creation falls under a single event category.  This is one
problem with trying for the super-generic, customizable event
model.. to handle this properly would involve having a whole sub-tree
under the object creation/deletion/change events, with each object
type being able to have its own notification list, like GASH has.

14. [CLIENT] Embedded objects in newly created objects are opened

Before, when you created a user in the GASH schema, you had to manually
open up the auto.home.default entry to set the user's home volume.  Now
all embedded objects in newly created objects start out opened by
default.

15. [SERVER/CLIENT] The log/history system has been optimized

All of the log code has been heavily optimized, and is now both a
great deal faster and a great deal more memory efficient on the
server.

We're intending to support more general (i.e., non admin or
object-limited) log searching by the client in the next pre-release.

16. [SERVER] Event/Email notification system has been totally revised

GASH's event/mail/logging model had separate event codes for the
creation, inactivation, and editing of objects by their type.  So it
was possible to specify that whenever a user was created, someone in
personnel could be notified.  The code in GASH that manipulated users
was custom-coded to use those event codes.  Ganymede uses a more
generic model, in which the event logging/email system is designed to
work with any kind of object handled by Ganymede.  However, there is
still a need to be able to specify that certain users be notified
whenever an object of a specific type has had a specific operation
performed on it.  So there is now a second kind of event object listed
under Admin-Level Objects, an 'Object Event' object, which lets the
adopter create special email for whenever an object of a specific type
is created, edited, inactivated, deleted, reactivated, etc.  The orignal
event object type has been renamed 'System Event'.

Admin Persona objects now include a field to specify an email address
where email to that administrator should be sent.  If Ganymede is
managing your email database, you won't need to set this field,
but it's there otherwise.

Owner Groups and System Events now have an 'external email list' field,
used when you want email related to those objects to go to email
addresses not contained within Ganymede.

17. [TREE] Significant tree fixes/enhancements

The JTree code had an error in its drag/drop logic when both
tween-dropping and on-dropping were enabled, that made it impossible
for on-dropping to ever occur.  This has been fixed, which corrects a
problem in the schema editor.  I added a moveNode() method to allow
the schema editor to do the right thing in moving shuffling categories
and objects around within the tree.

Made treeCanvas extend JComponent instead of JPanel.. this seems to
fix some responsiveness problems that the tree was exhibiting under
Java Plug-In 1.1 on Win32. (ref. changes dev3 #5)

18. [SCHEMA EDITOR] Fixed lots of bugs in schema editing

Moving object types and categories between categories now works
reliably.  This involved both adding a new primitive to the server,
Category.moveCategoryNode() and to the tree, moveNode().  The
server-side schema editing context does a better job of mapping remote
Base references supplied by the client-side schema editor to the
server-side local DBObjectBase objects.  Basically, schema editing
should be robust and reliable now.  Or at least, much more so.

Forced the schema editor tree to be black on white instead of
black on SystemColor.background.. testing the admin console on a
friend's FreeBSD system showed the ugliness that results if a system
had SystemColor.background set to black.

19. [SERVER/CUSTOM] Pulled classes for critical objects into ganymedeServer.jar

Previously, all subclasses of DBEditObject were packaged along with
the custom schema code.  This was inappropriate, as the server depends
on those classes for proper authentication and logging, and there is
little to be gained by forcing adopters to include those classes in
their customization efforts.  Worse, if an adopter did not select a
schema at install time, no support classes for the permission system
were installed.  Now, all the code that the server _depends_ on for
its own logic is kept safe and bundled.

20. [CLIENT] Fixes to the tree icon logic

There were some circumstances in which an object with more than one
exceptional condition (both checked out for editing and marked for
inactivation, say..) would not have the most sensible icon displayed
for it in the tree.  The client now takes the possibility of multiple
conditons into account and takes the relevance of the various
conditions into account when assigning an icon for the object's node
in the tree.

21. [CLIENT/ADMIN CONSOLE/SERVER] Tweaks for 1.2b4 compatibility

The new security system supported in the 1.2b4 and (presumably) later
releases of the JDK forces a new security model on code that installs
a SecurityManager, in such a way that the code is not compatible
across 1.1 and 1.2, at least as of 1.2b4.  To get around this, the
Ganymede client and server code no longer install the
RMISecurityManager.  There is no practical downside to this, as the
only thing that the RMISecurityManager enabled was the transfer of
executable classfiles between the client and the server, which
Ganymede did not do anyway.

22. [SERVER] Various fixes

a. The fully-privileged internalSession GanymedeSession that the
server uses for its internal operations has had oversight turned off,
to speed things up somewhat, and as an attempt at debugging stuff.

b. Object reference (invid) fields can now lookup a remote object's
label in a transaction, even if the remote object has had its fields
cleared in preparation for deleting that object at transaction commit
time.  This comes into play when the details of a transaction is being
logged to disk at transaction commit time.  One side effect of this is
that if you (say) rename a user and then delete the user in one
transaction, the logging system will report that user <newname> was
deleted, but that <oldname> was removed from account groups, and the
like.  Fixing this would be rather more involved than the payoff would
be worth at this time, I think.

c. Boolean fields are considered to be undefined if they are set to
false.  This makes it possible to edit the schema to remove boolean
fields if all instances of a boolean field are false.  Previously, the
boolean fields would be undefined until someone set them, at which
point they would remain defined, regardless of value.  One consequence
of this is that the logging for boolean toggles may seem
counter-intuitive, with true-to-false transitions recorded as the
field being removed.

d. The database dumper, expiration processor, and expiration warning
tasks won't fire if the schema is being edited.

e. The Ganymede server will never explicitly record an object as
being owned by supergash, since by definition supergash implicitly
owns all objects.  This change reduces the size and memory loading
of the database, but will increase the time it takes to do initial
bulk loading.

23. [ADMIN CONSOLE] Admin Console will exit when server is shutdown

If you use the 'shutdown server' menu option in the Ganymede Admin
Console, the console itself will shut down once the server finishes
its shutdown sequence.

24. [SERVER/CUSTOM] anonymousLinkOK and anonymousUnlinkOK expanded

In order to properly secure privileges to add or remove objects from
owner groups on the server, we have added a new parameter to the
anonymousLinkOK and anonymousUnlinkOK methods in DBEditObject.  This
is the GanymedeSession parameter, so the code can determine whether to
allow the link or unlink based on the identity of the user attempting
the link.  If a custom subclass author does not override the expanded
version of these methods, the old methods will be called, without
the GanymedeSession reference.

25. [SERVER] Ownership security hole fixed

Previously, the Ganymede system depended on the client being
trustworthy when it came to restricting the ability to grant ownership
of objects to an owner group.  The server now checks this operation
against the admin's owner group membership to prevent abuse.

A related change fixes a similar vulnerability in all object-linking
logic.  The server will no longer allow values to be placed in
InvidDBFields if the field is choice-restricted and if the value was
not a choice presented to the client.

26. [CUSTOM] Added bsd schema

Added a simple passwd/group BSD 4.4 compatible schema, analagous to
the nisonly schema, but with support for the BSD 4.4 master.passwd
file format.

-------------------- Changes from dev3b to dev3c -------------------

RELEASE DATE: 17 June 1998

1. [CLIENT] Improvements in the view/edit/delete/inactivate object dialog

 Previously, the view object dialog would only search for objects that
the user had permission to edit.  The dialog is smarter now about what
is appropriate for the different operations.

2. [CUSTOM] GASH, nisonly loader code fixed.

 Ugh.  In dev3b, the GASH and nisonly loader code was simply broken..
the change in create_db_object() and edit_db_object() broke the
directLoader class in both schemas.  I had caught the changes in the
custom_src directory, but not in loader/source.  The loader code
for both work now.

3. [SERVER] Made InvidDBField checkpoint/rollback code issued selectively

 In dev3b, all Invid binding operations was checkpointed, which made
doing bulk-loading far, far too slow.  The bind/unbind checkpointing
is now only done when GanymedeSession.enableOversight is true.  That
is, not during bulk-loading.

-------------------- Changes from dev3a to dev3b -------------------

RELEASE DATE: 15 June 1998

1. [SERVER] Memory, Performance Optimizations

 By using custom-crafted DBObjectTable, DBFieldTable, and
DBBaseFieldTable classes instead of java.util.Hashtable's for the
primary Ganymede server data structures, we have reduced the memory
loading for the server by over 20% and eliminated the creation of a
lot of unnecessary temporary objects.  A number of operations that
were previously synchronized unnecessarily are now unsync'ed, and a
number of operations that required explicit casts are now type
specific, leading to further performance improvements.

2. [CLIENT] Swing Deadlock Prevented

 The Swing GUI library is not thread safe, and the client had a risk
of locking on updating the status label at the bottom of the client
window if the user attempted to open up several object windows
simultaneously.  The client now uses the Swing thread synchronization
primitives to update the status label, eliminating the potential for
client thread lock.

3. [CLIENT] Object Window ProgressBar Improved

 The object view/edit window progress bar has been improved so it
shows progress across vector fields, rather than simply halting while
a large number of vector components are loaded.  This gives a better
indication of the true progress when loaded an object with many
embedded objects.

4. [CLIENT] Query Dialog Allows Matches Against Non-Editable Objects

 Before, the query box would allow you to do queries on invid fields,
searching for objects whose invid field pointed to a listed object.
The choices listed, however, only included objects that the admin had
edit privilege on.  Now the list of options that is included in the
pull-down list for such fields will show all objects of the given type
that the admin has read privileges for.

5. [CUSTOM] Fixes to GASH Schema

 The system interface code was not properly handling the display of
the name and alias fields.. this was due to a broken canSeeField()
fix in dev3a.

6. [SERVER/CLIENT] edit/create/view/clone_db_object now return ReturnVal

 The server now has the ability to return error dialogs in response
to requests to view, edit, create, or clone objects.  The server will
now provide a detailed report explaining why an operation could not
be successfully completed.  If a user attempts to edit an object that
has already been checked out for editing by another user, the server
will report this, including the identity of the user who has the object
checked out.

7. [CLIENT] Query issue is now threaded

 Before, the client issued queries to the server on the GUI thread,
blocking the client's GUI refresh until the server responded.  The
client now handles queries in a separate thread, and displays a
window with an animated gif while waiting for the server to complete
the query.

8. [SERVER] Journal file optimized

 Before, whenever an object was changed in a transaction, the entire
state of the object would be written to the journal file.  Now, the
server only writes a record of the changes made to objects to the
journal, in some cases dramatically reducing the size of the journal
file and the time required to process it.

9. [SERVER] All Invid bind/unbind operations checkpointed

 The Ganymede server is now more robust in the face of errors in the
object linking logic.

10. [CLIENT] Fix in client refresh logic

 The client wouldn't properly display items in vector panels when
ordered to change the vector panel's visibility in certain cases.

11. [CUSTOM] Changes to gash, nisonly custom source

 Small changes to the gash and nisonly custom source to cohere with
change #6, above.  Since Session.edit_db_object() now returns a
ReturnVal, the custom code for the two schemas had to be changed where
it called edit_db_object().  No changes were made to NISBuilderTask.java
and GASHBuilderTask.java.

-------------------- Changes from dev3 to dev3a --------------------

RELEASE DATE: 8 June 1998

1. [CLIENT] Notes, History Panels reorganized.

 The object created, object modified timestamps are now on the history
panel.

2. [CLIENT] Can now do vector search operations on embedded invid fields.

 Previously, it wasn't possible to do things like search for systems
with multiple interfaces, as the client-side query code just displayed
the fields contained under the embedded interfaces.  Now it is possible
to query based on the status of the interfaces vector itself.

3. [INSTALL SCRIPTS] Fixed install scripts to work with Perl5.003

 It turns out that the Copy module in perl 5.003 is less friendly than
the one in perl 5.004_4, which we used to develop the install scripts.
We have fixed the install scripts to run under 5.003.

We also made the installServer and installClient scripts check to
prevent relative pathnames.

4. [CUSTOM] A number of fixes in the GASH/nisonly schema/custom code.

 Fixed interfaceCustom.canSeeField(), which was breaking the
viewing (not editing) of multi-interface systems.

 Made the directLoader code a bit more liberal, and made it able
to handle admins in admin_info with supergash-level privs.  Made it
able to handle alias_info lines with program invocation targets.

  Both the GASH and nisonly schemas now allow single-character
usernames.  Previously, the schemas were configured to require
a minimum of 2 characters for usernames, which was unnecessarily
restrictive.

5. [SCHEMA EDITOR] Turned off debug output.

-------------------- Changes from dev2c to dev3 --------------------

RELEASE DATE: 28 May 1998

IMPORTANT NOTE: The GASH schema and custom code have been very
significantly revised since dev2c.  You will not be able to port
an existing ganymede.db file from 2c or prior for use with the
dev3 GASH schema module.  As a general matter, we are not committing
to a lock-down on either schemas or classes until the initial
'production' release.

1. [CLIENT] Double-clicking on objects in the tree opens them for viewing.

 It is now more straight-forward to use Ganymede without a
multi-button mouse.

2. [CLIENT] Simplified ContainerPanel Menus.

 The menus attached to Object windows have been reduced in number and
made more intuitive.

3. [ADMIN CONSOLE] Fixed Initialization Exception on JDK 1.1.6 / Swing 1.0.2.

 The Admin Console used to throw an IllegalArgumentException on
startup when run under JDK 1.1.6 and Swing 1.0.2.

4. [SERVER/CLIENT] Fixed a lot of things regarding the query system.

 The client is now a lot smarter about handling non-String query
types, and will provide a list of choices for restricted object
reference fields.  Dates are handled with a pop-up calendar, and the
client properly implements 'same day as', 'same week as', and 'same
month as' logic.  A single query can handle searching on top-level
fields as well as fields in embedded objects.  The whole system is
significantly reworked and improved.  The GUI was reorganized.

5. [CLIENT] Custom Table Code Improved.

 Previously, the table code used in the admin console and query
results windows was subclassed from the Swing JPanel class.  This
caused a lot of mouse events to not get propagated to the table canvas
for some reason.  The table code now subclasses directly from
JComponent and works more reliably now.  Menus and row selection
occurs reliably on the first mouse click.

6. [CLIENT] Object Panel Loading Speedups.

 The manner in which certain GUI components load what may be large lists
of objects has been improved, leading to possibly significant speedups
in bringing up an object window.

7. [CUSTOM] The GASH schema has been significantly revised and completed.

 The GASH schema and custom code has been significantly revised.
Instead of there being a separate NISBuilderTask and DNSBuilderTask,
there is now just a single GASHBuilderTask, which generates all the
files supported by the GASH make process. The hosts_info file emitted
does not contain a list of administrators, so you will lose
information if you import GASH files into Ganymede, modify them, and
write them back out via the GASHBuilderTask.

 The GASH schema has been revised so that the systems database closely
adheres to the features supported by GASH.  The following changes
were made in this regard:

  1. Single IP address and DNS record per interface
  2. Rooms are bound to a list of networks, and the interface objects
     for each system provide a list of IP network choices from the
     room the system is placed in. 

 In addition, the GASHBuilderTask now emits an aliases_info file for
the first time.  In theory, you should be able to plug an installation
of Ganymede with the GASH schema loaded into the back-end GASH makefiles
you may already have.

8. [SERVER] Client code can now use the server to send mail.

 It is now possible to write client-side code that can send mail out,
even if that code is running as an applet in a restricted browser
context.  The mail is sent by the Ganymede server rather than the
client, and includes a signature identifying the mail as coming from a
Ganymede client.  The server supports sending both plain ASCII (rfc
822) mail, and mixed HTML/ascii MIME mail.

9. [CLIENT] Object windows and query result tables now save and mail reports.

 The object windows and the query result table windows now have a menu
allowing you to save and/or mail their contents in either text or HTML
format.  If the client is running in a restricted applet context, the
save option will not be available, but the client can still email
reports.

 The save function uses the version of the JFileChooser provided in
Swing 1.0.2, it may not work properly with earlier versions of the
Swing GUI libraries.

10. [SCHEMA EDITOR] Fixed a few schema editor bugs.

 Made the schema editor generally more robust when removing objects
types that have fields in other object types pointing to them.

11. [CLIENT/ADMIN CONSOLE] Put in some work-arounds for bug in Swing 1.0.2

 There is a significant bug in the JComboBox code in Swing 1.0.2.. see
bug #4132528 in the Javasoft Bug Parade at 
http://developer.javasoft.com/developer/bugParade/bugs/4132528.html.

 We put a few workarounds in the code, but there may still be times
when JComboBox operations will throw IllegalArgumentExceptions.  I
think folks are still better off using Swing 1.0.2 over previous
releases.

12. [SERVER] Added a reserve() method to the DBNameSpace class.

 Previously, a transaction could only allocate a unique name/number by
actually placing that value in a field of an object.  Now custom code
can 'pre-allocate' a set of values which can then be shown to the
client as a list of available options.  The newly revised GASH schema
uses this code to pre-allocate IP addresses for the networks available
in a particular room.

13. [SERVER] Fixed various elements relating to IP address handling.

 The java.util.Hashtable class does not work properly for the array of
Byte representation used in Ganymede to handle IP addresses.
GHashtable was modified to wrap bare Byte arrays with a wrapper class
that enables proper Hashtable functioning.

 The IPDBField class was not properly invoking a DBEditObject subclass'
wizardHook() method.

14. [DOCUMENTATION] Added more documentation.

 We have added doc/editobject.html, doc/server.html, and
doc/client-custom.html.  Each of these documents should be
significantly expanded in the next dev release.

15. [SERVER] Added default field permissions support for object types.

 In modifying the directLoader to properly initialize permissions for
the GASH schema, it became clear that we needed a way to set the
default permissions for an object's fields to something other than the
top-level permissions that apply to the object.  We modified
perm_field and PermissionMatrixDBField to add setDefaultFieldPerms().

16. [SERVER] invid_field.createNewEmbedded() returns a ReturnVal

 Previously, there was no way to get a detailed error report or rescan
information from a createNewEmbedded call.  We added a getInvid()
method to ReturnVal and made the client able to handle rescan requests
when adding a new edit-in-place object to a vectorPanel.

17. [SERVER] Various changes in Invid handling.

 Fixed/altered a number of things involving invid binding to make
things more robust across a wider range of circumstances.

18. [SERVER] Dumped schemas now retain builder task information.

 Previously, a raw schema file dump would not retain any information
about builder tasks associated with the schema, forcing end-users to
manually configure builder tasks after initially populating the
database from their data.  Ganymede now saves the builder task
information in the schema file, and users implementing Ganymede no
longer need to register the default builder task.

19. [DOCUMENTATION] Added CREDITS file.

20. [INSTALL SCRIPTS] Made the install scripts provide schema-specific options.

 The installServer.perl script has been made a bit smarter, and will
not prompt for configuration variables that are not applicable to the
schema selected.

-------------------- Changes from dev2b to dev2c --------------------

RELEASE DATE: 5 May 1998

1. [SERVER] DBSession.createDBObject() checkpoints DBEditObject.initializeNewObject().

 The server now performs a checkpoint/rollback when it calls
DBEditObject.initializeNewObject() if enableOversight is turned on.
That is, as long as the system is not doing bulk loading, the
DBEditObject.initializeNewObject() method is no longer responsible
for doing its own checkpoint/rollback.

2. [CUSTOM] Bulk loading Streamlined for nisonly, gash Schemas.

 The nisonly and gash userCustom and groupCustom classes no longer try
to automatically allocate uid's and gid's in initializeNewObject()
during bulk loading.  The gash schema previously tried to create
automounter entries at user creation time, which could confuse the
gash directLoader code.  Both the nisonly and gash schemas now only
attempt to do user and group initialization if the system is not
in bulk-load mode (enableOversight is true).

3. [CUSTOM] nisonly, gash schema code cleaned up.

 I went through and cleaned up the NISBuilderTask source in the
nisonly and gash schemas.  They now use schema constants rather
than numbers for field id's.  Removed a bunch of code from the
nisonly NISBuilderTask class that was no longer relevant.

4. [SERVER] Added a DBObject Parameter to anonymousLink methods in DBEditObject.

 I added a DBObject parameter to anonymousLinkOK() and anonymousUnlinkOK()
in DBEditObject.  This allows DBEditObject subclasses to enable or
disable anonymous linking and unlinking to a given field based on the
state of the object.

5. [CUSTOM] The GASH Schema Always Allows Linking, Unlinking from auto.home.default.

 In dev2b, it was not possible to create a new user as a GASH administrator
without specifically setting the permission matrix privileges to allow all
GASH administrators to edit all automounter maps.  With the new parameter
added to anonymousLinkOK(), we have now made the mapCustom object always
allow remote linking to auto.home.default.

6. [SERVER] Fixed InvidDBField.getEncodedValues() To Show Custom Labels on Viewing.

 In dev2b and before, Invid fields were supposed to be able to generate
custom labels for objects referenced through the lookupLabel() method
in DBEditObject subclasses.  This was only occurring with editable objects,
and not when such objects were being viewed.

7. [CLIENT] Fixed Objects Owned Panel.

 The client was not enabling the commit button when ownership of objects
was changed in the objects owned panel when an administrator edited
an owner group.

-------------------- Changes from dev2a to dev2b --------------------

RELEASE DATE: 4 May 1998

1. [SERVER] Creating New Objects With Embedded Objects.

 In dev2a, creating objects whose initializeNewObject() methods
created embedded objects would fail with a NullPointerException.  This
was due to the object being initialized before being added to the
transaction's working set, and caused NullPointerExceptions when
creating users with the GASH schema.

2. [CLIENT] Queries Were Not Attached To Tree Nodes Before Loading.

 In the client, if a user tried to issue a query on an object base 
folder in the tree prior to opening the folder, a null query would
be issued, and no results would come back.

3. [CUSTOM] Groups Field Broken In nisonly User Object.

 When using the nisonly schema, adding groups to the user's group
list was not working properly.  The home group choice box was not
updated properly, and the change to the group list would not be
committed properly.

4. [CLIENT] Editable/non-editable Choice GUI Component Logic Fixed.

 The release of Swing 1.0.2 from Javasoft has revealed a logic error
that would invert the editability status of a choice list.  It is now
possible to manually enter arbitrary strings for the shell field in
user objects in the gash and nisonly schemas.

5. [CLIENT] Tab Pane In Object Windows No Longer Transparent.

 Another bug that showed up when running the Ganymede client against
the 1.0.2 Swing release.  With Swing 1.0.2., the tab panes in dev2a
were transparent, allowing obscured windows to show through.

-------------------- Changes from dev2 to dev2a --------------------

RELEASE DATE: 1 May 1998

1. [SERVER] Required Fields Not Checked For Deleted Objects.

 DBEditSet (the Ganymede transaction class) no longer checks required
fields for objects that are being dropped or deleted.

2. [HTML] HTML for Java Activator/Plug-In Updated for Plug-In 1.1 Release

 We have updated the HTML template for use with the Java Activator to
work with the official release of the 1.1 Java Plug-In.

3. [SERVER] Added GanymedeSession.enableOversight(boolean) Method

 It is now possible for server-side code to turn off required field
checking and all wizard activity.  This is intended to be used
by the offline bulk loader code.

4. [CUSTOM] Updated nisonly, gash Loader Code

 Both the gash and nisonly loader code now uses enableOversight() to
turn off wizards and required field checking during bulk loading.  The
nisonly loader hadn't been recompiled since the delete bit was added
to the PermEntry class, so the nisonly loader code as broken.


-------------------- Changes from dev1b to dev2 --------------------

RELEASE DATE: 27 April 1998

Following are the most significant changes since dev1b.  There are a
number of additional small performance and behavior improvements
throughout.  We have continued to evolve the ARL Ganymede schema
and custom code, which has prompted us to enrich the customization
plug-in classes to allow for needed functionality.  The ARL schema
is not yet ready for release, but our work on it is driving the
improvement of the system generally.

1. [SERVER] Deadlock Prevention.

 There were a number of cases in which the server could become
deadlocked due to a nested-monitor condition.  We have corrected a
good number of these, and the server should be far less susceptible to
deadlocked threads.

2. [SERVER] Transactions Can Fail Without Mandatory Abort.

 The server now has the ability to have a transaction fail without
having to throw out the entire transaction.  This is built on the
checkpoint logic in DBEditSet and DBEditObject.

3. [CUSTOM] DBEditObject Customization Class Enriched.

 We have added a method to DBEditObject that will allow custom
plug-ins on the server to specify what fields must be filled in at
commit time.  The server's commit engine uses (2.) above to return an
explanatory dialog to the client, allowing the user to fill in the
additional required fields before trying to re-commit the transaction.

 In addition, the DBEditObject class now has the ability for an object
to determine for itself when it should be considered owned by the
current Ganymede administrator, as well as the ability to return
expanded or restricted permissions as needed.

4. [CLIENT/SERVER] Client Automatically Refreshes Object Pointers.

 The server now returns to the client a list of objects and fields
that need to be updated in response to an action by the client.  The
basic object linking code automatically handles this, so whenever you
change an object reference pointer with the client, you will see
affected references in other windows update.  There are still a couple
of cases in which this is not yet handled correctly, including when a
change to an object causes the object's label to change, and in
certain cases when objects are deleted.

5. [SERVER] String Relative Compares Work In Query.

 Before, if you attempted to use >, >=, <, or <= in a string field in
the Ganymede query mechanism, you would not get any results back.
Relative string comparisons is now working properly.

6. [CLIENT] Several GUI Fixes.

 The calendar panel now shows up correctly.  The GUI logic for the
vector of embedded objects has a number of bug fixes.  More.

7. [CUSTOM] Now Using *Schema.java Files To Enumerate Fields.

 The custom code associated with the provided schema files now use
symbolic constants to refer to fields in the customized object types.
This should make that code easier to read and maintain.

8. [CLIENT/SERVER] Permissions System Now Has Delete Bit.

 The permissions system now maintains a delete permission that is
distinct from an edit permission.  It is now possible to allow an
administrator permission to edit an object while denying that
administrator deletion privileges.  The permissions editor currently
shows the delete bit as applying to object fields as well as objects,
but currently the server only consults the delete bit when an attempt
is made to remove, inactivate, or reactivate objects.

9. [CUSTOM] GASH Schema Uses Properties.

 We have made the GASH schema custom code use a couple of properties
to specify the default home directory location and default email
address suffix.  You will be prompted for the values for these
properties when you run the installServer.perl script.  We may
want to move these out of the ganymede.properties file and into the
database proper to make it possible to change these values without
having to stop and restart the server.

 installServer.perl should be smart enough not to prompt for these
properties if the user is not installing the GASH schema.


-------------------- Changes from dev1a to dev1b --------------------

RELEASE DATE: 6 April 1998

1. [SERVER] Tasks Loading / Server dependency fix fixed.

 In amending the arlut.csd.ganymede.QueryResult class to not be dependent
on server-side classes, I broke a method that was required for the
server to load any registered builder tasks.  As a result, installers
were not able to get the DNS/NIS builder tasks to load.  This problem
was considered serious enough to precipitate this release.

2. [SERVER] Default Builder Tasks Will Now Call External Build Scripts.

 I have modified the builderPhase2() method in the builder tasks
included in the gash and nisonly schemas to automatically call a
script, "nisbuilder" or "dnsbuilder" in the db/out directory whenever
a transaction is committed that resulted in changes to the object
bases monitored by the installed build scripts.  With this change,
it is now possible for the nisonly schema install to be used for
actually managing passswd and group without much hassle.

 We are still not including any actual NIS or DNS build scripts.

3. [SERVER] Permissions Failures No Longer Throw Server Exceptions.

 Pretty much everywhere the server previously threw exceptions on
permissions violations are now properly caught and an error dialog
is returned to the client.

4. [CLIENT] Persona Panel Works Properly.

 In dev1a, the client could freeze up when the user attempted to carry
out an action that they did not have permissions for.  The persona
panel is more robust now.

5. [CLIENT] Miscellaneous Client Fixes.

 A small number of minor blemishes were cleaned up in the client.

-------------------- Changes from dev1 to dev1a --------------------

RELEASE DATE: 1 April 1998

1. [DOCUMENTATION] INSTALL

  We have slightly revised this file to better reflect the state of
things after the install scripts have run.

2. [DOCUMENTATION] Javadocs improved

  We used the 1.2beta3 JDK's javadoc to produce the class documentation.
The 1.2b3 javadoc includes a lot more information about the classes,
and will give you a better idea of how things fit together.

3. [INSTALL] Install Script Fixes.

  The dev1 prerelease installServer script was broken when it
came to properly configuring the loader code.

4. [CONSOLE] Schema Editor Fixes.

  Check boxes were not working properly in the schema editor,
making it impossible to configure certain aspects of new fields.

  Dragging newly created object types around between categories
was throwing an exception.

5. [CLIENT] Permission Editor Fixes.

  When the user attempted to edit permissions in a permission
object, it wasn't possible to change the top-level permissions
for an object type, only for individual fields.

6. [CLIENT] Reworked client architecture.

  We broke out the basic client logic into a new class,
arlut.csd.ganymede.client.ClientBase.  This change makes it easy
to write new clients without having to restart the server.
Previously, the server couldn't talk to a client unless it had
the custom RMI stub for that client.  Now, all clients simply use
the ClientBase class to connect to the server.  The server jar file
has this stub in place, so any clients written to use ClientBase will
work without needing to restart the server.

  We rewrote the Password client to demonstrate the use of ClientBase.

7. [SERVER/CLIENT] Fixed client dependency on server class.

  The client referred to a class, arlut.csd.ganymede.QueryResult,
which in turn contained a reference to a server class,
arlut.csd.ganymede.DBObject.  This made the client crash out
with a class not found exception when run as configured in the
client install.

8. [SERVER] Expanded DBEditObject to allow permission customization.

  We added permOverride() and permExpand() methods to
arlut.csd.ganymede.DBEditObject to allow custom objects to be able to
customize permission authentication for special cases.

9. [SERVER] Fixed initialization bug in DBStore.initializeSchema().

  This code that is supposed to create the standard object types
for a newly created ganymede.db file had an error that caused an
exception to be thrown.

10. [CLIENT] Object reference GUI field changed.

  When an object has a single reference to another object in a field
(as opposed to a vector of references), the client will now allow you
to link to the referred object.  The editable version of this field
type will be a bit more polished in the next release.  Currently, you'll
see a simple 'click' button.  We're going to come up with some sort of
icon for this by the next release.

			 --------------------

The remainder of our coding efforts have been in the development of a
new schema set, called 'ganymede' for now, which is being tailored for
our laboratory environment.  Our initial DNS support will be in this
schema, but we are not yet ready to release this set of
customizations.
