Top Description Fields Constructors Methods
com.sun.mail.imap

public Class IdleManager

extends Object
Class Inheritance
Imports
java.io.IOException, .InterruptedIOException, java.net.Socket, java.nio.*, java.nio.channels.*, java.util.*, java.util.logging.*, java.util.concurrent.ConcurrentLinkedQueue, .Executor, javax.mail.*, com.sun.mail.imap.protocol.IMAPProtocol, com.sun.mail.util.MailLogger

IdleManager uses the optional IMAP IDLE command (RFC 2177) to watch multiple folders for new messages. IdleManager uses an Executor to execute tasks in separate threads. An Executor is typically provided by an ExecutorService. For example, for a Java SE application:
	ExecutorService es = Executors.newCachedThreadPool();
	final IdleManager idleManager = new IdleManager(session, es);
 
For a Java EE 7 application:
	@Resource
	ManagedExecutorService es;
	final IdleManager idleManager = new IdleManager(session, es);
 
To watch for new messages in a folder, open the folder, register a listener, and ask the IdleManager to watch the folder:
	Folder folder = store.getFolder("INBOX");
	folder.open(Folder.READ_WRITE);
	folder.addMessageCountListener(new MessageCountAdapter() {
	    public void messagesAdded(MessageCountEvent ev) {
		Folder folder = (Folder)ev.getSource();
		Message[] msgs = ev.getMessages();
		System.out.println("Folder: " + folder +
		    " got " + msgs.length + " new messages");
		try {
		    // process new messages
		    idleManager.watch(folder); // keep watching for new messages
		} catch (MessagingException mex) {
		    // handle exception related to the Folder
		}
	    }
	});
	idleManager.watch(folder);
 
This delivers the events for each folder in a separate thread, NOT using the Executor. To deliver all events in a single thread using the Executor, set the following properties for the Session (once), and then add listeners and watch the folder as above.
	// the following should be done once...
	Properties props = session.getProperties();
	props.put("mail.event.scope", "session"); // or "application"
	props.put("mail.event.executor", es);
 
Note that, after processing new messages in your listener, or doing any other operations on the folder in any other thread, you need to tell the IdleManager to watch for more new messages. Unless, of course, you close the folder.

The IdleManager is created with a Session, which it uses only to control debug output. A single IdleManager instance can watch multiple Folders from multiple Stores and multiple Sessions.

Due to limitations in the Java SE nio support, a SocketChannel must be used instead of a Socket to connect to the server. However, SocketChannels don't support all the features of Sockets, such as connecting through a SOCKS proxy server. SocketChannels also don't support simultaneous read and write, which means that the idle method can't be used if SocketChannels are being used; use this IdleManager instead. To enable support for SocketChannels instead of Sockets, set the mail.imap.usesocketchannels property in the Session used to access the IMAP Folder. (Or mail.imaps.usesocketchannels if you're using the "imaps" protocol.) This will effect all connections in that Session, but you can create another Session without this property set if you need to use the features that are incompatible with SocketChannels.

Note

The IdleManager, and all APIs and properties related to it, should be considered EXPERIMENTAL. They may be changed in the future in ways that are incompatible with applications using the current APIs.

Since
JavaMail 1.5.2

Field Summary

Modifier and TypeField and Description
private volatile boolean
private Executor
private MailLogger
private volatile boolean
private Selector
private Queue<IMAPFolder>
private Queue<IMAPFolder>

Constructor Summary

AccessConstructor and Description
public
IdleManager(Session
the Session containing configuration information
session
,
Executor
the Executor used to create threads
es
)

Create an IdleManager.

Method Summary

Modifier and TypeMethod and Description
private static String
folderName(Folder folder)

Return the fully qualified name of the folder, for use in log messages.

public boolean

Returns:

true if the IdleMaanger is running
isRunning
()

Is the IdleManager currently running?

private void
processKeys()

Process the selected keys.

pack-priv void
requestAbort(IMAPFolder folder)

Request that the specified folder abort an IDLE command.

private void
select()

Run the select loop to poll each watched folder for events sent from the server.

public synchronized void
stop()

Stop the IdleManager.

private void
unwatchAll()

Stop watching all folders.

public void
watch(Folder
the folder to watch
folder
)

Watch the Folder for new messages and other events using the IMAP IDLE command.

private void
watchAll()

Register all of the folders in the queue with the selector, switching them to nonblocking I/O mode first.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

dieback to summary
private volatile boolean die
esback to summary
private Executor es
loggerback to summary
private MailLogger logger
runningback to summary
private volatile boolean running
selectorback to summary
private Selector selector
toAbortback to summary
private Queue<IMAPFolder> toAbort
toWatchback to summary
private Queue<IMAPFolder> toWatch

Constructor Detail

IdleManagerback to summary
public IdleManager(Session session, Executor es) throws IOException

Create an IdleManager. The Session is used only to configure debugging output. The Executor is used to create the "select" thread.

Parameters
session:Session

the Session containing configuration information

es:Executor

the Executor used to create threads

Exceptions
IOException:
for Selector failures

Method Detail

folderNameback to summary
private static String folderName(Folder folder)

Return the fully qualified name of the folder, for use in log messages. Essentially just the getURLName method, but ignoring the MessagingException that can never happen.

isRunningback to summary
public boolean isRunning()

Is the IdleManager currently running? The IdleManager starts running when the Executor schedules its task. The IdleManager stops running after its task detects the stop request from the stop method, or if it terminates abnormally due to an unexpected error.

Returns:boolean

true if the IdleMaanger is running

Since
JavaMail 1.5.5
processKeysback to summary
private void processKeys() throws IOException

Process the selected keys.

requestAbortback to summary
pack-priv void requestAbort(IMAPFolder folder)

Request that the specified folder abort an IDLE command. We can't do the abort directly because the DONE message needs to be sent through the (potentially) SSL socket, which means we need to be in blocking I/O mode. We can only switch to blocking I/O mode when not selecting, so wake up the selector, which will process this request when it wakes up.

selectback to summary
private void select()

Run the select loop to poll each watched folder for events sent from the server.

stopback to summary
public synchronized void stop()

Stop the IdleManager. The IdleManager can not be restarted.

unwatchAllback to summary
private void unwatchAll()

Stop watching all folders. Cancel any selection keys and, most importantly, switch the channel back to blocking mode. If there's any folders waiting to be watched, need to abort them too.

watchback to summary
public void watch(Folder folder) throws MessagingException

Watch the Folder for new messages and other events using the IMAP IDLE command.

Parameters
folder:Folder

the folder to watch

Exceptions
MessagingException:
for errors related to the folder
watchAllback to summary
private void watchAll()

Register all of the folders in the queue with the selector, switching them to nonblocking I/O mode first.