Developer Notes

5. The Pliny Data Model

Pliny represents information about resources, annotations, notes, etc. using its data model. Pliny is largely built using the MVC (Model-View-Controller) paradigm, and here we speak about the "M" part of MVC -- the data model.

The Pliny-wide Model classes are found in package This package consists mainly of classes that represent data that Pliny is interested in -- resources, notes, reference objects, connections between them, object types, etc.. These must ableo to be persisted so that when the user returns to Pliny for another session another day the work s/he have done will be still there. There are also a few helper classes in this package which make implementation in GEF easier, but do not really have obvious persistence needs.

Persistence is achieved by storing the data in a relational database (Derby ( is used) and by creating classes that manage the DB data that are generated using a modified version of rdb2java -- a toolkit developed by me at CCH to facilitate the construction of web applications that work with RDB data. rdb2java (in its modified form) both manages persistence so that changes in values of data or relationships between instances are recorded automatically in the backing database, and it also makes sure that only a single instance of an object exists in memory that represents a particular instance of data in the DB. Once the data is created in memory for a particular instance of a DB table, this modified version of rdb2java will ensure that that same memory instance will always be given when a particular DB instance is required.

Here is an informal UML class diagram that shows the Pliny model classes and suggests the major relationships between them. Be aware that not all the associations between classes are shown here!

The role of the classes are:

  • Pliny Resources are stored in instances of this rdb2java generated class.
  • The note content field comes from the Note class which should be viewed as an extension of the Resource class. It is rdb2java generated.
  • This class extends Note by providing connections to Lucene ( for textual searching of Note text. This class is, in fact, the one that is instantiated by Pliny code whenever a Note is referenced, so that all Notes are "lucenable".
  • This class extends Resource and is used in situations where a placeholder Resource is needed that shouldn't actually immediately exist in the Database. A VirtualResource is used, for example, to act as an owner for a reference area for a web page before any actual LinkableObjects are put on it. Although it has memory, and is a Resource class so that it can act as a reference area owner, it is not actually yet in the DB. If the user actually creates a something (say, Linkable Object to a new note) in its reference area, it is made "real" -- effectively, a DB record is created for it -- by invoking its makeMeReal() method.
  • Pliny Resources are associated to an object type which tells Pliny which type of editor should be used. This is the place where a Web page resource is differentiated from a PDF file resource. Information about each type of Resource Pliny knows about is stored in the ObjectType.
  • ObjectTypes are associated, in turn, with Eclipse Plugins which can provide code that can work with the data that Resources of this kind represent. Information about Plugins which have ObjectTypes associated with them are stored in data of this class.
  • The LinkableObject class represents what in Pliny terminology is called the reference object. It specifies that a particular Resource (called a resource "surrogate") appears in the reference/annotation area of another Resource (called the "displayedIn" resource). It also contains placement information (for 2D reference/annotation areas, this is a Rectangle) that indicates where the reference object should be displayed.
  • The Link class represents when in Pliny terminology is called a connection. It records a connection between a LinkableObject (source) and another LinkableObject (target).
  • Both LinkableObjects and Links can be assigned a type which controls the colours used to display the object, and manages information regarding how the LinkableObject or Link should be exported as a Topic Map assocation.
  • Instances of this data record general information about the DB as a whole. In current usage, this table contains only one record, and that record announces the version number of the current DB design. Pliny uses this information when it starts up to see if a newer version of Pliny is starting than the existing DB. If it is, the is asked to update the DB structure whenever a new version of Pliny has been installed, and some change in structure to the underlying DB is required.

Two classes in the other two Pliny plugins provide extensions to the Resource class so that information specific to the needs of those plugins can be stored there:

Deleting and Restoring rdb2java objects

A word about the use of rdb2java methods deleteMe() and reIntroduceMe() -- methods that come in all rdb2java generated classes. Recall that, in general, an instance in memory of an rdb2java class corresponds to a record in the backing store DB's corresponding table. deleteMe() requests that the record that corresponds to the instance in hand be deleted from the backing database. reIntroduceMe() requests that the memory instance in hand be introduced (perhaps "re"-introduced) into the DB as a record in the appropriate corresponding table. deleteMe(), then, by removing the record from the backing DB means that the data the memory instance holds is then no longer persistent -- it will be completely gone the next time Pliny is started although it will continue to exist in memory as long as other class instances hold references to it.

These two methods are particularly useful when operation that results in the removal of data from the DB needs to be undoable, as most delete operations in Pliny need to be. When the delete request is made against a particular instance of an rdb2java class by calling deleteMe(), the corresponding DB record is removed, but, of course the memory instance is still intact. If the user asks that the particular delete request be undone, then reIntroduceMe() can be called to recreate the same memory instance in the backing store DB.

John Bradley
Center for Computing in the Humanities
King's College London