--- /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 <e32base.h>
+#include <e32std.h>
+#include <e32debug.h>
+#include "MGDebugPrint.h"
+#include "MGTracePrint.h"
+#include <mdecondition.h>
+#include <mdeconstants.h>
+#include <mdetextpropertycondition.h>
+#include <mdeobject.h>
+#include <mdeproperty.h>
+#include <mdequery.h>
+#include <mdenamespacedef.h>
+
+// ======== 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<TInt>& 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