phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkxSPContactsOperation.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkxSPContactsOperation.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,392 @@
+/*
+* Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  xSP Contact operation
+ *
+*/
+
+
+// INCLUDES
+#include "CVPbkxSPContactsOperation.h"
+
+
+#include <barsc.h>
+#include <barsread.h>
+
+
+#include <TVPbkWordParserCallbackParam.h>
+#include <VPbkEng.rsg>
+#include <CVPbkContactFieldIterator.h>
+#include <CVPbkContactManager.h>
+#include <CVPbkFieldTypeRefsList.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactFieldUriData.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactLink.h>
+#include <MVPbkContactStoreProperties.h>
+#include <VPbkContactStoreUris.h>
+#include "VPbkDebug.h"
+
+#include <CVPbkEComImplementationsList.h>
+#include <spsettings.h>
+#include <spproperty.h>
+namespace
+    {
+
+#ifdef _DEBUG	
+    enum TxSPErrors
+        {
+        ExSPErrorWrongLogic1,
+        ExSPErrorWrongState,
+        EInvalidOperation,
+        ExSPErrorWrongStateRun
+        };
+
+    _LIT( KPanicStrxSPManagement, "VPbk_xSPManag");
+
+    void Panic(TxSPErrors aReason)
+        {
+        User::Panic(KPanicStrxSPManagement, aReason);
+        }
+#endif	
+    }
+
+///////////////////////////////////////////////////////////////////////////////
+
+CVPbkxSPContactsOperation* CVPbkxSPContactsOperation::NewLC(
+        const MVPbkStoreContact& aContact,
+        CVPbkContactManager& aContactManager,
+        MVPbkOperationErrorObserver& aErrorObserver, TxSPOperation aOperation)
+    {
+    CVPbkxSPContactsOperation* self = new (ELeave) CVPbkxSPContactsOperation(
+            aContact,
+            aContactManager,
+            aErrorObserver,
+            aOperation );
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    return self;
+    }
+
+void CVPbkxSPContactsOperation::ConstructL()
+    {
+    iContactLink = iContact.CreateLinkLC();
+    CleanupStack::Pop();  //iContactLink
+    iContactLinks = CVPbkContactLinkArray::NewL();
+    CompleteOurself(); //start execution right away    
+    }
+
+CVPbkxSPContactsOperation::CVPbkxSPContactsOperation(
+    const MVPbkStoreContact& aContact,
+    CVPbkContactManager& aContactManager,
+    MVPbkOperationErrorObserver& aErrorObserver, 
+    TxSPOperation /*aOperation*/) :
+    CActive(EPriorityStandard), 
+        iNextState(EStateNone), iContact(aContact),
+        iContactManager(aContactManager), iErrorObserver(&aErrorObserver)
+    {
+    CActiveScheduler::Add(this);
+    }
+
+CVPbkxSPContactsOperation::~CVPbkxSPContactsOperation()
+    {
+    Cancel();
+    delete iContactOperation;
+
+    if(iContactLinks) 
+        {
+        iContactLinks->ResetAndDestroy();
+        }
+    
+    delete iContactLinks;
+    delete iContactLink;
+    delete iFieldTypeRefList;
+    delete iXspIdArray;
+    }
+
+MVPbkContactOperationBase* CVPbkxSPContactsOperation::NewGetxSPLinksOperationL(
+        const MVPbkStoreContact& aContact,
+        CVPbkContactManager& aContactManager,
+        MVPbkOperationResultObserver<MVPbkContactLinkArray*>& aObserver,
+        MVPbkOperationErrorObserver& aErrorObserver, TxSPOperation aOperation)
+    {
+    __ASSERT_DEBUG( aOperation == EGetxSPContactLinks,
+            Panic(EInvalidOperation) );
+
+    CVPbkxSPContactsOperation* self = NewLC(aContact, aContactManager,
+            aErrorObserver, aOperation);
+    self->iLinksObserver = &aObserver;
+    self->iNextState = EStateFind;
+
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+void CVPbkxSPContactsOperation::DoCancel()
+    {
+    delete iContactOperation;
+    iContactOperation = NULL;
+    }
+
+void CVPbkxSPContactsOperation::RunL()
+    {
+    switch(iNextState)
+        {
+        case EStateFind:
+            {
+            GetIMPPDataL();
+            }
+            break;
+        
+        case EStateAbortWithError:
+            {
+            NotifyError(iAbortError);
+            }
+            break;
+            
+        default:
+            {
+            __ASSERT_DEBUG( EFalse,Panic( ExSPErrorWrongStateRun ) );
+            }
+        }
+    }
+
+TInt CVPbkxSPContactsOperation::RunError(TInt aError)
+    {
+    NotifyError(aError);
+    return KErrNone;
+    }
+
+//---------------------------------------------------------------
+// These are from MVPbkContactStoreObserver
+
+void CVPbkxSPContactsOperation::FindFromStoreSucceededL(
+        MVPbkContactStore& /*aStore*/,
+        MVPbkContactLinkArray* aResultsFromStore)
+    {
+    ProcessContactLinksL(aResultsFromStore);
+    delete aResultsFromStore;
+    }
+
+void CVPbkxSPContactsOperation::FindFromStoreFailed(
+        MVPbkContactStore& /*aStore*/, TInt /*aError*/)
+    {
+    //do nothing
+    }
+
+void CVPbkxSPContactsOperation::FindFromStoresOperationComplete()
+    {
+    TRAP_IGNORE(SubsearchCompleteL());
+    }
+
+// ----------------------------------------------------------
+// CVPbkxSPContactsOperation::GetIMPPDataL
+// 
+// ----------------------------------------------------------
+//
+void CVPbkxSPContactsOperation::GetIMPPDataL()
+    {
+    //Check is contact valid.
+    __ASSERT_ALWAYS ( NULL != &iContact, User::Leave(KErrArgument));
+    
+    TBool imppFound = EFalse;
+    iXspIdArray = new ( ELeave ) CDesCArrayFlat( 5 );    
+    const MVPbkFieldType* type = 
+        iContactManager.FieldTypes().Find( R_VPBK_FIELD_TYPE_IMPP);
+    CVPbkBaseContactFieldTypeIterator* itr =
+            CVPbkBaseContactFieldTypeIterator::NewLC( *type,
+                    iContact.Fields() );
+    if (itr->HasNext() )
+        {
+        imppFound = ETrue;
+        while (itr->HasNext() )
+            {
+            const MVPbkBaseContactField* field = itr->Next();
+            const MVPbkContactFieldUriData& uri =
+                    MVPbkContactFieldUriData::Cast(field->FieldData() );
+            HBufC* data = uri.Uri().AllocL();
+            CleanupStack::PushL(data);
+            iXspIdArray->AppendL(data->Des() ); 
+            CleanupStack::PopAndDestroy(data); 
+            }
+
+        iFieldTypeRefList = CVPbkFieldTypeRefsList::NewL();
+        iFieldTypeRefList->AppendL( 
+            *iContactManager.FieldTypes().Find( R_VPBK_FIELD_TYPE_IMPP) );
+        FindUsingIdL();
+        }
+
+    CleanupStack::PopAndDestroy(itr);     
+
+    //If there isn't any impp fields, notify empty contact link array. 
+    if (!imppFound)
+        {
+        NotifyResult();
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CVPbkxSPContactsOperation::FindUsingIdL
+// ---------------------------------------------------------------------------
+//
+TBool CVPbkxSPContactsOperation::FindUsingIdL()
+    {
+    TBool started(EFalse);
+
+    if( iXspIdArray->MdcaCount() > iNextXspId )
+        {
+        if ( iContactOperation != NULL )
+            {
+            delete iContactOperation;
+            iContactOperation = NULL;
+            }
+   
+        started = ETrue;
+        CDesCArrayFlat* idArray = new ( ELeave ) CDesCArrayFlat( 1 );
+        CleanupStack::PushL(idArray);
+        idArray->AppendL( iXspIdArray->MdcaPoint(iNextXspId) );
+        iNextXspId++;
+        TCallBack parser(CVPbkxSPContactsOperation::WordParserL, this);        
+        CDesC16ArrayFlat* aXUriArray = new ( ELeave ) CDesCArrayFlat( 52 );
+		CleanupStack::PushL(aXUriArray);
+		RIdArray ids;
+		CleanupClosePushL( ids );
+		CSPSettings* settings = CSPSettings::NewL();
+		CleanupStack::PushL( settings ); 
+		TInt error = settings->FindServiceIdsL( ids );  
+		const TInt count = ids.Count();
+       	TVPbkContactStoreUriPtr defaultUri = VPbkContactStoreUris::DefaultCntDbUri();
+
+		for( TInt i = 0; i < count; i++ )
+		    {
+		    CSPProperty* property = CSPProperty::NewLC();
+		    error = settings->FindPropertyL( ids[i], EPropertyContactStoreId,
+		        *property );
+		    if( KErrNone == error )
+		        {
+		        RBuf uri;
+		        uri.Create( KSPMaxDesLength );
+		        CleanupClosePushL( uri );  
+		        property->GetValue( uri );
+		        
+		        // Append the uri which is not equal to default store uri
+		       	if ( defaultUri.UriDes().CompareF(uri) != KErrNone )
+		       		{
+		       		aXUriArray->AppendL( uri );
+		       		}
+		        CleanupStack::PopAndDestroy();  //uri
+		        }
+		    CleanupStack::PopAndDestroy();  //property
+		    }
+		CleanupStack::PopAndDestroy( 2 ); // settings, ids
+        
+        iContactOperation = iContactManager.FindL( *idArray, *iFieldTypeRefList,
+                *this, parser,*aXUriArray);
+                
+        CleanupStack::PopAndDestroy( 2 );
+        }
+    
+    return started;
+    }
+
+// ----------------------------------------------------------
+// CVPbkxSPContactsOperation::WordParserL
+// 
+// ----------------------------------------------------------
+//
+TInt CVPbkxSPContactsOperation::WordParserL(TAny* aWordParserParam)
+    {
+    //Get all data, no need to parse anything.. 
+    TVPbkWordParserCallbackParam* param =
+            static_cast<TVPbkWordParserCallbackParam*>(aWordParserParam );
+    TPtrC data(param->iStringToParse->Ptr() );
+    param->iWordArray->AppendL(data);
+    return 0;
+    }
+
+void CVPbkxSPContactsOperation::ProcessContactLinksL(
+        MVPbkContactLinkArray* aResultsFromStore)
+    {
+    TInt count = aResultsFromStore->Count();
+
+    for (TInt a = 0; a < count; a++)
+        {
+        const MVPbkContactLink& link = aResultsFromStore->At(a);
+
+        //If not from original storage, add to array.
+        if (!link.RefersTo(iContact))
+            {
+            if(iContactLinks->Find(link) == KErrNotFound)
+                {
+                iContactLinks->AppendL(link.CloneLC());
+                CleanupStack::Pop(); //Clone
+                }
+            }
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Completes this active object.
+// --------------------------------------------------------------------------
+void CVPbkxSPContactsOperation::CompleteOurself()
+    {
+    if ( !IsActive() )
+        {
+        TRequestStatus* status = &iStatus;
+        User::RequestComplete(status, KErrNone);
+        SetActive();
+        }
+    else
+        {
+        __ASSERT_DEBUG( EFalse, Panic(ExSPErrorWrongLogic1) );
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Search completed 
+// --------------------------------------------------------------------------
+void CVPbkxSPContactsOperation::SubsearchCompleteL()
+    {
+    if(!FindUsingIdL())
+        {
+        NotifyResult();
+        }
+    }
+
+// --------------------------------------------------------------------------
+// Notifies operation observer of results
+// --------------------------------------------------------------------------
+void CVPbkxSPContactsOperation::NotifyResult()
+    {
+    iLinksObserver->VPbkOperationResultCompleted( this, iContactLinks);
+    }
+
+// --------------------------------------------------------------------------
+// Sends error notification to the error observer
+// --------------------------------------------------------------------------
+inline void CVPbkxSPContactsOperation::NotifyError(TInt aErr)
+    {
+    iErrorObserver->VPbkOperationFailed( this, aErr);
+    }
+
+// --------------------------------------------------------------------------
+// Notify error async
+// --------------------------------------------------------------------------
+void CVPbkxSPContactsOperation::AbortWithError(TInt aErr)
+    {
+    iAbortError = aErr;
+    iNextState = EStateAbortWithError;
+    CompleteOurself();
+    }
+
+// end of file