diff -r 000000000000 -r c53acadfccc6 metadataengine/client/src/mdenotifierao.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/metadataengine/client/src/mdenotifierao.cpp Mon Jan 18 20:34:07 2010 +0200 @@ -0,0 +1,385 @@ +/* +* Copyright (c) 2005-2009 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: Notifier client side active object +* +*/ + + +// INCLUDE FILES +#include "mdenotifierao.h" + +#include "mdcresult.h" +#include "mdeenginesession.h" +#include "mdesessionimpl.h" +#include "mdenamespacedef.h" +#include "mdcserializationbuffer.h" +#include "mdccommon.pan" + +// ========================= MEMBER FUNCTIONS ================================== + +CMdENotifierAO* CMdENotifierAO::NewL( + CMdESessionImpl& aSessionImpl, RMdEEngineSession& aSession ) + { + CMdENotifierAO* self = CMdENotifierAO::NewLC( aSessionImpl, aSession ); + CleanupStack::Pop( self ); + return self; + } + + +CMdENotifierAO* CMdENotifierAO::NewLC( + CMdESessionImpl& aSessionImpl, RMdEEngineSession& aSession ) + { + CMdENotifierAO* self = + new ( ELeave ) CMdENotifierAO( aSessionImpl, aSession ); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + + +CMdENotifierAO::CMdENotifierAO( + CMdESessionImpl& aSessionImpl, RMdEEngineSession& aSession ) + : CActive( CActive::EPriorityUserInput ) + , iSessionImpl( aSessionImpl ) + , iSession( aSession ) + { + CActiveScheduler::Add( this ); + } + +void CMdENotifierAO::ConstructL() + { + } + + +CMdENotifierAO::~CMdENotifierAO() + { + Cancel(); // Causes call to DoCancel() + delete iDataBuffer; + iIdArray.Close(); + iRelationItemArray.Close(); + } + + +void CMdENotifierAO::RegisterL( TUint32 aType, TAny* aObserver, + CMdECondition* aCondition, CMdENamespaceDef& aNamespaceDef ) + { + iObserver = aObserver; + iType = aType; + iNamespaceDefId = aNamespaceDef.Id(); + + CMdCSerializationBuffer* buffer = NULL; + + if( aCondition ) + { + buffer = CMdCSerializationBuffer::NewLC( aCondition->RequiredBufferSize() ); + + // only needed, because method needs it as parameter + TUint32 freespaceOffset = 0; + + aCondition->SerializeL( *buffer, freespaceOffset ); + } + else + { + // create empty serialized condition buffer + buffer = CMdCSerializationBuffer::NewLC( 0 ); + } + + iSession.DoRegisterL( Id(), iType, *buffer, iNamespaceDefId ); + CleanupStack::PopAndDestroy( buffer ); + + // listen for first event + iSession.DoListen( Id(), &iResultSize, iStatus ); + SetActive(); + } + +TBool CMdENotifierAO::Match( TUint32 aType, TAny* aObserver, CMdENamespaceDef& aNamespaceDef ) + { + if( aNamespaceDef.Id() != iNamespaceDefId ) + { + return EFalse; + } + + if ( iObserver != aObserver ) + { + return EFalse; + } + + return ( iType & aType ); + } + +TInt CMdENotifierAO::Id() + { + return (TInt)this; + } + +void CMdENotifierAO::DoCancel() + { + TRAP_IGNORE( iSession.DoUnregisterL( Id() ) ); + // the current pending call will return with KErrCancel + } + +void CMdENotifierAO::RunL() + { + const TInt status = iStatus.Int(); + + if ( status >= KErrNone ) + { + if ( status & ( EObjectNotifyAdd | EObjectNotifyModify | EObjectNotifyRemove + | EObjectNotifyPresent | EObjectNotifyNotPresent + | ERelationNotifyAdd | ERelationNotifyModify | ERelationNotifyRemove + | ERelationNotifyPresent | ERelationNotifyNotPresent + | EEventNotifyAdd | EEventNotifyRemove ) ) + { + if( !iDataBuffer ) + { + iDataBuffer = CMdCSerializationBuffer::NewL( iResultSize() ); + } + else if( iDataBuffer->Buffer().MaxSize() < iResultSize() ) + { + delete iDataBuffer; + iDataBuffer = NULL; + iDataBuffer = CMdCSerializationBuffer::NewL( iResultSize() ); + } + + if( iResultSize() ) + { + iSession.DoGetDataL( *iDataBuffer, Id() ); // reads ids to the buffer + DecodeIdBufferL(); // decodes ids from the data buffer and puts them to iIdArray + + delete iDataBuffer; + iDataBuffer = NULL; + + DoNotifyObserver(); // notifies the observer about the event with an array of ids + } + iSession.DoListen( Id(), &iResultSize, iStatus ); // continue listening for events + SetActive(); + } + else if ( status & ( /*ERelationItemNotifyAdd | ERelationItemNotifyModify + |*/ ERelationItemNotifyRemove ) ) // a relation was removed + { + if( !iDataBuffer ) + { + iDataBuffer = CMdCSerializationBuffer::NewL(iResultSize()); + } + else if( iDataBuffer->Size() < (TUint32)iResultSize() ) + { + delete iDataBuffer; + iDataBuffer = NULL; + iDataBuffer = CMdCSerializationBuffer::NewL(iResultSize()); + } + + if(iResultSize()) + { + iSession.DoGetDataL( *iDataBuffer, Id() ); // reads ids to the buffer + DecodeRelationItemBufferL(); // decodes ids from the data buffer and puts them to iIdArray + + delete iDataBuffer; + iDataBuffer = NULL; + + DoNotifyObserver(); // notifies the observer about the event with an array of ids + } + iSession.DoListen( Id(), &iResultSize, iStatus ); // continue listening for events + SetActive(); + } + else if ( status == ESchemaModify ) // schema has been modified + { + DoNotifyObserver(); // notifies the observer about the event with an array of ids + iSession.DoListen( Id(), &iResultSize, iStatus ); // continue listening for events + SetActive(); + } + } + else + { + // error in notifier mechanism + if( status != KErrServerTerminated ) + { + iSession.DoUnregisterL( Id() ); // no response expected + } + else + { + iSessionImpl.NotifyError( status ); + } + iSessionImpl.NotifierInError( this ); + } + } + +TInt CMdENotifierAO::RunError(TInt aError) + { + if( aError == KErrServerTerminated ) + { + iSessionImpl.NotifyError( aError ); + } + + // notifying observer failed - continue listening anyway. + iSessionImpl.NotifierInError( this ); + return KErrNone; + } + +void CMdENotifierAO::DoNotifyObserver() + { + if( !iObserver ) + { + return; + } + const TInt status = iStatus.Int(); + switch( iType & status ) + { + case EObjectNotifyAdd: + { + MMdEObjectObserver* obs = static_cast( iObserver ); + obs->HandleObjectNotification( iSessionImpl, ENotifyAdd, iIdArray ); + iIdArray.Reset(); + break; + } + case EObjectNotifyModify: + { + MMdEObjectObserver* obs = static_cast( iObserver ); + obs->HandleObjectNotification( iSessionImpl, ENotifyModify, iIdArray ); + iIdArray.Reset(); + break; + } + case EObjectNotifyRemove: + { + MMdEObjectObserver* obs = static_cast( iObserver ); + obs->HandleObjectNotification( iSessionImpl, ENotifyRemove, iIdArray ); + iIdArray.Reset(); + break; + } + + case EObjectNotifyPresent: + { + MMdEObjectPresentObserver* obs = static_cast( iObserver ); + obs->HandleObjectPresentNotification( iSessionImpl, ETrue, iIdArray ); + iIdArray.Reset(); + break; + } + case EObjectNotifyNotPresent: + { + MMdEObjectPresentObserver* obs = static_cast( iObserver ); + obs->HandleObjectPresentNotification( iSessionImpl, EFalse, iIdArray ); + iIdArray.Reset(); + break; + } + + case ERelationNotifyAdd: + { + MMdERelationObserver* obs = static_cast( iObserver ); + obs->HandleRelationNotification( iSessionImpl, ENotifyAdd, iIdArray ); + iIdArray.Reset(); + break; + } + case ERelationNotifyModify: + { + MMdERelationObserver* obs = static_cast( iObserver ); + obs->HandleRelationNotification( iSessionImpl, ENotifyModify, iIdArray ); + iIdArray.Reset(); + break; + } + case ERelationNotifyRemove: + { + MMdERelationObserver* obs = static_cast( iObserver ); + obs->HandleRelationNotification( iSessionImpl, ENotifyRemove, iIdArray ); + iIdArray.Reset(); + break; + } + + case ERelationNotifyPresent: + { + MMdERelationPresentObserver* obs = static_cast( iObserver ); + obs->HandleRelationPresentNotification( iSessionImpl, ETrue, iIdArray ); + iIdArray.Reset(); + break; + } + case ERelationNotifyNotPresent: + { + MMdERelationPresentObserver* obs = static_cast( iObserver ); + obs->HandleRelationPresentNotification( iSessionImpl, EFalse, iIdArray ); + iIdArray.Reset(); + break; + } + + case ERelationItemNotifyRemove: + { + MMdERelationItemObserver* obs = static_cast( iObserver ); + obs->HandleRelationItemNotification( iSessionImpl, ENotifyRemove, iRelationItemArray ); + iRelationItemArray.Reset(); + break; + } + + case EEventNotifyAdd: + { + MMdEEventObserver* obs = static_cast( iObserver ); + obs->HandleEventNotification( iSessionImpl, ENotifyAdd, iIdArray); + iIdArray.Reset(); + break; + } + case EEventNotifyRemove: + { + MMdEEventObserver* obs = static_cast( iObserver ); + obs->HandleEventNotification( iSessionImpl, ENotifyRemove, iIdArray); + iIdArray.Reset(); + break; + } + + case ESchemaModify: + { + MMdESchemaObserver* obs = static_cast( iObserver ); + obs->HandleSchemaModified(); + break; + } + + default: + // no observer to call - this should be skipped on server side! + break; + } + } + +void CMdENotifierAO::DecodeIdBufferL() + { + // IDs are always stored in object IDs, + // even if those are actually relation or event IDs + + iIdArray.Reset(); + iDataBuffer->PositionL( KNoOffset ); + const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( *iDataBuffer ); + __ASSERT_DEBUG( iNamespaceDefId == itemIds.iNamespaceDefId, User::Panic( _L("Incorrect namespaceDef from returned items!"), KErrCorrupt ) ); + + iDataBuffer->PositionL( itemIds.iObjectIds.iPtr.iOffset ); + for( TUint32 i = 0; i < itemIds.iObjectIds.iPtr.iCount; ++i ) + { + TItemId id; + iDataBuffer->ReceiveL( id ); + iIdArray.AppendL( id ); + } + } + +void CMdENotifierAO::DecodeRelationItemBufferL() + { + iRelationItemArray.Reset(); + iDataBuffer->PositionL( KNoOffset ); + const TMdCItems& items = TMdCItems::GetFromBufferL( *iDataBuffer ); + __ASSERT_DEBUG( iNamespaceDefId == items.iNamespaceDefId, User::Panic( _L("Incorrect namespaceDef from returned items!"), KErrCorrupt ) ); + + CMdENamespaceDef& namespaceDef = iSessionImpl.GetNamespaceDefL( iNamespaceDefId ); + iDataBuffer->PositionL( items.iRelations.iPtr.iOffset ); + TMdERelation relation; + for (TInt i = 0; i < items.iRelations.iPtr.iCount; ++i ) + { + relation.DeSerializeL( *iDataBuffer, namespaceDef ); + if ( relation.Id() ) + { + iRelationItemArray.Append( relation ); + } + } + }