The GroupCal Servlet

As we saw in Part I, we tend to ask more of email than it can deliver. Conferencing can help restore email to its realm of appropriate use while providing an alternate venue for groupthink activities. But newsgroups, too, have their limits. A private newsgroup is a great place to share drafts of work in progress or to discuss travel plans. You don’t want to go there, though, to find out whether Bob turned in the report that was due yesterday or to find out who’s going to be at the conference next week.

These kinds of things belong in a calendar. Unfortunately, Internet calendaring isn’t yet as standard or as universal as the core mail/news/Web services. Netscape and Microsoft both offer calendar servers—but they’re quite different creatures. Netscape’s Calendar Server works only with Communicator’s Calendar client. Likewise, the calendaring features of Microsoft’s Exchange Server, though exportable to web clients, work best with the Exchange client. The standard Internet client doesn’t yet include a calendar client that can interoperate with mature, open, standard, and multiply implemented calendar servers.

Internet Engineering Task Force (IETF) committees are working to define a framework for standard Internet calendaring and scheduling (see http://www.ietf.org/html.charters/calsch-charter.html). Works in progress include iCalendar, a MIME type specialized to represent things like people, appointments, and todo items; and Calendar Access Protocol (CAP), which will enable diverse calendar clients and servers to interoperate. But it’s early days for iCalendar/CAP products. We can only hope that the next generation of standard Internet clients will support these formats and protocols.

In the meantime, there are web-based calendar applications popping up all over the place. The GroupCal servlet belongs to this genre. It doesn’t tackle the scheduling problem at all; it’s just a shared bulletin board with a simple web API that both people and programs can use. Daily information pertaining to a user or a group is represented as chunk of plain text or HTML. Browsers and scripts can view, edit, and search the calendar.

GroupCal could doubtless be extended to support the features that today’s proprietary calendar products tout and that tomorrow’s open Internet-based products will also support: meeting scheduling, resource allocation, reminders, and the like. But that’s a wheel that I’m not going to try to reinvent. For our purposes here, I’ll use GroupCal to make two points about the role any calendar service ought to play in an Internet groupware architecture. First, a calendar service should double as an application and a component. It should do useful things right out of the box, but since group dynamics are complex and subtle, it should also be fully programmable. GroupCal is, just because it’s a Java servlet with a web API. Second, a calendar service should exploit a flexible, object-oriented data model. Java servlets can naturally create and use simple object stores and can transparently upgrade to industrial-strength object databases.

GroupCal’s HTML Interface

From a user’s perspective, GroupCal is a typical Web-based calendar viewer and editor. The main screen is shown in Figure 10.1.

GroupCal’s main screen

Figure 10-1. GroupCal’s main screen

From this screen, you can do the following things:

Select a week.

GroupCal defaults to the week that contains the current day; you can use the weeks picklist to select another week.

Select one or more users or groups to view.

GroupCal maintains a calendar for each user and for each group. It also maintains a set of mappings among users and groups. If Ed belongs to the analysts group, then all views of his calendar will inherit entries from that group calendar. There can be multiple inheritance, in the sense that Ed can belong to two groups—analysts and it-staff—and inherit entries from both of these group calendars into his personal calendar. In addition, all users inherit from the global calendar. Entries made there, for company holidays, birthdays, or other events of general interest, will appear on everyone’s personal calendar regardless of group membership.

View calendars.

The viewing screen (see Figure 10.2) presents the set of calendars selected (checked) on the main screen. Each calendar view begins with the current week and extends for the number of weeks specified in the View n weeks input field. By default each calendar view extends for four weeks.

Edit a calendar for the current week.

Clicking any hyperlinked name invokes the edit screen (see Figure 10.3). There you can add or modify calendar entries for the selected user or group.

Search calendars.

The search function returns calendar entries containing the search term you specify. By default it searches all calendars. You can use the picklist to restrict the search to a single user or group. Note that a restricted search will only match terms found in the selected calendar. If Ben is a member of the analysts group and that group’s calendar contains an entry about an LDAP conference, a search of Ben’s calendar won’t find that entry. A search of the group calendar, or of all calendars, will.

Figure 10.2 shows a one-week view for one user’s calendar.

GroupCal’s view screen

Figure 10-2. GroupCal’s view screen

Note how entries from groups—analysts and Global—merge with personal entries.

Figure 10.3 shows the edit screen.

GroupCal’s edit screen

Figure 10-3. GroupCal’s edit screen

The weeks picklist defaults to the main screen’s selected week. You can change it in order to edit any other week on Ben’s calendar. Daily entries are just chunks of plain text or HTML. There’s no requirement to use HTML, but an entry more complex than a phrase or two will display more nicely if you do.

Should users write HTML?

GroupCal ’s HTML policy differs from the one we enforced in the ProductAnalysis docbase. There, we assumed that users should not be allowed to fuss with HTML, and we implemented some simple translations—converting newlines to <p> and <hr> tags, converting URLs into hyperlinks—to make that unnecessary. Why allow HTML in GroupCal entries? Partly because the users for whom I originally wrote this application enjoyed trying out a few simple HTML tags. But mainly because GroupCal is written in Java, which is nowhere near as effective as Perl for text-transformation work.

There are freely available regular-expression libraries for Java, and the translations implemented for the ProductAnalysis docbase could be carried over to GroupCal as well. The problem is a bit more complicated, though, because the calendar isn’t a write-once-then-read-only docbase; it’s a fully rewritable data store. That would require a two-way translation. HTML tags added to the input supplied in an entry field would have to be stripped out when the data is subsequently loaded back into an entry field for re-editing. The ideal solution would be an HTML (or preferably, XML) editing widget, lightweight and scriptable, built into every browser just as the basic HTML form widgets (text boxes, radio buttons, dropdown lists) are. Unfortunately there isn’t yet a standard HTML/XML data-entry widget.

GroupCal’s data store

As with Polls, the central data structure of GroupCal is a hash-of-hashes. Table 10.3 illustrates this structure.

Table 10-3. GroupCal’s hash-of-hashes

Calendar

Day

Entry

Joy-Lyn Blake

Jun 22 1999

Write monthly status report

 

Jun 23 1999

Phone conference at 3

Ed DeJesus

Jun 24 1999

Remember to call Aldo

Global

Jun 20 1999

Company picnic

 

Jul 04 1999

Independence day holiday

The data structure is sparsely populated—that is, the per-user and per-group hashtables contain key/value pairs only for days for which calendar entries have been made. That sparseness, along with the relatively compact format that Java uses to represent this data, enables GroupCal to manage a set of calendars entirely in memory. Like Polls, it writes updates to a disk file, but only for safekeeping. All read and write operations on calendars use the in-memory hashtables. Why? It’s fast, easy, and effective. One of the delightful aspects of Java is that it contains everything you need to create a simple object store. As we saw in the case of Polls, you can do that using synchronization and serialization.

However, synchronization alone can’t fully protect GroupCal’s data. It’s true that by synchronizing its update( ) method, we can ensure that any thread calling that method will block if another thread is executing the same method. But the fact that updates are serialized inside the servlet, and can’t make a mess out of the hashtables, doesn’t necessarily mean updates are serialized from the perspective of the calendar users. Why not? Suppose you fetch a week of my calendar into an edit screen in your browser, then I fetch a week into mine. When we both click our respective submit buttons, the possible outcomes are as follows:

No conflict

If we fetched different weeks, or even if we fetched the same week but modified entries for different days within that same week, everything’s OK. First your edits are applied, then mine, or vice versa.

Conflict

If we fetched the same week and modified an entry for the same day, there’s a problem. Buffered in a form inside each of our browsers was the same original version of that day’s entry, which we have each changed in a different way. Whoever submits the form last, wins.

There’s nothing Java-specific or even web-specific about this dilemma. It’s just a classic problem that arises when a database record is buffered simultaneously on multiple clients. To solve this problem, GroupCal could maintain a list of locked calendar records and refuse to edit any locked records. Or it could always allow revisions but keep a complete version history for each record. It needn’t be costly to do that. Since records are rarely edited, the data structure will remain sparse. This is a handy technique, especially if you enable users to drill down into the version history to see who changed what and when. GroupCal doesn’t support that feature, but the task-tracking application we’ll see in Chapter 15, does.

Before implementing a record-locking or versioning mechanism, though, you might want to step back and consider the bigger picture. We’re only in this apparent fix, after all, because GroupCal allows every user to edit every calendar. Some groups will think this policy is fine, but others won’t. In that case, no record-locking protocol will suffice. You may not want some users to even see, never mind edit, other calendars. If that’s so, see Chapter 11, and Chapter 12, for a discussion of membership systems and access-control techniques.

From simple serialization to object databases

I said earlier that synchronization and serialization can combine to create lightweight databases of Java objects. We’ve seen how synchronization protects the integrity of the hashtables that Polls and GroupCal manage, by guaranteeing that only one thread at a time can execute an update method. Like Polls, GroupCal synchronizes its update( ) method, which uses serialization to save in-memory hashtables to disk.

Although GroupCal ’s update( ) method could serialize the master HoH, as does Polls, it instead serializes individual per-user calendar objects. This makes no difference to the update( ) method, which only knows that it’s been given some kind of serializable object. Why the more granular approach? It’s more efficient, because it saves only an individual calendar touched by an update, not the whole set of calendars. In practice, though, saving the whole set isn’t as problematic as you might think. Thanks to sparse storage, GroupCal object files grow slowly. Web latency—that is, the time it takes to send a request to a web server and receive a response—more than offsets the time needed to serialize months’ worth of calendar data for a dozen users.

Another reason to serialize on a per-user basis is that each individual calendar then becomes a discrete and potentially mobile object. Suppose I need to use my calendar on an untethered notebook PC that can’t connect to the calendar server. I can detach my calendar, copy that file to my notebook, and use a local instance of GroupCal to interact with it. We’ll see more of this local-web-server approach in Chapter 15.

Despite the surprising efficiency of simple serialization, there’s a limit to the amount of data that you can manage in a memory-resident data structure. With sparse data and lots of memory, you might be able to get away with this approach for a long time. And while you can, you’ll enjoy the twin benefits of simplicity and high performance. But it would be nice to know that if your application scales up dramatically, as Internet-based applications are wont to do, a more robust storage mechanism will be available. Happily, that’s so. Commercial object databases now come with bindings to Java. That means that an in-memory Java object, such as a Hashtable, can be a window onto disk storage. An application that uses that object can access its parts just as though they were present in memory, because, for the most part, they are. When a referenced part isn’t already available, the object database automatically pages it in.

How does an application acquire this enhanced object storage? The details vary depending on the particular object database you use. In the case of Object Design’s ObjectStore, the Java binding kit comes with alternate, persistence-enabled versions of Java storage classes such as Hashtable and Vector. An OSHashtable, for example, is the ObjectStore version of Java’s Hashtable. OSHashtable has the same interface as Hashtable, and the two can be used interchangeably.

To create a persistence-enabled GroupCal , you make a new root object in an ObjectStore database and associate that root with the OSHashtable object that represents GroupCal’s collection of calendars. Now all references to that object—gets, puts, enumerations—refer without any modification to persistent objects that live in the ObjectStore database. You do have to wrap begin-transaction and end-transaction calls around all references to persistent objects. There’s a trade-off here between transaction granularity and simplicity. An easy solution is to bracket the servlet’s main service( ) routine with a single pair of transaction calls.

In this scenario, memory is no longer an issue. A persistence-enabled GroupCal can handle 10,000 calendars as easily as 10. And its data store can be managed using the transactional controls and querying capabilities of the database engine.

Why groupware needs objects

In the case of GroupCal, is object database technology just a solution in search of a problem? After all, its structures are simple and regular. With the exception of the daily entries—which are text fields of variable length and unlimited size—there is nothing that you couldn’t model equally well in any conventional SQL database. I’ll admit that in its present form, GroupCal ’s use of object storage is perhaps gratuitous. But I chose the technique because I envisioned features that would push the limits of SQL and exploit the strengths of object storage.

Consider how group scheduling might benefit from this approach. Mark Drummond, CTO of TimeDance.com, describes his company’s web-based group scheduler as follows:

What we’re doing, in essence, is bolting a bulletin board to an event. In our approach, an event is an object (in a fairly technical sense). In a traditional approach, an event is an entry in a database. Without a start time, there’s no way that the event can be put into the DB. With the event-as-object approach, there are a number of nice benefits. We can collect constraints on acceptable values for various parameters of the event. For instance, we can collect constraints on the start time of an event. “Any day next week” might work for you; “Not Friday” is a constraint that I bring to bear; and “Not Tuesday morning” is requested by someone else.

The event’start time now has a set of constraints on it and it’s possible to add value to the user’s lives by putting some “constraint satisfactory machinery” around the information to help them make better decisions. The bulletin board attached to each event is a catch-all mechanism that allows the users to share information that would otherwise be forced out of band, into email or voicemail.[11]

TimeDance models these events using server-side Java objects, which are then mapped into an SQL data store. My hunch is that over time this object-to-relational mapping will matter less. Object-oriented applications will increasingly rely on object data stores.

There’s an XML angle here as well. An XML file is really just a textual representation of object data. Browsers are learning to map that data into their document object models. At the same time, object databases are evolving XML bindings that will, in theory, simplify the work of middle-tier groupware components.[12] In its current form, GroupCal uses procedural logic to express Java objects as HTML. That doesn’t change when it’s backed by an object database—it still has to externalize objects as HTML. But as object databases begin to make XML persistent, the boundaries between XML data structures and Java data structures (or those of other object-oriented languages) will begin to blur. Middle-tier components can get out of the business of mapping from live data objects to presentation services, data-exchange formats, and storage, and focus more on what it is they actually do with that data.

This notion of a calendar service as a middle-tier component, isolated from presentation and storage issues, is crucial. Java servlets are well suited to this role because they’re inherently efficient, as we’ve seen. They’re also inherently programmable. Just because it presents a web API, a servlet can be driven by a scripted web client. The inverse is also possible. A servlet can itself be a web client with respect to other URL-accessible services. This ability to simultaneously provide and consume HTTP-based services enables a simple yet powerful approach to middle-tier development. We’ll explore some of the possibilities here and go more deeply into the subject in Chapter 15.



[11] Private correspondence, quoted with permission.

[12] Early examples of this new breed of XML data server were POET Software’s Content Management Suite (http://www.poet.com/) and Object Design’s eXcelon (http://www.odi.com/).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.14.83.223