Some more re-arrangement of code

No real code changes; just moving where code / constants live. Removed
one unused method of Store.

Change-Id: Ie7532381759a568cb23601e1071c8e199b6beb07
This commit is contained in:
Todd Kennedy 2011-05-16 14:47:49 -07:00
parent ebece4dbdc
commit 171c3f2273
8 changed files with 40 additions and 75 deletions

View File

@ -67,6 +67,12 @@ public abstract class Store {
@VisibleForTesting @VisibleForTesting
static final HashMap<String, Store> sStores = new HashMap<String, Store>(); static final HashMap<String, Store> sStores = new HashMap<String, Store>();
protected Context mContext;
protected Account mAccount;
protected Transport mTransport;
protected String mUsername;
protected String mPassword;
/** /**
* Static named constructor. It should be overrode by extending class. * Static named constructor. It should be overrode by extending class.
* Because this method will be called through reflection, it can not be protected. * Because this method will be called through reflection, it can not be protected.
@ -242,17 +248,6 @@ public abstract class Store {
return com.android.email.activity.setup.AccountSetupIncoming.class; return com.android.email.activity.setup.AccountSetupIncoming.class;
} }
/**
* Some stores cannot download a message based only on the uid, and need the message structure
* to be preloaded and provided to them. This method allows a remote store to signal this
* requirement. Most stores do not need this and do not need to overload this method, which
* simply returns "false" in the base class.
* @return Return true if the remote store requires structure prefetch
*/
public boolean requireStructurePrefetch() {
return false;
}
/** /**
* Some protocols require that a sent message be copied (uploaded) into the Sent folder * Some protocols require that a sent message be copied (uploaded) into the Sent folder
* while others can take care of it automatically (ideally, on the server). This function * while others can take care of it automatically (ideally, on the server). This function

View File

@ -39,7 +39,7 @@ import java.util.HashMap;
*/ */
public class ExchangeStore extends Store { public class ExchangeStore extends Store {
public static final String LOG_TAG = "ExchangeStore"; public static final String LOG_TAG = "ExchangeStore";
@SuppressWarnings("hiding")
private final ExchangeTransport mTransport; private final ExchangeTransport mTransport;
/** /**
@ -82,16 +82,6 @@ public class ExchangeStore extends Store {
return com.android.email.activity.setup.AccountSetupExchange.class; return com.android.email.activity.setup.AccountSetupExchange.class;
} }
/**
* Inform MessagingController that this store requires message structures to be prefetched
* before it can fetch message bodies (this is due to EAS protocol restrictions.)
* @return always true for EAS
*/
@Override
public boolean requireStructurePrefetch() {
return true;
}
/** /**
* Inform MessagingController that messages sent via EAS will be placed in the Sent folder * Inform MessagingController that messages sent via EAS will be placed in the Sent folder
* automatically (server-side) and don't need to be uploaded. * automatically (server-side) and don't need to be uploaded.

View File

@ -46,6 +46,9 @@ import javax.net.ssl.SSLException;
* A cacheable class that stores the details for a single IMAP connection. * A cacheable class that stores the details for a single IMAP connection.
*/ */
class ImapConnection { class ImapConnection {
// Always check in FALSE
private static final boolean DEBUG_FORCE_SEND_ID = false;
/** ID capability per RFC 2971*/ /** ID capability per RFC 2971*/
public static final int CAPABILITY_ID = 1 << 0; public static final int CAPABILITY_ID = 1 << 0;
/** NAMESPACE capability per RFC 2342 */ /** NAMESPACE capability per RFC 2342 */
@ -100,7 +103,7 @@ class ImapConnection {
try { try {
// copy configuration into a clean transport, if necessary // copy configuration into a clean transport, if necessary
if (mTransport == null) { if (mTransport == null) {
mTransport = mImapStore.mRootTransport.clone(); mTransport = mImapStore.cloneTransport();
} }
mTransport.open(); mTransport.open();
@ -306,7 +309,7 @@ class ImapConnection {
if (mUserAgent != null) { if (mUserAgent != null) {
mIdPhrase = ImapConstants.ID + " (" + mUserAgent + ")"; mIdPhrase = ImapConstants.ID + " (" + mUserAgent + ")";
} else if (ImapStore.DEBUG_FORCE_SEND_ID) { } else if (DEBUG_FORCE_SEND_ID) {
mIdPhrase = ImapConstants.ID + " " + ImapConstants.NIL; mIdPhrase = ImapConstants.ID + " " + ImapConstants.NIL;
} }
// else: mIdPhrase = null, no ID will be emitted // else: mIdPhrase = null, no ID will be emitted

View File

@ -60,6 +60,9 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
class ImapFolder extends Folder { class ImapFolder extends Folder {
private final static Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.SEEN, Flag.FLAGGED };
private static final int COPY_BUFFER_SIZE = 16*1024;
private final ImapStore mStore; private final ImapStore mStore;
private final String mName; private final String mName;
private int mMessageCount = -1; private int mMessageCount = -1;
@ -619,7 +622,7 @@ class ImapFolder extends Folder {
BinaryTempFileBody tempBody = new BinaryTempFileBody(); BinaryTempFileBody tempBody = new BinaryTempFileBody();
OutputStream out = tempBody.getOutputStream(); OutputStream out = tempBody.getOutputStream();
try { try {
byte[] buffer = new byte[ImapStore.COPY_BUFFER_SIZE]; byte[] buffer = new byte[COPY_BUFFER_SIZE];
int n = 0; int n = 0;
int count = 0; int count = 0;
while (-1 != (n = in.read(buffer))) { while (-1 != (n = in.read(buffer))) {
@ -640,7 +643,7 @@ class ImapFolder extends Folder {
@Override @Override
public Flag[] getPermanentFlags() { public Flag[] getPermanentFlags() {
return ImapStore.PERMANENT_FLAGS; return PERMANENT_FLAGS;
} }
/** /**

View File

@ -67,8 +67,8 @@ import java.util.regex.Pattern;
* TODO Need to start keeping track of UIDVALIDITY * TODO Need to start keeping track of UIDVALIDITY
* TODO Need a default response handler for things like folder updates * TODO Need a default response handler for things like folder updates
* TODO In fetch(), if we need a ImapMessage and were given * TODO In fetch(), if we need a ImapMessage and were given
* something else we can try to do a pre-fetch first.
* TODO Collect ALERT messages and show them to users. * TODO Collect ALERT messages and show them to users.
* something else we can try to do a pre-fetch first.
* *
* ftp://ftp.isi.edu/in-notes/rfc2683.txt When a client asks for * ftp://ftp.isi.edu/in-notes/rfc2683.txt When a client asks for
* certain information in a FETCH command, the server may return the requested * certain information in a FETCH command, the server may return the requested
@ -79,31 +79,17 @@ import java.util.regex.Pattern;
* </pre> * </pre>
*/ */
public class ImapStore extends Store { public class ImapStore extends Store {
/** Charset used for converting folder names to and from UTF-7 as defined by RFC 3501. */
private static final Charset MODIFIED_UTF_7_CHARSET =
new CharsetProvider().charsetForName("X-RFC-3501");
// Always check in FALSE
static final boolean DEBUG_FORCE_SEND_ID = false;
static final int COPY_BUFFER_SIZE = 16*1024;
static final Flag[] PERMANENT_FLAGS = { Flag.DELETED, Flag.SEEN, Flag.FLAGGED };
final Context mContext;
private final Account mAccount;
Transport mRootTransport;
@VisibleForTesting static String sImapId = null; @VisibleForTesting static String sImapId = null;
@VisibleForTesting String mPathPrefix; @VisibleForTesting String mPathPrefix;
@VisibleForTesting String mPathSeparator; @VisibleForTesting String mPathSeparator;
private String mUsername;
private String mPassword;
private final ConcurrentLinkedQueue<ImapConnection> mConnectionPool = private final ConcurrentLinkedQueue<ImapConnection> mConnectionPool =
new ConcurrentLinkedQueue<ImapConnection>(); new ConcurrentLinkedQueue<ImapConnection>();
/**
* Charset used for converting folder names to and from UTF-7 as defined by RFC 3501.
*/
private static final Charset MODIFIED_UTF_7_CHARSET =
new CharsetProvider().charsetForName("X-RFC-3501");
/** /**
* Cache of ImapFolder objects. ImapFolders are attached to a given folder on the server * Cache of ImapFolder objects. ImapFolders are attached to a given folder on the server
* and as long as their associated connection remains open they are reusable between * and as long as their associated connection remains open they are reusable between
@ -121,7 +107,8 @@ public class ImapStore extends Store {
} }
/** /**
* Creates a new store for the given account. * Creates a new store for the given account. Always use
* {@link #newInstance(Account, Context, PersistentDataCallbacks)} to create an IMAP store.
*/ */
private ImapStore(Context context, Account account) throws MessagingException { private ImapStore(Context context, Account account) throws MessagingException {
mContext = context; mContext = context;
@ -147,10 +134,10 @@ public class ImapStore extends Store {
if (recvAuth.mPort != HostAuth.PORT_UNKNOWN) { if (recvAuth.mPort != HostAuth.PORT_UNKNOWN) {
port = recvAuth.mPort; port = recvAuth.mPort;
} }
mRootTransport = new MailTransport("IMAP"); mTransport = new MailTransport("IMAP");
mRootTransport.setHost(recvAuth.mAddress); mTransport.setHost(recvAuth.mAddress);
mRootTransport.setPort(port); mTransport.setPort(port);
mRootTransport.setSecurity(connectionSecurity, trustCertificates); mTransport.setSecurity(connectionSecurity, trustCertificates);
String[] userInfo = recvAuth.getLogin(); String[] userInfo = recvAuth.getLogin();
if (userInfo != null) { if (userInfo != null) {
@ -176,7 +163,7 @@ public class ImapStore extends Store {
*/ */
@VisibleForTesting @VisibleForTesting
void setTransportForTest(Transport testTransport) { void setTransportForTest(Transport testTransport) {
mRootTransport = testTransport; mTransport = testTransport;
} }
/** /**
@ -511,6 +498,11 @@ public class ImapStore extends Store {
return mContext; return mContext;
} }
/** Returns a clone of the transport associated with this store. */
Transport cloneTransport() {
return mTransport.clone();
}
/** /**
* Fixes the path prefix, if necessary. The path prefix must always end with the * Fixes the path prefix, if necessary. The path prefix must always end with the
* path separator. * path separator.
@ -549,7 +541,8 @@ public class ImapStore extends Store {
} }
/** /**
* Save a {@link ImapConnection} in the pool for reuse. * Save a {@link ImapConnection} in the pool for reuse. Any responses associated with the
* connection are destroyed before adding the connection to the pool.
*/ */
void poolConnection(ImapConnection connection) { void poolConnection(ImapConnection connection) {
if (connection != null) { if (connection != null) {
@ -561,7 +554,7 @@ public class ImapStore extends Store {
/** /**
* Prepends the folder name with the given prefix and UTF-7 encodes it. * Prepends the folder name with the given prefix and UTF-7 encodes it.
*/ */
/* package */ static String encodeFolderName(String name, String prefix) { static String encodeFolderName(String name, String prefix) {
// do NOT add the prefix to the special name "INBOX" // do NOT add the prefix to the special name "INBOX"
if (ImapConstants.INBOX.equalsIgnoreCase(name)) return name; if (ImapConstants.INBOX.equalsIgnoreCase(name)) return name;
@ -581,7 +574,7 @@ public class ImapStore extends Store {
/** /**
* UTF-7 decodes the folder name and removes the given path prefix. * UTF-7 decodes the folder name and removes the given path prefix.
*/ */
/* package */ static String decodeFolderName(String name, String prefix) { static String decodeFolderName(String name, String prefix) {
// TODO bypass the conversion if name doesn't have special char. // TODO bypass the conversion if name doesn't have special char.
String folder; String folder;
folder = MODIFIED_UTF_7_CHARSET.decode(ByteBuffer.wrap(Utility.toAscii(name))).toString(); folder = MODIFIED_UTF_7_CHARSET.decode(ByteBuffer.wrap(Utility.toAscii(name))).toString();
@ -594,7 +587,7 @@ public class ImapStore extends Store {
/** /**
* Returns UIDs of Messages joined with "," as the separator. * Returns UIDs of Messages joined with "," as the separator.
*/ */
/* package */ static String joinMessageUids(Message[] messages) { static String joinMessageUids(Message[] messages) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
boolean notFirst = false; boolean notFirst = false;
for (Message m : messages) { for (Message m : messages) {

View File

@ -55,16 +55,11 @@ public class Pop3Store extends Store {
private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED }; private static final Flag[] PERMANENT_FLAGS = { Flag.DELETED };
/** The name of the only mailbox available to POP3 accounts */ /** The name of the only mailbox available to POP3 accounts */
private static final String POP3_MAILBOX_NAME = "INBOX"; private static final String POP3_MAILBOX_NAME = "INBOX";
private final Context mContext;
private final Account mAccount;
private Transport mTransport;
private String mUsername;
private String mPassword;
private final HashMap<String, Folder> mFolders = new HashMap<String, Folder>(); private final HashMap<String, Folder> mFolders = new HashMap<String, Folder>();
// /** // /**
// * Detected latency, used for usage scaling. // * Detected latency, used for usage scaling.
// * Usage scaling occurs when it is neccesary to get information about // * Usage scaling occurs when it is necessary to get information about
// * messages that could result in large data loads. This value allows // * messages that could result in large data loads. This value allows
// * the code that loads this data to decide between using large downloads // * the code that loads this data to decide between using large downloads
// * (high latency) or multiple round trips (low latency) to accomplish // * (high latency) or multiple round trips (low latency) to accomplish
@ -76,7 +71,7 @@ public class Pop3Store extends Store {
// //
// /** // /**
// * Detected throughput, used for usage scaling. // * Detected throughput, used for usage scaling.
// * Usage scaling occurs when it is neccesary to get information about // * Usage scaling occurs when it is necessary to get information about
// * messages that could result in large data loads. This value allows // * messages that could result in large data loads. This value allows
// * the code that loads this data to decide between using large downloads // * the code that loads this data to decide between using large downloads
// * (high latency) or multiple round trips (low latency) to accomplish // * (high latency) or multiple round trips (low latency) to accomplish

View File

@ -534,13 +534,6 @@ public class ImapStoreUnitTests extends InstrumentationTestCase {
assertEquals(Folder.FolderRole.UNKNOWN, mFolder.getRole()); assertEquals(Folder.FolderRole.UNKNOWN, mFolder.getRole());
} }
/**
* Lightweight test to confirm that IMAP isn't requesting structure prefetch.
*/
public void testNoStructurePrefetch() {
assertFalse(mStore.requireStructurePrefetch());
}
/** /**
* Lightweight test to confirm that IMAP is requesting sent-message-upload. * Lightweight test to confirm that IMAP is requesting sent-message-upload.
* TODO: Implement Gmail-specific cases and handle this server-side * TODO: Implement Gmail-specific cases and handle this server-side

View File

@ -333,13 +333,6 @@ public class Pop3StoreUnitTests extends InstrumentationTestCase {
} }
} }
/**
* Lightweight test to confirm that POP3 isn't requesting structure prefetch.
*/
public void testNoStructurePrefetch() {
assertFalse(mStore.requireStructurePrefetch());
}
/** /**
* Lightweight test to confirm that POP3 is requesting sent-message-upload. * Lightweight test to confirm that POP3 is requesting sent-message-upload.
*/ */