diff -r 000000000000 -r 094583676ce7 PECengine/AttributeLibrary2/SrcTransactions/CPEngPresenceAttrTransactionEnv.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PECengine/AttributeLibrary2/SrcTransactions/CPEngPresenceAttrTransactionEnv.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,428 @@ +/* +* 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: Presence attribute transaction environment. +* +*/ + +// INCLUDE FILES +#include +#include +#include "CPEngPresenceAttrTransactionEnv.h" +#include "CPEngPresenceNotificationHandler.h" +#include "MPEngPresenceAttrManager.h" +#include "MPEngPresenceAttrModel2.h" +#include "MPEngPresenceAdvancedAttrModel2.h" +#include "MPEngXMLParser.h" +#include "RObjectArray.h" +#include "CPEngSessionSlotId.h" +#include "PEngAddressUtils.h" +#include "PEngAttrModelHelper.h" + +#include "CPEngSubscribedUsers.h" +#include "CPEngSubscribedUser.h" +#include "CPEngOrphanNotificationQue.h" +#include "PresenceDebugPrint.h" + + +//CONSTANTS +const TInt KQuedOrphanNotifications = 10; + + + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPEngPresenceAttrTransactionEnv* CPEngPresenceAttrTransactionEnv::NewL( + const CPEngSessionSlotId& aSlotId, + MPEngPresenceAttrManager& aAttrMan ) + { + CPEngPresenceAttrTransactionEnv* self = new ( ELeave ) CPEngPresenceAttrTransactionEnv + ( aAttrMan ); + + CleanupClosePushL( *self ); //Reference counted object + self->ConstructL( aSlotId ); + CleanupStack::Pop(); //self + + return self; + } + + +// Destructor +CPEngPresenceAttrTransactionEnv::~CPEngPresenceAttrTransactionEnv() + { + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::~CPEngPresenceAttrTransactionEnv()" ) ); + delete iSubscribedUsers; + delete iOrphanNotifications; + iSessTracingAttribs.ResetAndDestroy(); + delete iDomain; + + if ( iAttributeManagerOwned ) + { + iAttributeManager.Close(); + } + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::CPEngPresenceAttrTransactionEnv +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPEngPresenceAttrTransactionEnv::CPEngPresenceAttrTransactionEnv( MPEngPresenceAttrManager& aAttrMan ) + : iAttributeManager( aAttrMan ), + iAttributeManagerOwned( EFalse ) + { + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::CPEngPresenceAttrTransactionEnv()" ) ); + } + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::ConstructL( const CPEngSessionSlotId& aSlotId ) + { + CPEngSessionSlotObject::ConstructL( aSlotId ); + + //resolve transaction domain + iDomain = PEngAddressUtils::WVDomain( aSlotId.UserId() ).AllocL(); + + iSubscribedUsers = CPEngSubscribedUsers::NewL(); + iOrphanNotifications = CPEngOrphanNotificationQue::NewL( KQuedOrphanNotifications ); + + iAttributeManagerOwned = ETrue; + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::Close() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::Close() + { + CPEngSessionSlotObject::Close(); + } + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::AddSubscriptionL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::AddSubscriptionL( const TDesC& aPresenceID ) + + { + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::AddSubscriptionL() [%S]" ), + &aPresenceID ); + + __ASSERT_ALWAYS( aPresenceID.Length() > 0, User::Leave( KErrArgument ) ); + + + //Locate existing user subscription entry or create a new one + const TInt uIndex = iSubscribedUsers->FindSubscribedUser( aPresenceID ); + if ( uIndex == KErrNotFound ) + { + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::AddSubscriptionL() - adding new" ) ); + + CPEngSubscribedUser* userDetails = CPEngSubscribedUser::NewLC( aPresenceID ); + userDetails->AddSubscription(); //increase subscription count + iSubscribedUsers->AddSubscribedUserL( userDetails ); + CleanupStack::Pop(); //userDetails + + DoInitializeAttributesToCacheL( aPresenceID ); + + //New subscription added + //Process possibly pending orphan presence notifications. + DoProcessAndStoreOrphanNotificationsL(); + } + + else + { + CPEngSubscribedUser& userDetails = iSubscribedUsers->SubscribedUser( uIndex ); + + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::AddSubscriptionL() - Increasing existing, count %d" ), + userDetails.SubscriptionsCount() ); + + + userDetails.AddSubscription(); //increase subscription count + } + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::RemoveSubscriptionL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::RemoveSubscriptionL( const TDesC& aPresenceID ) + { + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::RemoveSubscriptionL() [%S]" ), + &aPresenceID ); + + + if ( aPresenceID.Length() == 0 ) + { + return; + } + + + const TInt uIndex = iSubscribedUsers->FindSubscribedUser( aPresenceID ); + if ( uIndex != KErrNotFound ) + { + CPEngSubscribedUser& userDetails = iSubscribedUsers->SubscribedUser( uIndex ); + userDetails.RemoveSubscription(); + + PENG_DP( D_PENG_LIT( "CPEngPresenceAttrTransactionEnv::RemoveSubscription() - Subscription removed, Subscriptions left %d" ), + userDetails.SubscriptionsCount() ); + + if ( userDetails.SubscriptionsCount() == 0 ) + { + //no active subscription anymore for this user + //==> all stored subscribed attributes can be deleted from storage + DoClearAttributesFromCacheL( aPresenceID ); + + //and actual subscription entry also + iSubscribedUsers->DeleteSubscribeUser( uIndex ); + } + } + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::SubscribedPresenceIDs() +// ----------------------------------------------------------------------------- +// +const MDesCArray& CPEngPresenceAttrTransactionEnv::SubscribedPresenceIDs() const + { + return *iSubscribedUsers; + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::SetSessionTracingAttributesL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::SetSessionTracingAttributesL( + RPointerArray< MPEngPresenceAttrModel2 >& aAttributeModels ) + { + __ASSERT_DEBUG( !PEngAttrModelHelper::HasDuplicateTypes( aAttributeModels ), + User::Leave( KErrAlreadyExists ) ); + + //Replace internal model array with given ones + iSessTracingAttribs.ResetAndDestroy(); + PEngAttrModelHelper::MoveModelsL( aAttributeModels, iSessTracingAttribs ); + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::UpdateSessionTracingAttributesL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::UpdateSessionTracingAttributesL( + RPointerArray< MPEngPresenceAttrModel2 >& aAttributeModels ) + { + //go from end to start ==> remove is safe + for ( TInt sourceIx = ( aAttributeModels.Count() - 1 ); sourceIx >= 0; sourceIx-- ) + { + MPEngPresenceAttrModel2* sourceModel = aAttributeModels [ sourceIx ]; + + const TInt tracedCount = iSessTracingAttribs.Count(); + for ( TInt tracedIx = 0; tracedIx < tracedCount; tracedIx++ ) + { + MPEngPresenceAttrModel2* tracedModel = iSessTracingAttribs[ tracedIx ]; + if ( ( sourceModel->Type() == tracedModel->Type() ) && + ( sourceModel->PresenceID() == tracedModel->PresenceID() ) ) + { + //replace traced model with new one instance + //and remove new instance from source array + delete iSessTracingAttribs[ tracedIx ]; + iSessTracingAttribs[ tracedIx ] = sourceModel; + aAttributeModels.Remove( sourceIx ); + break; + } + } + } + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::HandleNetworkSessionStateChangeL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::HandleNetworkSessionStateChangeL( + TBool aSessionOpen ) + { + const TInt count = iSessTracingAttribs.Count(); + for ( TInt ii = 0; ii < count; ii++ ) + { + MPEngPresenceAttrModel2* model = iSessTracingAttribs[ ii ]; + model->Advanced()->HandleNetworkSessionStateChangeL( aSessionOpen ); + } + + iAttributeManager.ForceStoreBatchL( iSessTracingAttribs ); + } + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::QueOrphanNotificationL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::QueOrphanNotificationL( + const TDesC8& aPresenceBlock ) + { + iOrphanNotifications->AddToQueL( aPresenceBlock ); + } + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::ProcessOrphanNotificationsL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::ProcessOrphanNotificationsL( + RPointerArray< MPEngPresenceAttrModel2 >& aModels ) + { + MPEngXMLParser* xmlParser = CreateXMLParserLC(); + const TDesC8* notification = iOrphanNotifications->GetFirst(); + + while ( notification ) + { + TBool notificationMached = + CPEngPresenceNotificationHandler::ProcessNotifyBlockL( *notification, + *iDomain, + *iSubscribedUsers, + iAttributeManager, + *xmlParser, + aModels ); + + //If notification matched to subscribed user => discard the cache entry + //Otherwise proceed to next cache entry + if ( notificationMached ) + { + notification = iOrphanNotifications->DeleteCurrentAndGetNext(); + } + else + { + notification = iOrphanNotifications->GetNext(); + } + } + + CleanupStack::PopAndDestroy(); //xmlParser + } + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::DoInitializeAttributesToCacheL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::DoInitializeAttributesToCacheL( + const TDesC& aPresenceID ) + { + TArray attributes = iAttributeManager.KnownAttributeTypes(); + const TInt count = attributes.Count(); + + RObjectArray models; + CleanupClosePushL( models ); + + for ( TInt ii = 0; ii < count; ii++ ) + { + TUint32 attribute = attributes[ ii ]; + MPEngPresenceAttrModel2* model = NULL; + TInt err = iAttributeManager.LoadAttributeLC( model, + aPresenceID, + attribute, + EPEngStorableModel ); + if ( err == KErrNotFound ) + { + models.AppendL( model ); + CleanupStack::Pop(); //model + } + else + { + CleanupStack::PopAndDestroy(); //model + } + } + + iAttributeManager.ForceStoreBatchL( models ); + CleanupStack::PopAndDestroy(); //models + } + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::DoClearAttributesFromCacheL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::DoClearAttributesFromCacheL( + const TDesC& aPresenceID ) + { + TArray attributes = iAttributeManager.KnownAttributeTypes(); + const TInt count = attributes.Count(); + + RObjectArray models; + CleanupClosePushL( models ); + + for ( TInt ii = 0; ii < count; ii++ ) + { + TUint32 attribute = attributes[ ii ]; + MPEngPresenceAttrModel2* model = NULL; + TInt err = iAttributeManager.LoadAttributeLC( model, + aPresenceID, + attribute, + EPEngStorableModel ); + if ( err == KErrNone ) + { + models.AppendL( model ); + CleanupStack::Pop(); //model + } + else + { + CleanupStack::PopAndDestroy(); //model + } + } + + iAttributeManager.ForceRemoveFromStoreBatchL( models ); + CleanupStack::PopAndDestroy(); //models + } + + + + +// ----------------------------------------------------------------------------- +// CPEngPresenceAttrTransactionEnv::DoProcessAndStoreOrphanNotificationsL() +// ----------------------------------------------------------------------------- +// +void CPEngPresenceAttrTransactionEnv::DoProcessAndStoreOrphanNotificationsL() + { + RObjectArray models; + CleanupClosePushL( models ); + + ProcessOrphanNotificationsL( models ); + + iAttributeManager.ForceStoreBatchL( models ); + CleanupStack::PopAndDestroy(); //models + } + + +// End of File +