contentpublishingsrv/contentpublishingserver/cpserver/src/cpnotificationhandler.cpp
changeset 0 79c6a41cd166
child 12 502e5d91ad42
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/contentpublishingsrv/contentpublishingserver/cpserver/src/cpnotificationhandler.cpp	Thu Dec 17 08:54:17 2009 +0200
@@ -0,0 +1,520 @@
+/*
+* Copyright (c) 2008 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:  ?Description
+
+ *
+*/
+
+
+#include <liwcommon.h>
+#include <s32mem.h>
+
+#include "cpnotificationhandler.h"
+#include "cpdebug.h"
+#include "cpliwmap.h"
+#include "cpglobals.h"
+#include "cpserverdef.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CCPNotificationHandler::CCPNotificationHandler()
+    {
+
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+void CCPNotificationHandler::ConstructL( RPointerArray<CLiwDefaultList>& 
+        aNotifications)
+    {
+    iChangeInfoList = CLiwGenericParamList::NewL( );
+    for ( TInt i(0); i< aNotifications.Count( ); i++ )
+        {
+        iNotifications.AppendL(aNotifications[i]);
+        aNotifications[i]->IncRef();
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CCPNotificationHandler* CCPNotificationHandler::NewL(  
+        RPointerArray<CLiwDefaultList>& aNotifications )
+    {
+    CCPNotificationHandler* self = CCPNotificationHandler::NewLC( 
+                                                            aNotifications );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CCPNotificationHandler* CCPNotificationHandler::NewLC( 
+        RPointerArray<CLiwDefaultList>& aNotifications )
+    {
+    CCPNotificationHandler* self = new( ELeave ) CCPNotificationHandler;
+    CleanupStack::PushL( self );
+    self->ConstructL( aNotifications );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+//
+CCPNotificationHandler::~CCPNotificationHandler()
+    {
+    THashMapIter<TInt32, CCPLiwMap*> iter( iFilters );
+
+    const TInt32* transaction = iter.NextKey();
+    while( transaction )
+        {
+        CCPLiwMap** filter = iFilters.Find( *transaction );// leaves if not found
+        if ( filter )
+        	{
+        	(*filter)->Reset();
+        	(*filter)->Close();
+        	}
+        transaction = iter.NextKey( );
+        }  
+    iFilters.Close();    
+    Reset( );
+    for ( TInt i(0); i< iNotifications.Count( ); i++ )
+        {
+        iNotifications[i]->Close( );
+        }
+    iNotifications.Close( );
+    delete iChangeInfoList;
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//    
+void CCPNotificationHandler::SaveMessageL( const RMessage2& aMessage )
+    {
+    iIsReadyToSend = ETrue;
+    iMessage = aMessage;
+    
+    TInt32 transactionId = aMessage.Int3();
+    if ( transactionId != KErrAlreadyExists )
+    	{
+    	TInt deslen = aMessage.GetDesLengthL( KDescriptorPosition );
+    	if( deslen > 0 )
+    		{
+    		HBufC8* buffer = HBufC8::NewLC( deslen );
+    		TPtr8 tempDes = buffer->Des( );
+    		aMessage.Read( KDescriptorPosition, tempDes );
+    		RDesReadStream datastrm( *buffer);
+    		CleanupClosePushL( datastrm );
+    		CCPLiwMap* filterMap = CCPLiwMap::NewL( datastrm );
+    		CleanupStack::PushL( filterMap );
+    		iFilters.InsertL( transactionId, filterMap );
+    		CleanupStack::Pop( filterMap );
+    		CleanupStack::PopAndDestroy( &datastrm );
+    		CleanupStack::PopAndDestroy( buffer );
+    		}
+    	}
+	if ( iNotifications.Count( ) )
+		{
+		SendNotificationL( NULL );
+		}   
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//    
+void CCPNotificationHandler::AddObserverL( const RMessage2& aMessage )
+    {
+    TInt32 transactionId = aMessage.Int3();
+    TInt deslen = aMessage.GetDesLength( KDescriptorPosition );
+    if( deslen > 0 )
+        {
+        HBufC8* buffer = HBufC8::NewLC( deslen );
+        TPtr8 tempDes = buffer->Des( );
+        aMessage.Read( KDescriptorPosition, tempDes );
+        RDesReadStream datastrm( *buffer);
+        CleanupClosePushL( datastrm );
+        CCPLiwMap* filterMap = CCPLiwMap::NewL( datastrm );
+		CleanupStack::PushL( filterMap );
+        iFilters.InsertL( transactionId, filterMap );
+		CleanupStack::Pop( filterMap );
+        CleanupStack::PopAndDestroy( &datastrm );
+        CleanupStack::PopAndDestroy( buffer );
+        }    
+    }
+
+// ---------------------------------------------------------------------------
+//
+// ---------------------------------------------------------------------------
+//    
+void CCPNotificationHandler::RemoveObserverL( const RMessage2& aMessage )
+    {
+    TInt32 transactionId = aMessage.Int3();
+    CCPLiwMap* filter = iFilters.FindL( transactionId );// leaves if not found
+    filter->Reset();
+    filter->Close();
+    iFilters.Remove( transactionId );
+    }
+
+// -----------------------------------------------------------------------------
+// 
+// -----------------------------------------------------------------------------
+//
+TBool CCPNotificationHandler::IsProperForFilterL( const CLiwDefaultMap& aMap, 
+		const CCPLiwMap& aFilter )
+    {
+    CP_DEBUG( _L8("CCPNotificationHandler::IsProperForFilter()") );
+    TBool result( EFalse );
+    if( CheckRegistryTypeL( aMap, aFilter ) && 
+    		CheckOperationTypeL( aMap, aFilter ) )
+        {
+        if( CheckIdL( aMap, aFilter ) )
+            {
+            result= ETrue;
+            }
+        else if( CheckPropertiesL( aMap, aFilter ) )
+            {
+            result = ETrue;
+            }
+        }
+    return result;
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCPNotificationHandler::SendNotificationL( CLiwDefaultList* aListOfMaps )
+    {
+    CP_DEBUG( _L8("CCPNotificationHandler::SendNotificationL()") );
+    if ( iIsReadyToSend )
+        {
+        //notification can be send
+        if ( iNotifications.Count( ) )
+            {
+            //at least one notification is waiting to be sent
+            TBool sent;
+            sent = SendChangeInfoListL( iNotifications[0] );
+            iNotifications[0]->Close( );
+            iNotifications.Remove( 0 );
+            if ( !sent )
+                {
+                //if notification from array wasn't sent because it didn't 
+                //match the filter, try to send the next one
+                SendNotificationL( NULL );
+                }
+            else
+                {
+                //message was send
+                iIsReadyToSend = EFalse;
+                }
+            }
+        else
+            {
+            //no notification is waiting, so send the new one
+            if ( aListOfMaps && SendChangeInfoListL( aListOfMaps ) )
+                {
+                iIsReadyToSend = EFalse;
+                }
+            }
+        }
+    else
+        {
+        //notification cannot be sent in this moment
+        aListOfMaps->IncRef( );
+        iNotifications.AppendL( aListOfMaps );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+
+const CLiwGenericParamList* CCPNotificationHandler::GetPointerToChangeInfoList()
+    {
+    return iChangeInfoList;
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCPNotificationHandler::Reset()
+    {
+    iIsReadyToSend = EFalse;
+    iChangeInfoList->Reset( );
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCPNotificationHandler::ErrorComplete( TInt aErrCode )
+    {
+    if( iIsReadyToSend && iMessage.IsNull() == EFalse )
+        {
+        iMessage.Complete( aErrCode );
+        iIsReadyToSend = EFalse;
+        }
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+TBool CCPNotificationHandler::SendChangeInfoListL(
+    const CLiwDefaultList* aListOfMaps )
+    {
+    CP_DEBUG( _L8("CCPNotificationHandler::SendChangeInfoListL()") );
+	iChangeInfoList->Reset( );
+    TBool sent(EFalse);
+    //for every observer in session
+    THashMapIter<TInt32, CCPLiwMap*> iter( iFilters );
+    const CCPLiwMap*const* filter = iter.NextValue( );
+    while( filter )
+        {
+        
+        CLiwDefaultList* listOfMatchingMaps = CLiwDefaultList::NewLC( );
+
+        //for every item in the input list
+		for ( TInt j = 0; j < aListOfMaps->Count( ); j++ )
+			{
+			CLiwDefaultMap* map = CLiwDefaultMap::NewLC( );
+	        TLiwVariant variant;
+	        variant.PushL( );
+			aListOfMaps->AtL( j, variant );
+			variant.Get( *map );
+			if ( IsProperForFilterL( *map, **filter ) )
+				{
+				listOfMatchingMaps->AppendL( TLiwVariant( map ) );
+				}
+			CleanupStack::PopAndDestroy( &variant );
+			CleanupStack::PopAndDestroy( map );
+			}
+		if ( listOfMatchingMaps->Count( ) )
+			{
+			//append transaction id
+			listOfMatchingMaps->AppendL( TLiwVariant( *iter.CurrentKey() ));
+			iChangeInfoList->AppendL( TLiwGenericParam( KChangeInfo,
+				TLiwVariant( listOfMatchingMaps ) ) );
+			}
+		CleanupStack::PopAndDestroy( listOfMatchingMaps );
+		filter = iter.NextValue( );
+        }
+
+    if( iChangeInfoList->Count( ) )
+    	{
+    	TPckgBuf<TInt> sizeDes( iChangeInfoList->Size( ) );
+    	TInt err = iMessage.Write( KReturnPosition, sizeDes );
+    	iMessage.Complete( err );
+    	sent = ETrue;
+    	}
+	return sent;
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+void CCPNotificationHandler::GetPropertyL( const CLiwDefaultMap& aMap,
+    const TDesC8& aProperty, RBuf& aResult )
+    {
+    TLiwVariant value;
+    value.PushL( );
+    if ( aMap.FindL( aProperty, value ) )
+        {
+        TPtrC result( KNullDesC );
+        value.Get( result );
+        aResult.CreateL( result );
+        }
+    CleanupStack::PopAndDestroy( &value );
+    }
+    
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+TBool CCPNotificationHandler::CheckIdL( const CLiwDefaultMap& aMap, 
+		const CCPLiwMap& aFilter )
+    {
+    TBool result = EFalse;
+    TInt32 id( 0);
+    if ( aFilter.GetProperty( KId, id ) )
+        {
+        TLiwVariant value;
+        value.PushL( );
+        if ( aMap.FindL( KId, value ) )
+            {
+            TUint idToCompare( 0);
+            if ( value.Get( idToCompare ) )
+                {
+                if ( id == idToCompare )
+                    {
+                    result = ETrue;
+                    }
+                }
+            }
+        CleanupStack::PopAndDestroy( &value );
+        }
+    return result;
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+TBool CCPNotificationHandler::CheckPropertiesL( const CLiwDefaultMap& aMap,
+		const CCPLiwMap& aFilter )
+    {
+    TBool result( EFalse );
+    TBool publisherName( ETrue );
+    TBool contentType( ETrue );
+    TBool contentId( ETrue );
+    RBuf publisher;
+    publisher.CleanupClosePushL();
+
+    if ( aFilter.GetPropertyL( KPublisherId, publisher ) )
+        {
+        if ( publisher != KAll )
+            {
+            RBuf str2compare;
+            str2compare.CleanupClosePushL();
+            GetPropertyL( aMap, KPublisherId, str2compare );
+            if ( publisher!=str2compare )
+                {
+                publisherName = EFalse;
+                }
+            CleanupStack::PopAndDestroy( &str2compare );
+            }
+        }
+    RBuf content;
+    content.CleanupClosePushL();
+    if ( aFilter.GetPropertyL( KContentType, content ) )
+        {
+        if ( content != KAll )
+            {
+            RBuf str2compare;
+            str2compare.CleanupClosePushL();
+            GetPropertyL( aMap, KContentType, str2compare );
+            if ( content!=str2compare )
+                {
+                contentType = EFalse;
+                }
+            CleanupStack::PopAndDestroy( &str2compare );
+            }
+        }
+    RBuf content_id;
+    content_id.CleanupClosePushL();
+    if ( (publisher != KAll)||(content != KAll) )
+        {
+        if ( aFilter.GetPropertyL( KContentId, content_id ) )
+            {
+            if ( content_id != KAll )
+                {
+				RBuf str2compare;
+				str2compare.CleanupClosePushL();
+				GetPropertyL( aMap, KContentId, str2compare );
+				if ( content_id!=str2compare )
+					{
+					contentId = EFalse;
+					}
+				CleanupStack::PopAndDestroy( &str2compare );
+                }
+            }
+        }
+    if ( publisherName && contentType && contentId )
+        {
+        result = ETrue;
+        }
+    CleanupStack::PopAndDestroy( &content_id );
+    CleanupStack::PopAndDestroy( &content );
+    CleanupStack::PopAndDestroy( &publisher );
+    return result;
+    }
+
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+TBool CCPNotificationHandler::CheckOperationTypeL( const CLiwDefaultMap& aMap,
+		const CCPLiwMap& aFilter )
+    {
+    TBool result = ETrue;
+    RBuf operation;
+    operation.CleanupClosePushL();
+    if ( aFilter.GetPropertyL( KOperation, operation ) )
+        {
+        result = EFalse;
+        TLiwVariant value;
+        value.PushL( );
+        if ( aMap.FindL( KOperation, value ) )
+            {
+            TPtrC operationToCompare( KNullDesC );
+            if ( value.Get( operationToCompare ) )
+                {
+                if ( operation.Find( operationToCompare ) != KErrNotFound )
+                    {
+                    result = ETrue;
+                    }
+                }
+            }
+        CleanupStack::PopAndDestroy( &value );
+        }
+    CleanupStack::PopAndDestroy( &operation );
+    return result;
+    }
+    
+// ----------------------------------------------------------------------------
+//
+// ----------------------------------------------------------------------------
+//
+TBool CCPNotificationHandler::CheckRegistryTypeL( const CLiwDefaultMap& aMap,
+		const CCPLiwMap& aFilter )
+    {
+    TBool result = ETrue;
+    RBuf type;
+    type.CleanupClosePushL();
+    if ( aFilter.GetPropertyL( KType, type ) )
+        {
+        result = EFalse;
+        TLiwVariant value;
+        value.PushL( );
+        if ( aMap.FindL( KType, value ) )
+            {
+            TPtrC typeToCompare( KNullDesC );
+            if ( value.Get( typeToCompare ) )
+                {
+                if ( type.Find( typeToCompare ) != KErrNotFound )
+                    {
+                    result = ETrue;
+                    }
+                }
+            }
+        CleanupStack::PopAndDestroy( &value );
+        }
+    CleanupStack::PopAndDestroy( &type );
+    return result;
+    }