PECengine/AttributeLibrary2/SrcTransactions/CPEngPresenceNotificationHandler.cpp
changeset 0 094583676ce7
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PECengine/AttributeLibrary2/SrcTransactions/CPEngPresenceNotificationHandler.cpp	Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,323 @@
+/*
+* 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 notification handler.
+*
+*/
+
+// INCLUDE FILES
+#include "CPEngPresenceNotificationHandler.h"
+#include "MPEngXMLParser.h"
+
+#include "MPEngPresenceAdvancedAttrModel2.h"
+#include "MPEngPresenceAttrManager.h"
+#include "MPEngPresenceAttrTransactionEnv.h"
+#include "PEngAddressUtils.h"
+#include "PEngAttrModelHelper.h"
+#include "PresenceDebugPrint.h"
+#include "PEngWVPresenceAttributes2.h"
+
+#include <E32Std.h>
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::NewL()
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CPEngPresenceNotificationHandler* CPEngPresenceNotificationHandler::NewL(
+    const TDesC& aDomain,
+    TPEngWVCspVersion aCspVersion,
+    MPEngPresenceAttrManager& aAttrManager,
+    MPEngPresenceAttrTransactionEnv& aTransEnv )
+    {
+    CPEngPresenceNotificationHandler* self = new ( ELeave ) CPEngPresenceNotificationHandler(
+        aAttrManager,
+        aTransEnv,
+        aCspVersion );
+
+    CleanupStack::PushL( self );
+    self->ConstructL( aDomain );
+    CleanupStack::Pop(); //self
+
+    return self;
+    }
+
+
+
+// Destructor
+CPEngPresenceNotificationHandler::~CPEngPresenceNotificationHandler()
+    {
+    iPresenceDataBlocks.Reset();
+    iModels.ResetAndDestroy();
+    delete iXmlParser;
+    delete iDomain;
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::CPEngPresenceNotificationHandler
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+// Useually only one or two users presence is updated at time ==> 2 blocks
+// -----------------------------------------------------------------------------
+//
+CPEngPresenceNotificationHandler::CPEngPresenceNotificationHandler(
+    MPEngPresenceAttrManager& aAttrManager,
+    MPEngPresenceAttrTransactionEnv& aTransEnv,
+    TPEngWVCspVersion aCspVersion )
+        : iAttributeManager( aAttrManager ),
+        iTransEnv( aTransEnv ),
+        iCspVersion( aCspVersion ),
+        iPresenceDataBlocks( 2 )
+    {
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::ConstructL()
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CPEngPresenceNotificationHandler::ConstructL( const TDesC& aDomain )
+    {
+    iXmlParser = CreateXMLParserL();
+    iDomain = aDomain.AllocL();
+    }
+
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::ProcessRequestL()
+// -----------------------------------------------------------------------------
+//
+void CPEngPresenceNotificationHandler::ProcessRequestL( const TDesC8& aRequest,
+                                                        TRequestStatus& /*aStatus*/ )
+    {
+    PENG_DP_TXT( "CPEngPresenceNotificationHandler::ProcessRequestL()" );
+
+
+    if ( !iXmlParser->DecodeL( aRequest,
+                               KPresenceNotificationRequest,
+                               ETrue ) )
+        {
+        return;
+        }
+
+
+    if ( iXmlParser->DecodeL( iXmlParser->ResultL(),
+                              KPresenceXMLTag,
+                              ETrue ) )
+        {
+        //Place found presence data blocks to an array
+        const TInt foundPresencesCount = iXmlParser->Count();
+        TInt presenceIx = 0;
+        for ( presenceIx = 0; presenceIx < foundPresencesCount; presenceIx++ )
+            {
+            iPresenceDataBlocks.AppendL( iXmlParser->ResultL( presenceIx ) );
+            }
+
+
+        //And process each presence notify block one by one
+        for ( presenceIx = 0; presenceIx < foundPresencesCount; presenceIx++ )
+            {
+            TPtrC8 notifyBlock = iPresenceDataBlocks[ presenceIx ];
+            TBool matchedToSubscription = ProcessNotifyBlockL( notifyBlock,
+                                                               *iDomain,
+                                                               iTransEnv.SubscribedPresenceIDs(),
+                                                               iAttributeManager,
+                                                               *iXmlParser,
+                                                               iModels );
+            if ( !matchedToSubscription )
+                {
+                //notification wasn't matched to any subscription
+                //que the orphan for later processing
+                iTransEnv.QueOrphanNotificationL( notifyBlock );
+                }
+            }
+
+        iAttributeManager.ForceStoreBatchL( iModels );
+        iModels.ResetAndDestroy();
+        }
+    }
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::CancelProcessing()
+// -----------------------------------------------------------------------------
+//
+void CPEngPresenceNotificationHandler::CancelProcessing()
+    {
+    PENG_DP_TXT( "CPEngPresenceNotificationHandler::ProcessRequestL()" );
+    }
+
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::CanHandleL()
+// -----------------------------------------------------------------------------
+//
+TBool CPEngPresenceNotificationHandler::CanHandleL( const TDesC8& aIncomingRequest )
+    {
+    PENG_DP_TXT( "CPEngPresenceNotificationHandler::CanHandleL()" );
+
+    TBool retStatus( EFalse );
+    MPEngXMLParser* xmlParser = CreateXMLParserLC();
+    if ( xmlParser->DecodeL( aIncomingRequest,
+                             KPresenceNotificationRequest,
+                             EFalse ) )
+        {
+        //This is a presence notification,
+        retStatus = ETrue;
+        }
+
+    CleanupStack::PopAndDestroy(); //xmlParser
+    PENG_DP( D_PENG_LIT( "CPEngPresenceNotificationHandler::CanHandleL() - %d" ), retStatus );
+
+    return retStatus;
+    }
+
+
+
+
+// -----------------------------------------------------------------------------
+// CPEngPresenceNotificationHandler::ProcessNotifyBlockL()
+// -----------------------------------------------------------------------------
+//
+TBool CPEngPresenceNotificationHandler::ProcessNotifyBlockL(
+    const TDesC8& aPresenceBlock,
+    const TDesC& aDomain,
+    const MDesCArray& aSubscribedPresences,
+    MPEngPresenceAttrManager& aAttributeManager,
+    MPEngXMLParser& aParser,
+    RPointerArray< MPEngPresenceAttrModel2 >& aModels )
+    {
+    if ( aParser.DecodeL( aPresenceBlock, KUserIDXMLTag, EFalse ) )
+        {
+        //There is a presence id => unescape the id
+        HBufC* nwPresenceID = aParser.ResultAsWVAddressL();
+        CleanupStack::PushL( nwPresenceID );
+
+        PENG_DP( D_PENG_LIT( "CPEngPresenceNotificationHandler - Presence notification for NW ID [%S]" ),
+                 nwPresenceID );
+
+        //Try get the presence id as it is subscribed
+        TInt subscribedIx = PEngAddressUtils::FindWVAddressF( *nwPresenceID,
+                                                              aSubscribedPresences,
+                                                              aDomain,
+                                                              PEngAddressUtils::EMatchToUniqueId );
+        CleanupStack::PopAndDestroy( nwPresenceID );
+
+        if ( subscribedIx == KErrNotFound )
+            {
+            //Matching subscription ID for notified presence ID not found
+            PENG_DP( D_PENG_LIT( "CPEngPresenceNotificationHandler - NW ID not matched" ) );
+            return EFalse;
+            }
+
+
+        const TDesC& subscribedPresenceID = aSubscribedPresences.MdcaPoint( subscribedIx );
+        PENG_DP( D_PENG_LIT( "CPEngPresenceNotificationHandler - NW ID matches to local [%S]" ),
+                 &subscribedPresenceID );
+
+
+        //go through all known network attributes
+        const TArray<TUint32> types = aAttributeManager.KnownAttributeTypes();
+        const TInt typeCount = types.Count();
+
+        MPEngPresenceAttrModel2* model = NULL;
+        // load and store online status to notify change
+        aAttributeManager.LoadAttributeLC( model,
+                                           subscribedPresenceID,
+                                           KUidPrAttrOnlineStatus,
+                                           EPEngStorableModel );
+        PEngAttrModelHelper::AddOrReplaceModelL( aModels,  *model );
+
+        CleanupStack::Pop(); //model
+
+        for ( TInt ii = 0; ii < typeCount; ii++ )
+            {
+            const TUint32 attributeType = types[ ii ];
+            TPtrC8 attributeName;
+            TPtrC8 attributeNameSpace;
+            TInt err = aAttributeManager.GetAttributeXmlNameAndNameSpace( attributeType,
+                                                                          attributeName,
+                                                                          attributeNameSpace );
+            if ( err == KErrNone )
+                {
+                if ( aParser.DecodeL( aPresenceBlock, attributeName, ETrue ) )
+                    {
+                    //attribute type was found from presence data block
+                    //==> Update the attribute
+
+                    PENG_DP( D_PENG_LIT( "CPEngPresenceNotificationHandler - Updating attribute [%08x]" ),
+                             attributeType );
+
+                    model = NULL;
+                    aAttributeManager.LoadAttributeLC( model,
+                                                       subscribedPresenceID,
+                                                       attributeType,
+                                                       EPEngStorableModel );
+
+                    model->Advanced()->DecodeFromXmlL( aParser, aParser.ResultL() );
+
+                    //Array might have already a same attribute for user
+                    //==> replace existing or add the new
+                    PEngAttrModelHelper::AddOrReplaceModelL( aModels, *model );
+                    CleanupStack::Pop(); //model
+                    }
+                else
+                    {
+                    if ( attributeType == KUidPrAttrStatusText )
+                        {
+
+                        model = NULL;
+                        aAttributeManager.LoadAttributeLC( model,
+                                                           subscribedPresenceID,
+                                                           KUidPrAttrStatusText,
+                                                           EPEngStorableModel );
+
+                        // model->Advanced()->DecodeFromXmlL( aParser, aParser.ResultL() );
+
+                        //Array might have already a same attribute for user
+                        //==> replace existing or add the new
+
+                        model->SetDataDesC16L( KNullDesC, EPEngStatusText );
+
+                        PEngAttrModelHelper::AddOrReplaceModelL( aModels, *model );
+                        CleanupStack::Pop(); //model
+
+                        }
+
+                    }
+                }
+
+
+            }
+
+        }
+
+    //Not a notification at all or matching subscription
+    //for notified presence ID was found
+    //==> XML block succesfully processed
+    return ETrue;
+    }
+
+
+
+//  End of File
+