contentstorage/extsrc/cahandlerengine.cpp
author hgs
Tue, 23 Mar 2010 23:28:12 +0200
changeset 86 e492551a0d54
parent 85 7feec50967db
permissions -rw-r--r--
201005

/*
 * Copyright (c) 2008 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:  ?Description
 *
 */

#include "cahandlerengine.h"
#include "cahandler.h"
#include "cahandlerplugin.h"
#include "cahandlerplugin.hrh"
#include "cadef.h"
#include "cainnerentry.h"

// ======== LOCAL FUNCTIONS ========

// ---------------------------------------------------------------------------
// Cleanupstack support method, calls RImplInfoPtrArray::ResetAndDestroy()
// of the passed argument (array).
// ---------------------------------------------------------------------------
//
LOCAL_C void ResetAndDestroyArray( TAny* aArray )
    {
    ( (RImplInfoPtrArray* ) aArray )->ResetAndDestroy();
    }

// ======== MEMBER FUNCTIONS ========

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
EXPORT_C CCaHandlerEngine::~CCaHandlerEngine()
    {
    iHandlers.ResetAndDestroy();
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
EXPORT_C CCaHandlerEngine* CCaHandlerEngine::NewL()
    {
    CCaHandlerEngine* self = NewLC();
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
EXPORT_C CCaHandlerEngine* CCaHandlerEngine::NewLC()
    {
    CCaHandlerEngine* self = new ( ELeave ) CCaHandlerEngine();
    CleanupStack::PushL( self );
    self->ConstructL();
    return self;
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
void CCaHandlerEngine::ConstructL()
    {
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
CCaHandlerEngine::CCaHandlerEngine()
    {
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
EXPORT_C void CCaHandlerEngine::HandleCommandL( CCaInnerEntry& aEntry,
        const TDesC8& aCommand )
    {
    // Currently, we load handlers on demand and never unload them.
    // As there aren't many types of items, this seems appropriate.
    CCaHandler* handler = FindHandler( aEntry.GetEntryTypeName() );
    if( !handler )
        {
        //TODO: need to change this
        if( aEntry.GetEntryTypeName() == KCaTypeApp()
                || aEntry.GetEntryTypeName() == KCaTypeWidget() )
            {
            handler = LoadHandlerL( KCaTypeApp() );
            }
        else
            {
            handler = LoadHandlerL( aEntry.GetEntryTypeName() );
            }
        }
    if( handler )
        {
        handler->HandleCommandL( aEntry, aCommand );
        }
    else
        {
        User::Leave( KErrNotFound );
        }
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
CCaHandler* CCaHandlerEngine::FindHandler( const TDesC& aType )
    {
    for( TInt i = 0; i < iHandlers.Count(); i++ )
        {
        CCaHandler* handler = iHandlers[i];
        if( handler->SupportsType( aType ) )
            {
            return handler;
            }
        }
    return NULL;
    }

// ---------------------------------------------------------
//
// ---------------------------------------------------------
//
CCaHandler* CCaHandlerEngine::LoadHandlerL( const TDesC& aType )
    {
    CCaHandlerPlugin* handler = NULL;
    TBuf8<KCaMaxTypeLen> type;
    type.Copy( aType );
    TEComResolverParams resolverParams;
    resolverParams.SetDataType( type );
    RImplInfoPtrArray implInfoArray;
    CleanupStack::PushL(
            TCleanupItem( ResetAndDestroyArray, &implInfoArray ) );
    REComSession::ListImplementationsL( TUid::Uid( HANDLER_IF_UID ),
            resolverParams, implInfoArray );

    __ASSERT_DEBUG( implInfoArray.Count() <= 1, User::Invariant() );

    if( implInfoArray.Count() != 0 )
        {
        TUid implUid = implInfoArray[0]->ImplementationUid();
        handler = CCaHandlerPlugin::NewL( implUid );
        CleanupStack::PushL( handler );
        // Here we check if this is the handler we need. Currently we only do
        // a sanity check for the handler (it should support the registered
        // types!), but later this can be extended with better support query.
        // E.g. support for type AND command, etc.
        if( handler->SupportsType( aType ) )
            {
            iHandlers.AppendL( handler );
            CleanupStack::Pop( handler );
            }
        else
            {
            CleanupStack::PopAndDestroy( handler );
            handler = NULL;
            }
        }

    CleanupStack::PopAndDestroy( &implInfoArray );
    return handler;
    }