emailservices/emailstore/base_plugin/src/baseplugindelayedops.cpp
changeset 0 8466d47a6819
child 8 e1b6206813b4
--- /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<TFSMailMsgId>& 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<TFSMailMsgId>& 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<const TUint8*>(
+                iContent->Ptr() ), iContent->Size() ) );
+        __LOG_WRITE8_FORMAT1_INFO(
+            "Stored the content of part 0x%X.", part->Id() )
+        }
+    else
+        {
+        part->AddOrUpdatePropertyL(
+            KMsgStorePropertySize, static_cast<TUint32>( iContentLength ) );
+        part->AddOrUpdatePropertyL(
+            KMsgStorePropertyRetrievedSize,
+            static_cast<TUint32>( 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 )
+    {
+    }