com.google.sitebricks.mail.MailClient Maven / Gradle / Ivy
package com.google.sitebricks.mail;
import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.sitebricks.mail.imap.*;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Set;
/**
* An IMAP mail client based on JBoss Netty and Event-driven IO.
*
* @author [email protected] (Dhanji R. Prasanna)
*/
public interface MailClient {
/**
* Connects to the IMAP server logs in with the given credentials. Waits until the
* connection is established before returning. Returns true if the connection auth
* was successful. If not, the login error message can be obtained by calling
* {@link #lastError()}
*/
boolean connect();
/**
* Identical to {@link #connect()}.
*
* @param listener A listener to be notified when this client is disconnected due
* to any IO error or closed normally. Can be null.
*/
boolean connect(DisconnectListener listener);
/**
* Logs out of the current IMAP session and releases all resources, including
* executor services.
*/
void disconnect();
/**
* Same as {@link #disconnect()} but does so on a separate worker thread, the caller
* returns immediately.
*/
void disconnectAsync();
/**
* Returns true if the underlying channels are connected to the remote server, logged in and
* open for business.
*/
boolean isConnected();
List capabilities();
ListenableFuture> listFolders();
ListenableFuture statusOf(String folder);
/**
* Opens a logical 'session' to the given folder name. This method must be called
* prior to using many of the in-folder methods on this API. Opens folder in
* READ-ONLY mode.
*
* Equivalent of calling {@link #open(String, boolean)} with readWrite as false.
*/
ListenableFuture open(String folder);
/**
* Opens a logical 'session' to the given folder name. This method must be called
* prior to using many of the in-folder methods on this API.
* @param folder The canonical name of the folder on the IMAP server.
* @param readWrite If true, will open the folder in READ-WRITE mode. Otherwise,
* in READ-ONLY mode.
*/
ListenableFuture open(String folder, boolean readWrite);
/**
* Returns a list of message headers in the given folder, between {@code start}
* and {@code end}. The start is a 1-based index into the current session's "view"
* of an IMAP folder. The message numbers are guaranteed not to change UNLESS
* new mail is added or removed during a session (listen for this using the
* {@link #watch(Folder, FolderObserver)} method.
*
* The returned list is in ascending order (start : end) determined by the IMAP
* server (the protocol requires chronological descending order--recent : old).
*
* The messages returned in the list are lightweight {@link MessageStatus} objects
* which only contain cursory information and some metadata about a message,
* including the subject. This is useful to quickly obtain a list of messages
* whose bodies can be fetched later with the more comprehensive
* {@link #fetch(Folder, int, int)} method.
*
* NOTE: you must call {@link #open(String)} first.
*/
ListenableFuture> list(Folder folder, int start, int end);
/**
*
* Exactly the same as {@link #list(com.google.sitebricks.mail.imap.Folder, int, int)}
* except the range specified is in IMAP UID, rather than sequence number.
*
* NOTE: you must call {@link #open(String)} first.
*/
ListenableFuture> listUidThin(Folder folder, int start, int end);
ListenableFuture> listUidThin(Folder folder, List sequences);
/**
* Runs a search for a raw query as provided by gmail, and returns the UIDs of the
* corresponding result. Returns an empty list if there were no results.
*/
ListenableFuture> searchUid(Folder folder, String query, Date since);
/**
* Returns the list of uids that exist in the given folder. Returns an empty list if
* none existed.
*/
ListenableFuture> exists(Folder folder, Collection uids);
/**
* Flush the messages marked as \Deleted in this connection/session.
*/
void expunge();
/**
* Copies a given imap message to the specified folder by UID.
*/
ListenableFuture copy(Folder folder, int imapUid, String toFolder);
/**
* Adds flags to a range of messages.
*
* @return the new flags on the message, null on failure.
* NOTE: these can be different to those set due to concurrent updates by other clients.
* NOTE: you must call {@link #open(String)} first.
*/
ListenableFuture> addFlags(Folder folder, int imapUid, Set flags);
/**
* Removes flags from a range of messages.
*
* @return the new flags on the message, null on failure.
* NOTE: these can be different to those set due to concurrent updates by other clients.
* NOTE: you must call {@link #open(String)} first.
*/
ListenableFuture> removeFlags(Folder folder, int imapUid, Set flags);
/**
* Adds or Removes flags from a range of messages.
*
* @param add if true, flags are added, otherwise they're removed.
* @return the new flags on the message, null on failure.
* NOTE: these can be different to those set due to concurrent updates by other clients.
* NOTE: you must call {@link #open(String)} first.
*/
ListenableFuture> addOrRemoveFlags(Folder folder, int imapUid, Set flags,
boolean add);
/**
* Adds or removes Gmail labels from a range of messages.
*
* @param add if true, flags are added, otherwise they're removed.
* @return the new labels on the message, null on failure.
* NOTE: these can be different to those set due to concurrent updates by other clients.
* NOTE: you must call {@link #open(String)} first.
*/
ListenableFuture> addOrRemoveGmailLabels(Folder folder, int imapUid,
Set labels, boolean add);
/**
* Similar to {@link #list(Folder, int, int)} but fetches the entire message
* instead of merely a header. Runs a bit slower as a result.
*
* This returns the complete details of an email message. Prefer {@link #list(Folder, int, int)}
* for fetching just subjects/status info as this method can be slower
* for messages with large bodies.
*
* NOTE: you must call {@link #open(String)} first.
*/
public ListenableFuture> fetch(Folder folder, int start, int end);
/**
* Watches a folder for changes. This is an implementation of the IMAP IDLE command and
* is the preferred method for push notification.
*
* NOTE: you must call {@link #open(String)} first.
*/
void watch(Folder folder, FolderObserver observer);
/**
* Stops watching a folder if one was currently being watched (otherwise
* a noop). Events from 'IDLEing' will immediately stop when this method
* returns and the registered {@link FolderObserver} will be forgotten.
*
* Note the subtle point that this method (though it doesn't block) will
* immediately stop firing events to its FolderObserver. This happens
* even before IDLEing ceases on the server.
* @return whether the connection was being watched when called.
*/
boolean unwatch();
/**
* Returns a string containing the last error message from the server or
* null if no errors occurred recently.
*/
WireError lastError();
/**
* Returns the last few items received on the wire, useful for debugging.
*/
List getWireTrace();
/**
* Returns the last few commands sent on the wire, used for debugging.
* @return
*/
public List getCommandTrace();
/**
* Returns true if this client has successfully entered and is currently in IMAP IDLE.
*/
boolean isIdling();
/**
* Allows you to dynamically update the value of access token and tokenSecret if using
* XOAuth to access an imap server. This is useful if a user logs in from multiple locations
* and you always want the last authorized token to be used when reconnecting existing mail
* clients.
*
* @param accessToken A string containing the access token as retrieved from the oauth server.
* @param tokenSecret A string contianing the token secret pair of the accessToken.
*/
void updateOAuthAccessToken(String accessToken, String tokenSecret);
/**
* Allows you to dynamically update the value of access token if using XOAuth2 to access
* an imap server. This is useful if a user logs in from multiple locations
* and you always want the last authorized token to be used when reconnecting existing mail
* clients.
*
* @param accessToken A string containing the access token as retrieved from the oauth server.
*/
void updateOAuth2AccessToken(String accessToken);
/**
* Fetches a single message by its uid.
*/
ListenableFuture fetchUid(Folder folder, int uid);
ListenableFuture> setGmailLabels(Folder folder, int imapUid,
Set labels);
static interface DisconnectListener {
void disconnected();
/**
* Called when the server acknowledges IDLE.
*/
void idled();
/**
* Called when the server acknowledges exit from IDLE.
*/
void unidled();
}
public static interface WireError {
String message();
List trace();
String expected();
String toString();
}
public static class Sequence {
public final int start;
public final int end;
/**
* A range of uids or seq number. Specify -1 for wildcard for either bound.
* An end of 0 indicates
*/
public Sequence(int start, int end) {
Preconditions.checkArgument(start != 0, "Start of range cannot be 0");
this.start = start;
this.end = end;
}
/**
* A single number to fetch.
*/
public Sequence(int start) {
this(start, 0);
}
}
}