diff -r 000000000000 -r 8466d47a6819 emailservices/emailstore/base_plugin/src/baseplugindelayedops.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/emailservices/emailstore/base_plugin/src/baseplugindelayedops.cpp Thu Dec 17 08:39:21 2009 +0200 @@ -0,0 +1,478 @@ +/* +* Copyright (c) 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: Email interface implementation. +* +*/ +#include "MsgStoreWritablePropertyContainer.h" + +#include "baseplugindelayedops.h" +#include "baseplugindelayedopsprivate.h" + + +/////////////////////////////////////////////////// +// CDelayedOp // +/////////////////////////////////////////////////// + +/** + * + */ +/*public virtual*/ EXPORT_C CDelayedOp::~CDelayedOp() + { + Cancel(); + __LOG_DESTRUCT + } + +/** + * + */ +/*public*/ EXPORT_C void CDelayedOp::SetContext( + CBasePlugin& aPlugin, MDelayedOpsManager& aManager ) + { + iPlugin = &aPlugin; + iManager = &aManager; + } + +/** + * + */ +/*protected*/ EXPORT_C CDelayedOp::CDelayedOp() + : CAsyncOneShot( CActive::EPriorityIdle ) + { + } + +/** + * + */ +/*private virtual*/ EXPORT_C void CDelayedOp::RunL() + { + __LOG_ENTER_SUPPRESS( "Run" ); + TRAPD( err, ExecuteOpL() ); + + if ( KErrNone != err ) + { + __LOG_WRITE8_FORMAT1_INFO( + "Error while executing delayed operation: %d.", err ); + } + + //self-destroy. + iManager->DequeueOp( *this ); + delete this; + } + +/** + * + */ +/*protected*/ EXPORT_C CBasePlugin& CDelayedOp::GetPlugin() + { + return *iPlugin; + } + +/** + * + */ +/*private virtual*/ EXPORT_C void CDelayedOp::DoCancel() + { + } + + +/////////////////////////////////////////////////// +// CDelayedOpsManager // +/////////////////////////////////////////////////// + +/** + * + */ +/*static public*/ +CDelayedOpsManager* CDelayedOpsManager::NewL( CBasePlugin& aPlugin ) + { + CDelayedOpsManager* self = new (ELeave) CDelayedOpsManager( aPlugin ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +/** + * + */ +/*public virtual*/ CDelayedOpsManager::~CDelayedOpsManager() + { + ExecutePendingOps(); + + iDelayedOps.ResetAndDestroy(); + iDelayedOps.Close(); + + __LOG_DESTRUCT + } + +/** + * + */ +/*public virtual*/ void CDelayedOpsManager::EnqueueOpL( CDelayedOp* aOp ) + { + iDelayedOps.AppendL( aOp ); + aOp->SetContext( iPlugin, *this ); + aOp->Call(); + } + +/** + * + */ +/*public virtual*/ void CDelayedOpsManager::DequeueOp( const CDelayedOp& aOp ) + { + TInt count = iDelayedOps.Count(); + for ( TInt i = 0; i < count; ++i ) + { + CDelayedOp* op = iDelayedOps[i]; + if ( &aOp == op ) + { + iDelayedOps.Remove( i ); + break; + } + } + } + +/** + * + */ +/*public virtual*/ TInt CDelayedOpsManager::Extension1( + TUint /*aExtensionId*/, TAny*& /*a0*/, TAny* /*a1*/ ) + { + return KErrNotSupported; + } + +/** + * + */ +/*private*/ CDelayedOpsManager::CDelayedOpsManager( CBasePlugin& aPlugin ) + : iPlugin ( aPlugin ) + { + } + +/** + * + */ +/*private*/ void CDelayedOpsManager::ConstructL() + { + __LOG_CONSTRUCT( "baseplugin", "CDelayedOpsManager" ); + } + +/** + * + */ +/*private*/ void CDelayedOpsManager::ExecutePendingOps() + { + //check the count on every iteration to avoid missing operations being + //enqueued by another operations. + for ( TInt i = 0; i < iDelayedOps.Count(); ++i ) + { + CDelayedOp* op = iDelayedOps[i]; + + op->Cancel(); + TRAP_IGNORE( op->ExecuteOpL() ); + } + } + + +/////////////////////////////////////////////////// +// CDelayedDeleteMessagesOp // +/////////////////////////////////////////////////// + +/** + * + */ +/*public static */ CDelayedDeleteMessagesOp* CDelayedDeleteMessagesOp::NewLC( + TMsgStoreId aMailBoxId, + TMsgStoreId aFolderId, + const RArray& aMessages ) + { + CDelayedDeleteMessagesOp* self = new (ELeave) CDelayedDeleteMessagesOp( + aMailBoxId, aFolderId ); + CleanupStack::PushL( self ); + self->ConstructL( aMessages ); + return self; + } + +/** + * + */ +/*public static */ CDelayedDeleteMessagesOp* CDelayedDeleteMessagesOp::NewLC( + TMsgStoreId aMailBoxId, + TMsgStoreId aFolderId, + TMsgStoreId aMsgId ) + { + CDelayedDeleteMessagesOp* self = new (ELeave) CDelayedDeleteMessagesOp( + aMailBoxId, aFolderId ); + CleanupStack::PushL( self ); + self->ConstructL( aMsgId ); + return self; + } + +/** + * + */ +/*public virtual*/ CDelayedDeleteMessagesOp::~CDelayedDeleteMessagesOp() + { + iMessages.Close(); + __LOG_DESTRUCT + } + + +/** + * + */ +/*private*/ +void CDelayedDeleteMessagesOp::ConstructL( + const RArray& aMessages ) + { + __LOG_CONSTRUCT( "baseplugin", "CDelayedDeleteMessagesOp" ); + + TInt count = aMessages.Count(); + for ( TInt i = 0; i < count; ++i ) + { + iMessages.AppendL( aMessages[i].Id() ); + } + } + +/** + * + */ +/*private*/ +void CDelayedDeleteMessagesOp::ConstructL( + TMsgStoreId aMsgId ) + { + __LOG_CONSTRUCT( "baseplugin", "CDelayedDeleteMessagesOp" ); + iImmediateDelete = ETrue; + iMessages.AppendL( aMsgId ); + } + +/** + * + */ +/*private*/ CDelayedDeleteMessagesOp::CDelayedDeleteMessagesOp( + TMsgStoreId aMailBoxId, + TMsgStoreId aFolderId ) + : + iMailBoxId( aMailBoxId ), iFolderId( aFolderId ), + iImmediateDelete( EFalse ) + { + } + +/** + * + */ +/*private*/ void CDelayedDeleteMessagesOp::ExecuteOpL() + { + __LOG_ENTER( "ExecuteOpL" ); + + CMailboxInfo& mailBoxInfo + = GetPlugin().GetMailboxInfoL( iMailBoxId ); + CMsgStoreMailBox& mailBox = mailBoxInfo(); + + TInt count = iMessages.Count(); + for ( TInt i = 0; i < count; ++i ) + { + TMsgStoreId msgId = iMessages[i]; + + if ( EFalse == iImmediateDelete ) + { + //try to find the message in the deleted items folder. + CMsgStoreMessage* theMessage = NULL; + TRAP_IGNORE( theMessage = mailBox.FetchMessageL( + msgId, mailBoxInfo.iRootFolders.iFolders[EFSDeleted] ) ); + + if ( NULL == theMessage ) + { + //if not in deleted items then move it there. + __LOG_WRITE8_FORMAT1_INFO( + "Moving message 0x%X to the deleted items.", msgId ); + mailBox.MoveMessageL( + msgId, KMsgStoreInvalidId, + mailBoxInfo.iRootFolders.iFolders[EFSDeleted] ); + } + else + { + //in deleted items, really delete it. + __LOG_WRITE8_FORMAT1_INFO( "Deleting message 0x%X.", msgId ); + + delete theMessage; + mailBox.DeleteMessageL( msgId, iFolderId ); + } + } + else + { + mailBox.DeleteMessageL( msgId, iFolderId ); + } + } + + __LOG_EXIT; + } + + +/////////////////////////////////////////////////// +// CDelayedStorePropertiesOp // +/////////////////////////////////////////////////// + +/** + * + */ +/*public static*/ +CDelayedSetContentOp* CDelayedSetContentOp::NewLC( + TMsgStoreId aMailBoxId, + TMsgStoreId aMessageId, + TMsgStoreId aMessagePartId, + const TDesC& aContent ) + { + CDelayedSetContentOp* self = new (ELeave) CDelayedSetContentOp( + aMailBoxId, aMessageId, aMessagePartId ); + CleanupStack::PushL( self ); + self->ConstructL( aContent ); + return self; + } + +/** + * + */ +/*public static*/ +CDelayedSetContentOp* CDelayedSetContentOp::NewLC( + TMsgStoreId aMailBoxId, + TMsgStoreId aMessageId, + TMsgStoreId aMessagePartId, + TInt aContentLength ) + { + CDelayedSetContentOp* self = new (ELeave) CDelayedSetContentOp( + aMailBoxId, aMessageId, aMessagePartId, aContentLength ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +/** + * + */ +/*public virtual*/ CDelayedSetContentOp::~CDelayedSetContentOp() + { + delete iContent; + + __LOG_DESTRUCT + } + +/** + * + */ +/*private*/ void CDelayedSetContentOp::ConstructL( const TDesC& aContent ) + { + __LOG_CONSTRUCT( "baseplugin", "CDelayedSetContentOp1" ); + + iContent = aContent.AllocL(); + } + +/** + * + */ +/*private*/ void CDelayedSetContentOp::ConstructL() + { + __LOG_CONSTRUCT( "baseplugin", "CDelayedSetContentOp2" ); + } + +/** + * CDelayedOp::ExecuteOpL + */ +/*public virtual*/ void CDelayedSetContentOp::ExecuteOpL() + { + __LOG_ENTER( "ExecuteOpL" ) + + CMsgStoreMessagePart* part = FetchMessagePartLC(); + + if ( iStepOne ) + { + part->ReplaceContentL( + TPtrC8( reinterpret_cast( + iContent->Ptr() ), iContent->Size() ) ); + __LOG_WRITE8_FORMAT1_INFO( + "Stored the content of part 0x%X.", part->Id() ) + } + else + { + part->AddOrUpdatePropertyL( + KMsgStorePropertySize, static_cast( iContentLength ) ); + part->AddOrUpdatePropertyL( + KMsgStorePropertyRetrievedSize, + static_cast( iContentLength ) ); + + part->StorePropertiesL(); + __LOG_WRITE8_FORMAT1_INFO( + "Updated the properties of part 0x%X.", part->Id() ) + } + + CleanupStack::PopAndDestroy( part ); + __LOG_EXIT + } + +/** + * + */ +/*private*/ CMsgStoreMessagePart* CDelayedSetContentOp::FetchMessagePartLC() + { + __LOG_ENTER_SUPPRESS( "FetchMessagePartLC" ) + CMailboxInfo& mailBox = GetPlugin().GetMailboxInfoL( iMailBoxId ); + + CMsgStoreMessage* msg = mailBox().FetchMessageL( + iMessageId, KMsgStoreInvalidId ); + CleanupStack::PushL( msg ); + + CMsgStoreMessagePart* part; + if ( KMsgStoreInvalidId == iMessagePartId ) + { + __LOG_WRITE_INFO( "Fetched the message itself." ); + //watch the cleanupstack, part will point to the same thing thus the + //popanddestroy is ok. + part = msg; + } + else + { + __LOG_WRITE_INFO( "Fetched a child part of the message." ); + part = msg->ChildPartL( iMessagePartId, ETrue ); + CleanupStack::PopAndDestroy( msg ); + CleanupStack::PushL( part ); + } + + return part; + } + +/** + * + */ +/*private*/ CDelayedSetContentOp::CDelayedSetContentOp( + TMsgStoreId aMailBoxId, + TMsgStoreId aMessageId, + TMsgStoreId aMessagePartId ) + : iMailBoxId( aMailBoxId ), iMessageId( aMessageId ), + iMessagePartId( aMessagePartId ), iStepOne( ETrue ) + { + } + +/** + * + */ +/*private*/ CDelayedSetContentOp::CDelayedSetContentOp( + TMsgStoreId aMailBoxId, + TMsgStoreId aMessageId, + TMsgStoreId aMessagePartId, + TInt aContentLength ) + : iMailBoxId( aMailBoxId ), iMessageId( aMessageId ), + iMessagePartId( aMessagePartId ), iContentLength( aContentLength ), + iStepOne( EFalse ) + { + }