PECengine/JanitorPlugin2/Src/CPEngContactMapper.cpp
changeset 0 094583676ce7
equal deleted inserted replaced
-1:000000000000 0:094583676ce7
       
     1 /*
       
     2 * Copyright (c) 2005 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:  Container of one contact list item. It includes, wv ID, nick name,
       
    15 *				 List of contact IDs, flag if there is need to notify about change of the
       
    16 *				 Presence change of the wv ID, and flag if wv ID: was checked by Janitor
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 // INCLUDE FILES
       
    23 #include	"CPEngContactMapper.h"
       
    24 
       
    25 #include    <e32std.h>
       
    26 #include	<bamdesca.h>
       
    27 #include	<cntitem.h>
       
    28 
       
    29 #include	"CPEngListObserver.h"
       
    30 #include	"CPEngContact.h"
       
    31 
       
    32 #include	"CPEngNWSessionSlotNotifier2.h"
       
    33 #include	"CPEngNWSessionSlotEvent2.h"
       
    34 #include	"CPEngNWSessionSlotID2.h"
       
    35 
       
    36 // Debug prints
       
    37 #include    "PresenceDebugPrint.h"
       
    38 
       
    39 
       
    40 // CONSTANTS
       
    41 #define ORDER TLinearOrder<CPEngContact> (CPEngContact::Compare)
       
    42 
       
    43 // ============================ MEMBER FUNCTIONS ===============================
       
    44 
       
    45 // -----------------------------------------------------------------------------
       
    46 // CPEngContactMapper::CPEngContactMapper
       
    47 // C++ default constructor can NOT contain any code, that
       
    48 // might leave.
       
    49 // -----------------------------------------------------------------------------
       
    50 //
       
    51 CPEngContactMapper::CPEngContactMapper()
       
    52     {
       
    53     PENG_DP( D_PENG_LIT( "PEngJanitorPlugIn: CPEngContactMapper::CPEngContactMapper" ) );
       
    54     }
       
    55 
       
    56 // -----------------------------------------------------------------------------
       
    57 // CPEngContactMapper::ConstructL
       
    58 // Symbian 2nd phase constructor can leave.
       
    59 // -----------------------------------------------------------------------------
       
    60 //
       
    61 void CPEngContactMapper::ConstructL()
       
    62     {
       
    63     // create contact cache and register observer
       
    64     iCntDatabase = CContactDatabase::OpenL();
       
    65     iCntNotifier = CContactChangeNotifier::NewL( *iCntDatabase, this );
       
    66     RebuildContactDbCacheL();
       
    67 
       
    68     iSessionNotifier = CPEngNWSessionSlotNotifier2::NewL();
       
    69     User::LeaveIfError( iSessionNotifier->AddObserver( *this ) );
       
    70     User::LeaveIfError( iSessionNotifier->Start() );
       
    71     }
       
    72 
       
    73 // -----------------------------------------------------------------------------
       
    74 // CPEngContactMapper::NewL
       
    75 // Two-phased constructor.
       
    76 // -----------------------------------------------------------------------------
       
    77 //
       
    78 CPEngContactMapper* CPEngContactMapper::NewL()
       
    79     {
       
    80     CPEngContactMapper* self = NewLC( );
       
    81 
       
    82     CleanupStack::Pop(); // self
       
    83 
       
    84     return self;
       
    85     }
       
    86 
       
    87 // -----------------------------------------------------------------------------
       
    88 // CPEngContactMapper::NewLC
       
    89 // Two-phased constructor.
       
    90 // -----------------------------------------------------------------------------
       
    91 //
       
    92 CPEngContactMapper* CPEngContactMapper::NewLC()
       
    93     {
       
    94     CPEngContactMapper* self = new( ELeave ) CPEngContactMapper();
       
    95 
       
    96     CleanupStack::PushL( self );
       
    97     self->ConstructL( );
       
    98 
       
    99     return self;
       
   100     }
       
   101 
       
   102 // Destructor
       
   103 CPEngContactMapper::~CPEngContactMapper()
       
   104     {
       
   105     iContacts.ResetAndDestroy();
       
   106     iListObservers.ResetAndDestroy();
       
   107     delete iSessionNotifier;
       
   108     delete iCntNotifier;
       
   109     delete iCntDatabase;
       
   110     }
       
   111 
       
   112 // =============================================================================
       
   113 // ===============Function for MPEngContactMapper class ========================
       
   114 // =============================================================================
       
   115 
       
   116 // -----------------------------------------------------------------------------
       
   117 // CPEngContactMapper::MappWvIdL
       
   118 // Map wv id to the contact db id
       
   119 // (other items were commented in a header).
       
   120 // -----------------------------------------------------------------------------
       
   121 //
       
   122 CContactIdArray* CPEngContactMapper::MapWvIdToContactIdLC(
       
   123     const TDesC& aWVId )
       
   124     {
       
   125     CContactIdArray* contactIds = NULL;
       
   126     TInt count ( iContacts.Count() );
       
   127     for ( TInt x( 0 ) ; x < count ; ++x )
       
   128         {
       
   129         if ( iContacts[ x ]->ValidateWVId( aWVId ) )
       
   130             {
       
   131             if ( !contactIds )
       
   132                 {
       
   133                 contactIds = CContactIdArray::NewLC();
       
   134                 }
       
   135             contactIds->AddL( iContacts[ x ]->ContactId() );
       
   136             }
       
   137         }
       
   138     // even no contact id was created, push NULL to maintain LC continuity
       
   139     if ( !contactIds )
       
   140         {
       
   141         CleanupStack::PushL( contactIds );
       
   142         }
       
   143     return contactIds;
       
   144     }
       
   145 
       
   146 // =============================================================================
       
   147 // ===============Function for MContactDBObserver class ========================
       
   148 // =============================================================================
       
   149 
       
   150 // -----------------------------------------------------------------------------
       
   151 // CPEngContactMapper::HandleDatabaseEventL
       
   152 // Handle Contact Database event
       
   153 // (other items were commented in a header).
       
   154 // -----------------------------------------------------------------------------
       
   155 //
       
   156 void CPEngContactMapper::HandleDatabaseEventL(
       
   157     TContactDbObserverEvent aEvent )
       
   158     {
       
   159     switch ( aEvent.iType )
       
   160         {
       
   161         case EContactDbObserverEventContactDeleted:
       
   162             {
       
   163             RemoveContactL( aEvent.iContactId );
       
   164             break;
       
   165             }
       
   166         case EContactDbObserverEventContactAdded:
       
   167             {
       
   168             AddContactL( aEvent.iContactId );
       
   169             break;
       
   170             }
       
   171         case EContactDbObserverEventContactChanged:
       
   172             {
       
   173             UpdateContactL( aEvent.iContactId );
       
   174             break;
       
   175             }
       
   176         case EContactDbObserverEventUnknownChanges:
       
   177             {
       
   178             // reload whole contact cache, since more changes has happened
       
   179             HandleMultipleChangesL();
       
   180             }
       
   181         default:
       
   182             {
       
   183             break;
       
   184             }
       
   185         }
       
   186     }
       
   187 
       
   188 
       
   189 // =============================================================================
       
   190 // ===============Function for MPEngNWSessionSlotObserver2 class ===============
       
   191 // =============================================================================
       
   192 
       
   193 // -----------------------------------------------------------------------------
       
   194 // CPEngContactMapper::HandleNWSessionSlotChangeL
       
   195 // NWSessionSlot change handler.
       
   196 // (other items were commented in a header).
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 void CPEngContactMapper::HandleNWSessionSlotChangeL(
       
   200     CPEngNWSessionSlotNotifier2& /*aNotifier*/,
       
   201     CPEngNWSessionSlotEvent2& aEvent )
       
   202     {
       
   203     TInt index( FindListObserver( aEvent.NWSessionSlotID() ) );
       
   204     if ( EPEngNWPresenceSessionOpen == aEvent.NWSessionSlotState() )
       
   205         {
       
   206         // make sure we are observing such a session
       
   207         if ( index != KErrNotFound )
       
   208             {
       
   209             return;
       
   210             }
       
   211         CPEngListObserver* observer = CPEngListObserver::NewLC(
       
   212                                           *this,
       
   213                                           aEvent.NWSessionSlotID() );
       
   214         iListObservers.AppendL( observer );
       
   215         CleanupStack::Pop( observer ); // observer
       
   216         }
       
   217     else
       
   218         {
       
   219         // stop observing of such a session
       
   220         if ( index != KErrNotFound )
       
   221             {
       
   222             delete iListObservers[ index ];
       
   223             iListObservers.Remove( index );
       
   224             }
       
   225         }
       
   226     }
       
   227 
       
   228 // -----------------------------------------------------------------------------
       
   229 // CPEngContactMapper::HandleNWSessionSlotError
       
   230 // Notification failure handler.
       
   231 // (other items were commented in a header).
       
   232 // -----------------------------------------------------------------------------
       
   233 //
       
   234 void CPEngContactMapper::HandleNWSessionSlotError(
       
   235     TInt /*aError*/,
       
   236     CPEngNWSessionSlotNotifier2& /*aNotifier */ )
       
   237     {
       
   238     // no error handling here
       
   239     }
       
   240 
       
   241 // =============================================================================
       
   242 // =============== New Function of base class =================================
       
   243 // =============================================================================
       
   244 
       
   245 // -----------------------------------------------------------------------------
       
   246 // CPEngContactMapper::AddContactL
       
   247 // Inserts new contact to the contact db cache
       
   248 // (other items were commented in a header).
       
   249 // -----------------------------------------------------------------------------
       
   250 //
       
   251 void CPEngContactMapper::AddContactL(
       
   252     TContactItemId& aContactId )
       
   253     {
       
   254     CContactItem* cntItem = iCntDatabase->ReadMinimalContactLC( aContactId );
       
   255     CPEngContact* contactEntry = CPEngContact::NewL( cntItem ); // careful no in CleanUpStack
       
   256     CleanupStack::PopAndDestroy( cntItem ); // cntItem
       
   257     const MDesCArray& wvIds = contactEntry->WvIds();
       
   258     if ( ! wvIds.MdcaCount() )
       
   259         {
       
   260         delete contactEntry;
       
   261         return;
       
   262         }
       
   263     CleanupStack::PushL( contactEntry );
       
   264     iContacts.AppendL( contactEntry );
       
   265     CleanupStack::Pop( contactEntry );
       
   266     // update mapping, for each wv id
       
   267     RemapWvIdsL( wvIds );
       
   268     }
       
   269 
       
   270 // -----------------------------------------------------------------------------
       
   271 // CPEngContactMapper::RemoveContactL
       
   272 // Remove contact from contact db cache
       
   273 // (other items were commented in a header).
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 void CPEngContactMapper::RemoveContactL(
       
   277     TContactItemId& aContactId )
       
   278     {
       
   279     TInt index( FindContact( aContactId ) );
       
   280     // if contact is in our cache, we can leave, nothing to do
       
   281     if ( index == KErrNotFound )
       
   282         {
       
   283         return;
       
   284         }
       
   285     CPEngContact* contact = iContacts[ index ];
       
   286     CleanupStack::PushL( contact );
       
   287     iContacts.Remove( index );
       
   288     RemapWvIdsL( contact->WvIds() );
       
   289     CleanupStack::PopAndDestroy( contact );
       
   290     }
       
   291 
       
   292 // -----------------------------------------------------------------------------
       
   293 // CPEngContactMapper::UpdateContactL
       
   294 // Update content of the contact in  contact db cache
       
   295 // (other items were commented in a header).
       
   296 // -----------------------------------------------------------------------------
       
   297 //
       
   298 void CPEngContactMapper::UpdateContactL(
       
   299     TContactItemId& aContactId )
       
   300     {
       
   301     TInt index( FindContact( aContactId ) );
       
   302     CPEngContact* contactEntry = NULL;
       
   303     if ( index == KErrNotFound )
       
   304         {
       
   305         // contact is not in the cache, try to add it
       
   306         CContactItem* cntItem = iCntDatabase->ReadMinimalContactLC( aContactId );
       
   307         contactEntry = CPEngContact::NewL( cntItem ); // careful no in CleanUpStack
       
   308         CleanupStack::PopAndDestroy( cntItem ); // cntItem
       
   309         const MDesCArray& wvIds = contactEntry->WvIds();
       
   310         TInt wvIdCount( wvIds.MdcaCount() );
       
   311         if ( !wvIdCount )
       
   312             {
       
   313             delete contactEntry;
       
   314             return;
       
   315             }
       
   316         CleanupStack::PushL( contactEntry );
       
   317         iContacts.AppendL( contactEntry );
       
   318         CleanupStack::Pop( contactEntry );
       
   319         RemapWvIdsL( contactEntry->WvIds() );
       
   320         }
       
   321     else
       
   322         {
       
   323         // contact is in cache, update it, first store old wv ids
       
   324         contactEntry = iContacts[ index ];
       
   325         const MDesCArray& oldIds = contactEntry->WvIds();
       
   326         TInt count ( oldIds.MdcaCount() );
       
   327         CDesCArray* oldWVIds = new( ELeave ) CDesCArrayFlat( count );
       
   328         CleanupStack::PushL( oldWVIds );
       
   329         for ( TInt x( 0 ) ; x < count ; ++x )
       
   330             {
       
   331             oldWVIds->AppendL( oldIds.MdcaPoint( x ) );
       
   332             }
       
   333         contactEntry->UpdateContactL( *iCntDatabase );
       
   334 
       
   335         // does contact entry need have any wv ids or it can be removed
       
   336         const MDesCArray& newIds = contactEntry->WvIds();
       
   337         TInt newCount( newIds.MdcaCount() );
       
   338         if ( ! newCount )
       
   339             {
       
   340             iContacts.Remove( index );
       
   341             delete contactEntry;
       
   342             }
       
   343         else
       
   344             {
       
   345             // remove new wv ids from old ones if the are same
       
   346             // so we avoid double remapping
       
   347             for ( TInt x( 0 ) ;  x < newCount ; ++x )
       
   348                 {
       
   349                 TInt pos( 0 );
       
   350                 if ( KErrNone == oldWVIds->Find( newIds.MdcaPoint( x ), pos ) )
       
   351                     {
       
   352                     oldWVIds->Delete( pos );
       
   353                     }
       
   354                 }
       
   355             RemapWvIdsL( newIds );
       
   356             }
       
   357         RemapWvIdsL( *oldWVIds );
       
   358         CleanupStack::PopAndDestroy( oldWVIds ); //
       
   359         }
       
   360     }
       
   361 
       
   362 // -----------------------------------------------------------------------------
       
   363 // CPEngContactMapper::HandleMultipleChangesL
       
   364 // More changes happened in the contact db
       
   365 // (other items were commented in a header).
       
   366 // -----------------------------------------------------------------------------
       
   367 //
       
   368 void CPEngContactMapper::HandleMultipleChangesL()
       
   369     {
       
   370     // rebuild whole contact db and call on all contact list full re-mapping
       
   371     RebuildContactDbCacheL();
       
   372     TInt count( iListObservers.Count() );
       
   373     for ( TInt x( 0 ) ; x < count ; ++x )
       
   374         {
       
   375         iListObservers[ x ]->ReMappAllContactsL();
       
   376         }
       
   377     }
       
   378 
       
   379 // -----------------------------------------------------------------------------
       
   380 // CPEngContactMapper::UpdateMappingOnContactListsL
       
   381 // Notify all list observers about wv Ids mapping change
       
   382 // (other items were commented in a header).
       
   383 // -----------------------------------------------------------------------------
       
   384 //
       
   385 void CPEngContactMapper::UpdateMappingOnContactListsL(
       
   386     const TDesC& aWVId,
       
   387     const CContactIdArray* aContactIds )
       
   388     {
       
   389     TInt count( iListObservers.Count() );
       
   390     for ( TInt x( 0 ) ; x < count ; ++x )
       
   391         {
       
   392         iListObservers[ x ]->UpdateMappingL( aWVId, aContactIds );
       
   393         }
       
   394     }
       
   395 
       
   396 // -----------------------------------------------------------------------------
       
   397 // CPEngContactMapper::RebuildContactDbCacheL()
       
   398 // Rebuild contact db cache
       
   399 // (other items were commented in a header).
       
   400 // -----------------------------------------------------------------------------
       
   401 //
       
   402 void CPEngContactMapper::RebuildContactDbCacheL()
       
   403     {
       
   404     // check all contacts
       
   405     _LIT( KWVStart, "" );
       
   406     // Specify in which fields search should be performed
       
   407     CContactItemFieldDef* fieldToSearchIn = new ( ELeave ) CContactItemFieldDef();
       
   408     CleanupStack::PushL( fieldToSearchIn );
       
   409     fieldToSearchIn->AppendL( KPbkFieldWVIdMapping );
       
   410     fieldToSearchIn->AppendL( KPbkFieldIMAddress );
       
   411     // search in contact database
       
   412     CContactIdArray* contactIds = iCntDatabase->FindLC( KWVStart,
       
   413                                                         fieldToSearchIn );
       
   414 
       
   415     // OK now we have Contact Ids, time to add contacts to cache
       
   416     // reset our array
       
   417     iContacts.ResetAndDestroy();
       
   418     CPEngContact* contact = NULL;
       
   419     CContactItem* contactItem = NULL;
       
   420     TInt count ( contactIds->Count() );
       
   421     for ( TInt x( 0 ) ; x < count ; x++ )
       
   422         {
       
   423         contactItem = iCntDatabase->ReadMinimalContactLC( ( *contactIds )[ x ] );
       
   424         contact = CPEngContact::NewLC( contactItem );
       
   425         // store back up of the contact only if there was some id
       
   426         if ( contact->WvIds().MdcaCount() )
       
   427             {
       
   428             iContacts.AppendL( contact );
       
   429             CleanupStack::Pop( contact ); // contact
       
   430             }
       
   431         else
       
   432             {
       
   433             CleanupStack::PopAndDestroy( contact ); // contact
       
   434             }
       
   435         CleanupStack::PopAndDestroy( contactItem ); // contactItem
       
   436         }
       
   437     CleanupStack::PopAndDestroy( 2 ); // contactIDArray, fieldToSearchIn
       
   438     }
       
   439 
       
   440 
       
   441 // -----------------------------------------------------------------------------
       
   442 // CPEngContactMapper::FindContact
       
   443 // Find Contact in contact cache
       
   444 // (other items were commented in a header).
       
   445 // -----------------------------------------------------------------------------
       
   446 //
       
   447 TInt CPEngContactMapper::FindContact(
       
   448     TContactItemId& aContactId ) const
       
   449     {
       
   450     TInt count ( iContacts.Count() );
       
   451     for ( TInt x( 0 ) ; x < count ; ++x )
       
   452         {
       
   453         if (  iContacts[ x ]->ContactId() == aContactId )
       
   454             {
       
   455             return x;
       
   456             }
       
   457         }
       
   458     return KErrNotFound;
       
   459     }
       
   460 
       
   461 // -----------------------------------------------------------------------------
       
   462 // CPEngContactMapper::RemapWvIdsL
       
   463 // Remap given wv Ids
       
   464 // (other items were commented in a header).
       
   465 // -----------------------------------------------------------------------------
       
   466 //
       
   467 void CPEngContactMapper::RemapWvIdsL( const MDesCArray& aWVIds )
       
   468     {
       
   469     TInt count( aWVIds.MdcaCount() );
       
   470     for ( TInt x( 0 ) ;  x < count ; ++x )
       
   471         {
       
   472         CContactIdArray* contactIds =
       
   473             MapWvIdToContactIdLC( aWVIds.MdcaPoint( x ) );
       
   474         UpdateMappingOnContactListsL( aWVIds.MdcaPoint( x ), contactIds );
       
   475         CleanupStack::PopAndDestroy( contactIds ); // contactIds
       
   476         }
       
   477     }
       
   478 
       
   479 
       
   480 // -----------------------------------------------------------------------------
       
   481 // CPEngContactMapper::FindListObserver
       
   482 // Find Contact list observer
       
   483 // (other items were commented in a header).
       
   484 // -----------------------------------------------------------------------------
       
   485 //
       
   486 TInt CPEngContactMapper::FindListObserver(
       
   487     const CPEngNWSessionSlotID2& aSessionId ) const
       
   488     {
       
   489     TInt count( iListObservers.Count() );
       
   490     for ( TInt x( 0 ) ; x < count ; ++x )
       
   491         {
       
   492         if ( KErrNone
       
   493              ==
       
   494              iListObservers[ x ]->SessionId().MatchBasePart( aSessionId )
       
   495            )
       
   496             {
       
   497             return x;
       
   498             }
       
   499         }
       
   500     return KErrNotFound;
       
   501     }
       
   502 
       
   503 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   504 
       
   505 
       
   506 //  End of File