1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-02-15 06:30:17 -05:00

Keep the sync state of a remote EasFolder in sync with its local counterpart when synchronizing the folder.

This commit is contained in:
Kris Wong 2012-01-02 19:41:38 -05:00
parent 474780cbf4
commit a212965b99
5 changed files with 48 additions and 41 deletions

View File

@ -64,7 +64,6 @@ import com.fsck.k9.mail.store.UnavailableStorageException;
import com.fsck.k9.mail.store.LocalStore.LocalFolder; import com.fsck.k9.mail.store.LocalStore.LocalFolder;
import com.fsck.k9.mail.store.LocalStore.LocalMessage; import com.fsck.k9.mail.store.LocalStore.LocalMessage;
import com.fsck.k9.mail.store.LocalStore.PendingCommand; import com.fsck.k9.mail.store.LocalStore.PendingCommand;
import com.fsck.k9.mail.store.EasStore.EasFolder;
/** /**
@ -503,28 +502,21 @@ public class MessagingController implements Runnable {
private void syncLocalFoldersWithRemoteFolders(List<? extends Folder> localFolders, private void syncLocalFoldersWithRemoteFolders(List<? extends Folder> localFolders,
List<? extends Folder> remoteFolders, final Account account) throws MessagingException { List<? extends Folder> remoteFolders, final Account account) throws MessagingException {
HashSet<String> remoteFolderNames = new HashSet<String>(); HashSet<String> remoteFolderNames = new HashSet<String>();
HashMap<String, Folder> localFolderNames = new HashMap<String, Folder>(); HashSet<String> localFolderNames = new HashSet<String>();
List<LocalFolder> foldersToCreate = new LinkedList<LocalFolder>(); List<LocalFolder> foldersToCreate = new LinkedList<LocalFolder>();
LocalStore localStore = account.getLocalStore(); LocalStore localStore = account.getLocalStore();
for (Folder localFolder : localFolders) { for (Folder localFolder : localFolders) {
localFolderNames.put(localFolder.getRemoteName(), localFolder); localFolderNames.add(localFolder.getRemoteName());
} }
// Add any new folders in the remote store to the local store. // Add any new folders in the remote store to the local store.
for (Folder remoteFolder : remoteFolders) { for (Folder remoteFolder : remoteFolders) {
LocalFolder localFolder = (LocalFolder)localFolderNames.get(remoteFolder.getRemoteName()); if (!localFolderNames.contains(remoteFolder.getRemoteName())) {
if (localFolder == null) { foldersToCreate.add(localStore.getFolder(remoteFolder.getRemoteName(), remoteFolder.getName()));
localFolder = localStore.getFolder(remoteFolder.getRemoteName(),
remoteFolder.getName());
foldersToCreate.add(localFolder);
} }
remoteFolderNames.add(remoteFolder.getRemoteName()); remoteFolderNames.add(remoteFolder.getRemoteName());
if (remoteFolder instanceof EasFolder) {
((EasFolder)remoteFolder).setLocalFolder(localFolder, false);
}
} }
localStore.createFolders(foldersToCreate, account.getDisplayCount()); localStore.createFolders(foldersToCreate, account.getDisplayCount());
@ -849,7 +841,9 @@ public class MessagingController implements Runnable {
* TODO Break this method up into smaller chunks. * TODO Break this method up into smaller chunks.
* @param providedRemoteFolder TODO * @param providedRemoteFolder TODO
*/ */
private void synchronizeMailboxSynchronous(final Account account, final String folder, final MessagingListener listener, Folder providedRemoteFolder) { private void synchronizeMailboxSynchronous(final Account account, final String folder,
final MessagingListener listener, Folder providedRemoteFolder) {
Store remoteStore = null;
Folder remoteFolder = null; Folder remoteFolder = null;
LocalFolder tLocalFolder = null; LocalFolder tLocalFolder = null;
@ -859,6 +853,7 @@ public class MessagingController implements Runnable {
for (MessagingListener l : getListeners(listener)) { for (MessagingListener l : getListeners(listener)) {
l.synchronizeMailboxStarted(account, folder); l.synchronizeMailboxStarted(account, folder);
} }
/* /*
* We don't ever sync the Outbox or errors folder * We don't ever sync the Outbox or errors folder
*/ */
@ -907,17 +902,17 @@ public class MessagingController implements Runnable {
Log.v(K9.LOG_TAG, "SYNC: using providedRemoteFolder " + folder); Log.v(K9.LOG_TAG, "SYNC: using providedRemoteFolder " + folder);
remoteFolder = providedRemoteFolder; remoteFolder = providedRemoteFolder;
} else { } else {
Store remoteStore = account.getRemoteStore(); remoteStore = account.getRemoteStore();
if (K9.DEBUG) if (K9.DEBUG)
Log.v(K9.LOG_TAG, "SYNC: About to get remote folder " + folder); Log.v(K9.LOG_TAG, "SYNC: About to get remote folder " + folder);
remoteFolder = remoteStore.getFolder(folder); remoteFolder = remoteStore.getFolder(folder);
if (remoteFolder == null) { if (remoteFolder == null) {
throw new Exception("Store returned null remote folder for " + folder); throw new Exception("Attempted to synchronize a local-only folder " + folder);
} }
if (! verifyOrCreateRemoteSpecialFolder(account, folder, remoteFolder, listener)) { if (!verifyOrCreateRemoteSpecialFolder(account, folder, remoteFolder, listener)) {
return; return;
} }
@ -951,7 +946,6 @@ public class MessagingController implements Runnable {
Log.d(K9.LOG_TAG, "SYNC: Expunging folder " + account.getDescription() + ":" + folder); Log.d(K9.LOG_TAG, "SYNC: Expunging folder " + account.getDescription() + ":" + folder);
remoteFolder.expunge(); remoteFolder.expunge();
} }
} }
/* /*
@ -975,7 +969,6 @@ public class MessagingController implements Runnable {
Log.v(K9.LOG_TAG, "SYNC: Remote message count for folder " + folder + " is " + remoteMessageCount); Log.v(K9.LOG_TAG, "SYNC: Remote message count for folder " + folder + " is " + remoteMessageCount);
final Date earliestDate = account.getEarliestPollDate(); final Date earliestDate = account.getEarliestPollDate();
if (remoteMessageCount > 0 || syncMode) { if (remoteMessageCount > 0 || syncMode) {
/* Message numbers start at 1. */ /* Message numbers start at 1. */
int remoteStart; int remoteStart;
@ -994,7 +987,6 @@ public class MessagingController implements Runnable {
l.synchronizeMailboxHeadersStarted(account, folder); l.synchronizeMailboxHeadersStarted(account, folder);
} }
remoteMessageArray = remoteFolder.getMessages(remoteStart, remoteEnd, earliestDate, null); remoteMessageArray = remoteFolder.getMessages(remoteStart, remoteEnd, earliestDate, null);
int messageCount = remoteMessageArray.length; int messageCount = remoteMessageArray.length;
@ -1042,7 +1034,6 @@ public class MessagingController implements Runnable {
} }
} }
localFolder.destroyMessages(destroyMessages.toArray(EMPTY_MESSAGE_ARRAY)); localFolder.destroyMessages(destroyMessages.toArray(EMPTY_MESSAGE_ARRAY));
for (Message destroyMessage : destroyMessages) { for (Message destroyMessage : destroyMessages) {
@ -1061,7 +1052,6 @@ public class MessagingController implements Runnable {
int unreadMessageCount = setLocalUnreadCountToRemote(localFolder, remoteFolder, newMessages); int unreadMessageCount = setLocalUnreadCountToRemote(localFolder, remoteFolder, newMessages);
setLocalFlaggedCountToRemote(localFolder, remoteFolder); setLocalFlaggedCountToRemote(localFolder, remoteFolder);
for (MessagingListener l : getListeners()) { for (MessagingListener l : getListeners()) {
l.folderStatusChanged(account, folder, unreadMessageCount); l.folderStatusChanged(account, folder, unreadMessageCount);
} }
@ -1079,7 +1069,6 @@ public class MessagingController implements Runnable {
l.synchronizeMailboxFinished(account, folder, remoteMessageCount, newMessages); l.synchronizeMailboxFinished(account, folder, remoteMessageCount, newMessages);
} }
if (commandException != null) { if (commandException != null) {
String rootMessage = getRootCauseMessage(commandException); String rootMessage = getRootCauseMessage(commandException);
Log.e(K9.LOG_TAG, "Root cause failure in " + account.getDescription() + ":" + Log.e(K9.LOG_TAG, "Root cause failure in " + account.getDescription() + ":" +
@ -1115,13 +1104,25 @@ public class MessagingController implements Runnable {
Log.e(K9.LOG_TAG, "Failed synchronizing folder " + account.getDescription() + ":" + folder + " @ " + new Date()); Log.e(K9.LOG_TAG, "Failed synchronizing folder " + account.getDescription() + ":" + folder + " @ " + new Date());
} finally { } finally {
// For certain store types, we need to make sure to keep the push state of the local
// and remote folder in sync.
if (remoteStore.keepPushStateInSync()) {
if (remoteFolder != null && tLocalFolder != null) {
try {
tLocalFolder.setPushState(remoteFolder.getPushState());
}
catch (MessagingException e) {
Log.e(K9.LOG_TAG, "Unable to update the local push state for folder " + tLocalFolder.getName(), e);
}
}
}
if (providedRemoteFolder == null) { if (providedRemoteFolder == null) {
closeFolder(remoteFolder); closeFolder(remoteFolder);
} }
closeFolder(tLocalFolder); closeFolder(tLocalFolder);
} }
} }

View File

@ -223,4 +223,8 @@ public abstract class Folder {
public boolean isSyncMode() { public boolean isSyncMode() {
return false; return false;
} }
public String getPushState() {
return null;
}
} }

View File

@ -175,6 +175,10 @@ public abstract class Store {
public boolean isExpungeCapable() { public boolean isExpungeCapable() {
return false; return false;
} }
public boolean keepPushStateInSync() {
return false;
}
public void sendMessages(Message[] messages) throws MessagingException { public void sendMessages(Message[] messages) throws MessagingException {
} }

View File

@ -62,7 +62,6 @@ import com.fsck.k9.mail.ServerSettings;
import com.fsck.k9.mail.Store; import com.fsck.k9.mail.Store;
import com.fsck.k9.mail.filter.EOLConvertingOutputStream; import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
import com.fsck.k9.mail.internet.MimeMessage; import com.fsck.k9.mail.internet.MimeMessage;
import com.fsck.k9.mail.store.LocalStore.LocalFolder;
import com.fsck.k9.mail.store.exchange.Eas; import com.fsck.k9.mail.store.exchange.Eas;
import com.fsck.k9.mail.store.exchange.adapter.EasEmailSyncParser; import com.fsck.k9.mail.store.exchange.adapter.EasEmailSyncParser;
import com.fsck.k9.mail.store.exchange.adapter.FolderSyncParser; import com.fsck.k9.mail.store.exchange.adapter.FolderSyncParser;
@ -802,6 +801,7 @@ public class EasStore extends Store {
throw new MessagingException("io", e); throw new MessagingException("io", e);
} }
// EASTODO: This needs to preserve the sync key for each folder.
synchronized (mFolderList) { synchronized (mFolderList) {
mFolderList.clear(); mFolderList.clear();
for (Folder folder : folderList) { for (Folder folder : folderList) {
@ -868,7 +868,7 @@ public class EasStore extends Store {
EasFolder remoteFolder = new EasFolder(folder.getName(), folder.getRemoteName(), type); EasFolder remoteFolder = new EasFolder(folder.getName(), folder.getRemoteName(), type);
mFolderList.put(folder.getRemoteName(), remoteFolder); mFolderList.put(folder.getRemoteName(), remoteFolder);
remoteFolder.setLocalFolder((LocalFolder)folder, true); remoteFolder.setSyncKey(folder.getPushState());
} }
} }
} }
@ -908,6 +908,11 @@ public class EasStore extends Store {
public boolean isSendCapable() { public boolean isSendCapable() {
return true; return true;
} }
@Override
public boolean keepPushStateInSync() {
return true;
}
@Override @Override
public void sendMessages(Message[] messages) throws MessagingException { public void sendMessages(Message[] messages) throws MessagingException {
@ -999,7 +1004,6 @@ public class EasStore extends Store {
private int mType; private int mType;
private boolean mIsOpen = false; private boolean mIsOpen = false;
private String mSyncKey = null; private String mSyncKey = null;
private LocalFolder mLocalFolder = null;
protected EasStore getStore() { protected EasStore getStore() {
return EasStore.this; return EasStore.this;
@ -1012,16 +1016,6 @@ public class EasStore extends Store {
mType = type; mType = type;
} }
public void setLocalFolder(LocalFolder folder, boolean setSyncKey) {
mLocalFolder = folder;
if (setSyncKey && mLocalFolder != null) {
if (mSyncKey != null && !mSyncKey.equals(INITIAL_SYNC_KEY)) {
Log.d(K9.LOG_TAG, "Overriding non-default SyncKey: " + mSyncKey);
}
mSyncKey = mLocalFolder.getPushState();
}
}
public String getSyncKey() throws MessagingException { public String getSyncKey() throws MessagingException {
if (mSyncKey == null) { if (mSyncKey == null) {
Log.d(K9.LOG_TAG, "Reset SyncKey to 0"); Log.d(K9.LOG_TAG, "Reset SyncKey to 0");
@ -1032,9 +1026,6 @@ public class EasStore extends Store {
public void setSyncKey(String key) throws MessagingException { public void setSyncKey(String key) throws MessagingException {
mSyncKey = key; mSyncKey = key;
if (mLocalFolder != null) {
mLocalFolder.setPushState(mSyncKey);
}
} }
@Override @Override
@ -1449,10 +1440,15 @@ public class EasStore extends Store {
"Unimplemented method setFlags(Flag[], boolean) breaks markAllMessagesAsRead and EmptyTrash"); "Unimplemented method setFlags(Flag[], boolean) breaks markAllMessagesAsRead and EmptyTrash");
// Try to make this efficient by not retrieving all of the messages // Try to make this efficient by not retrieving all of the messages
} }
@Override
public String getPushState() {
return mSyncKey;
}
@Override @Override
public String getNewPushState(String oldPushState, Message message) { public String getNewPushState(String oldPushState, Message message) {
return mSyncKey; return getPushState();
} }
} }

View File

@ -1419,9 +1419,11 @@ public class LocalStore extends Store implements Serializable {
} }
} }
@Override
public String getPushState() { public String getPushState() {
return mPushState; return mPushState;
} }
@Override @Override
public FolderClass getDisplayClass() { public FolderClass getDisplayClass() {
return mDisplayClass; return mDisplayClass;