diff -r 000000000000 -r c53acadfccc6 clfwrapper/ClientSrc/CCLFQueryAdapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/clfwrapper/ClientSrc/CCLFQueryAdapter.cpp Mon Jan 18 20:34:07 2010 +0200 @@ -0,0 +1,368 @@ +/* +* Copyright (c) 2006-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: QueryAdapter implementation for CLF +* +*/ + + +// Includes +#include "CCLFQueryAdapter.h" +#include "CLFConsts.h" +#include "CLFPanics.h" +#include "CLF2MdEConsts.h" +#include "CLFUtils.h" +#include +#include +#include +#include "MGDebugPrint.h" +#include "MGTracePrint.h" +#include +#include +#include +#include +#include +#include +#include + +// ======== MEMBER FUNCTIONS ======== + + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::CCLFQueryAdapter +// Default constructor +// --------------------------------------------------------------------------- +// +CCLFQueryAdapter::CCLFQueryAdapter( CMdESession& aMdESession ) + : iMdESession( aMdESession ), iDefaultNamespaceDef( NULL ) + { + // pass + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::ConstructL +// Two-phase constructor +// --------------------------------------------------------------------------- +// +void CCLFQueryAdapter::ConstructL() + { + iDefaultNamespaceDef = &iMdESession.GetDefaultNamespaceDefL(); + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::NewL +// Two-phase API constructor +// --------------------------------------------------------------------------- +// +CCLFQueryAdapter* CCLFQueryAdapter::NewL( CMdESession& aMdESession ) + { + CCLFQueryAdapter* self = new( ELeave ) CCLFQueryAdapter( aMdESession ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::~CCLFQueryAdapter +// Destructor +// --------------------------------------------------------------------------- +// +CCLFQueryAdapter::~CCLFQueryAdapter() + { + iQueryArray.Reset(); + iStatusArray.Reset(); + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::QueryMdEObjectsL +// Queries the objects based on CLF media and mime types +// --------------------------------------------------------------------------- +// +void CCLFQueryAdapter::QueryMdEObjectsL( const MDesCArray& aMimeTypeArray, + const TArray& aMediaTypeArray, + CMdEObjectQuery*& aQuery, + TRequestStatus& aStatus ) + { + // hard-coded mime types for music + const TDesC* clfwrappermusictypes[] = + { + &KCLFWrapperMusicTypeMpeg, + &KCLFWrapperMusicTypeAac, + &KCLFWrapperMusicTypeMp3, + &KCLFWrapperMusicTypeX_Mp3, + &KCLFWrapperMusicTypeMp4, + &KCLFWrapperMusicType3gpp, + &KCLFWrapperMusicTypeM4a, + &KCLFWrapperMusicType3gpp2, + &KCLFWrapperMusicTypeMpeg4, + &KCLFWrapperMusicTypeX_Pn_RealAudio, + &KCLFWrapperMusicTypeX_Ms_Wma, + }; + + CMdEObjectDef& def = iDefaultNamespaceDef->GetObjectDefL( MdeConstants::Object::KBaseObject ); + __ASSERT_DEBUG( !aQuery, User::Panic( KCLFPanicText, KErrNotReady )); + aQuery = iMdESession.NewObjectQueryL( *iDefaultNamespaceDef, def, this ); + aQuery->SetResultMode( EQueryResultModeId ); + + CMdELogicCondition& rootCondition = aQuery->Conditions(); + + if ( aMimeTypeArray.MdcaCount() > 0 ) + { + rootCondition.SetOperator( ELogicConditionOperatorOr ); + CMdEPropertyDef& propDef = def.GetPropertyDefL( MdeConstants::Object::KItemTypeProperty ); + + // Add object conditions based on mime types. + for ( TInt index( 0 ); index < aMimeTypeArray.MdcaCount(); index++ ) + { + CMdELogicCondition& logicCond = rootCondition.AddLogicConditionL( ELogicConditionOperatorOr ); + AddMimeTypeConditionL(logicCond, propDef, aMimeTypeArray.MdcaPoint( index )); + } + } + else + { + TBool music = EFalse; + TBool sounds = EFalse; + + // Add mime conditions for audio types + CMdEObjectDef* objDef = NULL; + CMdEPropertyDef* propDef = NULL; + + const TInt typeCount( aMediaTypeArray.Count() ); + + // Add object conditions based on CLF media types. + if ( typeCount > 0 ) + { + rootCondition.SetOperator( ELogicConditionOperatorOr ); + + for ( TInt index( 0 ); index < typeCount; index++ ) + { + const TDesC& type = CLFUtils::MapClfType( aMediaTypeArray[ index ] ); + if ( type != KNullDesC ) + { + CMdEObjectDef& objDef = iDefaultNamespaceDef->GetObjectDefL( type ); + if( aMediaTypeArray[ index ] == ECLFMediaTypeSound ) + { + sounds = ETrue; + } + else if( aMediaTypeArray[ index ] == ECLFMediaTypeMusic ) + { + music = ETrue; + } + else + { + rootCondition.AddObjectConditionL( objDef ); + } + } + } + if( sounds && music ) + { + CMdEObjectDef& objDef = iDefaultNamespaceDef->GetObjectDefL( CLFUtils::MapClfType( ECLFMediaTypeMusic ) ); + rootCondition.AddObjectConditionL( objDef ); + } + else if( sounds ) + { + objDef = &iDefaultNamespaceDef->GetObjectDefL( CLFUtils::MapClfType( ECLFMediaTypeSound ) ); + propDef = &objDef->GetPropertyDefL( MdeConstants::Object::KItemTypeProperty ); + CMdELogicCondition& soundCond = rootCondition.AddLogicConditionL( ELogicConditionOperatorAnd ); + + // add all necessary mime types to query conditions + const TInt num = sizeof ( clfwrappermusictypes ) / sizeof( TDesC* ); + for ( TInt i = 0; i < num; ++i ) + { + CMdELogicCondition& mimeCond = soundCond.AddLogicConditionL( ELogicConditionOperatorOr ); + mimeCond.AddPropertyConditionL( *propDef, ETextPropertyConditionCompareEquals, *clfwrappermusictypes[i] ); + mimeCond.SetNegate( ETrue ); + } + soundCond.AddObjectConditionL( *objDef ); + } + else if( music ) + { + objDef = &iDefaultNamespaceDef->GetObjectDefL( CLFUtils::MapClfType( ECLFMediaTypeMusic ) ); + propDef = &objDef->GetPropertyDefL( MdeConstants::Object::KItemTypeProperty ); + CMdELogicCondition& musicCond = rootCondition.AddLogicConditionL( ELogicConditionOperatorAnd ); + + // add all necessary mime types to query conditions + const TInt num = sizeof ( clfwrappermusictypes ) / sizeof( TDesC* ); + CMdELogicCondition& mimeCond = musicCond.AddLogicConditionL( ELogicConditionOperatorOr ); + for ( TInt i = 0; i < num; ++i ) + { + mimeCond.AddPropertyConditionL( *propDef, ETextPropertyConditionCompareEquals, *clfwrappermusictypes[i] ); + } + musicCond.AddObjectConditionL( *objDef ); + } + } + } + + aStatus = KRequestPending; + iStatusArray.Append( &aStatus ); + iQueryArray.Append( aQuery ); + + // Check that we can actually execute the query. We can if we have at least one query condition. + if ( rootCondition.Count() > 0 ) + { + MG_DEBUG1( QMO5, "[CLF]\t CCLFQueryAdapter::QueryMdEObjectsL execute query"); + aQuery->FindL(); + } + else + { + MG_DEBUG1( QMO6, "[CLF]\t CCLFQueryAdapter::QueryMdEObjectsL unknown conditions"); + CompleteRequest( *aQuery, KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::QueryMdEObjectsL +// Queries the objects based on CLF ids +// --------------------------------------------------------------------------- +// +void CCLFQueryAdapter::QueryMdEObjectsL( const TArray< TCLFItemId >& aItemIDArray, + const TDesC& aObjDefStr, + CMdEObjectQuery*& aQuery, + TRequestStatus& aStatus ) + { + CMdEObjectDef& objDef = iDefaultNamespaceDef->GetObjectDefL( aObjDefStr ); + __ASSERT_DEBUG( !aQuery, User::Panic( KCLFPanicText, KErrNotReady )); + aQuery = iMdESession.NewObjectQueryL( *iDefaultNamespaceDef, objDef, this ); + aQuery->SetResultMode( EQueryResultModeId ); + + CMdELogicCondition& rootCondition = aQuery->Conditions(); + rootCondition.SetOperator( ELogicConditionOperatorOr ); + + const TInt idCount( aItemIDArray.Count() ); + if ( idCount > 0 ) + { + RArray< TItemId > objectIds; + + // Add object conditions based on CLF ids. + for ( TInt index( 0 ); index < idCount; index++ ) + { + objectIds.Append( aItemIDArray[ index ] ); + } + CleanupClosePushL( objectIds ); + rootCondition.AddObjectConditionL( objectIds ); + CleanupStack::PopAndDestroy( &objectIds ); + } + + aStatus = KRequestPending; + iStatusArray.Append( &aStatus ); + iQueryArray.Append( aQuery ); + + // Check that we can actually execute the query. We can if we have at least one query condition. + if ( rootCondition.Count() > 0 ) + { + MG_DEBUG1( QMO4, "[CLF]\t CCLFQueryAdapter::QueryMdEObjectsL execute query" ); + aQuery->FindL(); + } + else + { + MG_DEBUG1( QMO5, "[CLF]\t CCLFQueryAdapter::QueryMdEObjectsL unknown conditions" ); + CompleteRequest( *aQuery, KErrNone ); + } + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::HandleQueryNewResults +// Called to notify the observer that new results have been received +// --------------------------------------------------------------------------- +// +#ifdef MG_ENABLE_TRACE_PRINT +void CCLFQueryAdapter::HandleQueryNewResults( CMdEQuery& /* aQuery */, + const TInt aFirstNewItemIndex, + const TInt aNewItemCount ) +#else +void CCLFQueryAdapter::HandleQueryNewResults( CMdEQuery& /* aQuery */, + const TInt /* aFirstNewItemIndex */, + const TInt /* aNewItemCount */ ) +#endif + { + MG_DEBUG3( HQN1, "[CLF]\t HandleQueryNewResults, aFirstNewItemIndex == %d, aNewItemCount == %d", + aFirstNewItemIndex, aNewItemCount ); + + /* This method could be used to receive metadata query results in batches. + * This feature is currently unimplemented. */ + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::HandleQueryCompleted +// Called to notify the observer that the query has been completed +// --------------------------------------------------------------------------- +// +void CCLFQueryAdapter::HandleQueryCompleted( CMdEQuery& aQuery, const TInt aError ) + { + MG_DEBUG2( HQC1, "[CLF]\t CCLFQueryAdapter::HandleQueryCompleted %d", aError ); + MG_DEBUG2( HQC2, "[CLF]\t aQuery.Count() returns: %d", aQuery.Count() ); + MG_DEBUG2( HQC3, "[CLF]\t Class instance %d", this ); + + CompleteRequest( aQuery, aError ); + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::CompleteRequest +// --------------------------------------------------------------------------- +// +void CCLFQueryAdapter::CompleteRequest( CMdEQuery& aQuery, const TInt aError ) + { + MG_DEBUG1( HQC4, "[CLF]\t CCLFQueryAdapter::CompleteRequest" ); + const TInt count = iQueryArray.Count(); + TInt i( 0 ); + + for ( i = 0; i < count; ++i ) + { + if ( iQueryArray[ i ] == &aQuery ) + { + User::RequestComplete( iStatusArray[ i ], aError ); + iStatusArray.Remove( i ); + iQueryArray.Remove( i ); + break; + } + } +#ifdef _DEBUG + _LIT( KCLFWQAPanicText, "HandleQueryCompleted"); + __ASSERT_DEBUG( i < count, User::Panic( KCLFWQAPanicText, KErrAbort )); +#endif + } + +// --------------------------------------------------------------------------- +// CCLFQueryAdapter::AddMimeTypeConditionL +// --------------------------------------------------------------------------- +// +void CCLFQueryAdapter::AddMimeTypeConditionL( CMdELogicCondition& aLogicCondition, + const CMdEPropertyDef& aPropDef, + const TPtrC& aMimeType ) + { + HBufC16* result = HBufC16::NewLC( aMimeType.Length() ); + TPtr16 modResult = result->Des(); + modResult.Copy( aMimeType ); + + // strip possible left asterisk + if ( modResult.Locate( '*' ) == 0 ) + { + modResult.Copy( modResult.Right( modResult.Length() - 1 )); + } + + if ( modResult.Length() > 0 ) + { + // strip possible right asterisk + if ( modResult.LocateReverse( '*' ) == modResult.Length() - 1 ) + { + modResult.Copy( modResult.Left( modResult.Length() - 1 )); + } + + // add type condition + aLogicCondition.AddPropertyConditionL( aPropDef, ETextPropertyConditionCompareContains, modResult ); + } + CleanupStack::PopAndDestroy( result ); + } + +// End of File