clfwrapper/ClientSrc/CCLFQueryAdapter.cpp
changeset 0 c53acadfccc6
child 9 82c0024438c8
--- /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