![]() |
|
|
grendel architecture
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Date: | Tue, 12 Aug 1997 21:07:09 -0700 |
|---|---|
| From: | |
| Subject: | Re: some doodling about mail |
| To: | terry@netscape.com, jevering@netscape.com |
Since I don't have Terry's spiffy drawing program, I've converted his stuff to HTML and expanded on it.
Things I changed:
We need to be able to open /var/mail/$USER as a folder and have it work. You know how much I hate that model of operation, but we need to do it.
But more importantly (and it's a more general problem) we need to let people use procmail, and dump messages right into their folders. This means we need some sort of asynchronous notification mechanism, where the backend tells the front end that new messages have appeared? I don't know.
Perhaps the incoming-message-filter-rules should live on MessageStore. I guess this is distinct from killfiles, which really seem like they ought to live on MessageSetView.setSearchTerm().
Here's a distinction between public and private folders: on a private folder, you want your filters to actually delete messages. On a public folder, you simply want it to never show them to you. Hmmmm...
So here's a new backend class hierarchy...
| MessageStore | |
| This is the central storage place for the list of folders. There would be one of these for each IMAP and NNTP server, for example; and one for the folders on the local disk. | |
| |
| Folder | |
| Folders might contain messages, or folders, or both, depending on the underlying representation. | |
| |
| LocalFolder | |
| An abstract class for folders living on the local disk. | |
|
| |
| BSDFolder | |
| A folder who's underlying representation is a BSD mbox file (or perhaps the Content-Length variant, if we really feel adventurous.) This would contain the implementation of the caches used to quickly generate summary information (what used to be .summary files.) | |
|
| |
| RemoteFolder | |
| An abstract class for folders living on the network. | |
|
| |
| IMAPFolder | |
| A folder who's underlying representation resides on an IMAP server. This would implement summarization by talking to the server. | |
|
| |
| NewsFolder | |
| A folder who's underlying representation resides on an NNTP server. This implements deleteMessage in terms of ``cancel'', and addMessage by raising an exception (I guess.) | |
|
| |
| MessageSetView | |
|
A view into one or more Folders; the UI will mostly be dealing with
FolderViews, not Folders. The SearchTerm specifies
how the set of messages in this view was acquired.
The SearchTerm is where killfiles live. What about scorefiles? | |
| |
| FolderView | |
|
This is a particular, highly-constrained variant of
MessageSetView, where the search term is chosen to show only
messages from one particular folder. It might not show all
of the messages in the folder, but all messages will be in the same
folder.
This does not imply that, should a search only happen to return messages from one particular folder, that a FolderView will be used: FolderView is only used when the desire to have messages from one particular folder is specified at the outset. The important distinction here is that you can unambiguously delete a message, and it's clear that it's going to vanish from the real folder, and not just from the ``virtual'' search-results folder. | |
| |
| Message | |
|
Actually this is more along the lines of MessageDescriptor, or
MessageSummary, since this object represents a message without
necessarily having access to the message itself: just the summary
information. That's why it doesn't return an object representing
the whole header block: that data probably isn't available until
the message is actually displayed.
The getMimeStructure() method might return ``unknown'' if the underlying folder representation doesn't save that information. (NNTP doesn't; BSD doesn't currently but could.) In no event will that method parse the folder to find out, because that would be expensive (and should be explicit.) What if someday someone wants to add some other header to their summary? Say they want to have a column listing the ``Approved'' header, just to pick a random example. Suppose further that some of the summary formats used support this (they might.) This model (with one method for each available header) doesn't deal with that nicely. Perhaps instead, there should be a getSummaryHeaders() method, which would return an object which contains some set of headers and values (some minimal set of which can be assumed to exist, but with others potentially present.) | |
| |
| MimePart | |
| This describes, and gives access to, the MIME tree within a message: this is what Message.getMimeStructure() returns. | |
| |
| MimeParser | |
| TBD. | |
What follows is a class hierarchy for what we used to call the front end. Does any of this make sense? At some level, this all just describes windows which interact with the objects described above, and with the user.
| Displayer | |
| This is a generic window, basically. | |
| LeafDisplayer | |
| Displayers which display single objects (not sets.) | |
| MessageDisplayer | |
| Displays a single MIME message. | |
| |
| PersonDisplayer | |
| Displays a single person (mail recipient.) | |
| |
| SetDisplayer | |
| Displayers which display sets of objects. | |
| MessageSetDisplayer | |
| Displays a set of messages (a FolderView.) | |
| |
| MessageSetSetDisplayer | |
| Displays a set of folders (a MessageStore.) | |
| |
| PersonSetDisplayer | |
| Displays a set of people (an Address Book.) | |
| |
| FrameDisplayer | |
| A window with subwindows. These bind together windows of other types. | |
| ThreePaneMessageViewer | |
| This looks like Cheddar/Akbar. | |
| |
| MultiWindowMessageViewer | |
| This looks like Dogbert. | |
| |
Comments?