public class IdleManager
extends java.lang.Object
For a Java EE 7 application:ExecutorService es = Executors.newCachedThreadPool(); 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:@Resource ManagedExecutorService es; final IdleManager idleManager = new IdleManager(session, es);
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.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"); // process new messages idleManager.watch(folder); // keep watching for new messages } }); idleManager.watch(folder);
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 following should be done once... Properties props = session.getProperties(); props.put("mail.event.scope", "session"); // or "application" props.put("mail.event.executor", es);
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.
Modifier and Type | Field and Description |
---|---|
private boolean |
die |
private java.util.concurrent.Executor |
es |
private MailLogger |
logger |
private java.nio.channels.Selector |
selector |
private java.util.Queue<IMAPFolder> |
toAbort |
private java.util.Queue<IMAPFolder> |
toWatch |
Constructor and Description |
---|
IdleManager(Session session,
java.util.concurrent.Executor es)
Create an IdleManager.
|
Modifier and Type | Method and Description |
---|---|
private boolean |
processKeys()
Process the selected keys, returning true if any folders have
been added to the watch list.
|
(package private) 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. |
void |
stop()
Stop the IdleManager.
|
private void |
unwatchAll()
Stop watching all folders.
|
void |
watch(Folder 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.
|
private java.util.concurrent.Executor es
private java.nio.channels.Selector selector
private MailLogger logger
private volatile boolean die
private java.util.Queue<IMAPFolder> toWatch
private java.util.Queue<IMAPFolder> toAbort
public IdleManager(Session session, java.util.concurrent.Executor es) throws java.io.IOException
session
- the Session containing configuration informationes
- the Executor used to create threadsjava.io.IOException
public void watch(Folder folder) throws java.io.IOException, MessagingException
folder
- the folder to watchMessagingException
- for errors related to the folderjava.io.IOException
- for SocketChannel errorsvoid requestAbort(IMAPFolder folder)
private void select()
select
loop
to poll each watched folder for events sent from the server.private void watchAll()
private boolean processKeys() throws java.io.IOException
java.io.IOException
private void unwatchAll()
public void stop()