From 9e14a37cb81cf1dce955e5e16440fe413e4f656a Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Mon, 8 Dec 2014 10:25:37 -0500 Subject: [PATCH] Improvements over fixes for #2982 --- ActiveSync/SOGoActiveSyncDispatcher+Sync.m | 1 + ActiveSync/SOGoActiveSyncDispatcher.m | 57 ++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m index bb2f67d4e..d59102eb5 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m +++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m @@ -130,6 +130,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [[o properties] removeObjectForKey: @"SyncCache"]; [[o properties] removeObjectForKey: @"DateCache"]; [[o properties] removeObjectForKey: @"MoreAvailable"]; + [[o properties] removeObjectForKey: @"SuccessfulMoveItemsOps"]; [[o properties] addEntriesFromDictionary: values]; [o save]; diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index 2223ea379..2c05a1fae 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -130,6 +130,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @interface SOGoActiveSyncDispatcher (Sync) - (NSMutableDictionary *) _folderMetadataForKey: (NSString *) theFolderKey; +- (void) _setFolderMetadata: (NSDictionary *) theFolderMetadata forKey: (NSString *) theFolderKey; @end @@ -1398,7 +1399,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - (void) processMoveItems: (id ) theDocumentElement inResponse: (WOResponse *) theResponse { - NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId; + NSString *srcMessageId, *srcFolderId, *dstFolderId, *dstMessageId, *nameInCache, *currentFolder; + NSMutableDictionary *folderMetadata, *prevSuccessfulMoveItemsOps, *newSuccessfulMoveItemsOps; SOGoMicrosoftActiveSyncFolderType srcFolderType, dstFolderType; id aMoveOperation; NSArray *moveOperations; @@ -1407,6 +1409,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. NSData *d; int i; + currentFolder = nil; + moveOperations = (id)[theDocumentElement getElementsByTagName: @"Move"]; s = [NSMutableString string]; @@ -1422,6 +1426,19 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. srcMessageId = [[(id)[aMoveOperation getElementsByTagName: @"SrcMsgId"] lastObject] textValue]; srcFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] realCollectionIdWithFolderType: &srcFolderType]; dstFolderId = [[[(id)[aMoveOperation getElementsByTagName: @"DstFldId"] lastObject] textValue] realCollectionIdWithFolderType: &dstFolderType]; + + if (srcFolderType == ActiveSyncMailFolder) + nameInCache = [NSString stringWithFormat: @"folder%@", [[[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL] substringFromIndex: 5]]; + else + nameInCache = [[[(id)[aMoveOperation getElementsByTagName: @"SrcFldId"] lastObject] textValue] stringByUnescapingURL]; + + if (![nameInCache isEqualToString: currentFolder]) + { + folderMetadata = [self _folderMetadataForKey: nameInCache]; + prevSuccessfulMoveItemsOps = [folderMetadata objectForKey: @"SuccessfulMoveItemsOps"]; + newSuccessfulMoveItemsOps = [NSMutableDictionary dictionary] ; + currentFolder = nameInCache; + } [s appendString: @""]; @@ -1477,7 +1494,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // See http://msdn.microsoft.com/en-us/library/gg651088(v=exchg.80).aspx for Status response codes. // - [s appendFormat: @"%d", 1]; + if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId]) + { + // Previous move failed operation but we can recover the dstMessageId from previous request + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%@", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId]]; + [s appendFormat: @"%d", 3]; + [newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId]; + } + else + { + [s appendFormat: @"%d", 1]; + } } else { @@ -1506,6 +1534,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [s appendFormat: @"%@", srcMessageId]; [s appendFormat: @"%@", dstMessageId]; [s appendFormat: @"%d", 3]; + + // Save dstMessageId in cache - it will help to recover if the request fails before the response can be sent to client + [newSuccessfulMoveItemsOps setObject: dstMessageId forKey: srcMessageId]; } } @@ -1549,11 +1580,25 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. [s appendFormat: @"%@", srcMessageId]; [s appendFormat: @"%@", newUID]; [s appendFormat: @"%d", 3]; + + // Save dstMessageId in cache - it will help to recover if the request fails before the response can be sent to client + [newSuccessfulMoveItemsOps setObject: newUID forKey: srcMessageId]; } else { - [s appendFormat: @"%@", srcMessageId]; - [s appendFormat: @"%d", 1]; + if ([prevSuccessfulMoveItemsOps objectForKey: srcMessageId]) + { + // Move failed but we can recover the dstMessageId from previous request + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%@", [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] ]; + [s appendFormat: @"%d", 3]; + [newSuccessfulMoveItemsOps setObject: [prevSuccessfulMoveItemsOps objectForKey: srcMessageId] forKey: srcMessageId]; + } + else + { + [s appendFormat: @"%@", srcMessageId]; + [s appendFormat: @"%d", 1]; + } } } else @@ -1570,6 +1615,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. } [s appendString: @""]; + + [folderMetadata removeObjectForKey: @"SuccessfulMoveItemsOps"]; + [folderMetadata setObject: newSuccessfulMoveItemsOps forKey: @"SuccessfulMoveItemsOps"]; + [self _setFolderMetadata: folderMetadata forKey: nameInCache]; } [s appendString: @""];