clfwrapper/ClientSrc/CCLFEngineImpl.cpp
changeset 0 c53acadfccc6
child 15 3cebc1a84278
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/clfwrapper/ClientSrc/CCLFEngineImpl.cpp	Mon Jan 18 20:34:07 2010 +0200
@@ -0,0 +1,542 @@
+/*
+* Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+
+// INCLUDE FILES
+#include    <MCLFOperationObserver.h>
+#include    <MCLFSortingStyle.h>
+#include    <MCLFItem.h>
+#include    <MCLFChangedItemObserver.h>
+#include    "CCLFEngineImpl.h"
+#include    "CCLFDbItemProvider.h"
+#include    "CCLFItemImpl.h"
+#include    "CCLFDefaultOperation.h"
+#include    "CCLFItemListModelImpl.h"
+#include    "CCLFEventHandler.h"
+#include    "CCLFDbItemContainer.h"
+#include    "MGDebugPrint.h"
+#include    "CCLFQueryAdapter.h"
+
+// CONSTANTS
+const TInt KCLFObserverArrayGranularity( 2 );
+const TInt KCLFChangedItemIdArrayGranularity( 10 );
+
+// -----------------------------------------------------------------------------
+// CleanupTempModel
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::CleanupTempModel( TAny* aObj )
+    {
+    static_cast< CCLFEngineImpl::CCLFTempModel* >( aObj )->ResetModelArray();
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFEngineImpl
+// -----------------------------------------------------------------------------
+//
+CCLFEngineImpl::CCLFEngineImpl()
+    : iCLFServerProxy( NULL ),
+      iMdESession( NULL ),
+      iError( KErrNone ),
+      iUpdateStartEventHandler( NULL ),
+      iUpdateEndEventHandler( NULL ),
+      iChangedItemObserverArray( KCLFObserverArrayGranularity ),
+      iProcessObserverArray( KCLFObserverArrayGranularity ),
+      iDbItemContainer( NULL ),
+      iItemProvider( NULL ),
+      iQueryAdapter( NULL )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::ConstructL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::ConstructL()
+    {
+    iMdESession = CMdESession::NewL( *this );
+    if( !iActiveSchedulerWait.IsStarted() )
+        {
+        iActiveSchedulerWait.Start();
+        }
+    User::LeaveIfError( iError );
+    iCLFServerProxy = CCLFServerProxy::NewL( *iMdESession );
+    iQueryAdapter = CCLFQueryAdapter::NewL( *iMdESession );
+    iUpdateStartEventHandler = CCLFEventHandler::NewL( *iCLFServerProxy, *this );
+    iUpdateEndEventHandler = CCLFEventHandler::NewL( *iCLFServerProxy, *this );
+    iDbItemContainer = CCLFDbItemContainer::NewL();
+    iItemProvider = CCLFDbItemProvider::NewL( *iDbItemContainer, *iQueryAdapter, iMdESession );
+    iUpdateEndEventHandler->ObserverUpdateEndEvent();
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::NewLC
+// -----------------------------------------------------------------------------
+//
+CCLFEngineImpl* CCLFEngineImpl::NewLC()
+    {
+    CCLFEngineImpl* self = new( ELeave ) CCLFEngineImpl;
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::~CCLFEngineImpl
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CCLFEngineImpl::~CCLFEngineImpl()
+    {
+    delete iItemProvider;
+    delete iUpdateStartEventHandler;
+    delete iUpdateEndEventHandler;
+    delete iDbItemContainer;
+    delete iCLFServerProxy;
+    iChangedItemObserverArray.Close();
+    iProcessObserverArray.Close();
+    delete iQueryAdapter;
+    delete iMdESession;
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::AddChangedItemObserverL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::AddChangedItemObserverL( MCLFChangedItemObserver& aObserver )
+    {
+    iChangedItemObserverArray.AppendL( &aObserver );
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::RemoveChangedItemObserver
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::RemoveChangedItemObserver( MCLFChangedItemObserver& aObserver )
+    {
+    const TInt index( iChangedItemObserverArray.Find( &aObserver ) );
+    if ( index >= 0 )
+        {
+        iChangedItemObserverArray.Remove( index );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::AddCLFProcessObserverL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::AddCLFProcessObserverL( MCLFProcessObserver& aObserver )
+    {
+    iProcessObserverArray.AppendL( &aObserver );
+    if ( !iUpdateStartEventHandler->IsActive() )
+        {
+        iUpdateStartEventHandler->ObserverUpdateStartEvent();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::RemoveCLFProcessObserver
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::RemoveCLFProcessObserver( MCLFProcessObserver& aObserver )
+    {
+    const TInt index( iProcessObserverArray.Find( &aObserver ) );
+    if ( index >= 0 )
+        {
+        iProcessObserverArray.Remove( index );
+        }
+
+    StopEventHandling();
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::UpdateItemsL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::UpdateItemsL()
+    {
+    User::LeaveIfError( iCLFServerProxy->UpdateAllItemsL() );
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::UpdateItemsL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::UpdateItemsL( const TArray<TCLFItemId>& aItemIDArray )
+    {
+    User::LeaveIfError( iCLFServerProxy->UpdateItemsL( aItemIDArray ) );
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::UpdateItemsL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::UpdateItemsL( TInt aSemanticId, const TDesC8& aOpaqueData )
+    {
+    User::LeaveIfError( iCLFServerProxy->UpdateItemsL( aSemanticId, aOpaqueData ) );
+    }
+
+// ---------------------------------------------------------------------------
+// CCLFEngineImpl::HandleSessionOpened
+// ---------------------------------------------------------------------------
+//
+void CCLFEngineImpl::HandleSessionOpened( CMdESession& /* aSession */, const TInt aError )
+    {
+    MG_DEBUG2( HSO, "[CLF]\t CCLFEngineImpl::HandleSessionOpened %d", aError );
+    iActiveSchedulerWait.AsyncStop();
+
+    iError = aError;
+    }
+
+// ---------------------------------------------------------------------------
+// CCLFEngineImpl::HandleSessionError
+// ---------------------------------------------------------------------------
+//
+void CCLFEngineImpl::HandleSessionError( CMdESession& /*aSession*/, const TInt aError )
+    {
+    MG_DEBUG2( HSE, "[CLF]\t CCLFEngineImpl::HandleSessionError %d", aError );
+
+    iError = aError;
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CreateListModelLC
+// -----------------------------------------------------------------------------
+//
+MCLFItemListModel* CCLFEngineImpl::CreateListModelLC(
+                                            MCLFOperationObserver& aObserver )
+    {
+
+    CCLFDbItemProvider* itemProvider = CCLFDbItemProvider::NewL( *iDbItemContainer, *iQueryAdapter, iMdESession );
+    // self takes ownership of itemProvider.
+    CCLFItemListModelImpl* self = CCLFItemListModelImpl::NewLC( itemProvider, aObserver, iChangedItemModel );
+    iChangedItemModel.AddObserverL( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CreateListModelLC
+// -----------------------------------------------------------------------------
+//
+MCLFItemListModel* CCLFEngineImpl::CreateListModelLC(
+                                            MCLFOperationObserver& aObserver,
+                                            TResourceReader& aReader )
+    {
+    CCLFDbItemProvider* itemProvider = CCLFDbItemProvider::NewL( *iDbItemContainer, *iQueryAdapter, iMdESession );
+    // self takes ownership of itemProvider.
+    CCLFItemListModelImpl* self = CCLFItemListModelImpl::NewLC( itemProvider, aObserver, iChangedItemModel, aReader );
+    iChangedItemModel.AddObserverL( self );
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::HandleUpdateEndEventL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::HandleUpdateEndEventL( const TInt aError )
+    {
+    if ( aError == KErrNone )
+        {
+        // get changed items and add new ones to array
+        RArray< TCLFItemId > changedItemIdArray;
+        CleanupClosePushL( changedItemIdArray );
+        iUpdateEndEventHandler->GetChangedItemsL( changedItemIdArray );
+        const TInt count( changedItemIdArray.Count() );
+        for ( TInt i = 0; i < count; ++i )
+            {
+            const TCLFItemId id( changedItemIdArray[ i ] );
+            const TInt index(
+                    iChangedItemModel.iChangedItemIdArray.Find( id ) );
+            if ( index == KErrNotFound )
+                {
+                iChangedItemModel.iChangedItemIdArray.AppendL( id );
+                }
+            }
+        CleanupStack::PopAndDestroy( &changedItemIdArray );
+
+        if ( iChangedItemModel.iChangedItemIdArray.Count() )
+            {
+            iDbItemContainer->SetDeprecatedItems(
+                                    iChangedItemModel.iChangedItemIdArray );
+
+            iItemProvider->PrepareItemsL(
+                                iChangedItemModel.iChangedItemIdArray.Array(),
+                                *this );
+            }
+        else
+            {
+            // no changed items -> just notify process observers
+            NotifyProcessObserversL( ECLFUpdateStop );
+            }
+        }
+    else
+        {
+        const TInt count( iChangedItemObserverArray.Count() );
+        for ( TInt i = 0 ; i < count ; ++i )
+            {
+            iChangedItemObserverArray[i]->HandleError( aError );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::OperationCompleteL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::OperationCompleteL( const TInt aError )
+    {
+    // make sure that changed item model is reset
+    // array must be reset when changed items are handled (also in leave case)
+    CleanupStack::PushL( TCleanupItem( CleanupTempModel,
+                                       &iChangedItemModel) );
+
+    if ( aError )
+        {
+        const TInt count( iChangedItemObserverArray.Count() );
+        for( TInt i = 0 ; i < count ; ++i )
+            {
+            iChangedItemObserverArray[i]->HandleError( aError );
+            }
+        }
+    else
+        {
+        // put items to container
+        User::LeaveIfError( iItemProvider->GetItems(
+                                    iChangedItemModel.iItemArray ) );
+
+        // notify process observers
+        NotifyProcessObserversL( ECLFUpdateStop );
+
+        // notify changed item observers
+        if ( iChangedItemModel.iChangedItemIdArray.Count() > 0 )
+            {
+            const TInt count( iChangedItemObserverArray.Count() );
+            for( TInt i = 0 ; i < count ; ++i )
+                {
+                iChangedItemObserverArray[i]->HandleItemChangeL(
+                            iChangedItemModel.iChangedItemIdArray.Array() );
+                }
+
+            // notify models
+            iChangedItemModel.NotifyObserverL();
+            }
+        }
+    CleanupStack::PopAndDestroy(); // TCleanupItem
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::HandleUpdateStartEventL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::HandleUpdateStartEventL( const TInt aError )
+    {
+    if ( aError == KErrNone )
+        {
+        NotifyProcessObserversL( ECLFUpdateStart );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::NotifyProcessObserversL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::NotifyProcessObserversL( TCLFProcessEvent aEvent )
+    {
+    const TInt count( iProcessObserverArray.Count() );
+    for ( TInt i = 0 ; i < count ; ++i )
+        {
+        iProcessObserverArray[i]->HandleCLFProcessEventL( aEvent );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::StopEventHandling
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::StopEventHandling()
+    {
+    if ( iProcessObserverArray.Count() == 0 )
+        {
+        // stop "start observing"
+        iUpdateStartEventHandler->Cancel();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::IsItemsForModel
+// -----------------------------------------------------------------------------
+//
+TBool CCLFEngineImpl::CCLFTempModel::IsItemsForModel(
+                                        const MDesCArray& aMimeTypes,
+                                        const TArray<TInt>& aMediaTypes,
+                                        const TArray<TUint>& aModelItemIds )
+    {
+    // first from item IDs
+    TInt count( aModelItemIds.Count() );
+    for ( TInt i = 0 ; i < count ; ++i )
+        {
+        const TInt index( iChangedItemIdArray.FindInOrder( aModelItemIds[ i ] ) );
+        if( index >= 0 )
+            {
+            return ETrue;
+            }
+        }
+
+    // find second from media types (faster)
+    count = aMediaTypes.Count();
+    for ( TInt i = 0 ; i < count ; ++i )
+        {
+        const TInt index( iMediaTypeArray.FindInOrder( aMediaTypes[ i ] ) );
+        if ( index >= 0 )
+            {
+            return ETrue;
+            }
+        }
+
+    // and mimetypes, final from mimetypes, 
+    // because descriptor comparation is slow
+    count = aMimeTypes.MdcaCount();
+    const TInt mCount( iMimeTypeArray.MdcaCount() );
+    for ( TInt i = 0 ; i < count ; ++i )
+        {
+        // match model mimetypes to changed item(s) mimetypes
+        const TDesC& modelMimeType = aMimeTypes.MdcaPoint( i );
+        for ( TInt j = 0 ; j < mCount ; ++j )
+            {
+            const TDesC& changedItemMimeType = iMimeTypeArray.MdcaPoint( j );
+            const TInt match( changedItemMimeType.Match( modelMimeType ) );
+            if ( match != KErrNotFound )
+                {
+                return ETrue;
+                }
+            }
+        }
+
+    return EFalse;
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::CCLFTempModel
+// -----------------------------------------------------------------------------
+//
+CCLFEngineImpl::CCLFTempModel::CCLFTempModel()
+    : iItemArray( KCLFChangedItemIdArrayGranularity ),
+      iChangedItemIdArray( KCLFChangedItemIdArrayGranularity ),
+      iChangedItemProviderObserverArray( KCLFChangedItemIdArrayGranularity ),
+      iMimeTypeArray( KCLFChangedItemIdArrayGranularity ),
+      iMediaTypeArray( KCLFChangedItemIdArrayGranularity )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::~CCLFTempModel
+// -----------------------------------------------------------------------------
+//
+CCLFEngineImpl::CCLFTempModel::~CCLFTempModel()
+    {
+    ResetModelArray();
+    iChangedItemProviderObserverArray.Close();
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::AddObserverL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::CCLFTempModel::AddObserverL(
+                                MCLFChangedItemProviderObserver* aObserver )
+    {
+    iChangedItemProviderObserverArray.AppendL( aObserver );
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::ResetModelArray
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::CCLFTempModel::ResetModelArray()
+    {
+    iItemArray.ResetAndDestroy();
+    iMimeTypeArray.Reset();
+    iMediaTypeArray.Reset();
+    iChangedItemIdArray.Reset();
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::NotifyObserverL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::CCLFTempModel::NotifyObserverL()
+    {
+    PrepareModelL();
+
+    const TInt providerObserverCount(
+                                    iChangedItemProviderObserverArray.Count() );
+    for ( TInt i = 0 ; i < providerObserverCount ; ++i )
+        {
+        iChangedItemProviderObserverArray[i]->NewChangedItemsL();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::PrepareModelL
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::CCLFTempModel::PrepareModelL()
+    {
+    // sort array for faster find
+    iChangedItemIdArray.Sort();
+
+    // get mimetypes and media types from items
+    const TInt modelCount( iItemArray.Count() );
+    for ( TInt i = 0 ; i < modelCount ; ++i )
+        {
+        MCLFItem* item = iItemArray[ i ];
+
+        TInt32 mediaType( 0 );
+        TInt error( item->GetField( ECLFFieldIdMediaType, mediaType ) );
+        if ( error == KErrNone &&
+            iMediaTypeArray.FindInOrder( mediaType ) == KErrNotFound )
+            {
+            User::LeaveIfError( iMediaTypeArray.InsertInOrder( mediaType ) );
+            }
+        TPtrC mimeType;
+        error = item->GetField( ECLFFieldIdMimeType, mimeType );
+        TInt pos( 0 );
+        if ( error == KErrNone &&
+            iMimeTypeArray.FindIsq( mimeType, pos ) != 0 ) // not found
+            {
+            iMimeTypeArray.InsertIsqL( mimeType );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CCLFEngineImpl::CCLFTempModel::ChangedItemProviderRemoveObserver
+// -----------------------------------------------------------------------------
+//
+void CCLFEngineImpl::CCLFTempModel::RemoveChangedItemProviderObserver(
+                                MCLFChangedItemProviderObserver* aObserver )
+    {
+    const TInt index( iChangedItemProviderObserverArray.Find( aObserver ) );
+    if ( index >= 0 )
+        {
+        iChangedItemProviderObserverArray.Remove( index );
+        }
+    }
+
+//  End of File