java-mail: tree-like mail structure traversal

Just as of recently, I have been playing around with Java Mail, a library I overally enjoy working with, except for one thing perhaps: Somehow I miss a consistent data structure backing it to allow for traversing an e-mail structure in a clean way…

Maybe I just haven’t yet found a better starting point, but somehow then and now I am still unsure why to have javax.mail.Multipart as an abstract class extending Object, representing multipart messages (i.o.w. virtually everything to include either attachments, forwarded messages, inline images or “alternate” parts, like the same content in plain text and in HTML), and, on the other side, the javax.mail.Part interface to deal with parts included in messages. Somehow the latter seems sane, and, given javax.mail.Multipart would actually implement javax.mail.Part, some things possibly would be a little easier… or wouldn’t, if I just did them right, however. 😉

Anyway, to programmatically deal with mails in our internal environment (where mail processing happens to be done automatically from within a Java EE application traversing an IMAP folder tree, looking at new messages and extracting things as it sees fit), I made up a tree structure to wrap these things up and provide a (hopefully) straighforward yet concise way of accessing mail-parts and content despite its actual content type, MIME structure and related things. Sample code can be found here, explanations on that:

  • The project uses maven2 and the Swing Application Framework for the UI stuff. Along with the maven2 project structure this project can be simply opened and launched from within NetBeans IDE with installed maven2 toolings. Running “natively” (without an IDE), make sure to invoke mvn assembly:assembly to build the project and then run the app using java -jar target/toys-text-mailarchiver-0.0.8-SNAPSHOT-jar-with-dependencies.jar to actually get things goin’.
  • Before building and eventually running things, open the net.z428.toys.mailtext.VisualMailView class and set the mail server host name and credentials (your.server.name, your.server.userid, your.server.password) to sane values. While in there, also make sure to set a valid IMAP starting folder or, better, uncomment the //this.mailViewMain.setFolderList(this.connector.getStore().getDefaultFolder().list()); line to use the standard folder prefix.
  • Likewise, you should have a look at pom.xml, download and possibly install the Swing Application Framework .jar to your local .m2 repository – don’t worry as if you don’t, maven2 will tell you (how) to do so.

Running the application (and given you set up your IMAP access right), you will want to see a screen something like the following (after you chose a folder and clicked the “List” button, that is). What to see:

At first, each message is a child of the tree root. If possible, the messages are labeled using either the “Subject” string as found in the mail or some other meaningful value (attachment, filename, content type or the like). Names starting with ">" indicate a “top-level” mail container which is not of that much interest in the UI as it might be in a non-UI application using the same structure. Expanding the messages in the tree allows for browsing their MIME structure, exploring what kind of data they do contain:

mailtree.jpg

Talking implementation, there basically are two classes of interest here:

  • net.z428.toys.mailtext.PartContainer is ought to be an abstraction of javax.mail.Part, javax.mail.Multipart and the data objects they could contain. The idea of PartContainer mainly is to provide a straightforward way of accessing part headers as well as the part content (accessible at best using the getPayloadAsStream() method returning an InputStream to read the mail content in this part from. PartContainer objects are supposed to have other PartContainers (representing embedded parts they might contain) as children, as well as having the PartContainer that encloses them added as parent (in other words, a tree structure). In “stock” Java Mail, you are likely to use the getContent() method for that and figure out which kind of class to get in return. In the PartContainer structure, a difference is being made between “actual” data and embedded parts, which might or might not make sense depending upon what you want / need.
  • Along with it there is a net.z428.toys.mailtext.PartDumper class which provides a facility for building PartContainer trees from javax.mail.Message objects.
  • This contains some of the logic to differ between javax.mail.Part, javax.mail.Multipart and actual data in an e-mail representation.

  • net.z428.toys.mailtext.ui.TreeHelper, finally, provides a helper function for building a DefaultMutableTreeNode based tree for display in JTree.

Concluding, I have to state that at least the UI is rather flaky and not very fault tolerant, and most of the code has yet to see heavy load test (which will happen the next days as it is to replace an older, way more limited implementation of mail parsing not honouring the tree-like structure of nested parts which brings some serious issues at times). However as I’ve been searching quite a while for something like that in relation to Java-Mail, I’m still posting it here, maybe it will ease someones search and / or prove usable to one or another – mainly this is not a “finished”, ready-to-use implementation of anything but rather thought of as an inspiration for you to have a look at and get started in case you also might be searching… Comments / hints / suggestions, of course, always appreciated.

Code: toys-mailarchiver.tgz (to be used according to the terms of CDDL)