diff -r 000000000000 -r 72b543305e3a email/imap4mtm/imapprotocolcontroller/src/cimapcompoundsynctree.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imapprotocolcontroller/src/cimapcompoundsynctree.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,215 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +#include "cimapcompoundsynctree.h" + +#include "cimapfolder.h" +#include "cimapsession.h" +#include "cimaplogger.h" +#include "imappaniccodes.h" + +#include "mobilitytestmtmapi.h" + +CImapCompoundSyncTree::CImapCompoundSyncTree(CImapSyncManager& aSyncManager, CMsvServerEntry& aServerEntry, CImapSettings& aImapSettings) + : CImapCompoundBase(aSyncManager, aServerEntry, aImapSettings) + { + // Set default progress values here so that any progress request before + // the operation is started returns valid information. + iProgressState = TImap4GenericProgress::ESyncing; + iSyncProgressState = TImap4SyncProgress::ESyncFolderTree; + } + +CImapCompoundSyncTree::~CImapCompoundSyncTree() + { + } + +CImapCompoundSyncTree* CImapCompoundSyncTree::NewL(CImapSyncManager& aSyncManager, CMsvServerEntry& aServerEntry, CImapSettings& aImapSettings) + { + CImapCompoundSyncTree* self = new (ELeave) CImapCompoundSyncTree(aSyncManager, aServerEntry, aImapSettings); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +void CImapCompoundSyncTree::ConstructL() + { + CActiveScheduler::Add(this); + } + +void CImapCompoundSyncTree::StartOperation(TRequestStatus& aStatus, CImapSession& aSession) + { + iSession = &aSession; + __LOG_TEXT(iSession->LogId(), "CImapCompoundSyncTree::StartOperation()"); + iNextStep = ESyncTree; + Queue(aStatus); + CompleteSelf(); + } + +/** +Handles the compound operation state machine + +@return ETrue if compound operation is completed, + EFalse otherwise (will be called again, unless active) +*/ +TBool CImapCompoundSyncTree::DoRunLoopL() + { + SetCurrentStep(); + switch (iCurrentStep) + { + case ESyncTree: + { + MOBILITY_TEST_MTM_STATE(iImapSettings.ServiceId(), KMobilityTestMtmStateImapSyncFolderTree); + + // SyncManager does the tree synchronisation. + iSyncManager.SynchroniseFolderTreeL(iStatus, *iSession); + iNextStep = EFinished; + SetActive(); + break; + } + + case EFinished: + { + __LOG_TEXT(iSession->LogId(), "CImapCompoundSyncTree::Completing OK"); + iProgressState = TImap4GenericProgress::EIdle; + iSyncProgressState = TImap4SyncProgress::EIdle; + Complete(KErrNone); + return ETrue; + } + + default: + { + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::ESyncTreeCompoundUnexpectedState)); + // unexpected state - complete the request + iProgressState = TImap4GenericProgress::EIdle; + iSyncProgressState = TImap4SyncProgress::EIdle; + return ETrue; + } + } // end of switch (iCurrentStep) + + return EFalse; + } + + +/** +May be called in case of a genuine cancel or a cancel for migrate. +Following a genuine cancel, the compound operation will be deleted. +Following a cancel for migrate, the compound operation will be resumed, +so the iNextState is updated here to ensure the operation is +correctly restarted. + +In either case, CMsgActive::DoCancel() is called to complete the +user request with KErrCancel. + +Note that if the default CMsgActive::DoComplete() is overridden, +then that must also be modified to handle either case described above. +*/ +void CImapCompoundSyncTree::DoCancel() + { + switch (iCurrentStep) + { + case ESyncTree: + { + // outstanding request on syncmanager + iSyncManager.Cancel(); + iNextStep=ESyncTree; + break; + } + case EFinished: + { + // self-completed or no outstanding request. + break; + } + case ESuspendedForMigrate: + default: + { + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::ESyncTreeCompoundCancelUnexpectedState)); + break; + } + } // end of switch (iCurrentStep) + + // always re-start after migration + iNextStep=ESelectSourceMailboxRW; + + if (!iCancelForMigrate) + { + // genuine cancel - update progress + iProgressErrorCode = KErrCancel; + } + CMsgActive::DoCancel(); + } + +void CImapCompoundSyncTree::Progress(TImap4CompoundProgress& aCompoundProgress) + { + aCompoundProgress.iGenericProgress.iOperation = TImap4GenericProgress::ESync; + aCompoundProgress.iGenericProgress.iState = iProgressState; + + iSyncManager.Progress(aCompoundProgress.iSyncProgress); + aCompoundProgress.iSyncProgress.iState = iSyncProgressState; + + // Put error into progress buffer + if( aCompoundProgress.iGenericProgress.iErrorCode == KErrNone ) + { + aCompoundProgress.iGenericProgress.iErrorCode = iProgressErrorCode; + } + } + +/** +Handles NO/BAD responses according to current step. +Negative server responses are not fatal - the error is saved in +the message currently being operated on and the state machine pushed +on to process the next message in the requested selection. + +@return KErrNone if the error has been handled + Completion error code otherwise. +*/ +TInt CImapCompoundSyncTree::ProcessNegativeServerResponse() + { + TInt err = iStatus.Int(); + switch (iCurrentStep) + { + case ESyncTree: + { + // Just store the error code in the progress response. + break; + } + case ESuspendedForMigrate: + case EFinished: + default: + { + // positive error code not expected, + // self-completed states or no outstanding request. + TImapServerPanic::ImapPanic(TImapServerPanic::ESyncTreeCompoundUnexpectedState); + break; + } + } // end of switch (iCurrentStep) + iProgressErrorCode = err; + return KErrNone; + } + + +/** +Resume the operation following a bearer migration. +*/ +void CImapCompoundSyncTree::ResumeOperationL(TRequestStatus& aStatus, CImapSession& aSession) + { + iSession = &aSession; + __LOG_TEXT(iSession->LogId(), "CImapCompoundSyncTree::Resuming"); + __ASSERT_DEBUG(iCurrentStep==ESuspendedForMigrate, TImapServerPanic::ImapPanic(TImapServerPanic::ESyncTreeCompoundUnexpectedState)); + iStopForMigrate = EFalse; + iNextStep = ESyncTree; + Queue(aStatus); + CompleteSelf(); + }