ipsservices/ipssosplugin/src/ipsplgsmtpoperation.cpp
changeset 0 8466d47a6819
child 4 e7aa27f58ae1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ipsservices/ipssosplugin/src/ipsplgsmtpoperation.cpp	Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,374 @@
+/*
+* Copyright (c) 2007 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: This file implements class CIpsPlgSmtpOperation.
+*
+*/
+
+
+#include "emailtrace.h"
+#include "ipsplgheaders.h"
+
+
+const TInt KIpsSmtpOperationCharLessThan = '<';
+const TInt KIpsSmtpOperationCharMoreThan = '>';
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CIpsPlgSmtpOperation* CIpsPlgSmtpOperation::NewL( 
+    CMsvSession& aMsvSession, 
+    TInt aPriority, TRequestStatus& 
+    aObserverRequestStatus,
+    TBool /*aUsePublishSubscribe*/ )
+    {
+    FUNC_LOG;
+    CIpsPlgSmtpOperation* self = CIpsPlgSmtpOperation::NewLC(
+        aMsvSession, aPriority, aObserverRequestStatus, ETrue );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CIpsPlgSmtpOperation* CIpsPlgSmtpOperation::NewLC( 
+    CMsvSession& aMsvSession, 
+    TInt aPriority, 
+    TRequestStatus& aObserverRequestStatus,
+    TBool /*aUsePublishSubscribe*/ )
+    {
+    FUNC_LOG;
+    CIpsPlgSmtpOperation* self = new( ELeave ) CIpsPlgSmtpOperation(
+        aMsvSession, aPriority, aObserverRequestStatus );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+   
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+CIpsPlgSmtpOperation::CIpsPlgSmtpOperation( 
+    CMsvSession& aMsvSession, 
+    TInt aPriority, 
+    TRequestStatus& aObserverRequestStatus ) :
+    CMsvOperation( aMsvSession, aPriority, aObserverRequestStatus ),
+    iSmtpMtm( NULL ),
+    iOperation( NULL ),
+    iSelection( NULL ),  
+    iMtmRegistry( NULL )
+    {
+    FUNC_LOG;
+    }
+  
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//    
+CIpsPlgSmtpOperation::~CIpsPlgSmtpOperation() 
+    {
+    FUNC_LOG;
+    Cancel();
+    delete iSmtpMtm;
+    delete iMtmRegistry;
+    delete iSelection;
+    delete iOperation;
+    } 
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::ConstructL()
+    {
+    FUNC_LOG;
+    iSelection = new (ELeave) CMsvEntrySelection();
+    CActiveScheduler::Add( this );
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::RunL()
+    {
+    FUNC_LOG;
+    
+    
+    if ( iState == EMovingOutbox )
+        {
+        delete iOperation;
+        iOperation = NULL;
+        iSelection->InsertL(0, iSmtpService );
+        CallSendL( );
+        }
+    else if ( iState == ESending )
+        {
+        TImSmtpProgress prog;
+        TPckg<TImSmtpProgress> param(prog);
+        param.Copy( iOperation->FinalProgress() ); 
+        
+        TRequestStatus* status = &iObserverRequestStatus;
+        User::RequestComplete( status, prog.Error() );
+        }    
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//    
+void CIpsPlgSmtpOperation::DoCancel()
+    {
+    FUNC_LOG;
+    
+    if ( iOperation )
+        {
+        iOperation->Cancel();
+        }
+    TRequestStatus* status = &iObserverRequestStatus;
+    User::RequestComplete(status, KErrCancel);
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//   
+const TDesC8& CIpsPlgSmtpOperation::ProgressL()
+    {
+    FUNC_LOG;
+    
+    if( iOperation && iState == ESending  )
+        {
+        return iOperation->ProgressL();
+        }
+    return KNullDesC8;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//       
+EXPORT_C void CIpsPlgSmtpOperation::StartSendL( TMsvId aMessageId )
+    {
+    FUNC_LOG;
+    
+    TMsvId service;
+    TMsvEntry entry;
+    User::LeaveIfError( 
+        iMsvSession.GetEntry( aMessageId, service, entry ) );
+    if ( entry.Id() == KMsvNullIndexEntryIdValue )
+        {
+        User::Leave( KErrNotFound );
+        }
+    
+    iSmtpService = entry.iServiceId;
+    ConstructSmtpMtmL();
+    iSmtpMtm->SwitchCurrentEntryL( entry.Id() );
+    
+    if ( entry.Parent() == KMsvGlobalOutBoxIndexEntryIdValue )
+        {
+        iSelection->Reset();
+        // smtp service id have to be first in array
+        // here must be iSmtpService
+        iSelection->AppendL( iSmtpService );
+        // then message id
+        iSelection->AppendL( entry.Id() );
+        CallSendL( );
+        }
+    else
+        {
+        // 1. perform validity checks for recipient addresses
+        // 2. move message to outbox
+        // Perform validity checks for recipient addresses
+        // before moving
+        CMsvEntry* msgCEntry = CMsvEntry::NewL(
+            iMsvSession, aMessageId, TMsvSelectionOrdering() );
+        CleanupStack::PushL( msgCEntry );
+        ValidateRecipientsL( *msgCEntry );
+        CleanupStack::PopAndDestroy( msgCEntry );
+        msgCEntry = NULL;
+        
+        iSelection->Reset();
+        // get message entry
+        msgCEntry = CMsvEntry::NewL(
+            iMsvSession, entry.Parent(), TMsvSelectionOrdering() );
+        CleanupStack::PushL( msgCEntry );
+
+        // do the move
+        iSelection->AppendL( entry.Id());
+        iStatus = KRequestPending;
+        delete iOperation;
+        iOperation = NULL;
+        iOperation = msgCEntry->MoveL( 
+            *iSelection, KMsvGlobalOutBoxIndexEntryIdValue, iStatus );
+        SetActive();
+        CleanupStack::PopAndDestroy( msgCEntry );
+        iState = EMovingOutbox; 
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//    
+EXPORT_C TInt CIpsPlgSmtpOperation::EmptyOutboxFromPendingMessagesL( 
+    TMsvId aMailboxId  )
+    {
+    FUNC_LOG;
+    TMsvId service;
+    TMsvEntry entry;
+    User::LeaveIfError( 
+        iMsvSession.GetEntry( aMailboxId, service, entry ) );
+    
+    iSmtpService = entry.iRelatedId;
+    
+    TInt retValue = KErrNone;
+    
+    iSelection->Reset();
+    ConstructSmtpMtmL();
+    iSmtpMtm->SwitchCurrentEntryL( KMsvGlobalOutBoxIndexEntryIdValue );
+    
+    // in sending first entry in selection array have to be service id
+    iSelection->AppendL(iSmtpService);
+    //index to first message entry of selection array
+    
+    CMsvEntrySelection* childs = GetOutboxChildrensL( );
+    CleanupStack::PushL( childs );
+    for ( TInt i = 0; i < childs->Count(); i++ )
+        {
+        iMsvSession.GetEntry( childs->At(i), service, entry );
+        TUint sendState = entry.SendingState();
+        
+        if ( iSmtpService == entry.iServiceId &&
+            ( sendState != KMsvSendStateUnknown
+              || sendState != KMsvSendStateUponRequest
+              || sendState != KMsvSendStateSent ) )
+            {
+            // chage suspended flag to waiting
+            // is it safe to change flag from suspended to waiting?
+            if ( sendState == KMsvSendStateSuspended )
+                {
+                CMsvEntry* cEntry = CMsvEntry::NewL(
+                    iMsvSession, entry.Id(), TMsvSelectionOrdering() );
+                CleanupStack::PushL( cEntry );
+                CIpsPlgOperationWait* wait = CIpsPlgOperationWait::NewLC( );
+                entry.SetSendingState( KMsvSendStateWaiting );
+                cEntry->ChangeL( entry, wait->iStatus );
+                wait->Start();
+                CleanupStack::PopAndDestroy(2, cEntry ); // wait, cEntry
+                }
+            // add to send list
+            iSelection->AppendL( entry.Id() );
+            ++retValue;
+            }
+        }
+    CleanupStack::PopAndDestroy( childs );
+    if (retValue > 0)
+        {
+        CallSendL();
+        }
+    return retValue;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CMsvEntrySelection* CIpsPlgSmtpOperation::GetOutboxChildrensL( )
+    {
+    FUNC_LOG;
+    ConstructSmtpMtmL();
+    iSmtpMtm->SwitchCurrentEntryL( KMsvGlobalOutBoxIndexEntryIdValue );
+    return iSmtpMtm->Entry().ChildrenL();
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::CallSendL( )
+    {
+    FUNC_LOG;
+    TBuf8<1> params;
+    
+    iOperation = iSmtpMtm->InvokeAsyncFunctionL(
+        KSMTPMTMSendOnNextConnection, *iSelection, params, iStatus);
+    SetActive();
+    iState = ESending;
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+//
+void CIpsPlgSmtpOperation::ConstructSmtpMtmL()
+    {
+    FUNC_LOG;
+    if ( !iMtmRegistry )
+        {
+        iMtmRegistry = CClientMtmRegistry::NewL( iMsvSession );
+        }
+    if ( !iSmtpMtm )
+        {
+        iSmtpMtm = static_cast<CSmtpClientMtm*>(
+            iMtmRegistry->NewMtmL( KSenduiMtmSmtpUid ) );
+        }
+    }
+    
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// 
+void CIpsPlgSmtpOperation::ValidateRecipientsL( CMsvEntry& aEntry )
+    {
+    FUNC_LOG;
+    
+    // get store object
+    CMsvStore* store = aEntry.ReadStoreL();
+    CleanupStack::PushL( store );   // << store
+    
+    // create symbian email header object
+    CImHeader* header = CImHeader::NewLC(); // << header
+    header->RestoreL( *store );
+
+    // checking separate recipient fields
+    ValidateAddressArrayL( header->ToRecipients() );
+    ValidateAddressArrayL( header->CcRecipients() );
+    ValidateAddressArrayL( header->BccRecipients() );
+    
+    // Cleanup
+    CleanupStack::PopAndDestroy( header );
+    CleanupStack::PopAndDestroy( store );
+    }
+
+// ---------------------------------------------------------------------------
+// ---------------------------------------------------------------------------
+// 
+void CIpsPlgSmtpOperation::ValidateAddressArrayL( const CDesCArray& aRecipients )
+    {
+    FUNC_LOG;
+    
+    TInt count( aRecipients.Count() );
+    for ( TInt i(0); i < count; i++ )
+        {
+        TPtrC fullName( aRecipients[i] );
+        
+        // Need to locate angle brackets from end of the data, if there
+        // is display name with special characters
+        TInt start( fullName.LocateReverse( KIpsSmtpOperationCharLessThan ) ); 
+        TInt end( fullName.LocateReverse( KIpsSmtpOperationCharMoreThan ) );
+        if ( KErrNotFound != start && KErrNotFound != end )
+            {
+            start += 1;
+            fullName.Set( aRecipients[i].Mid( start, ( end - start ) ) );
+            }
+        // make basic sanity checks for email address
+        if( !IpsSetUtils::IsValidEmailAddressL( fullName ) )
+            {
+            User::Leave( KErrBadName );
+            }
+        }
+    }
+
+// End of File
+