Reading Email

Problem

You need to read mail.

Solution

Use a JavaMail Store.

Discussion

The JavaMail API is designed to be easy to use. Store encapsulates the information and access methods for a particular type of mail storage; the steps for using it are listed in the sidebar.

Sun provides a Store class for the IMAP transport mechanism, and optionally for POP3.[44] In these examples I use the Unix mbox protocol[45] (when I started with Unix there was no POP3 protocol; it was traditional to access your mail spool file directly on a server). However, you could use all these programs with the POP or IMAP stores just by passing the appropriate protocol name where “mbox” appears in the following examples. I’ve tested several of the programs using Sun’s POP store and several POP servers (CUCIpop and PMDF).

I delete most of the email I get on one of my systems, so there were only two messages to be read when I ran my first "mailbox lister” program:

daroad.darwinsys.com$ java MailLister mbox localhost - - /var/mail/ian
Getting folder /var/mail/ian.
Name: ian(/var/mail/ian)
No New Messages
irate_client@nosuchd  Contract in Hawaii                      
mailer-daemon@kingcr  Returned mail: Data format error        
daroad.darwinsys.com$

The main program shown in Example 19-8 takes all five arguments from its command line.

Example 19-8. MailLister.java

import com.darwinsys.util.*;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;

/**
* List all available folders.
*/
public class MailLister {
    static StringFormat fromFmt = 
        new StringFormat(20, StringFormat.JUST_LEFT);
    static StringFormat subjFmt = 
        new StringFormat(40, StringFormat.JUST_LEFT);

    public static void main(String[] argv) throws Exception {
        String fileName = MailConstants.PROPS_FILE_NAME;
        String protocol = null;
        String host = null;
        String user = null;
        String password = null;
        String root = null;

        // If argc == 1, assume it's a Properties file.
        if (argv.length == 1) {
            fileName = argv[0];
            FileProperties fp = new FileProperties(fileName);
            fp.load(  );
            protocol = fp.getProperty(MailConstants.RECV_PROTO);
            host = fp.getProperty(MailConstants.RECV_HOST);
            user = fp.getProperty(MailConstants.RECV_USER);
            password = fp.getProperty(MailConstants.RECV_PASS);
            root = fp.getProperty(MailConstants.RECV_ROOT);
        }
        // If not, assume listing all args in long form.
        else if (argv.length == 5) {
            protocol = argv[0];
            host = argv[1];
            user = argv[2];
            password = argv[3];
            root = argv[4];
        }
        // Otherwise give up.
        else {
            System.err.println(
                "Usage: MailLister protocol host user pw root");
            System.exit(0);
        }

        boolean recursive = false;

        // Start with a Session object, as usual
        Session session = Session.getDefaultInstance(
            System.getProperties(  ), null);
        session.setDebug(false);

        // Get a Store object for the given protocol
        Store store = session.getStore(protocol);
        store.connect(host, user, password);

        // Get Folder object for root, and list it
        // If root name = "", getDefaultFolder(  ), else getFolder(root)
        Folder rf;
        if (root.length(  ) != 0) {
            System.out.println("Getting folder " + root + ".");
            rf = store.getFolder(root);
        } else {
            System.out.println("Getting default folder.");
            rf = store.getDefaultFolder(  );
        }
        rf.open(Folder.READ_WRITE);

        if (rf.getType(  ) == Folder.HOLDS_FOLDERS) {
            Folder[] f = rf.list(  );
            for (int i = 0; i < f.length; i++)
                listFolder(f[i], "", recursive);
        } else
                listFolder(rf, "", false);
    }

    static void listFolder(Folder folder, String tab, boolean recurse)
    throws Exception {
        folder.open(Folder.READ_WRITE);
        System.out.println(tab + "Name: " + folder.getName(  ) + '(' +
            folder.getFullName(  ) + ')'),
        if (!folder.isSubscribed(  ))
            System.out.println(tab + "Not Subscribed");
        if ((folder.getType(  ) & Folder.HOLDS_MESSAGES) != 0) {
            if (folder.hasNewMessages(  ))
                System.out.println(tab + "Has New Messages");
            else
                System.out.println(tab + "No New Messages");
            Message[] msgs = folder.getMessages(  );
            for (int i=0; i<msgs.length; i++) {
                Message m = msgs[i];
                Address from = m.getFrom(  )[0];
                String fromAddress;
                if (from instanceof InternetAddress)
                    fromAddress = ((InternetAddress)from).getAddress(  );
                else
                    fromAddress = from.toString(  );
                StringBuffer sb = new StringBuffer(  );
                fromFmt.format(fromAddress, sb, null);
                sb.    append("  ");
                subjFmt.format(m.getSubject(  ), sb, null);
                System.out.println(sb.toString(  ));
            }
        }
        if ((folder.getType(  ) & Folder.HOLDS_FOLDERS) != 0) {
            System.out.println(tab + "Is Directory");
        if (recurse) {
            Folder[] f = folder.list(  );
            for (int i=0; i < f.length; i++)
                listFolder(f[i], tab + "", recurse);
            }
        }
    }
}

This program has the core of a full mail reader but doesn’t actually fetch the articles. To display a message, you have to get it (by number) from the folder, then call methods like getSubject() , getFrom( ), and others. The listFolder( ) method does this to obtain identifying information on each message, and formats them using the StringFormat class from Section 3.6.

If we add a GUI and a bit of code to get all the relevant header fields, we can have a working mail reader. We’ll show the messages in a tree view, since some protocols let you have more than one folder containing messages. For this we’ll use a JTree widget, the Swing GUI component for displaying text or icons in a tree-like view. The objects stored in a JTree must be Node objects, but we also want them to be Folders and Messages. I handled this by subclassing DefaultMutableNode and adding a field for the folder or message, though you could also subclass Folder and implement the Node interface. Arguably, the way I did it is less “pure OO,” but also less work. Example 19-9 is my MessageNode ; FolderNode is similar, but simpler in that its toString( ) only calls the Folder’s getName( ) method.

Example 19-9. MessageNode.java

import javax.mail.*;
import javax.mail.internet.*;
import javax.swing.tree.*;

/** A Mutable Tree Node that is also a Message. */
public class MessageNode extends DefaultMutableTreeNode {
    Message m;

    StringFormat fromFmt = new StringFormat(20, StringFormat.JUST_LEFT);
    StringFormat subjFmt = new StringFormat(30, StringFormat.JUST_LEFT);

    MessageNode(Message m) {
        this.m = m;
    }

    public String toString(  ) {
        try {
            Address from = m.getFrom(  )[0];

            String fromAddress;
            if (from instanceof InternetAddress)
                fromAddress = ((InternetAddress)from).getAddress(  );
            else
                fromAddress = from.toString(  );

            StringBuffer sb = new StringBuffer(  );
            fromFmt.format(fromAddress, sb, null);
            sb.    append("  ");
            subjFmt.format(m.getSubject(  ), sb, null);
            return sb.toString(  );
        } catch (Exception e) {
            return e.toString(  );
        }
    }
}

These are all put together into a mail reader in Section 19.9.



[44] The POP3 Store classes must be downloaded and manually installed from http://java.sun.com/products/javamail/.

[45] This is free (GPL) software, which can be downloaded from the Giant Java Tree, http://www.gjt.org.

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

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