Receiving Mail with IMAP4
Table of Contents | Previous | Next | Index

Messaging Access SDK Guide
Part 1. Using the Messaging Access SDK


Chapter 4
Receiving Mail with IMAP4

This chapter is an overview of using IMAP4 (Internet Message Access Protocol 4) to retrieve and manage messages remotely.

[Top]

The IMAP4 Protocol

IMAP4 (Internet Message Access Protocol, Version 4), which was developed at the University of Washington, allows clients to retrieve and manage their email messages remotely. This can be very helpful to users who access mail on several different computers.

IMAP4 also provides these capabilities:

To send mail, use SMTP (Simple Mail Transport Protocol). For more information, see Chapter 2, "Sending Mail with SMTP."

For detailed information about IMAP4, consult one of the RFCs listed, with links, in IMAP4 RFCs.

[Top]

IMAP4 Session States

An IMAP4 session progresses through several stages, or states. Within each state, only certain commands are possible.

Figure 4.1   IMAP4 Session States

Table 4.1 IMAP4 Session States and Commands

Session State Commands

All States

Commands: CAPABILITY, LOGOUT, NOOP

Non-Authenticated

Before login. User login, approval. Command: LOGIN

Authenticated

User is logged in, can perform operations involving mailboxes and mailbox management. Commands: APPEND, CREATE, DELETE, EXAMINE, LIST, LSUB, RENAME, SELECT, STATUS, SUBSCRIBE, UNSUBSCRIBE

Selected

Operations involving messages. Commands: CHECK, CLOSE, COPY, EXPUNGE, FETCH, SEARCH, STORE, UID

The client must keep track of the current session state in order to know which commands are valid.

For a table of SDK-supported IMAP4 protocol commands that lists the state in which each can be called, see Supported IMAP4 Internet Protocol Commands. For detailed information about IMAP4 and IMAP4 session states, consult one of the RFCs listed, with links, in IMAP4 RFCs.

[Top]

Steps in an IMAP4 Session

Generally, a messaging application follows these steps when using IMAP4 to receive mail and manage mailboxes and messages. These steps are listed below with links to more detailed descriptions.

Step Section with details

Create a response sink.

Creating a Response Sink

Create a client.

Creating a Client

Connect to the server.

Connecting to a Server

Log in.

Logging In and Out

Check for new messages.

Checking for New Messages

Select a mailbox.

Searching for Messages

Fetch a new message.

Fetching Message Data

Perform other message and mailbox management tasks.

IMAP4 in the Messaging Access SDK

Close the mailbox.

Closing a Mailbox

[Top]

IMAP4 in the Messaging Access SDK

The IMAP4 class hierarchy is made up of the following classes.

[Top]

IMAP4 Callback Mapping

Callbacks are associated with many IMAP4 methods. For general information about the response sink and callbacks, see SDK Sink Classes for Java.

The IIMAP4Sink interface contains callbacks for each client call. The client's processResponses method invokes the interface method that corresponds to the client call.

Methods with multi-line responses map to two or more callbacks. For example, when a method is mapped to three callbacks, the first provides a notification of the start of the operation, the second of the response, and the third that the operation is complete.

Many IMAP4 methods generate a tag (out_ppTagID) that you can use to help match the command and the response associated with it within the within the IMAP4Client.taggedLine response.

If a server error occurs, the error callback is invoked.

Table 4.2 shows which IMAP4 methods are mapped to callbacks in the IIMAP4Sink interface.

Table 4.2 Methods with Callbacks

IMAP4Client Methods Possible Callbacks on IIMAP4Sink
General Commands
connect 
ok, error
disconnect 
bye 
sendCommand 
rawResponse, taggedLine, error 
Non-Authenticated State Commands
capability 
capability, taggedLine, error 
noop
exists, expunge, recent, fetchStart,
fetchFlags, fetchEnd, taggedLine, error
login 
taggedLine, error 
logout 
bye, taggedLine, error 
Authenticated State Commands
append 
taggedLine, error 
create
taggedLine, error 
delete
taggedLine, error 
examine 
flags, exists, recent, ok, taggedLine, error
list 
list, taggedLine, error 
lsub
lsub, taggedLine, error 
rename 
taggedLine, error 
select
flags, exists, recent, ok, taggedLine, error
status
statusMessages, statusRecent, 
statusUidnext, statusUidvalidity,
statusUnseen, taggedLine, error
subscribe
taggedLine, error 
unsubscribe
taggedLine, error 
Selected State Commands
check
taggedLine, error 
close
taggedLine, error 
copy
taggedLine, error 
uidCopy
taggedLine, error 
expunge 
expunge, taggedLine, error 
fetch 
fetchStart, fetchEnd, fetchSize, 
fetchData, fetchFlags, fetchBodyStructure,
fetchEnvelope, fetchInternalDate,
fetchHeader, fetchUid, taggedLine, error
uidFetch 
fetchStart, fetchEnd, fetchSize, 
fetchData, fetchFlags, fetchBodyStructure,
fetchEnvelope, fetchInternalDate,
fetchHeader, fetchUid, taggedLine, error
search 
searchStart, search, searchEnd,
taggedLine, error
uidSearch
searchStart, search, searchEnd, 
taggedLine, error
store
taggedLine, error 
uidStore
taggedLine, error 
Extended IMAP Commands
nameSpace 
nameSpaceStart, nameSpacePersonal,
nameSpaceOtherUsers, nameSpaceShared,
nameSpaceEnd, taggedLine, error
setACL 
taggedLine, error 
deleteACL
taggedLine, error 
getACL
aclStart, aclIdentifierRight, aclEnd, taggedLine, error 
myRights 
myRights, taggedLine, error 
listRights 
listRightsStart, listRightsRequiredRights,
listRightsOptionalRights, listRightsEnd,
taggedLine, error
[Top] [IMAP4 Callback Mapping]


Creating a Response Sink

The first step in starting an IMAP4 session is to create the IMAP4 response sink, which is defined in the IIMAP4Sink interface. For general information about the response sink, see SDK Sink Classes for Java.

The IIMAP4Sink interface contains callbacks for each client call. You must implement this interface in order to use the IMAP4 client object. The constructor for the IMAP4Client class takes an IIMAP4Sink object as a parameter.

To create a response sink class, you can implement the IIMAP4Sink interface. Use this syntax:

public class ResponseSink 
   implements IIMAP4Sink {
   /* implementation of all methods declared in the sink */
   }
As a convenience, the Messaging SDK provides the IMAP4Sink class, which implements the IIMAP4Sink interface. IMAP4Sink implements all the interfaces in IIMAP4Sink. By default, the implementation does nothing, except provide the error callback, which throws an exception. You can save time by extending this class, using this syntax:

public class ResponseSink extends IMAP4Sink{
   }
The following section of code creates a response sink.

ResponseSink l_sink = new ResponseSink();
After you create the response sink, the next step is Creating a Client.

[Top]

Creating a Client

The IMAP4 client uses an IMAP4Client object to communicate with the server. To create the IMAP4Client object and set the response sink for the client's use, call the IMAP4Client.IMAP4Client class constructor, which takes an existing response sink. Use this syntax:

public IMAP4Client(IIMAP4Sink in_sink)
The following section of code creates a client.

/* After Creating a Response Sink */
IMAP4Client l_client = new IMAP4Client(l_sink);
After you initialize the client, the next step is Connecting to a Server.

[Top]

Connecting to a Server

Before retrieving mail, the client must connect with the server through a service port. To connect to the server, call either of the two connect methods in the IMAP4Client class, depending on whether or not you want to specify the connection port.

To connect to the server using the default port (143) for the IMAP4 protocol, use this form of connect and supply the identifier of the server:

public synchronized boolean connect(String in_IMAPHost) 
                                    throws IOException
To specify the server port to use for the server connection, use the other form of connect. With this form, you can pass in the port number as well as the server identification, as follows:

public synchronized boolean connect(String in_IMAPHost, 
                                    int in_portNumber)
                                    throws IOException
These methods generate tags that you can use to help match the commands and the responses associated with them.

The following section of code connects the client to the server.

/* After Creating a Response Sink and Creating a Client */
l_client.connect ( "HOSTNAME", 143);
l_client.processResponses();
During the connect process, you can find out what extensions the server supports. For more information, see Determining Server Capabilities. You also might want to log in. For more information, see Logging In and Out.

To disconnect the client from the server and close the socket connection, use this IMAP4Client class method:

public synchronized void disconnect() throws IOException
You could use this method as part of a Cancel operation while retrieving a message. Remember that you do not call processResponses after disconnect.

NOTE: For the callback mapping for these methods, see IMAP4 Callback Mapping. §
[Top]

Determining Server Capabilities

To retrieve a listing of the capabilities that are supported by the server, call the IMAP4Client.capability method:

public synchronized String capability() throws IOException
This method calls the CAPABILITY IMAP4 protocol command, which can be issued in any session state, but is usually issued after connecting to the server.

NOTE: For this method's callback mapping, see IMAP4 Callback Mapping. §
The following section of code retrieves a list of server capabilities.

/* After Connecting to a Server */
l_client.capability();
l_client.processResponses();

[Top]

Logging In and Out

Once the client is connected to the server, the user can log in. Login identifies the client to the server. Logging in requires the user ID and the plain text password that authenticates this user. Use this IMAP4Client class method:

public synchronized String login(String in_user,
                  String in_password) throws IOException
The method sends the LOGIN IMAP4 protocol command, which can be issued during the Non-Authenticated state. Successful login moves the IMAP4 session to the Authenticated state, where the user can search for messages and manage messages on the server. This method generate a tag that you can use to help match the command and the response associated with it.

The following section of code logs the user in with user name and password.

l_client.login("userid", "password");
l_client.processResponses();
After you log in, the next step is Checking for New Messages.

To log out at the end of a session, use this IMAP4Client class method:

public synchronized String logout() throws IOException
The following section of code logs the user out.

l_client.logout();
l_client.processResponses();
NOTE: For the callback mapping for these methods, see IMAP4 Callback Mapping. §
[Top]

Checking for New Messages

Most IMAP4 servers check for messages whenever a command is issued. In the absence of commands, the server does not check for messages and may disconnect. To keep the server open indefinitely and check for messages periodically, the developer can call IMAP4Client.noop at set intervals.

The noop method is ideal for polling for new mail and ensuring that the server connection is still active. noop does nothing in itself, so it only produces the side effect of resetting the autologout timer inside the server and retrieving unsolicited server responses, which all commands do. The server responses may indicate the arrival of new messages or a change in the attributes of an existing message. Use this method:

public synchronized String noop() throws IOException 
NOTE: For this method's callback mapping, see IMAP4 Callback Mapping. §
The following section of code uses IMAP4Client.noop to check for messages.

l_client.noop();
l_client.processResponses();
After checking for new messages, the next step is Searching for Messages.

[Top]

Searching for Messages

The IMAP4Client class provides two ways to search for messages while in the Selected state. Two methods, search and uidsearch, search the currently selected mailbox and return the message numbers of messages that match a search key. These numbers can be used in turn to fetch the messages themselves.

You can supply one or more of the search keys defined in RFC 2060, section 6.4.4. Place more than one search key in a parenthesized list.

The IMAP4Client.search method searches the mailbox for messages that match the search criteria and returns their message numbers:

public synchronized String search(String in_criteria) 
This method sends the SEARCH IMAP4 protocol command, which can be issued in the Selected session state.

The IMAP4Client.uidSearch method retrieves the message numbers that match the search criteria in the currently selected mailbox:

public synchronized String uidSearch(String in_criteria)
                                     throws IOException
This method uses the UID IMAP4 protocol command to specify that the SEARCH command uses unique message identifiers rather than sequence numbers.

Both methods generate tags that you can use to help match the command and the response associated with it.

NOTE: For the callback mapping for these methods, see IMAP4 Callback Mapping. §
The following section of code searches for messages that have the SUBJECT "afternoon meeting."

l_client.search("SUBJECT \"Afternoon Meeting\"");
l_client.processResponses();
After locating messages, the next step is Fetching Message Data.

[Top]

Fetching Message Data

IMAP4 provides two methods that fetch messages while in the Selected state. IMAP4Client.fetch and IMAP4Client.uidfetch both search the currently selected mailbox and retrieve the data specified by the fetch criteria.

When you fetch messages, you supply the message set (mailbox) and one or more fetch criteria, placing more than one data item in a parenthesized list. The fetch criteria determine the information that is returned. You can fetch one or more of the data items defined in RFC 2060, section 6.4.5.

The IMAP4Client.fetch method performs a fetch:

public synchronized String fetch(String in_msgSet,
            String in_fetchCriteria) throws IOException
The IMAP4Client.uidfetch method performs a fetch using unique identifiers for messages:

public synchronized String uidFetch(String in_msgSet,
            String in_fetchCriteria) throws IOException
It uses the UID IMAP4 protocol command to specify that the FETCH command uses unique message identifiers rather than sequence numbers.

Both methods generate tags that you can use to help match the command and the response associated with it.

NOTE: For the callback mapping for these methods, see IMAP4 Callback Mapping. §
The following section of code fetches the body of the message specified by the message number.

l_client.fetch("1:*", "(BODY[HEADER])");
l_client.processResponses();
[Top]

Closing a Mailbox

To close a mailbox, use the IMAP4Client.close method. This method sends the CLOSE IMAP4 protocol command, which closes the mailbox and removes any messages marked with the \Deleted flag. You can close the mailbox without logging out. In this case, the session moves to the parent mailbox. Use this syntax:

public synchronized String close() throws IOException
If you need to permanently delete messages without closing, call the IMAP4Client.expunge method.

This method generate a tag that you can use to help match the command and the response associated with it.

NOTE: For this method's callback mapping, see IMAP4 Callback Mapping. §
The following section of code closes a mailbox.

l_client.close();
l_client.processResponses();
[Top]


Table of Contents | Previous | Next | Index

Last Updated: June 3, 1998

Copyright © 1998 Netscape Communications Corporation