Allow EasSyncCollectionTypeBase to use member variables

Change-Id: I5a59b8b1f21fb1dd9e13ddc15a4d9e3f25b45b47
(cherry picked from commit d6ee5946d0c3c1f47f11259ac3941d9967a9a70d)
diff --git a/src/com/android/exchange/eas/EasOperation.java b/src/com/android/exchange/eas/EasOperation.java
index 821aa43..e53363a 100644
--- a/src/com/android/exchange/eas/EasOperation.java
+++ b/src/com/android/exchange/eas/EasOperation.java
@@ -188,7 +188,7 @@
 
     /**
      * Some operations happen before the account exists (e.g. account validation).
-     * These operations cannot use {@link #loadAccount}, so instead we make a dummy account and
+     * These operations cannot use {@link #init}, so instead we make a dummy account and
      * supply a temporary {@link HostAuth}.
      * @param hostAuth
      */
@@ -200,14 +200,15 @@
 
     /**
      * Loads (or reloads) the {@link Account} for this operation, and sets up our connection to the
-     * server.
+     * server. This can be overridden to add additional functionality, but child implementations
+     * should always call super().
      * @param allowReload If false, do not perform a load if we already have an {@link Account}
      *                    (i.e. just keep the existing one); otherwise allow replacement of the
      *                    account. Note that this can result in a valid Account being replaced with
      *                    null if the account no longer exists.
      * @return Whether we now have a valid {@link Account} object.
      */
-    public final boolean loadAccount(final boolean allowReload) {
+    public boolean init(final boolean allowReload) {
         if (mAccount == null || allowReload) {
             mAccount = Account.restoreAccountWithId(mContext, getAccountId());
             if (mAccount != null) {
@@ -264,7 +265,9 @@
      */
     public int performOperation() {
         // Make sure the account is loaded if it hasn't already been.
-        if (!loadAccount(false)) {
+        if (!init(false)) {
+            // TODO: Fix this comment and error code, init() can now fail for reasons other than
+            // failing to load the account.
             LogUtils.i(LOG_TAG, "Failed to load account %d before sending request for operation %s",
                     getAccountId(), getCommand());
             return RESULT_ACCOUNT_ID_INVALID;
diff --git a/src/com/android/exchange/eas/EasSyncBase.java b/src/com/android/exchange/eas/EasSyncBase.java
index cf48ae1..dfa5e9b 100644
--- a/src/com/android/exchange/eas/EasSyncBase.java
+++ b/src/com/android/exchange/eas/EasSyncBase.java
@@ -2,7 +2,6 @@
 
 import android.content.Context;
 import android.text.format.DateUtils;
-import android.util.SparseArray;
 
 import com.android.emailcommon.provider.Account;
 import com.android.emailcommon.provider.EmailContent;
@@ -33,23 +32,10 @@
 
     private final boolean mInitialSync;
     private final Mailbox mMailbox;
+    private EasSyncCollectionTypeBase mCollectionTypeHandler;
 
     private int mNumWindows;
 
-    /**
-     * {@link EasSyncCollectionTypeBase} classes currently are stateless, so there's no need to
-     * create one per operation instance. We just maintain a single instance of each in a map and
-     * grab it as necessary.
-     */
-    private static final SparseArray<EasSyncCollectionTypeBase> COLLECTION_TYPE_HANDLERS;
-    static {
-        COLLECTION_TYPE_HANDLERS = new SparseArray<EasSyncCollectionTypeBase>(3);
-        // TODO: As the subclasses are created, add them to the map.
-        COLLECTION_TYPE_HANDLERS.put(Mailbox.TYPE_MAIL, new EasSyncMail());
-        COLLECTION_TYPE_HANDLERS.put(Mailbox.TYPE_CALENDAR, null);
-        COLLECTION_TYPE_HANDLERS.put(Mailbox.TYPE_CONTACTS, null);
-    }
-
     // TODO: Convert to accountId when ready to convert to EasService.
     public EasSyncBase(final Context context, final Account account, final Mailbox mailbox) {
         super(context, account);
@@ -79,19 +65,24 @@
     }
 
     @Override
+    public boolean init(final boolean allowReload) {
+        final boolean result = super.init(allowReload);
+        if (result) {
+            mCollectionTypeHandler = getCollectionTypeHandler(mMailbox.mType);
+            if (mCollectionTypeHandler == null) {
+                return false;
+            }
+        }
+        return result;
+    }
+
+    @Override
     protected HttpEntity getRequestEntity() throws IOException {
         final String className = Eas.getFolderClass(mMailbox.mType);
         final String syncKey = getSyncKey();
         LogUtils.d(TAG, "Syncing account %d mailbox %d (class %s) with syncKey %s", mAccount.mId,
                 mMailbox.mId, className, syncKey);
 
-        final EasSyncCollectionTypeBase collectionTypeHandler =
-                getCollectionTypeHandler(mMailbox.mType);
-        if (collectionTypeHandler == null) {
-            throw new IllegalStateException("No handler for collection type: "
-                    + Integer.toString(mMailbox.mType));
-        }
-
         final Serializer s = new Serializer();
         s.start(Tags.SYNC_SYNC);
         s.start(Tags.SYNC_COLLECTIONS);
@@ -102,7 +93,7 @@
         }
         s.data(Tags.SYNC_SYNC_KEY, syncKey);
         s.data(Tags.SYNC_COLLECTION_ID, mMailbox.mServerId);
-        collectionTypeHandler.setSyncOptions(mContext, s, getProtocolVersion(), mAccount, mMailbox,
+        mCollectionTypeHandler.setSyncOptions(mContext, s, getProtocolVersion(), mAccount, mMailbox,
                 mInitialSync, mNumWindows);
         s.end().end().end().done();
 
@@ -113,9 +104,8 @@
     protected int handleResponse(final EasResponse response)
             throws IOException, CommandStatusException {
         try {
-            final AbstractSyncParser parser =
-                    getCollectionTypeHandler(mMailbox.mType).getParser(mContext, mAccount, mMailbox,
-                            response.getInputStream());
+            final AbstractSyncParser parser = mCollectionTypeHandler.getParser(mContext, mAccount,
+                    mMailbox, response.getInputStream());
             final boolean moreAvailable = parser.parse();
             if (moreAvailable) {
                 return RESULT_MORE_AVAILABLE;
@@ -161,14 +151,25 @@
      * @param type The type of the {@link Mailbox} that we're trying to sync.
      * @return An {@link EasSyncCollectionTypeBase} appropriate for this type.
      */
-    private static EasSyncCollectionTypeBase getCollectionTypeHandler(final int type) {
-        EasSyncCollectionTypeBase typeHandler = COLLECTION_TYPE_HANDLERS.get(type);
-        if (typeHandler == null) {
-            // Treat mail as the default; this also means we don't bother mapping every type of
-            // mail folder.
-            // TODO: Should we just do that?
-            typeHandler = COLLECTION_TYPE_HANDLERS.get(Mailbox.TYPE_MAIL);
+    private EasSyncCollectionTypeBase getCollectionTypeHandler(final int type) {
+        switch (type) {
+            case Mailbox.TYPE_MAIL:
+            case Mailbox.TYPE_INBOX:
+            case Mailbox.TYPE_DRAFTS:
+//            case Mailbox.TYPE_SENT:
+//            case Mailbox.TYPE_TRASH:
+            case Mailbox.TYPE_JUNK: {
+                return new EasSyncMail();
+            }
+            case Mailbox.TYPE_CALENDAR:
+                // TODO: fill this in when we have EasSyncContacts;
+                return null;
+            case Mailbox.TYPE_CONTACTS:
+                // TODO: fill this in when we have EasSyncContacts;
+                return null;
+            default:
+                LogUtils.e(LOG_TAG, "unexpected collectiontype %d", type);
+                return null;
         }
-        return typeHandler;
     }
 }