diff -r 000000000000 -r 72b543305e3a email/imap4mtm/imapprotocolcontroller/src/cimapcompoundselect.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/email/imap4mtm/imapprotocolcontroller/src/cimapcompoundselect.cpp Thu Dec 17 08:44:11 2009 +0200 @@ -0,0 +1,229 @@ +// 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 "cimapcompoundselect.h" +#include "cimapfolder.h" +#include "cimapsession.h" +#include "cimapsessionconsts.h" +#include "cimaplogger.h" +#include "imappaniccodes.h" + +CImapCompoundSelect::CImapCompoundSelect( CImapSyncManager& aSyncManager, + CMsvServerEntry& aServerEntry, + CImapSettings& aImapSettings, + TMsvId aFolderId ) + : CImapCompoundBase( aSyncManager, aServerEntry, aImapSettings ), + iFolderId(aFolderId) + { + } + +CImapCompoundSelect::~CImapCompoundSelect( ) + { + } + +CImapCompoundSelect* CImapCompoundSelect::NewL( CImapSyncManager& aSyncManager, + CMsvServerEntry& aServerEntry, + CImapSettings& aImapSettings, + TMsvId aFolderId ) + { + CImapCompoundSelect* self = new ( ELeave ) CImapCompoundSelect( aSyncManager, + aServerEntry, + aImapSettings, + aFolderId ); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** +Secondary construction +*/ +void CImapCompoundSelect::ConstructL() + { + CActiveScheduler::Add(this); + } + +void CImapCompoundSelect::StartOperation( TRequestStatus& aStatus, CImapSession& aSession) + { + iSession = &aSession; + __LOG_TEXT(iSession->LogId(), "CImapCompoundSelect::StartOperation()"); + iNextStep = ESelectSourceMailboxRW; + 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 CImapCompoundSelect::DoRunLoopL() + { + SetCurrentStep(); + switch (iCurrentStep) + { + case ESelectSourceMailboxRW: // asynchronous + { + SetEntryL(iFolderId); + TMsvEmailEntry entry = iServerEntry.Entry(); + iImapFolder = iSyncManager.GetFolderL(iFolderId); + iNextStep = EFinished; + if (iImapFolder==NULL || !entry.Mailbox()) + { + // folder does not exist or is marked /noselect + iProgressErrorCode = KErrNotSupported; + return EFalse; + } + else + { + iImapFolder->SelectL(iStatus, *iSession); + SetActive(); + } + break; + } + + case EFinished: // finished + { + __LOG_TEXT(iSession->LogId(), "CImapCompoundSelect::Completing OK"); + iProgressState = TImap4GenericProgress::EIdle; + Complete(KErrNone); + return ETrue; + } + + default: + { + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::ESelectCompoundUnexpectedState)); + // unexpected state - complete the request + iProgressState = TImap4GenericProgress::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 CImapCompoundSelect::DoCancel() + { + switch (iCurrentStep) + { + case ESelectSourceMailboxRW : + { + // outstanding request on the session. + // Note that although select operations are performed on a folder they + // actually pass our iStatus to the session, so that is why we cancel + // the session for them. + iSession->Cancel(); + break; + } + case EFinished : + { + // self-completed or no outstanding request. + break; + } + case ESuspendedForMigrate: + default : + { + __ASSERT_DEBUG(EFalse, TImapServerPanic::ImapPanic(TImapServerPanic::ESelectCompoundCancelUnexpectedState)); + break; + } + } // end switch (iCurrentStep) + + if (!iCancelForMigrate) + { + // genuine cancel - update progress + iProgressErrorCode = KErrCancel; + } + CMsgActive::DoCancel(); + } + + +void CImapCompoundSelect::Progress(TImap4CompoundProgress& aCompoundProgress) + { + aCompoundProgress.iGenericProgress.iOperation = TImap4GenericProgress::ESelect; + + // 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 CImapCompoundSelect::ProcessNegativeServerResponse() + { + TInt err = iStatus.Int(); + switch (iCurrentStep) + { + case ESelectSourceMailboxRW: + { + if (err == KErrImapNo) + { + err = KErrNotFound; + } + break; + } + case ESuspendedForMigrate: + case EFinished: + default: + { + // positive error code not expected, + // self-completed states or no outstanding request. + TImapServerPanic::ImapPanic(TImapServerPanic::ESelectCompoundUnexpectedState); + break; + } + } // end of switch (iCurrentStep) + iProgressErrorCode = err; + return KErrNone; + } + +/** +Resumes the operation following a migration. +*/ +void CImapCompoundSelect::ResumeOperationL(TRequestStatus& aStatus, CImapSession& aSession) + { + iSession = &aSession; + __LOG_TEXT(iSession->LogId(), "CImapCompoundSelect::Resuming"); + __ASSERT_DEBUG(iCurrentStep==ESuspendedForMigrate, TImapServerPanic::ImapPanic(TImapServerPanic::ESelectCompoundUnexpectedState)); + iStopForMigrate = EFalse; + + iNextStep = ESelectSourceMailboxRW; + CompleteSelf(); + Queue(aStatus); + } +