clfwrapper/ClientSrc/CCLFEngineImpl.cpp
author William Roberts <williamr@symbian.org>
Mon, 08 Mar 2010 21:43:59 +0000
branchCompilerCompatibility
changeset 10 67b0a665852a
parent 0 c53acadfccc6
child 15 3cebc1a84278
permissions -rw-r--r--
Create CompilerCompatibility branch

/*
* 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