IMPSengine/engsrv/src/impsorphans.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/IMPSengine/engsrv/src/impsorphans.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,558 @@
+/*
+* Copyright (c) 2004 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: Class for imps oprhan manage.
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include    <e32std.h>
+#include    <e32base.h>
+#include    "ImpsOrphans.h"
+#include    "impsfields.h"
+#include    "impsdataaccessor.h"
+#include    "impssdatautils.h"
+#include    "impskey.h"
+
+// MACROS
+#ifndef _DEBUG
+#define _NO_IMPS_LOGGING_
+#endif
+
+// constant
+_LIT( KDefaultApplicationID, "Default" );
+static const TInt KDefaultQueueCapacity = 10; //The capacity of the orphan queue
+static const TInt KDefaultOrphanValidity = 3600;
+
+//**********************************
+// CImpsOrphans
+//**********************************
+CImpsOrphans::CImpsOrphans( )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::ConstructL
+// 2nd phase constructor
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::ConstructL()
+    {
+    iOrphanQueue = new( ELeave ) COrphanQueue( KDefaultQueueCapacity );
+    iLauncherProxy = CImpsAppLauncherProxy::NewL( this );
+    }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::NewL
+//
+// -----------------------------------------------------------------------------
+//
+CImpsOrphans* CImpsOrphans::NewL()
+    {
+    // Perform the construction.
+    CImpsOrphans* self = new ( ELeave ) CImpsOrphans( );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// Destructor
+//
+// -----------------------------------------------------------------------------
+//
+CImpsOrphans::~CImpsOrphans()
+    {
+    delete iLauncherProxy;
+    delete iOrphanQueue;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::NewOrphanL
+// Creates a new oprhan message and tries to launch the receiving application
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::NewOrphanL( CImpsFields* aMsg, TImpsSessIdent aCspId )
+    {
+    // Handle only NewMessage & Invitation
+    if ( ( aMsg->MessageType() != EImpsNewMessage ) &&
+         ( aMsg->MessageType() != EImpsInviteUserReq ) )
+        {
+#ifndef _NO_IMPS_LOGGING_
+        CImpsClientLogger::Log( _L( "CImpsOrphans: Orphan filtered out %d" ), aMsg->MessageType() );
+#endif
+        // Do not delete aMsg immediately but leave. This is because of
+        // CImpsCSPSession::CreateSapResponse still has references
+        // to CImpsFields entity used after this method call.
+        User::Leave( KErrNotSupported );
+        return;
+        }
+
+    TImpsEventType eventType( ServiceType( ( TImpsMessageType )aMsg->MessageType() ) );
+    COrphan* orphan = AddOrphanL( aMsg, eventType, aCspId ); // the ownership is in the iOrphanList
+    // Call application launcher
+    TInt err( iLauncherProxy->LaunchApplicationL( orphan->ApplicationId(), *( orphan->iSap ), *( orphan->iUserId ) ) );
+    if ( err != KErrNone )
+        {
+        // Application starting failed
+        // Orphaned message is kept in the queue until it expires or it is overwritten
+#ifndef _NO_IMPS_LOGGING_
+        CImpsClientLogger::Log( _L( "CImpsOrphans: Starting failed %d." ), err );
+#endif
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::NextOrphanLC
+// Transfers the next orphan message from the queue for handling
+// -----------------------------------------------------------------------------
+//
+CImpsFields* CImpsOrphans::NextOrphanLC( const TDesC& aCID,
+                                         TImpsEventType aServiceType,
+                                         TImpsSessIdent aCspId )
+    {
+    if ( ( aServiceType == EImpsEventMessage ) ||
+         ( aServiceType == EImpsEventCommon ) )
+        {
+        return iOrphanQueue->OrphanMessageLC( aCID, aServiceType, aCspId );
+        }
+    else
+        {
+        return NULL;
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::CheckExpiryL
+// Deletes the expired orphan messages
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::CheckExpiryL( )
+    {
+
+    TTime myExpiry;
+    myExpiry.HomeTime();
+
+    iOrphanQueue->DiscardExpired( myExpiry );
+
+    }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::Stop
+//
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::Stop( )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::HandleAppLaunchL
+// Handles the application launch
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::HandleAppLaunch( const TDesC& /*aApplicationId*/, TInt aStatus )
+    {
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsOrphans: HandleAppLaunchL status %d" ), aStatus );
+#endif
+
+    // removing the warning
+    aStatus++;
+    }
+// -----------------------------------------------------------------------------
+// CImpsOrphans::AddOrphanL
+// Creates and adds an orphan message to queue
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+COrphan* CImpsOrphans::AddOrphanL( CImpsFields *aFields,
+                                   TImpsEventType aServiceType,
+                                   TImpsSessIdent aCspId )
+    {
+    // Get the ClientID, SessionID
+    TPtrC sessionID = aFields->SessionIdL();
+    TPtrC applicationID;
+
+    TImpsDataAccessor myAc( aFields );
+    TImpsSDataUtils::GetApplicationIDL( &myAc, applicationID );
+    // Get the Validity time from message: relative time
+    TTimeIntervalSeconds validity;
+    GetValidityFromMessageL( myAc, validity );
+
+    if ( applicationID.Length() == 0 )
+        {
+        applicationID.Set( KDefaultApplicationID );
+        }
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsOrphans: NewOrphan(appID: %S, servType: %u, SAP: %S, user: %S)" ), &applicationID, aServiceType, &aCspId.SAP(), &aCspId.UserId() );
+#endif
+
+    // Set the validity as absolute time
+    TTime myTime;
+    myTime.HomeTime();
+    myTime += validity;
+
+#ifndef _NO_IMPS_LOGGING_
+    _LIT( KDateString5, "%-B%:0%J%:1%T%:2%S%:3%+B" );
+    TBuf<30> dateString;
+    myTime.FormatL( dateString, KDateString5 );
+    CImpsClientLogger::Log( _L( "CImpsOrphans: NewOrphan valid till %S" ), &dateString );
+#endif
+
+    COrphan* orphan = COrphan::NewL( applicationID,
+                                     sessionID,
+                                     aServiceType,
+                                     aCspId.SAP(),
+                                     aCspId.UserId(),
+                                     myTime,
+                                     aFields );
+    iOrphanQueue->Add( *orphan );
+    return orphan;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CImpsOrphans::GetValidityFromMessage
+// Retrieves the message validity from the instant message. The validity is in
+// seconds. If the message did not contain the validity then the default
+// validity is returned.
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+void CImpsOrphans::GetValidityFromMessageL( MImpsDataAccessor& aAc,
+                                            TTimeIntervalSeconds& aValidity )
+    {
+    TInt validity;
+    CImpsKey* myKey = CImpsKey::NewLC();
+    myKey->AddL( CREATEKEY( EImpsKeySession, 0 ) );
+    myKey->AddL( CREATEKEY( EImpsKeyTransaction, 0 ) );
+    myKey->AddL( CREATEKEY( EImpsKeyTransactionContent, 0 ) );
+    myKey->AddL( CREATEKEY( EImpsKeyNewMessage, 0 ) );
+    myKey->AddL( CREATEKEY( EImpsKeyMessageInfo, 0 ) );
+    myKey->AddL( CREATEKEY( EImpsKeyValidity, 0 ) );
+    if ( aAc.RestoreIntegerL( myKey, validity ) )
+        {
+        aValidity = validity;
+        }
+    else
+        {
+        aValidity = KDefaultOrphanValidity;
+        }
+    CleanupStack::PopAndDestroy( );  //myKey
+    }
+
+
+TImpsEventType CImpsOrphans::ServiceType( TImpsMessageType aMessageType )
+    {
+    TImpsEventType event( EImpsEventNone );
+
+    switch ( aMessageType )
+        {
+            // IM
+        case EImpsNewMessage:
+            event = EImpsEventMessage;
+            break;
+            // Fundamental
+        case EImpsInviteUserReq:
+            event = EImpsEventCommon;
+            break;
+        default:
+            event = EImpsEventNone;
+        }
+    return event;
+    }
+
+
+//////////////////////////////////////////////////////////////////////////
+// -----------------------------------------------------------------------------
+// COrphanQueue::COrphanQueue
+// Constructor
+// -----------------------------------------------------------------------------
+//
+COrphanQueue::COrphanQueue( TInt aCapacity ):
+        iOrphanList( _FOFF( COrphan, iLink ) ),  //lint !e413
+        iCapacity( aCapacity ),
+        iSize( 0 )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::~COrphanQueue
+// Destructor
+// -----------------------------------------------------------------------------
+//
+COrphanQueue::~COrphanQueue()
+    {
+    TDblQueIter<COrphan> iter ( iOrphanList );
+    iter.SetToFirst();
+
+    while ( iter )
+        {
+        COrphan* orphan = iter;
+        iter++;
+        orphan->Destroy();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::SetLength
+// Sets the new capacity of the queue
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::SetLength( TInt aNewCapacity )
+    {
+    iCapacity = aNewCapacity;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::Add
+// Adds a new orphan message to the queue
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::Add( COrphan& aOrphan )
+    {
+    // Check the capacity
+    __ASSERT_DEBUG( iCapacity, User::Panic( KImpsPanicCategory, EImpsCorrupted ) );
+    if ( iSize < iCapacity )
+        {
+        // Simply add to the end
+        iOrphanList.AddLast( aOrphan );
+        ++iSize;
+        }
+    else
+        {
+        // Remove the 1st and add to the last
+        COrphan* orphan = iOrphanList.First();
+        orphan->Destroy();
+        iOrphanList.AddLast( aOrphan );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::OrphanMessage
+// Returns the orphan message with the given client ID and removes it from the
+// queue. NULL is returned if not found.
+// -----------------------------------------------------------------------------
+//
+CImpsFields* COrphanQueue::OrphanMessageLC( const TDesC& aApplicationId,
+                                            TImpsEventType aServiceType,
+                                            TImpsSessIdent aCspId )
+    {
+    TPtrC applicationId;
+    aApplicationId.Length() ? applicationId.Set( aApplicationId ) : applicationId.Set( KDefaultApplicationID );
+
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsOrphans: NextOrphanLC(appID: %S, servType: %u, SAP: %S, user: %S)" ), &applicationId, aServiceType, &aCspId.SAP(), &aCspId.UserId() );
+#endif
+
+    TDblQueIter<COrphan> iter ( iOrphanList );
+    iter.SetToFirst();
+
+    while ( iter )
+        {
+        COrphan* orphan = iter;
+        iter++;
+        // Find the given ClientID, Service Type, SAP and UserId
+        if ( ( !applicationId.Compare( orphan->ApplicationId() ) )  &&
+             ( aServiceType == orphan->iServiceType ) &&
+             ( !orphan->iSap->CompareF( aCspId.SAP() ) )  &&
+             ( !orphan->iUserId->CompareF( aCspId.UserId() ) ) )
+            {
+            // found
+            // transfer the ownership to the caller
+            CImpsFields* impsFields = orphan->Message();
+            orphan->RemoveOwnership();
+            orphan->Destroy();
+            --iSize;
+            CleanupStack::PushL( impsFields );
+#ifndef _NO_IMPS_LOGGING_
+            CImpsClientLogger::Log( _L( "CImpsOrphans: NextOrphanLC(): Found! " ) );
+#endif
+            return impsFields;
+            }
+        }
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsOrphans: NextOrphanLC() Not found!" ) );
+#endif
+
+    return NULL;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::DestroyOrphans
+// Deletes all orphan messages which have the give ClientID
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::DestroyOrphans( TDesC& aApplicationId )
+    {
+    TDblQueIter<COrphan> iter ( iOrphanList );
+    iter.SetToFirst();
+
+    while ( iter )
+        {
+        COrphan* orphan = iter;
+        iter++;
+        if ( !aApplicationId.Compare( orphan->ApplicationId() ) )
+            {
+            orphan->Destroy();
+            --iSize;
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// COrphanQueue::DiscardExpired
+// Deletes all orphan messages which are expired
+// -----------------------------------------------------------------------------
+//
+void COrphanQueue::DiscardExpired( TTime aExpiry )
+    {
+
+#ifndef _NO_IMPS_LOGGING_
+    CImpsClientLogger::Log( _L( "CImpsOrphans: Check expired" ) );
+#endif
+
+    TDblQueIter<COrphan> iter ( iOrphanList );
+    iter.SetToFirst();
+
+    while ( iter )
+        {
+        COrphan* orphan = iter;
+        iter++;
+        // Check the validity
+
+        if ( orphan->Expiry() < aExpiry )
+            {
+#ifndef _NO_IMPS_LOGGING_
+            CImpsClientLogger::Log( _L( "CImpsOrphans: Expired discarded" ) );
+#endif
+            orphan->Destroy();
+            --iSize;
+            }
+        }
+
+
+    }
+//////////////////////////////////////////////////////////////////////////
+
+// -----------------------------------------------------------------------------
+// COrphan::COrphan
+// -----------------------------------------------------------------------------
+
+COrphan::COrphan(
+    const TDesC& aApplicationID,
+    const TDesC& aSessionId,
+    TImpsEventType aServiceType,
+    TTime aValidity,
+    CImpsFields* aFields ) :
+        iServiceType( aServiceType ),
+        iFields ( aFields ),
+        iExpiry( aValidity )
+    {
+    iCID = aApplicationID;
+    iSessionId = aSessionId;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphan::ConstructL
+// -----------------------------------------------------------------------------
+void COrphan::ConstructL(
+    const TDesC&    aSap,
+    const TDesC&    aUserId )
+    {
+    iSap = aSap.AllocL();
+    iUserId = aUserId.AllocL();
+    }
+
+// -----------------------------------------------------------------------------
+// COrphan::NewL
+// -----------------------------------------------------------------------------
+COrphan* COrphan::NewL(
+    const TDesC& aCID,
+    const TDesC& aSessionId,
+    TImpsEventType aServiceType,
+    const TDesC&    aSap,
+    const TDesC&    aUserId,
+    TTime aValidity,
+    CImpsFields* aFields )
+    {
+    COrphan* self = new ( ELeave ) COrphan( aCID, aSessionId, aServiceType, aValidity, aFields );
+
+    CleanupStack::PushL( self );
+    self->ConstructL( aSap, aUserId );
+    CleanupStack::Pop();
+
+    return self;
+
+    }
+// -----------------------------------------------------------------------------
+// COrphan::~COrphan
+// -----------------------------------------------------------------------------
+COrphan::~COrphan()
+    {
+    delete iSap;
+    delete iUserId;
+    } //lint !e1540 iFields freed in Destroy
+
+// -----------------------------------------------------------------------------
+// COrphan::Destroy
+// -----------------------------------------------------------------------------
+void COrphan::Destroy()
+    {
+    iLink.Deque();
+    delete iFields;
+    iFields = NULL;
+    delete this;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphan::ClientId
+// -----------------------------------------------------------------------------
+TDesC& COrphan::ApplicationId()
+    {
+    return iCID;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphan::Message
+// -----------------------------------------------------------------------------
+CImpsFields* COrphan::Message()
+    {
+    return iFields;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphan::Expiry
+// -----------------------------------------------------------------------------
+TTime COrphan::Expiry()
+    {
+    return iExpiry;
+    }
+
+// -----------------------------------------------------------------------------
+// COrphan::RemoveOwnership
+// -----------------------------------------------------------------------------
+void COrphan::RemoveOwnership()
+    {
+    iFields = NULL;
+    }
+
+//  End of File