phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkPhoneNumberMatchStrategy.cpp
changeset 0 e686773b3f54
child 12 4ae315f230bc
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2005-2007 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:  A high level class for matching phone numbers from stores.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 #include <CVPbkPhoneNumberMatchStrategy.h>
       
    21 
       
    22 #include <CVPbkContactManager.h>
       
    23 #include <CVPbkContactLinkArray.h>
       
    24 #include <MVPbkContactOperation.h>
       
    25 #include <MVPbkContactStoreList.h>
       
    26 #include <MVPbkContactStore.h>
       
    27 #include <MVPbkContactStoreProperties.h>
       
    28 #include <MVPbkContactLink.h>
       
    29 #include <MVPbkStoreContact.h>
       
    30 #include <MVPbkSingleContactOperationObserver.h>
       
    31 #include <RLocalizedResourceFile.h>
       
    32 #include <VPbkDataCaging.hrh>
       
    33 #include <VPbkEng.rsg>
       
    34 #include <VPbkFieldTypeSelectors.rsg>
       
    35 #include <CVPbkFieldTypeSelector.h>
       
    36 #include <CVPbkFieldFilter.h>
       
    37 #include <barsread.h>
       
    38 #include <MVPbkContactFieldTextData.h>
       
    39 #include <CVPbkContactStoreUriArray.h>
       
    40 
       
    41 #include "CVPbkPhoneNumberSequentialMatchStrategy.h"
       
    42 #include "CVPbkPhoneNumberParallelMatchStrategy.h"
       
    43 
       
    44 // CONSTANTS
       
    45 const TInt KMagicNumber = -1;
       
    46 
       
    47 NONSHARABLE_CLASS(CVPbkPhoneNumberMatchStrategyImpl) :
       
    48         public CActive,
       
    49         public MVPbkContactFindObserver,
       
    50         public MVPbkSingleContactOperationObserver
       
    51     {
       
    52     public: // Construction
       
    53         static CVPbkPhoneNumberMatchStrategyImpl* NewL(
       
    54                 CVPbkPhoneNumberMatchStrategy& aParent,
       
    55                 const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig,
       
    56                 CVPbkContactManager& aContactManager,
       
    57                 MVPbkContactFindObserver& aObserver);
       
    58         ~CVPbkPhoneNumberMatchStrategyImpl();
       
    59 
       
    60     public: // Interface
       
    61         void MatchL(const TDesC& aPhoneNumber);
       
    62         TInt MaxMatchDigits() const;
       
    63         TArray<MVPbkContactStore*> StoresToMatch() const;
       
    64 
       
    65     private: // From CActive
       
    66         void RunL();
       
    67         void DoCancel();
       
    68         TInt RunError(TInt aError);
       
    69 
       
    70     private: // From MVPbkContactFindObserver
       
    71         void FindCompleteL(MVPbkContactLinkArray* aResults);
       
    72         void FindFailed(TInt aError);
       
    73 
       
    74     private: // From MVPbkSingleContactOperationObserver
       
    75         void VPbkSingleContactOperationComplete(
       
    76                 MVPbkContactOperationBase& aOperation,
       
    77                 MVPbkStoreContact* aContact);
       
    78         void VPbkSingleContactOperationFailed(
       
    79                 MVPbkContactOperationBase& aOperation,
       
    80                 TInt aError);
       
    81 
       
    82     private: // Implementation
       
    83         CVPbkPhoneNumberMatchStrategyImpl(CVPbkPhoneNumberMatchStrategy& aParent);
       
    84         void ConstructL(
       
    85                 const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig,
       
    86                 CVPbkContactManager& aContactManager,
       
    87                 MVPbkContactFindObserver& aObserver);
       
    88 
       
    89         /**
       
    90          * Searches for a store that has given URI from the list of
       
    91          * stores that the contact manager has.
       
    92          * @param aUriPtr URI of the store to search for.
       
    93          * @return The store with aUriPtr, or NULL if store was not found.
       
    94          */
       
    95         MVPbkContactStore* FindStoreL(
       
    96                 const TVPbkContactStoreUriPtr& aUriPtr);
       
    97 
       
    98         /**
       
    99          * Issues new request to be handled in RunL.
       
   100          */
       
   101         void IssueRequest();
       
   102 
       
   103         MVPbkContactLink* IsValidResultLC(MVPbkStoreContact* aContact);
       
   104 
       
   105         /**
       
   106          * Creates name tokens array
       
   107          * @param aContact which is checking, RPointerArray reference
       
   108          */
       
   109         void CreateNameTokensArrayL( MVPbkStoreContact* aContact, RPointerArray <HBufC>& aNameTokensArray );
       
   110         
       
   111         /**
       
   112          * Check if contact already exists in results array
       
   113          * @param aContact which is checking
       
   114          * @return True if contact exist or if array was empty.
       
   115          */
       
   116         TBool CheckContactDuplicationL( MVPbkStoreContact* aContact );
       
   117         
       
   118         /**
       
   119          * Gets contact's field value
       
   120          * @param aContact to get field's value from
       
   121          * @param aFieldType: EVPbkVersitNameN for Last Name 
       
   122          * EVPbkVersitNameFN for First Name
       
   123          * @return Pointer descriptor with field's value.
       
   124          */
       
   125         TPtrC NameFieldValueL( MVPbkStoreContact* aContact, TVPbkFieldTypeName aFieldType );
       
   126         
       
   127     private: // Data
       
   128         CVPbkPhoneNumberMatchStrategy& iParent;
       
   129         /// Ref: The contact manager instance to be used for searching.
       
   130         CVPbkContactManager* iContactManager;
       
   131         /// Ref: Observer for the searching process.
       
   132         MVPbkContactFindObserver* iObserver;
       
   133         /// Own: The find operation that is currently ongoing.
       
   134         MVPbkContactOperationBase* iOperation;
       
   135         /// Maximum number of matched digits.
       
   136         TInt iMaxMatchDigits;
       
   137         /// Flags to configure matching process, @see TVPbkPhoneNumberMatchFlags
       
   138         TUint32 iMatchFlags;
       
   139 
       
   140         /// Own: Array of stores that are used in matching.
       
   141         RPointerArray<MVPbkContactStore> iStoresToMatch;
       
   142         /// Own: Phone number that is being matched.
       
   143         HBufC* iPhoneNumber;
       
   144         /// Own: Intermediate results of the matching process.
       
   145         CVPbkContactLinkArray* iWorkingResults;
       
   146         /// Own: Final results of the matching process.
       
   147         CVPbkContactLinkArray* iResults;
       
   148         /// iWorkingResults index of current contact retrieval
       
   149         TInt iCurrentContact;
       
   150 
       
   151         /// Own: Currently retrieved contact
       
   152         MVPbkStoreContact* iStoreContact;
       
   153         /// Own: Field type selector
       
   154         CVPbkFieldTypeSelector* iFieldTypeSelector;
       
   155         /// Own: A filtered and sorted collection of Virtual Phonebook contact fields.
       
   156         CVPbkFieldFilter* iFieldFilter;
       
   157 
       
   158         /// Active object states
       
   159         enum TState { EMatch, ERemoveDuplicates, ERefineSearch, EComplete };
       
   160         /// Active object current state
       
   161         TState iState;
       
   162         
       
   163         /// Own: First Name field type selector
       
   164         CVPbkFieldTypeSelector* iFirstNameSelector;
       
   165         /// Own: Last Name field type selector
       
   166         CVPbkFieldTypeSelector* iLastNameSelector;
       
   167         /// Own: Array of tokens gotten from first and last name fields of first matched contact
       
   168         RPointerArray <HBufC> iNameTokensArray;
       
   169         /// Own: Array of tokens gotten from first and last name fields of contact
       
   170         RPointerArray <HBufC> iTempNameTokensArray;
       
   171         /// Indicates if all contact in iResult are the same
       
   172         TBool iDoubledContacts;
       
   173     };
       
   174 
       
   175 CVPbkPhoneNumberMatchStrategyImpl::CVPbkPhoneNumberMatchStrategyImpl(
       
   176         CVPbkPhoneNumberMatchStrategy& aParent) :
       
   177     CActive(CActive::EPriorityIdle),
       
   178     iParent(aParent)
       
   179     {
       
   180     CActiveScheduler::Add(this);
       
   181     }
       
   182 
       
   183 inline void CVPbkPhoneNumberMatchStrategyImpl::ConstructL(
       
   184         const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig,
       
   185         CVPbkContactManager& aContactManager,
       
   186         MVPbkContactFindObserver& aObserver)
       
   187     {
       
   188     iContactManager = &aContactManager;
       
   189     iObserver = &aObserver;
       
   190 
       
   191     iMaxMatchDigits = aConfig.iMaxMatchDigits;
       
   192     iMatchFlags = aConfig.iMatchFlags;
       
   193 
       
   194     const TInt uriCount = aConfig.iUriPriorities.Count();
       
   195     for (TInt i = 0; i < uriCount; ++i)
       
   196         {
       
   197         MVPbkContactStore* store = FindStoreL(aConfig.iUriPriorities[i]);
       
   198         if (store)
       
   199             {
       
   200             iStoresToMatch.AppendL(store);
       
   201             }
       
   202         }
       
   203 
       
   204     VPbkEngUtils::RLocalizedResourceFile resFile;
       
   205     resFile.OpenLC(iContactManager->FsSession(),
       
   206                    KVPbkRomFileDrive,
       
   207                    KDC_RESOURCE_FILES_DIR,
       
   208                    KVPbkFieldTypeSelectorsResFileName);
       
   209     HBufC8* selectorBuf = resFile.AllocReadLC(R_VPBK_PHONE_NUMBER_SELECTOR);
       
   210     TResourceReader resReader;
       
   211     resReader.SetBuffer(selectorBuf);
       
   212 
       
   213     iFieldTypeSelector = CVPbkFieldTypeSelector::NewL(resReader, iContactManager->FieldTypes());
       
   214 
       
   215     CleanupStack::PopAndDestroy( selectorBuf );
       
   216     
       
   217     if ( iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkDuplicatedContactsMatchFlag )
       
   218     	{ 
       
   219 	    HBufC8* firstNameSelectorBuf = resFile.AllocReadLC( R_VPBK_FIRST_NAME_SELECTOR );
       
   220 	    resReader.SetBuffer( firstNameSelectorBuf );
       
   221 	    iFirstNameSelector = CVPbkFieldTypeSelector::NewL( resReader, iContactManager->FieldTypes() );
       
   222 	    CleanupStack::PopAndDestroy( firstNameSelectorBuf );
       
   223 	
       
   224 	    HBufC8* lastNameSelectorBuf = resFile.AllocReadLC( R_VPBK_LAST_NAME_SELECTOR );
       
   225 	    resReader.SetBuffer( lastNameSelectorBuf );
       
   226 	    iLastNameSelector = CVPbkFieldTypeSelector::NewL( resReader, iContactManager->FieldTypes() );
       
   227 	    CleanupStack::PopAndDestroy( lastNameSelectorBuf );
       
   228     	}
       
   229     
       
   230     CleanupStack::PopAndDestroy( &resFile );
       
   231     }
       
   232 
       
   233 CVPbkPhoneNumberMatchStrategyImpl* CVPbkPhoneNumberMatchStrategyImpl::NewL(
       
   234         CVPbkPhoneNumberMatchStrategy& aParent,
       
   235         const CVPbkPhoneNumberMatchStrategy::TConfig& aConfig,
       
   236         CVPbkContactManager& aContactManager,
       
   237         MVPbkContactFindObserver& aObserver)
       
   238     {
       
   239     CVPbkPhoneNumberMatchStrategyImpl* self =
       
   240             new(ELeave) CVPbkPhoneNumberMatchStrategyImpl(aParent);
       
   241     CleanupStack::PushL(self);
       
   242     self->ConstructL(aConfig, aContactManager, aObserver);
       
   243     CleanupStack::Pop(self);
       
   244     return self;
       
   245     }
       
   246 
       
   247 CVPbkPhoneNumberMatchStrategyImpl::~CVPbkPhoneNumberMatchStrategyImpl()
       
   248     {
       
   249     Cancel();
       
   250     
       
   251     delete iFieldFilter;
       
   252     delete iFieldTypeSelector;
       
   253     delete iWorkingResults;
       
   254     delete iResults;
       
   255     delete iStoreContact;
       
   256     delete iPhoneNumber;
       
   257     delete iOperation;
       
   258     delete iFirstNameSelector;
       
   259     delete iLastNameSelector;
       
   260     iNameTokensArray.ResetAndDestroy();
       
   261     iTempNameTokensArray.ResetAndDestroy();
       
   262     iStoresToMatch.Close();
       
   263     }
       
   264 
       
   265 void CVPbkPhoneNumberMatchStrategyImpl::MatchL(const TDesC& aPhoneNumber)
       
   266     {
       
   267     HBufC* phoneNumber = aPhoneNumber.AllocL();
       
   268     delete iPhoneNumber;
       
   269     iPhoneNumber = phoneNumber;
       
   270     
       
   271     if ( iWorkingResults )
       
   272         {
       
   273         iWorkingResults->ResetAndDestroy();
       
   274         }                
       
   275     if ( iResults )
       
   276         {
       
   277         iResults->ResetAndDestroy();
       
   278         }                
       
   279     iCurrentContact = KMagicNumber;
       
   280     
       
   281     if ( iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkDuplicatedContactsMatchFlag )
       
   282     	{
       
   283     	iDoubledContacts = ETrue;
       
   284     	}
       
   285     else
       
   286     	{
       
   287     	iDoubledContacts = EFalse;
       
   288     	}
       
   289     iState = EMatch;
       
   290     IssueRequest();
       
   291     }
       
   292 
       
   293 
       
   294 void CVPbkPhoneNumberMatchStrategyImpl::IssueRequest()
       
   295     {
       
   296     TRequestStatus* status = &iStatus;
       
   297     User::RequestComplete(status, KErrNone);
       
   298     SetActive();
       
   299     }
       
   300 
       
   301 void CVPbkPhoneNumberMatchStrategyImpl::RunL()
       
   302     {
       
   303     switch (iState)
       
   304         {
       
   305         case EMatch:
       
   306             {
       
   307             MVPbkContactOperation* operation = iParent.CreateFindOperationLC(*iPhoneNumber);
       
   308             if (operation)
       
   309                 {
       
   310                 operation->StartL();
       
   311                 CleanupStack::Pop(); // operation
       
   312                 delete iOperation;
       
   313                 iOperation = operation;
       
   314                 }
       
   315             else
       
   316                 {
       
   317                 // all needed operations are done if any
       
   318                 iState = ERemoveDuplicates;
       
   319                 IssueRequest();
       
   320                 }
       
   321             break;
       
   322             }
       
   323         case ERemoveDuplicates:
       
   324             {
       
   325             const TInt count = iWorkingResults ? iWorkingResults->Count() : 0;
       
   326             CVPbkContactLinkArray* results = CVPbkContactLinkArray::NewLC();
       
   327             for (TInt i = 0; i < count; ++i)
       
   328                 {
       
   329                 MVPbkContactLink* link = iWorkingResults->At(i).CloneLC();
       
   330                 if (results->Find(*link) == KErrNotFound)
       
   331                     {
       
   332                     results->AppendL(link);
       
   333                     CleanupStack::Pop(); // link
       
   334                     }
       
   335                 else
       
   336                     {
       
   337                     CleanupStack::PopAndDestroy(); // link
       
   338                     }
       
   339                 }
       
   340             CleanupStack::Pop(results);
       
   341             delete iWorkingResults;
       
   342             iWorkingResults = results;
       
   343             iState = ERefineSearch;
       
   344             iCurrentContact = 0;
       
   345             IssueRequest();
       
   346             break;
       
   347             }
       
   348         case ERefineSearch:
       
   349             {
       
   350             if (!iResults)
       
   351                 {
       
   352                 iResults = CVPbkContactLinkArray::NewL();
       
   353                 }
       
   354             if ( iDoubledContacts )
       
   355                 {
       
   356                 iDoubledContacts = CheckContactDuplicationL( iStoreContact );
       
   357                 }
       
   358             
       
   359             MVPbkContactLink* result = IsValidResultLC( iStoreContact );
       
   360             if ( result )
       
   361                 {
       
   362                 iResults->AppendL( result );
       
   363                 CleanupStack::Pop(); // MVPbkContactLink
       
   364                 }
       
   365             delete iStoreContact;
       
   366             iStoreContact = NULL;
       
   367                 
       
   368             const TInt count = iWorkingResults ? iWorkingResults->Count() : 0;
       
   369             if (iCurrentContact < count &&                 
       
   370                 !( iResults->Count() > 0 && 
       
   371                         (iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkStopOnFirstMatchFlag)))
       
   372                 {
       
   373                 const MVPbkContactLink& link = iWorkingResults->At(iCurrentContact);
       
   374                 delete iOperation;
       
   375                 iOperation = NULL;
       
   376                 iOperation = iContactManager->RetrieveContactL(link, *this);
       
   377                 ++iCurrentContact;
       
   378                 }
       
   379             else
       
   380                 {
       
   381                 iState = EComplete;
       
   382                 IssueRequest();
       
   383                 }
       
   384             break;
       
   385             }
       
   386         case EComplete:
       
   387             {
       
   388             iNameTokensArray.ResetAndDestroy();
       
   389             iTempNameTokensArray.ResetAndDestroy();
       
   390             if ( iDoubledContacts && iResults->Count() )
       
   391                 {
       
   392                 CVPbkContactLinkArray* results = CVPbkContactLinkArray::NewLC();
       
   393                 MVPbkContactLink* link = iResults->At(0).CloneLC(); // first element
       
   394                 results->AppendL( link );
       
   395                 CleanupStack::Pop( 2, results ); // results, link
       
   396                 delete iResults;
       
   397                 iResults = results;
       
   398                 }
       
   399             CVPbkContactLinkArray* results = iResults;
       
   400             iResults = NULL;            
       
   401             iObserver->FindCompleteL( results );
       
   402             break;
       
   403             }
       
   404         default:
       
   405             {
       
   406             // This case should not be possible
       
   407             User::Leave( KErrArgument );
       
   408             break;
       
   409             }
       
   410         }
       
   411     }
       
   412 
       
   413 void CVPbkPhoneNumberMatchStrategyImpl::DoCancel()
       
   414     {
       
   415     }
       
   416 
       
   417 TInt CVPbkPhoneNumberMatchStrategyImpl::RunError(TInt aError)
       
   418     {
       
   419     iObserver->FindFailed(aError);
       
   420     return KErrNone;
       
   421     }
       
   422 
       
   423 inline MVPbkContactStore* CVPbkPhoneNumberMatchStrategyImpl::FindStoreL(
       
   424         const TVPbkContactStoreUriPtr& aUriPtr)
       
   425     {
       
   426     const TInt storeCount = iContactManager->ContactStoresL().Count();
       
   427     for (TInt i = 0; i < storeCount; ++i)
       
   428         {
       
   429         MVPbkContactStore& store = iContactManager->ContactStoresL().At(i);
       
   430         if (store.StoreProperties().Uri().Compare(
       
   431                     aUriPtr,
       
   432                     TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0)
       
   433             {
       
   434             return &store;
       
   435             }
       
   436         }
       
   437     return NULL;
       
   438     }
       
   439 
       
   440 void CVPbkPhoneNumberMatchStrategyImpl::FindCompleteL(MVPbkContactLinkArray* aResults)
       
   441     {
       
   442     // This function called by operation which is created in 
       
   443     // iParent.CreateFindOperationLC
       
   444     if (aResults)
       
   445         {
       
   446         CleanupDeletePushL( aResults ); // Take ownership
       
   447         
       
   448         if (!iWorkingResults)
       
   449             {
       
   450             iWorkingResults = CVPbkContactLinkArray::NewL();
       
   451             }
       
   452         const TInt count = aResults->Count();
       
   453         for (TInt i = 0; i < count; ++i)
       
   454             {
       
   455             MVPbkContactLink* link = aResults->At(i).CloneLC();
       
   456             iWorkingResults->AppendL(link);
       
   457             CleanupStack::Pop(); // link
       
   458             }
       
   459 
       
   460         CleanupStack::PopAndDestroy(); // aResults
       
   461         }
       
   462     IssueRequest();
       
   463     }
       
   464 
       
   465 void CVPbkPhoneNumberMatchStrategyImpl::FindFailed(TInt aError)
       
   466     {
       
   467     iObserver->FindFailed(aError);
       
   468     }
       
   469 
       
   470 void CVPbkPhoneNumberMatchStrategyImpl::VPbkSingleContactOperationComplete(
       
   471         MVPbkContactOperationBase& aOperation,
       
   472         MVPbkStoreContact* aContact)
       
   473     {
       
   474     if (iOperation == &aOperation)
       
   475         {
       
   476         delete iOperation;
       
   477         iOperation = NULL;
       
   478 
       
   479         iStoreContact = aContact;
       
   480         IssueRequest();
       
   481         }
       
   482     }
       
   483 
       
   484 void CVPbkPhoneNumberMatchStrategyImpl::VPbkSingleContactOperationFailed(
       
   485         MVPbkContactOperationBase& aOperation,
       
   486         TInt aError)
       
   487     {
       
   488     if (iOperation == &aOperation)
       
   489         {
       
   490         delete iOperation;
       
   491         iOperation = NULL;
       
   492 
       
   493         iObserver->FindFailed(aError);
       
   494         }
       
   495     }
       
   496 
       
   497 TInt CVPbkPhoneNumberMatchStrategyImpl::MaxMatchDigits() const
       
   498     {
       
   499     return iMaxMatchDigits;
       
   500     }
       
   501 
       
   502 TArray<MVPbkContactStore*> CVPbkPhoneNumberMatchStrategyImpl::StoresToMatch() const
       
   503     {
       
   504     return iStoresToMatch.Array();
       
   505     }
       
   506 
       
   507 MVPbkContactLink* CVPbkPhoneNumberMatchStrategyImpl::IsValidResultLC(
       
   508         MVPbkStoreContact* aContact)
       
   509     {
       
   510     MVPbkContactLink* result = NULL;
       
   511 
       
   512     if (!(iMatchFlags & CVPbkPhoneNumberMatchStrategy::EVPbkExactMatchFlag))
       
   513         {
       
   514         // If exact match is not needed we will accept the contact as valid
       
   515         // if it is not NULL
       
   516         if ( aContact )
       
   517             {
       
   518             result = aContact->CreateLinkLC();
       
   519             }        
       
   520         }
       
   521     else if (aContact)
       
   522         {
       
   523         TPtrC matchedNumber = iPhoneNumber->Des().
       
   524                 Right(Min(iPhoneNumber->Length(), iMaxMatchDigits));
       
   525 
       
   526         CVPbkFieldFilter::TConfig config(aContact->Fields(), iFieldTypeSelector);
       
   527         if (!iFieldFilter)
       
   528             {
       
   529             iFieldFilter = CVPbkFieldFilter::NewL(config);
       
   530             }
       
   531         else
       
   532             {
       
   533             iFieldFilter->ResetL(config);
       
   534             }
       
   535         const TInt count = iFieldFilter->FieldCount();
       
   536         for (TInt i = 0; i < count; ++i)
       
   537             {
       
   538             MVPbkContactFieldData& data = iFieldFilter->FieldAt(i).FieldData();
       
   539             if (data.DataType() == EVPbkFieldStorageTypeText)
       
   540                 {
       
   541                 const TDesC& dataText = MVPbkContactFieldTextData::Cast(data).Text();
       
   542                 TPtrC dataTextPtr = dataText.Right(Min(dataText.Length(), iMaxMatchDigits));
       
   543                 if (dataTextPtr == matchedNumber)
       
   544                     {
       
   545                     result = iFieldFilter->FieldAt(i).CreateLinkLC();
       
   546                     break;
       
   547                     }
       
   548                 }
       
   549             }
       
   550         }
       
   551     return result;
       
   552     }
       
   553 
       
   554 TBool CVPbkPhoneNumberMatchStrategyImpl::CheckContactDuplicationL(
       
   555         MVPbkStoreContact* aContact )
       
   556     {
       
   557 
       
   558     if ( !aContact )
       
   559         {
       
   560         return ETrue;
       
   561         }
       
   562     
       
   563     if ( aContact && iCurrentContact == 1 )
       
   564         {
       
   565         CreateNameTokensArrayL( aContact, iNameTokensArray );
       
   566         return ETrue;
       
   567         }
       
   568     else 
       
   569         {
       
   570         iTempNameTokensArray.ResetAndDestroy();
       
   571         CreateNameTokensArrayL( aContact, iTempNameTokensArray );
       
   572         TInt count = iNameTokensArray.Count();
       
   573         if ( iNameTokensArray.Count() != iTempNameTokensArray.Count() )
       
   574         	{
       
   575         	return EFalse;
       
   576         	}
       
   577         else
       
   578         	{
       
   579         	TInt result = 0;
       
   580         	for ( TInt i = 0; i < count; i++ )
       
   581         		{
       
   582         		HBufC* token = iNameTokensArray[i];
       
   583         		TInt tempCount = iTempNameTokensArray.Count();
       
   584             	for ( TInt j = 0; j < tempCount; j++ )
       
   585             		{
       
   586             		result = token->Compare( *( iTempNameTokensArray[j] ) );
       
   587                 	if ( !result )
       
   588                 		{
       
   589                 		HBufC* removedToken = iTempNameTokensArray[j];
       
   590                 		iTempNameTokensArray.Remove( j );
       
   591                 		delete removedToken;
       
   592                 		break;
       
   593                 		}
       
   594             		}
       
   595             	if ( result )
       
   596             		{
       
   597             		return EFalse;
       
   598             		}
       
   599         		}
       
   600         	}
       
   601         return ETrue;
       
   602         }
       
   603     }
       
   604 
       
   605 void CVPbkPhoneNumberMatchStrategyImpl::CreateNameTokensArrayL( MVPbkStoreContact* aContact,
       
   606 										RPointerArray <HBufC>& aNameTokensArray )
       
   607 	{
       
   608     TPtrC firstName = NameFieldValueL( aContact, EVPbkVersitNameFN );
       
   609     TLex lexer;
       
   610     lexer.Assign( firstName );
       
   611     
       
   612     TPtrC ptr;
       
   613     TInt len = 0;
       
   614     while( ETrue )
       
   615         {
       
   616         ptr.Set( lexer.NextToken() );
       
   617         
       
   618         len = ptr.Length();
       
   619         if ( len )
       
   620             {
       
   621             HBufC* token = ptr.AllocLC();
       
   622             aNameTokensArray.AppendL( token );
       
   623             CleanupStack::Pop( token );
       
   624             }
       
   625         else
       
   626             {
       
   627             break;
       
   628             }
       
   629         } 
       
   630 
       
   631     TPtrC lastName = NameFieldValueL( aContact, EVPbkVersitNameN );
       
   632 
       
   633     lexer.Assign( lastName );
       
   634     
       
   635     len = 0;
       
   636     while( ETrue )
       
   637         {
       
   638         ptr.Set( lexer.NextToken() );
       
   639         
       
   640         len = ptr.Length();
       
   641         if ( len )
       
   642             {
       
   643             HBufC* token = ptr.AllocLC();
       
   644             aNameTokensArray.AppendL( token );
       
   645             CleanupStack::Pop( token );
       
   646             }
       
   647         else
       
   648             {
       
   649             break;
       
   650             }
       
   651         }
       
   652 	}
       
   653 
       
   654 TPtrC CVPbkPhoneNumberMatchStrategyImpl::NameFieldValueL( 
       
   655         MVPbkStoreContact* aContact, TVPbkFieldTypeName aFieldType )
       
   656     {
       
   657     if ( aContact )
       
   658         {
       
   659         CVPbkFieldFilter::TConfig config( aContact->Fields() );
       
   660         if ( aFieldType == EVPbkVersitNameFN )
       
   661             {
       
   662             config.iFieldSelector = iFirstNameSelector;
       
   663             }
       
   664         else if ( aFieldType == EVPbkVersitNameN )
       
   665             {
       
   666             config.iFieldSelector = iLastNameSelector;
       
   667             }
       
   668         else
       
   669             {
       
   670             return KNullDesC();
       
   671             }
       
   672         
       
   673         if (!iFieldFilter)
       
   674             {
       
   675             iFieldFilter = CVPbkFieldFilter::NewL(config);
       
   676             }
       
   677         else
       
   678             {
       
   679             iFieldFilter->ResetL(config);
       
   680             }
       
   681         const TInt count = iFieldFilter->FieldCount();
       
   682         for (TInt i = 0; i < count; ++i)
       
   683             {
       
   684             MVPbkContactFieldData& data = iFieldFilter->FieldAt(i).FieldData();
       
   685             if (data.DataType() == EVPbkFieldStorageTypeText)
       
   686                 {
       
   687                 return  MVPbkContactFieldTextData::Cast(data).Text();
       
   688                 }
       
   689             }
       
   690         return KNullDesC();
       
   691         }
       
   692     else
       
   693         {
       
   694         return KNullDesC();
       
   695         }
       
   696     }
       
   697 
       
   698 CVPbkPhoneNumberMatchStrategy::CVPbkPhoneNumberMatchStrategy()
       
   699     {
       
   700     }
       
   701 
       
   702 EXPORT_C CVPbkPhoneNumberMatchStrategy* CVPbkPhoneNumberMatchStrategy::NewL(
       
   703         const TConfig& aConfig,
       
   704         CVPbkContactManager& aContactManager,
       
   705         MVPbkContactFindObserver& aObserver)
       
   706     {
       
   707     if (aConfig.iMatchMode == EVPbkSequentialMatch)
       
   708         {
       
   709         return CVPbkPhoneNumberSequentialMatchStrategy::NewL(aConfig, aContactManager, aObserver);
       
   710         }
       
   711     else
       
   712         {
       
   713         return CVPbkPhoneNumberParallelMatchStrategy::NewL(aConfig, aContactManager, aObserver);
       
   714         }
       
   715    }
       
   716 
       
   717 CVPbkPhoneNumberMatchStrategy::~CVPbkPhoneNumberMatchStrategy()
       
   718     {
       
   719     delete iImpl;
       
   720     }
       
   721 
       
   722 EXPORT_C void CVPbkPhoneNumberMatchStrategy::MatchL(const TDesC& aPhoneNumber)
       
   723     {
       
   724     InitMatchingL();
       
   725 
       
   726     iImpl->MatchL(aPhoneNumber);
       
   727     }
       
   728 
       
   729 void CVPbkPhoneNumberMatchStrategy::BaseConstructL(
       
   730         const TConfig& aConfig,
       
   731         CVPbkContactManager& aContactManager,
       
   732         MVPbkContactFindObserver& aObserver)
       
   733     {
       
   734     iImpl = CVPbkPhoneNumberMatchStrategyImpl::NewL(
       
   735             *this, aConfig, aContactManager, aObserver);
       
   736     }
       
   737 
       
   738 MVPbkContactFindObserver& CVPbkPhoneNumberMatchStrategy::FindObserver() const
       
   739     {
       
   740     return *iImpl;
       
   741     }
       
   742 
       
   743 TInt CVPbkPhoneNumberMatchStrategy::MaxMatchDigits() const
       
   744     {
       
   745     return iImpl->MaxMatchDigits();
       
   746     }
       
   747 
       
   748 TArray<MVPbkContactStore*> CVPbkPhoneNumberMatchStrategy::StoresToMatch() const
       
   749     {
       
   750     return iImpl->StoresToMatch();
       
   751     }
       
   752 
       
   753 // End of File