metadataengine/server/src/mdsnotifier.cpp
changeset 0 c53acadfccc6
child 1 acef663c1218
equal deleted inserted replaced
-1:000000000000 0:c53acadfccc6
       
     1 /*
       
     2 * Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Notifier engine / server side*
       
    15 */
       
    16 
       
    17 #include "mdsnotifier.h"
       
    18 
       
    19 #include "mdcresult.h"
       
    20 #include "mdcitem.h"
       
    21 #include "mdsserversession.h"
       
    22 #include "mdsnotifycomparator.h"
       
    23 #include "mdslogger.h"
       
    24 #include "mdcserializationbuffer.h"
       
    25 #include "mdccommon.pan"
       
    26 
       
    27 __USES_LOGGER
       
    28 
       
    29 // ------------------------------------------------
       
    30 // NewL
       
    31 // ------------------------------------------------
       
    32 //
       
    33 CMdSNotifier* CMdSNotifier::NewL()
       
    34     {
       
    35     CMdSNotifier* that = CMdSNotifier::NewLC();
       
    36     CleanupStack::Pop( that );
       
    37     return that;
       
    38     }
       
    39 
       
    40 
       
    41 // ------------------------------------------------
       
    42 // NewLC
       
    43 // ------------------------------------------------
       
    44 //
       
    45 CMdSNotifier* CMdSNotifier::NewLC()
       
    46     {
       
    47     CMdSNotifier* that = new(ELeave) CMdSNotifier();
       
    48     CleanupStack::PushL( that );
       
    49     that->ConstructL();
       
    50     return that;
       
    51     }
       
    52 
       
    53 
       
    54 // ------------------------------------------------
       
    55 // Constructor
       
    56 // ------------------------------------------------
       
    57 //
       
    58 CMdSNotifier::CMdSNotifier()
       
    59     {
       
    60     
       
    61     }
       
    62 
       
    63 // ------------------------------------------------
       
    64 // ConstructL
       
    65 // ------------------------------------------------
       
    66 //
       
    67 void CMdSNotifier::ConstructL()
       
    68     {
       
    69     iComparator = CMdSNotifyComparator::NewL();
       
    70     }
       
    71 
       
    72 // ------------------------------------------------
       
    73 // Destructor
       
    74 // ------------------------------------------------
       
    75 //
       
    76 CMdSNotifier::~CMdSNotifier()
       
    77     {
       
    78     delete iComparator;
       
    79     iEntries.Close();
       
    80     }
       
    81 
       
    82 // ------------------------------------------------
       
    83 // Constructor
       
    84 // ------------------------------------------------
       
    85 //
       
    86 CMdSNotifier::TEntry::TEntry( TInt aId,
       
    87     TConditionType aType,
       
    88     CMdCSerializationBuffer* aSerializedBuffer,
       
    89     TDefId aNamespaceDefId, 
       
    90     CMdSServerSession& aSession, 
       
    91     TBool aConfidential)
       
    92     : iId( aId )
       
    93     , iType( aType )
       
    94     , iNamespaceDefId(aNamespaceDefId)
       
    95     , iSerializedCondition( aSerializedBuffer )
       
    96     , iSession( aSession )
       
    97     , iConfidential(aConfidential)    
       
    98     {
       
    99     iDataBuffer = NULL;
       
   100     iRemoteSizeMsgSlot = KErrNotFound;
       
   101     }
       
   102 
       
   103 // ------------------------------------------------
       
   104 // TriggerL completes the client message and sends the data size
       
   105 // ------------------------------------------------
       
   106 //
       
   107 void CMdSNotifier::TEntry::TriggerL(
       
   108 	TUint32 aCompleteCode,
       
   109     const RArray<TItemId>& aIdArray )
       
   110     {
       
   111     TInt remoteSizeMsgSlot = iRemoteSizeMsgSlot;
       
   112     iRemoteSizeMsgSlot = KErrNotFound;
       
   113 
       
   114     __ASSERT_DEBUG( !iDataBuffer, MMdCCommon::Panic( KErrCorrupt ) );
       
   115 
       
   116     if(aIdArray.Count())
       
   117 		{
       
   118 		iDataBuffer = CopyToBufferL( aIdArray );
       
   119 	    iSession.SizeToRemoteL( iMessage, remoteSizeMsgSlot, iDataBuffer->Size());
       
   120 		}
       
   121 	else
       
   122 		{
       
   123 	    iSession.SizeToRemoteL( iMessage, remoteSizeMsgSlot, 0);
       
   124 		}
       
   125 
       
   126     __LOG2( ELogServer, "<- Notify trigger %d (%d)", iId, aCompleteCode );
       
   127     iMessage.Complete( aCompleteCode );
       
   128     }
       
   129 
       
   130 // ------------------------------------------------
       
   131 // TriggerRelationItemsL completes the client
       
   132 //                  message and sends the data size
       
   133 // ------------------------------------------------
       
   134 //
       
   135 void CMdSNotifier::TEntry::TriggerRelationItemsL(
       
   136 	TUint32 aCompleteCode,
       
   137 	CMdCSerializationBuffer& aBuffer,
       
   138 	const RArray<TItemId>& aRelationIdArray)
       
   139     {
       
   140     TInt remoteSizeMsgSlot = iRemoteSizeMsgSlot;
       
   141     iRemoteSizeMsgSlot = KErrNotFound;
       
   142 
       
   143     __ASSERT_DEBUG( !iDataBuffer, MMdCCommon::Panic( KErrCorrupt ) );
       
   144 
       
   145     if(aRelationIdArray.Count())
       
   146 		{
       
   147 		iDataBuffer = CopyItemsToBufferL( aBuffer, aRelationIdArray );
       
   148 	    iSession.SizeToRemoteL( iMessage, remoteSizeMsgSlot, iDataBuffer->Size());
       
   149 		}
       
   150 	else
       
   151 		{
       
   152 	    iSession.SizeToRemoteL( iMessage, remoteSizeMsgSlot, 0);
       
   153 		}
       
   154 
       
   155     __LOG2( ELogServer, "<- Notify trigger %d (%d)", iId, aCompleteCode );
       
   156     iMessage.Complete( aCompleteCode );
       
   157     }
       
   158 
       
   159 // ------------------------------------------------
       
   160 // TriggerSchemaL sends a schema notification
       
   161 // ------------------------------------------------
       
   162 //
       
   163 void CMdSNotifier::TEntry::TriggerSchema()
       
   164     {
       
   165     iRemoteSizeMsgSlot = KErrNotFound;
       
   166     iMessage.Complete( ESchemaModify );
       
   167     }
       
   168 
       
   169 // ------------------------------------------------
       
   170 // TriggerError send a error message to the client
       
   171 // ------------------------------------------------
       
   172 //
       
   173 void CMdSNotifier::TEntry::TriggerError( TInt aErrorCode )
       
   174     {
       
   175     iRemoteSizeMsgSlot = KErrNotFound;
       
   176 	delete iDataBuffer;
       
   177     iDataBuffer = NULL;
       
   178     __LOG2( ELogServer, "<- Notify trigger %d (%d)", iId, aErrorCode );
       
   179 
       
   180     if( !iMessage.IsNull() )
       
   181     	{
       
   182     	iMessage.Complete( aErrorCode );
       
   183     	}
       
   184     }
       
   185 
       
   186 // ------------------------------------------------
       
   187 // CopyToBufferL copies id to buffer
       
   188 // ------------------------------------------------
       
   189 //
       
   190 CMdCSerializationBuffer* CMdSNotifier::TEntry::CopyToBufferL(const RArray<TItemId>& aIdArray)
       
   191 	{
       
   192 	// IDs are always stored in object ID, 
       
   193 	// even if those are actually relation or event IDs
       
   194 
       
   195 	const TUint32 count = aIdArray.Count();
       
   196 
       
   197 	CMdCSerializationBuffer* buffer = CMdCSerializationBuffer::NewLC(
       
   198 			sizeof( TMdCItemIds )
       
   199 			+ count * CMdCSerializationBuffer::KRequiredSizeForTItemId );
       
   200 
       
   201 	TMdCItemIds itemIds;
       
   202 	itemIds.iNamespaceDefId = NamespaceDefId();
       
   203 	itemIds.iObjectIds.iPtr.iCount = count;
       
   204 	itemIds.iObjectIds.iPtr.iOffset = sizeof(TMdCItemIds);
       
   205 	itemIds.SerializeL( *buffer );
       
   206 
       
   207 	for( TInt i = 0; i < count; ++i )
       
   208 		{
       
   209 		buffer->InsertL( aIdArray[i] );
       
   210 		}
       
   211 
       
   212 	CleanupStack::Pop( buffer );
       
   213 	return buffer;	
       
   214 	}
       
   215 
       
   216 // ------------------------------------------------
       
   217 // CopyItemsToBufferL copies relation items to buffer
       
   218 // ------------------------------------------------
       
   219 //
       
   220 CMdCSerializationBuffer* CMdSNotifier::TEntry::CopyItemsToBufferL(
       
   221 		CMdCSerializationBuffer& aRelationItemsBuffer, 
       
   222 		const RArray<TItemId>& aIdArray)
       
   223 	{
       
   224 	const TUint32 count = aIdArray.Count();
       
   225 	aRelationItemsBuffer.PositionL( KNoOffset );
       
   226 	const TMdCItems& items = TMdCItems::GetFromBufferL( aRelationItemsBuffer );
       
   227 
       
   228 	CMdCSerializationBuffer* buffer = NULL;
       
   229 	if ( items.iRelations.iPtr.iCount == count )
       
   230 		{
       
   231 		buffer = CMdCSerializationBuffer::NewLC( aRelationItemsBuffer );
       
   232 		}
       
   233 	else
       
   234 		{
       
   235 		buffer = CMdCSerializationBuffer::NewLC( sizeof(TMdCItems)
       
   236 				+ count * sizeof(TMdCRelation) );
       
   237 
       
   238 		TMdCItems returnItems;
       
   239 		returnItems.iNamespaceDefId = items.iNamespaceDefId;
       
   240 		returnItems.iRelations.iPtr.iCount = count;
       
   241 		returnItems.iRelations.iPtr.iOffset = sizeof(TMdCItems);
       
   242 		buffer->PositionL( sizeof(TMdCItems) );
       
   243 
       
   244 		for( TInt i = 0; i < items.iRelations.iPtr.iCount; ++i )
       
   245 			{
       
   246 			TMdCRelation relation;
       
   247 			relation.DeserializeL( aRelationItemsBuffer );
       
   248 
       
   249 			if ( aIdArray.Find( relation.iId ) >= 0 )
       
   250 				{
       
   251 				relation.SerializeL( *buffer );
       
   252 				}
       
   253 			}
       
   254 		buffer->PositionL( KNoOffset );
       
   255 		returnItems.SerializeL( *buffer );
       
   256 		}
       
   257 	
       
   258 	CleanupStack::Pop( buffer );
       
   259 	return buffer;
       
   260 	}
       
   261 
       
   262 // ------------------------------------------------
       
   263 // CacheL caches the notification
       
   264 // ------------------------------------------------
       
   265 //
       
   266 void CMdSNotifier::TEntry::CacheL(TUint32 aCompleteCode, const RArray<TItemId>& aIdArray )
       
   267     {
       
   268     if ( aIdArray.Count() <= 0 )
       
   269     	{
       
   270     	return;
       
   271     	}
       
   272 
       
   273     CMdCSerializationBuffer* data = CopyToBufferL( aIdArray );
       
   274     iSession.CacheNotificationL( iId, aCompleteCode, data );
       
   275     }
       
   276 
       
   277 // ------------------------------------------------
       
   278 // CacheRelationItemsL caches the notification
       
   279 // ------------------------------------------------
       
   280 //
       
   281 void CMdSNotifier::TEntry::CacheRelationItemsL(TUint32 aCompleteCode,
       
   282 		CMdCSerializationBuffer& aBuffer, 
       
   283 		const RArray<TItemId>& aRelationIdArray )
       
   284     {
       
   285     CMdCSerializationBuffer* data = CopyItemsToBufferL( aBuffer, 
       
   286     		aRelationIdArray );
       
   287     iSession.CacheNotificationL(iId, aCompleteCode, data);
       
   288     }
       
   289 
       
   290 // ------------------------------------------------
       
   291 // CacheL for schema mods
       
   292 // ------------------------------------------------
       
   293 //
       
   294 void CMdSNotifier::TEntry::CacheL(TUint32 aCompleteCode)
       
   295     {
       
   296     iSession.CacheNotificationL(iId, aCompleteCode, NULL);
       
   297     }
       
   298     
       
   299 // ------------------------------------------------
       
   300 // TriggerCachedL triggers a previously cached notification
       
   301 // ------------------------------------------------
       
   302 //
       
   303 void CMdSNotifier::TEntry::TriggerCachedL(TUint32 aCompleteCode, 
       
   304 		CMdCSerializationBuffer* aData)
       
   305     {
       
   306     TInt remoteSizeMsgSlot = iRemoteSizeMsgSlot;
       
   307     iRemoteSizeMsgSlot = KErrNotFound;
       
   308 
       
   309     __ASSERT_DEBUG( !iDataBuffer, MMdCCommon::Panic( KErrCorrupt ) );
       
   310 
       
   311     if( aData )
       
   312     	{
       
   313     	iSession.SizeToRemoteL( iMessage, remoteSizeMsgSlot, aData->Size());
       
   314     	}
       
   315 
       
   316 	iDataBuffer = aData;
       
   317 
       
   318     __LOG2( ELogServer, "<- Notify trigger %d (%d)", iId, aCompleteCode );
       
   319     iMessage.Complete( aCompleteCode );
       
   320     }
       
   321 
       
   322 // ------------------------------------------------
       
   323 // SetupForCallback
       
   324 // ------------------------------------------------
       
   325 //
       
   326 void CMdSNotifier::TEntry::SetupForCallback(
       
   327     RMessage2 aMessage, TInt aRemoteSizeMsgSlot )
       
   328     {
       
   329     __ASSERT_DEBUG( !IsPending(), MMdCCommon::Panic( KErrCorrupt ) );
       
   330     iMessage = aMessage;
       
   331     iRemoteSizeMsgSlot = aRemoteSizeMsgSlot;
       
   332     }
       
   333 
       
   334 // ------------------------------------------------
       
   335 // GetDataBuffer
       
   336 // ------------------------------------------------
       
   337 //
       
   338 CMdCSerializationBuffer* CMdSNotifier::TEntry::GetDataBuffer()
       
   339     {
       
   340     CMdCSerializationBuffer* data = iDataBuffer;
       
   341     iDataBuffer = NULL;
       
   342     return data;
       
   343     }
       
   344 
       
   345 // ------------------------------------------------
       
   346 // CreateEntry creates a new notifier entry
       
   347 // ------------------------------------------------
       
   348 //
       
   349 CMdSNotifier::TEntry& CMdSNotifier::CreateEntryL( TInt aId,
       
   350     TConditionType aType, CMdCSerializationBuffer* aSerializedBuffer,
       
   351     TDefId aNamespaceDefId, CMdSServerSession& aSession, TBool aConfidential )
       
   352     {
       
   353 
       
   354     User::LeaveIfError( iEntries.Append(
       
   355         TEntry( aId, aType, aSerializedBuffer, aNamespaceDefId, aSession, aConfidential ) ) );
       
   356     return iEntries[ iEntries.Count() - 1 ];
       
   357     }
       
   358 
       
   359 // ------------------------------------------------
       
   360 // FindEntry
       
   361 // ------------------------------------------------
       
   362 //
       
   363 CMdSNotifier::TEntry& CMdSNotifier::FindEntryL( TInt aId )
       
   364     {
       
   365     CMdSNotifier::TEntry* entry = NULL;
       
   366     
       
   367     const TInt count = iEntries.Count();
       
   368     
       
   369     for ( TInt i = 0; i < count; ++i )
       
   370         {
       
   371         if ( iEntries[i].iId == aId )
       
   372             {
       
   373             entry = &iEntries[i];
       
   374             break;
       
   375             }
       
   376         }
       
   377 
       
   378     if( !entry )
       
   379     	{
       
   380     	User::Leave( KErrNotFound );
       
   381     	}
       
   382     
       
   383     return *entry;
       
   384     }
       
   385 
       
   386 // ------------------------------------------------
       
   387 // RemoveEntryL
       
   388 // ------------------------------------------------
       
   389 //
       
   390 void CMdSNotifier::RemoveEntryL( TInt aId )
       
   391     {
       
   392     const TInt count = iEntries.Count();
       
   393     
       
   394     for ( TInt i = 0; i < count; ++i )
       
   395         {
       
   396         TEntry& e = iEntries[i];
       
   397         if ( e.iId == aId )
       
   398             {
       
   399             if ( e.IsPending() )
       
   400                 {
       
   401                 e.TriggerError( KErrCancel );
       
   402                 }
       
   403             
       
   404             if ( e.iSerializedCondition )
       
   405             	{
       
   406             	delete e.iSerializedCondition;
       
   407             	e.iSerializedCondition = NULL;
       
   408             	}
       
   409             if ( e.iDataBuffer )
       
   410             	{
       
   411             	delete e.iDataBuffer;
       
   412             	e.iDataBuffer = NULL;
       
   413             	}
       
   414             iEntries.Remove( i );
       
   415             return;
       
   416             }
       
   417         }
       
   418     User::Leave( KErrNotFound );
       
   419     }
       
   420 
       
   421 // ------------------------------------------------
       
   422 // RemoveEntriesBySession
       
   423 // ------------------------------------------------
       
   424 //
       
   425 void CMdSNotifier::RemoveEntriesBySession(
       
   426     const CMdSServerSession& aSession )
       
   427     {
       
   428     const TInt count = iEntries.Count();
       
   429     
       
   430     for ( TInt i = count; --i >= 0; )
       
   431         {
       
   432         TEntry& e = iEntries[i];
       
   433         if ( &e.iSession == &aSession ) // pointer comparision
       
   434             {
       
   435             if ( e.IsPending() )
       
   436                 {
       
   437                 e.TriggerError( KErrCancel );
       
   438                 }
       
   439             
       
   440             delete e.iSerializedCondition;
       
   441             delete e.iDataBuffer;
       
   442             iEntries.Remove( i );
       
   443             }
       
   444         }
       
   445     }
       
   446 
       
   447 // ------------------------------------------------
       
   448 // NotifyAdded
       
   449 // ------------------------------------------------
       
   450 //
       
   451 void CMdSNotifier::NotifyAddedL(CMdCSerializationBuffer& aSerializedItems, 
       
   452 							    CMdCSerializationBuffer& aSerializedItemIds)
       
   453     {
       
   454     const TInt count = iEntries.Count();
       
   455     
       
   456     for( TInt i = 0; i < count; ++i )
       
   457         {
       
   458         TEntry& e = iEntries[i];
       
   459 
       
   460         if ( ! (e.iType & ( EObjectNotifyAdd | ERelationNotifyAdd | EEventNotifyAdd ) ) )
       
   461         	{
       
   462         	continue;
       
   463         	}
       
   464         
       
   465         RArray<TItemId> matchingItemIdArray;
       
   466    		CleanupClosePushL( matchingItemIdArray );
       
   467 
       
   468 		aSerializedItems.PositionL( KNoOffset );
       
   469 		aSerializedItemIds.PositionL( KNoOffset );
       
   470 
       
   471 		TBool someMatches = iComparator->MatchL( e.NamespaceDefId(), e.iType, e.Condition(), 
       
   472 												 aSerializedItems, aSerializedItemIds, 
       
   473 												 matchingItemIdArray,
       
   474 												 e.AllowConfidential() );
       
   475 
       
   476         if( someMatches ) // check if there is some matches
       
   477             {
       
   478             if( e.IsPending() )
       
   479             	{
       
   480             	// match found. trigger notifier entry !
       
   481 	            TRAPD( err, e.TriggerL( EObjectNotifyAdd | ERelationNotifyAdd | EEventNotifyAdd,
       
   482 	            		matchingItemIdArray ) );
       
   483 	            if( err != KErrNone )
       
   484 	            	{
       
   485 	            	e.TriggerError( err );
       
   486 	            	}
       
   487             	}
       
   488             else
       
   489             	{
       
   490             	TRAP_IGNORE( e.CacheL( EObjectNotifyAdd | ERelationNotifyAdd | EEventNotifyAdd,
       
   491             			matchingItemIdArray ) );
       
   492             	}
       
   493             }
       
   494 
       
   495    		CleanupStack::PopAndDestroy( &matchingItemIdArray );
       
   496         }
       
   497     }
       
   498 
       
   499 // ------------------------------------------------
       
   500 // NotifyRemoved
       
   501 // ------------------------------------------------
       
   502 //
       
   503 void CMdSNotifier::NotifyRemovedL(CMdCSerializationBuffer& aSerializedItemIds, 
       
   504 								  TBool aItemIsConfidential)
       
   505     {
       
   506 	aSerializedItemIds.PositionL( KNoOffset );
       
   507 
       
   508 	const TMdCItemIds& itemIds = TMdCItemIds::GetFromBufferL( aSerializedItemIds );
       
   509 
       
   510     RArray<TItemId> objectIdArray;
       
   511 	CleanupClosePushL( objectIdArray );
       
   512     RArray<TItemId> eventIdArray;
       
   513 	CleanupClosePushL( eventIdArray );
       
   514     RArray<TItemId> relationIdArray;
       
   515 	CleanupClosePushL( relationIdArray );
       
   516 
       
   517     //get removed item IDs
       
   518 	if( itemIds.iObjectIds.iPtr.iCount > 0 )
       
   519 		{
       
   520 		aSerializedItemIds.PositionL( itemIds.iObjectIds.iPtr.iOffset );
       
   521 
       
   522     	objectIdArray.ReserveL( itemIds.iObjectIds.iPtr.iCount );
       
   523     	for( TUint32 i = 0; i < itemIds.iObjectIds.iPtr.iCount; i++ )
       
   524     		{
       
   525     		TItemId objectId;
       
   526     		aSerializedItemIds.ReceiveL( objectId );
       
   527     		if ( objectId != KNoId )
       
   528     			{
       
   529     			objectIdArray.Append( objectId );
       
   530     			}
       
   531     		}
       
   532 		}
       
   533 	if( itemIds.iEventIds.iPtr.iCount > 0 )
       
   534 		{
       
   535 		aSerializedItemIds.PositionL( itemIds.iEventIds.iPtr.iOffset );
       
   536 
       
   537     	eventIdArray.ReserveL( itemIds.iEventIds.iPtr.iCount );
       
   538     	for( TUint32 i = 0; i < itemIds.iEventIds.iPtr.iCount; i++ )
       
   539     		{
       
   540     		TItemId eventId;
       
   541     		aSerializedItemIds.ReceiveL( eventId );
       
   542     		if ( eventId != KNoId )
       
   543     			{
       
   544     			eventIdArray.Append( eventId );
       
   545     			}
       
   546     		}
       
   547 		}
       
   548 	if( itemIds.iRelationIds.iPtr.iCount > 0 )
       
   549 		{
       
   550 		aSerializedItemIds.PositionL( itemIds.iRelationIds.iPtr.iOffset );
       
   551 
       
   552     	relationIdArray.ReserveL( itemIds.iRelationIds.iPtr.iCount );
       
   553     	for( TUint32 i = 0; i < itemIds.iRelationIds.iPtr.iCount; i++ )
       
   554     		{
       
   555     		TItemId relationId;
       
   556     		aSerializedItemIds.ReceiveL( relationId );
       
   557     		if ( relationId != KNoId )
       
   558     			{
       
   559     			relationIdArray.Append( relationId );
       
   560     			}
       
   561     		}
       
   562 		}
       
   563 
       
   564 	if( objectIdArray.Count() != 0 
       
   565 			|| eventIdArray.Count() != 0 
       
   566 			|| relationIdArray.Count() != 0 )
       
   567 		{
       
   568 		const TInt entriesCount = iEntries.Count();
       
   569 	    for( TInt i=0; i < entriesCount; ++i )
       
   570 	        {
       
   571 	        TEntry& e = iEntries[i];
       
   572 	        
       
   573 	        // if namespace definition IDs don't match skip listener entry
       
   574 	        if( e.NamespaceDefId() != itemIds.iNamespaceDefId )
       
   575 	        	{
       
   576 	        	continue;
       
   577 	        	}
       
   578 
       
   579 	        if(aItemIsConfidential && !e.AllowConfidential())
       
   580 	        	{
       
   581 	        	continue;	
       
   582 	        	}
       
   583 
       
   584 	        if( e.iType & EObjectNotifyRemove && objectIdArray.Count() > 0 )
       
   585 	            {
       
   586 	            // collect matching object IDs
       
   587 	            RArray<TItemId> matchingObjectIdArray;
       
   588 				CleanupClosePushL( matchingObjectIdArray );
       
   589 	
       
   590 	            TBool allMatches = iComparator->MatchObjectIdsL( e.Condition(),
       
   591 	            		objectIdArray, matchingObjectIdArray );
       
   592 	
       
   593 				// check is there any matches
       
   594 				if( allMatches || matchingObjectIdArray.Count() > 0 )
       
   595 	            	{
       
   596 	            	if(e.IsPending())
       
   597 	            		{
       
   598 		            	// Match found. Trigger notifier entry.
       
   599 		            	TInt err;
       
   600 		            	
       
   601 		            	if( allMatches )
       
   602 		            		{
       
   603 		            		// all matches so send whole object ID array
       
   604 		            		TRAP( err, e.TriggerL( EObjectNotifyRemove, 
       
   605 		            				objectIdArray ) );
       
   606 		            		}
       
   607 		            	else
       
   608 		            		{
       
   609 		            		TRAP( err, e.TriggerL( EObjectNotifyRemove, 
       
   610 		            				matchingObjectIdArray ) );
       
   611 		            		}
       
   612 	
       
   613 		            	if( err != KErrNone )
       
   614 			            	{
       
   615 			            	e.TriggerError( err );
       
   616 		    	        	}
       
   617 	            		}
       
   618 	            	else
       
   619 	            		{
       
   620 						if( allMatches )
       
   621 		            		{
       
   622 		            		// all matches so send whole object ID array
       
   623 	            			TRAP_IGNORE( e.CacheL( EObjectNotifyRemove, 
       
   624 	            					objectIdArray ) );
       
   625 		            		}
       
   626 		            	else
       
   627 		            		{
       
   628 		            		TRAP_IGNORE( e.CacheL( EObjectNotifyRemove, 
       
   629 		            				matchingObjectIdArray ) );
       
   630 		            		}
       
   631 	            		}
       
   632 	            	}
       
   633 	
       
   634 				CleanupStack::PopAndDestroy( &matchingObjectIdArray );
       
   635 				}
       
   636 	        else if( ( e.iType & EEventNotifyRemove ) 
       
   637 	        		&& eventIdArray.Count() > 0 )
       
   638             	{
       
   639 				// event condition can't contain ID conditions, 
       
   640             	// so get all IDs
       
   641 	        	if(e.IsPending())
       
   642 	        		{
       
   643 	            	// Match found. Trigger notifier entry.
       
   644 	            	TRAPD( err, e.TriggerL( EEventNotifyRemove, 
       
   645 	            			eventIdArray ) );
       
   646 	            	if( err != KErrNone )
       
   647 		            	{
       
   648 		            	e.TriggerError( err );
       
   649 	    	        	}
       
   650 	        		}
       
   651 	        	else
       
   652 	        		{
       
   653 	        		TRAP_IGNORE( e.CacheL( EEventNotifyRemove, 
       
   654 	        				eventIdArray ) );
       
   655 	        		}
       
   656             	}
       
   657 	        else if( ( e.iType & ERelationNotifyRemove ) 
       
   658 	        		&& relationIdArray.Count() > 0 )
       
   659             	{
       
   660 	            // relation condition can't contain ID conditions, 
       
   661             	// so get all IDs
       
   662 	        	if(e.IsPending())
       
   663 	        		{
       
   664 	            	// Match found. Trigger notifier entry.
       
   665 	            	TRAPD( err, e.TriggerL( ERelationNotifyRemove, 
       
   666 	            			relationIdArray ) );
       
   667 	            	if( err != KErrNone )
       
   668 		            	{
       
   669 		            	e.TriggerError( err );
       
   670 	    	        	}
       
   671 	        		}
       
   672 	        	else
       
   673 	        		{
       
   674 	        		TRAP_IGNORE( e.CacheL( ERelationNotifyRemove, 
       
   675 	        				relationIdArray ) );
       
   676 	        		}
       
   677             	}
       
   678 	        }
       
   679 		}
       
   680 
       
   681 	CleanupStack::PopAndDestroy( 3, &objectIdArray ); // relationIdArray, eventIdArray, objectIdArray
       
   682     }
       
   683 
       
   684 // ------------------------------------------------
       
   685 // NotifyModified
       
   686 // ------------------------------------------------
       
   687 //
       
   688 void CMdSNotifier::NotifyModifiedL(CMdCSerializationBuffer& aSerializedItems, 
       
   689 							       CMdCSerializationBuffer& aSerializedItemIds)
       
   690     {
       
   691     const TInt count = iEntries.Count();
       
   692     
       
   693     for( TInt i = 0; i < count; ++i )
       
   694         {
       
   695         TEntry& e = iEntries[i];
       
   696 
       
   697         if ( ! (e.iType & ( EObjectNotifyModify | ERelationNotifyModify /*| ERelationItemNotifyModify*/ ) ) )
       
   698         	{
       
   699         	continue;
       
   700         	}
       
   701   
       
   702         RArray<TItemId> matchingObjectIdArray;
       
   703 		CleanupClosePushL( matchingObjectIdArray );
       
   704 
       
   705 		aSerializedItems.PositionL( KNoOffset );
       
   706 		aSerializedItemIds.PositionL( KNoOffset );
       
   707 
       
   708 		TBool someMatches = iComparator->MatchL( e.NamespaceDefId(), 
       
   709 				e.iType, e.Condition(), aSerializedItems, aSerializedItemIds, 
       
   710 				matchingObjectIdArray, e.AllowConfidential() );
       
   711 
       
   712         if( someMatches ) // check if there is some matches
       
   713             {
       
   714             if( e.IsPending() )
       
   715             	{
       
   716             	// match found. trigger notifier entry !
       
   717 	            TRAPD( err, e.TriggerL( EObjectNotifyModify | ERelationNotifyModify /*| ERelationItemNotifyModify*/,
       
   718 	            		matchingObjectIdArray ) );
       
   719 	            if( err != KErrNone )
       
   720 	            	{
       
   721 	            	e.TriggerError( err );
       
   722 	            	}
       
   723             	}
       
   724             else
       
   725             	{
       
   726             	TRAP_IGNORE( e.CacheL( EObjectNotifyModify | ERelationNotifyModify /*| ERelationItemNotifyModify*/,
       
   727             			matchingObjectIdArray ) );
       
   728             	}
       
   729             }
       
   730 
       
   731 		CleanupStack::PopAndDestroy( &matchingObjectIdArray );
       
   732         }
       
   733     }
       
   734 
       
   735 // ------------------------------------------------
       
   736 // NotifyModified
       
   737 // ------------------------------------------------
       
   738 //
       
   739 void CMdSNotifier::NotifyModifiedL(const RArray<TItemId>& aObjectIds)
       
   740 	{
       
   741 	if (aObjectIds.Count() == 0)
       
   742     	{
       
   743     	return;
       
   744     	}
       
   745 
       
   746     const TInt count = iEntries.Count();
       
   747 
       
   748     for( TInt i = 0; i < count; ++i )
       
   749         {
       
   750         TEntry& e = iEntries[i];
       
   751 
       
   752         if( e.iType & EObjectNotifyModify )
       
   753             {
       
   754             // collect matching object IDs
       
   755             RArray<TItemId> matchingObjectIdArray;
       
   756 			CleanupClosePushL( matchingObjectIdArray );
       
   757 
       
   758             TBool allMatches = iComparator->MatchObjectIdsL( e.Condition(), 
       
   759             		aObjectIds, matchingObjectIdArray );
       
   760 
       
   761 			// check is there any matches
       
   762 			if( allMatches || matchingObjectIdArray.Count() > 0 )
       
   763             	{
       
   764             	if(e.IsPending())
       
   765             		{
       
   766 	            	// Match found. Trigger notifier entry.
       
   767 	            	TInt err;
       
   768 
       
   769 	            	if( allMatches )
       
   770 	            		{
       
   771 	            		// all matches so send whole object ID array
       
   772 	            		TRAP( err, e.TriggerL( EObjectNotifyModify, 
       
   773 	            				aObjectIds ) );
       
   774 	            		}
       
   775 	            	else
       
   776 	            		{
       
   777 	            		TRAP( err, e.TriggerL( EObjectNotifyModify, 
       
   778 	            				matchingObjectIdArray ) );
       
   779 	            		}
       
   780 
       
   781 	            	if( err != KErrNone )
       
   782 		            	{
       
   783 		            	e.TriggerError( err );
       
   784 	    	        	}
       
   785             		}
       
   786             	else
       
   787             		{
       
   788 					if( allMatches )
       
   789 	            		{
       
   790 	            		// all matches so send whole object ID array
       
   791             			TRAP_IGNORE( e.CacheL( EObjectNotifyModify, 
       
   792             					aObjectIds ) );
       
   793 	            		}
       
   794 	            	else
       
   795 	            		{
       
   796 	            		TRAP_IGNORE( e.CacheL( EObjectNotifyModify, 
       
   797 	            				matchingObjectIdArray ) );
       
   798 	            		}
       
   799             		}
       
   800             	}
       
   801 
       
   802 			CleanupStack::PopAndDestroy( &matchingObjectIdArray );
       
   803             }
       
   804         }
       
   805 	}
       
   806 
       
   807 // ------------------------------------------------
       
   808 // NotifyRemoved
       
   809 // ------------------------------------------------
       
   810 //
       
   811 void CMdSNotifier::NotifyRemovedL(const RArray<TItemId>& aItemIdArray)
       
   812 	{
       
   813     for( TInt i=0; i<iEntries.Count(); ++i )
       
   814         {
       
   815         TEntry& e = iEntries[i];
       
   816 
       
   817         if( e.iType & EObjectNotifyRemove )
       
   818         	{
       
   819             if( e.IsPending() )
       
   820             	{
       
   821 	            TRAPD( err, e.TriggerL( EObjectNotifyRemove, aItemIdArray ) );
       
   822 	            if( err != KErrNone )
       
   823 	            	{
       
   824 	            	e.TriggerError( err );
       
   825 	            	}
       
   826             	}
       
   827             else
       
   828             	{
       
   829             	TRAP_IGNORE( e.CacheL( EObjectNotifyRemove, aItemIdArray ) );
       
   830             	}
       
   831         	}
       
   832         }
       
   833 	}
       
   834 
       
   835 // ------------------------------------------------
       
   836 // NotifyObjectPresent
       
   837 // ------------------------------------------------
       
   838 //
       
   839 void CMdSNotifier::NotifyObjectPresent(TBool aPresent, const RArray<TItemId>& aObjectIds)
       
   840     {
       
   841     if (aObjectIds.Count() == 0)
       
   842     	{
       
   843     	return;
       
   844     	}
       
   845 
       
   846     const TInt count = iEntries.Count();
       
   847     
       
   848     for( TInt i = 0; i < count; ++i )
       
   849         {
       
   850         TEntry& e = iEntries[i];
       
   851 
       
   852         // No condition matching, object present changes
       
   853         // are always notified to object present observers
       
   854         if( e.iType & ( EObjectNotifyPresent | EObjectNotifyNotPresent )  )
       
   855             {
       
   856             const TMdSObserverNotificationType objectState = 
       
   857             	aPresent ? EObjectNotifyPresent : EObjectNotifyNotPresent;
       
   858 
       
   859             if( e.IsPending() )
       
   860             	{
       
   861             	// match found. trigger notifier entry !
       
   862 	            TRAPD( err, e.TriggerL( objectState, aObjectIds ) );
       
   863 	            if( err != KErrNone )
       
   864 	            	{
       
   865 	            	e.TriggerError( err );
       
   866 	            	}
       
   867             	}
       
   868             else
       
   869             	{
       
   870             	TRAP_IGNORE( e.CacheL( objectState, aObjectIds ) );
       
   871             	}
       
   872             }
       
   873         }
       
   874     }
       
   875 
       
   876 // ------------------------------------------------
       
   877 // NotifyRelationPresent
       
   878 // ------------------------------------------------
       
   879 //
       
   880 void CMdSNotifier::NotifyRelationPresent(TBool aPresent, const RArray<TItemId>& aRelationIds)
       
   881     {
       
   882     if (aRelationIds.Count() == 0)
       
   883     	{
       
   884     	return;
       
   885     	}
       
   886 
       
   887     const TInt count = iEntries.Count();
       
   888     
       
   889     for( TInt i = 0; i < count; ++i )
       
   890         {
       
   891         TEntry& e = iEntries[i];
       
   892 
       
   893         // No condition matching, relation present changes
       
   894         // are always notified to relation present observers
       
   895         if( e.iType & ( ERelationNotifyPresent | ERelationNotifyNotPresent ) )
       
   896             {
       
   897             const TMdSObserverNotificationType relationState = 
       
   898             	aPresent ? ERelationNotifyPresent : ERelationNotifyNotPresent;
       
   899 
       
   900             if( e.IsPending() )
       
   901             	{
       
   902             	// match found. trigger notifier entry !
       
   903 	            TRAPD( err, e.TriggerL( relationState, aRelationIds ) );
       
   904 	            if( err != KErrNone )
       
   905 	            	{
       
   906 	            	e.TriggerError( err );
       
   907 	            	}
       
   908             	}
       
   909             else
       
   910             	{
       
   911             	TRAP_IGNORE( e.CacheL( relationState, aRelationIds ) );
       
   912             	}
       
   913             }
       
   914         }
       
   915     }
       
   916 
       
   917 
       
   918 // ------------------------------------------------
       
   919 // NotifySchemaAdded
       
   920 // ------------------------------------------------
       
   921 //
       
   922 void CMdSNotifier::NotifySchemaAddedL()
       
   923     {
       
   924     const TInt count = iEntries.Count();
       
   925     
       
   926     for( TInt i = 0; i < count; ++i )
       
   927         {
       
   928         TEntry& e = iEntries[i];
       
   929 
       
   930         // No condition matching, schema additions 
       
   931         // are always notified to schema observers
       
   932         if( e.iType == ESchemaModify )
       
   933             {
       
   934             if( e.IsPending() )
       
   935             	{
       
   936 	            // match found. trigger notifier entry
       
   937 	            e.TriggerSchema();
       
   938             	}
       
   939             else
       
   940             	{
       
   941             	TRAP_IGNORE( e.CacheL( ESchemaModify ) );
       
   942             	}
       
   943             }
       
   944         }
       
   945     }
       
   946 
       
   947 
       
   948 // ------------------------------------------------
       
   949 // CheckForNotifier
       
   950 // ------------------------------------------------
       
   951 //
       
   952 TBool CMdSNotifier::CheckForNotifier( TUint32 aNotifyTypes )
       
   953     {
       
   954     const TInt count = iEntries.Count();
       
   955     
       
   956     for( TInt i = 0; i < count; ++i )
       
   957         {
       
   958         if ( iEntries[i].iType & aNotifyTypes )
       
   959         	{
       
   960         	return ETrue;
       
   961         	}
       
   962         }
       
   963     return EFalse;
       
   964     }
       
   965 
       
   966 void CMdSNotifier::NotifyRemovedRelationItemsL( 
       
   967 		CMdCSerializationBuffer& aBuffer )
       
   968 	{
       
   969 	aBuffer.PositionL( KNoOffset );
       
   970 
       
   971 	const TMdCItems& items = TMdCItems::GetFromBufferL( aBuffer );
       
   972 
       
   973 	if( items.iRelations.iPtr.iCount )
       
   974 		{
       
   975 		const TInt entriesCount = iEntries.Count();
       
   976 	    for( TInt i = 0; i < entriesCount; ++i )
       
   977 	        {
       
   978 	        TEntry& e = iEntries[i];
       
   979 	        
       
   980 	        // if namespace definition IDs don't match skip listener entry
       
   981 	        if( e.NamespaceDefId() != items.iNamespaceDefId )
       
   982 	        	{
       
   983 	        	continue;
       
   984 	        	}
       
   985 	        
       
   986 	        if( e.iType & ERelationItemNotifyRemove )
       
   987             	{
       
   988             	aBuffer.PositionL( items.iRelations.iPtr.iOffset );
       
   989 	            // check relations condition
       
   990             	RArray<TItemId> matchedRelations;
       
   991             	CleanupClosePushL( matchedRelations );
       
   992             	TBool matches = iComparator->MatchRelationItemsL( 
       
   993             			e.Condition(), aBuffer, matchedRelations );
       
   994 
       
   995             	if ( matches )
       
   996 	        		{
       
   997 	        		if(e.IsPending())
       
   998 	        			{
       
   999 		            	// Match found. Trigger notifier entry.
       
  1000 		            	TRAPD( err, e.TriggerRelationItemsL( 
       
  1001 		            			ERelationItemNotifyRemove, aBuffer, 
       
  1002 		            			matchedRelations ) );
       
  1003 		            	if( err != KErrNone )
       
  1004 			            	{
       
  1005 			            	e.TriggerError( err );
       
  1006 		    	        	}
       
  1007 		        		}
       
  1008 		        	else
       
  1009 		        		{
       
  1010 		        		TRAP_IGNORE( e.CacheRelationItemsL( 
       
  1011 		        				ERelationItemNotifyRemove, aBuffer, 
       
  1012 		        				matchedRelations ) );
       
  1013 		        		}
       
  1014 	        		}
       
  1015             	CleanupStack::PopAndDestroy( &matchedRelations );
       
  1016             	}
       
  1017 	        }
       
  1018 		}
       
  1019 
       
  1020 	}
       
  1021