ncdengine/provider/server/src/ncdoperationmanager.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implements CNcdOperationManager class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdoperationmanager.h"
       
    20 
       
    21 #include <e32err.h>
       
    22 #include <s32mem.h>
       
    23 
       
    24 #include "ncdbaseoperation.h"
       
    25 #include "ncdstoragemanager.h"
       
    26 #include "ncdprotocol.h"
       
    27 #include "catalogshttpsession.h"
       
    28 #include "ncdnodemanager.h"
       
    29 #include "catalogsbasemessage.h"
       
    30 #include "ncdloadnodeoperationimpl.h"
       
    31 #include "ncdloadrootnodeoperationimpl.h"
       
    32 #include "ncdloadbundlenodeoperationimpl.h"
       
    33 #include "ncdnodefunctionids.h"
       
    34 #include "ncddownloadoperationimpl.h"
       
    35 #include "ncdnodeidentifier.h"
       
    36 #include "ncdproviderdefines.h"
       
    37 #include "ncdstoragemanager.h"
       
    38 #include "ncdpurchasehistorydbimpl.h"
       
    39 #include "ncdconfigurationmanager.h"
       
    40 #include "catalogssmssession.h"
       
    41 #include "ncdpurchaseoperationimpl.h"
       
    42 #include "ncdnodeimpl.h"
       
    43 #include "ncdnodelink.h"
       
    44 #include "catalogscontext.h"
       
    45 #include "catalogshttpconfig.h"
       
    46 #include "catalogsutils.h"
       
    47 #include "ncdproviderimpl.h"
       
    48 #include "ncdinstalloperationimpl.h"
       
    49 #include "ncdchildloadmode.h"
       
    50 #include "ncdrightsobjectoperationimpl.h"
       
    51 #include "ncdutils.h"
       
    52 #include "ncdsearchoperationimpl.h"
       
    53 #include "ncdnodefolder.h"
       
    54 #include "ncdsubscriptionoperationimpl.h"
       
    55 #include "ncdsubscriptionmanagerimpl.h"
       
    56 #include "ncdcontentdownloadoperation.h"
       
    57 #include "ncdstorageclient.h"
       
    58 #include "ncdstorage.h"
       
    59 #include "ncdstorageitem.h"
       
    60 #include "ncddatabasestorage.h"
       
    61 #include "ncdnodemetadataimpl.h"
       
    62 #include "ncdreportmanager.h"
       
    63 #include "ncdcreateaccesspointoperationimpl.h"
       
    64 #include "ncdsendhttprequestoperationimpl.h"
       
    65 #include "ncdconnectionmethod.h"
       
    66 #include "ncdserverreportoperationimpl.h"
       
    67 #include "ncdoperationtype.h"
       
    68 #include "ncdnodeidentifiereditor.h"
       
    69 #include "ncderrors.h"
       
    70 #include "ncdgeneralmanager.h"
       
    71 
       
    72 #include "catalogsdebug.h"
       
    73 
       
    74 
       
    75 // Because of security issues these capabilities are set for silent install
       
    76 static _LIT_SECURITY_POLICY_C1( KSilentInstallInfoPolicy,
       
    77                                 ECapabilityTrustedUI );
       
    78 
       
    79 
       
    80 // ---------------------------------------------------------------------------
       
    81 // NewL
       
    82 // ---------------------------------------------------------------------------
       
    83 //       
       
    84 CNcdOperationManager* CNcdOperationManager::NewL( 
       
    85     CNcdProvider& aProvider,
       
    86     CNcdGeneralManager& aGeneralManager,    
       
    87     CNcdSubscriptionManager& aSubscriptionManager )
       
    88     {
       
    89     DLTRACEIN( ( "" ) );
       
    90     CNcdOperationManager* self = new( ELeave ) CNcdOperationManager(
       
    91         aProvider,
       
    92         aGeneralManager,          
       
    93         aSubscriptionManager );
       
    94         
       
    95     CleanupClosePushL( *self );
       
    96     self->ConstructL();
       
    97     CleanupStack::Pop( self );
       
    98     DLTRACEOUT( ( "" ) );
       
    99     return self;        
       
   100     }
       
   101 
       
   102 
       
   103 // ---------------------------------------------------------------------------
       
   104 // Destructor
       
   105 // ---------------------------------------------------------------------------
       
   106 //       
       
   107 CNcdOperationManager::~CNcdOperationManager()
       
   108     {
       
   109     DLTRACEIN((""));
       
   110     // Should we destroy the operations here if operations
       
   111     // exist? operations should delete themselves when the operation
       
   112     // is finished? This class may implement some interface that
       
   113     // will be used to inform the manager when operation is
       
   114     // finished...
       
   115     // Close the cache array.
       
   116     
       
   117     DLTRACE(("Closing operations"));
       
   118     
       
   119     
       
   120     for ( TInt i = 0; i < iOperationCache.Count(); ++i )
       
   121         {        
       
   122         iOperationCache[i]->Close();
       
   123         }
       
   124     
       
   125 
       
   126     DLTRACE(("Operations closed"));
       
   127     iOperationCache.Reset();
       
   128     
       
   129     iOperationQueue.Close();
       
   130 
       
   131     DLTRACEOUT((""));
       
   132     }
       
   133 
       
   134     
       
   135 // ---------------------------------------------------------------------------
       
   136 // CreateOperationL
       
   137 // ---------------------------------------------------------------------------
       
   138 //       
       
   139 void CNcdOperationManager::CreateLoadNodeOperationRequestL(
       
   140     MCatalogsBaseMessage& aMessage )
       
   141     {
       
   142         
       
   143     DLTRACEIN((""));
       
   144 
       
   145     // Get the session that will contain the handle of the node
       
   146     MCatalogsSession& requestSession( aMessage.Session() );
       
   147 
       
   148     DLTRACE(("create buffer"));
       
   149 
       
   150     RBuf8 buf;
       
   151     buf.CreateL( aMessage.InputLength() );
       
   152     DLINFO(("input length=%d",aMessage.InputLength()));
       
   153     CleanupClosePushL( buf );
       
   154     User::LeaveIfError( aMessage.ReadInput( buf ) );
       
   155     
       
   156     
       
   157     RDesReadStream stream( buf );
       
   158     CleanupReleasePushL( stream );
       
   159 
       
   160     DLTRACE(("get buffer data"));
       
   161     
       
   162     // Create node identifier from the stream    
       
   163     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( 
       
   164         stream );
       
   165         
       
   166     if( ParallelOperationExistsForMetadataL( *identifier, aMessage.Session().Context() ) )
       
   167         {
       
   168         // Multiple simultaneous operations per one node are not supported, leave.
       
   169         User::Leave( KNcdErrorParallelOperationNotAllowed );
       
   170         }
       
   171         
       
   172     DLTRACE(("get load children flag"));
       
   173     TBool loadChildren = stream.ReadInt32L();
       
   174     DLTRACE(("get pageSize"));
       
   175     TInt pageSize = stream.ReadInt32L();
       
   176     DLTRACE(("get pageStart"));
       
   177     TInt pageStart = stream.ReadInt32L();
       
   178     DLTRACE(("get depth"));
       
   179     TInt depth = stream.ReadInt32L();
       
   180     DLTRACE(("get mode"));
       
   181     TNcdChildLoadMode mode = static_cast<TNcdChildLoadMode>(stream.ReadInt32L());
       
   182     DLTRACE(("get search flag"));
       
   183     TBool search = stream.ReadInt32L();
       
   184     CNcdSearchFilter* filter = NULL;
       
   185     if ( search )
       
   186         {
       
   187         DLTRACE(("get search filter"));
       
   188         filter = CNcdSearchFilter::NewLC();
       
   189         filter->SetContentPurposes( stream.ReadUint32L() );
       
   190         TInt keywordCount = stream.ReadInt32L();
       
   191         for ( TInt i = 0 ; i < keywordCount ; i++ )
       
   192             {
       
   193             HBufC* keyword = NULL;
       
   194             InternalizeDesL( keyword, stream );
       
   195             CleanupStack::PushL( keyword );
       
   196             filter->AddKeywordL( *keyword );
       
   197             CleanupStack::PopAndDestroy( keyword );
       
   198             }
       
   199         MNcdSearchFilter::TSearchMode mode;
       
   200         InternalizeEnumL( mode, stream );
       
   201         filter->SetSearchMode( mode );
       
   202         filter->SetRecursionDepthL( stream.ReadUint32L() );
       
   203         }
       
   204     
       
   205     DLTRACE(( _L("id, size, start, depth: %S, %d, %d, %d"),
       
   206               &identifier->NodeId(), pageSize, pageStart, depth ));
       
   207     
       
   208     
       
   209     CNcdNode& node = iNodeManager.NodeL( *identifier );
       
   210 
       
   211     DLTRACE(( _L("node found: %X"), &node ));
       
   212     
       
   213     TNcdResponseFilterParams filterParams;
       
   214     filterParams.iPageSize = pageSize;
       
   215     filterParams.iPageStart = pageStart;
       
   216     filterParams.iStructureDepth = depth;
       
   217     filterParams.iMetadataDepth = depth;
       
   218     filterParams.iMetadataPerLevel = pageSize;
       
   219                      
       
   220     // create the operation
       
   221     
       
   222     CNcdLoadNodeOperationImpl* operation = NULL;
       
   223     if( search )
       
   224         {
       
   225         DLTRACE(("Create search op"));
       
   226         const CNcdNodeIdentifier* parentId = NULL;
       
   227         if ( node.ClassId() == NcdNodeClassIds::ENcdSearchItemNodeClassId ||
       
   228             node.ClassId() == NcdNodeClassIds::ENcdSearchFolderNodeClassId ||
       
   229             node.ClassId() == NcdNodeClassIds::ENcdSearchRootNodeClassId ||
       
   230             node.ClassId() == NcdNodeClassIds::ENcdSearchBundleNodeClassId )
       
   231             {
       
   232             DLTRACE(("search folder, use node's own parent"));
       
   233             parentId = &node.CreateAndSetLinkL().ParentIdentifier();
       
   234             }
       
   235         else
       
   236             {
       
   237             DLTRACE(("not a search folder, set search root as parent"));
       
   238             parentId = 
       
   239                 &iNodeManager.CreateSearchRootL(aMessage.Session().Context()).Identifier();
       
   240             }
       
   241         // create op
       
   242         operation = CNcdSearchOperation::NewL(
       
   243             *identifier,
       
   244             *parentId,
       
   245             *filter,
       
   246             filterParams,
       
   247             iGeneralManager, 
       
   248             HttpSessionL( aMessage.Session().Context() ), 
       
   249             this, this, aMessage.Session(), loadChildren, mode,
       
   250             filter->RecursionDepth() );
       
   251         }
       
   252     else
       
   253         {
       
   254         DLTRACE(("Create load op"));
       
   255         CNcdNodeFactory::TNcdNodePurpose parentPurpose = CNcdNodeFactory::ENcdNormalNode;
       
   256         if ( !node.NodeLinkL().ParentIdentifier().ContainsEmptyFields() ) 
       
   257             {
       
   258             CNcdNode* parentNode = iNodeManager.NodePtrL( node.NodeLinkL().ParentIdentifier() );
       
   259             if ( parentNode )
       
   260                 {                
       
   261                 parentPurpose = CNcdNodeFactory::NodePurposeL( *parentNode );
       
   262                 }
       
   263             }
       
   264         operation = CNcdLoadNodeOperationImpl::NewL(
       
   265             *identifier,
       
   266             node.NodeLinkL().ParentIdentifier(),
       
   267             parentPurpose,
       
   268             filterParams,
       
   269             iGeneralManager, 
       
   270             HttpSessionL( aMessage.Session().Context() ), 
       
   271             this, this, aMessage.Session(), loadChildren, mode, EFalse, EFalse );
       
   272         }
       
   273 
       
   274     DLTRACE(( _L("operation created: %X"), operation ));
       
   275     if( filter )
       
   276         {
       
   277         CleanupStack::PopAndDestroy( filter );
       
   278         }
       
   279     CleanupStack::PopAndDestroy( identifier );
       
   280     CleanupStack::PopAndDestroy( &stream );
       
   281     CleanupStack::PopAndDestroy( &buf );
       
   282     
       
   283     
       
   284     CleanupStack::PushL( operation );
       
   285     // Add the operation to the session and get the handle.
       
   286     // If the operation already existed in the session we will still
       
   287     // get a new handle to the same object.
       
   288     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   289     operation->SetHandle( operationHandle );
       
   290     
       
   291     // AddObjectL adds reference count by 1
       
   292     operation->Close();
       
   293     DLTRACE(("operation handle: %d", operationHandle ));
       
   294 
       
   295     // Because we created a new operation, it should be added to the
       
   296     // cache. 
       
   297     iOperationCache.AppendL( operation );
       
   298     CleanupStack::Pop( operation );    
       
   299     
       
   300     // Send the information to the client side
       
   301     TRAPD( error, 
       
   302            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   303     if( error != KErrNone )
       
   304         {        
       
   305         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   306         // Is this ok?
       
   307         User::Leave( error );
       
   308         }
       
   309     }
       
   310     
       
   311 // ---------------------------------------------------------------------------
       
   312 // CreateOperationL
       
   313 // ---------------------------------------------------------------------------
       
   314 //       
       
   315 void CNcdOperationManager::CreateLoadRootNodeOperationRequestL(
       
   316     MCatalogsBaseMessage& aMessage )
       
   317     {
       
   318         
       
   319     DLTRACEIN((""));
       
   320 
       
   321     // Get the session that will contain the handle of the node
       
   322     MCatalogsSession& requestSession( aMessage.Session() );
       
   323 
       
   324     
       
   325     RBuf8 nodeIdentifierData;
       
   326     nodeIdentifierData.CreateL( aMessage.InputLength() );
       
   327     CleanupClosePushL( nodeIdentifierData );
       
   328     User::LeaveIfError( aMessage.ReadInput( nodeIdentifierData ) );
       
   329 
       
   330     // Create node identifier from the stream    
       
   331     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( 
       
   332         nodeIdentifierData );
       
   333             
       
   334     if( ParallelOperationExistsForMetadataL( *identifier, aMessage.Session().Context(),
       
   335             ETrue ) )
       
   336         {
       
   337         // Multiple simultaneous operations per one node are not supported, leave.
       
   338         User::Leave( KNcdErrorParallelOperationNotAllowed );
       
   339         }
       
   340         
       
   341     // create the operation
       
   342     CNcdLoadRootNodeOperation* operation = CNcdLoadRootNodeOperation::NewL(
       
   343         aMessage.Session().Context().FamilyId().iUid, 
       
   344         iGeneralManager, 
       
   345 		HttpSessionL( aMessage.Session().Context() ), 
       
   346 		this, 
       
   347 		aMessage.Session() );
       
   348     CleanupStack::PopAndDestroy( identifier );
       
   349     CleanupStack::PopAndDestroy( &nodeIdentifierData );
       
   350     
       
   351     CleanupStack::PushL( operation );
       
   352     // Add the operation to the session and get the handle.
       
   353     // If the operation already existed in the session we will still
       
   354     // get a new handle to the same object.
       
   355     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   356     
       
   357     operation->SetHandle( operationHandle );
       
   358     
       
   359     operation->Close();
       
   360     DLTRACE(("operation handle: %d", operationHandle ));
       
   361 
       
   362     // Because we created a new operation, it should be added to the
       
   363     // cache. 
       
   364     iOperationCache.AppendL( operation );
       
   365     CleanupStack::Pop( operation );    
       
   366     
       
   367     // Send the information to the client side
       
   368     TRAPD( error, 
       
   369            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   370     if( error != KErrNone )
       
   371         {        
       
   372         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   373         }
       
   374     } 
       
   375 
       
   376 
       
   377 // ---------------------------------------------------------------------------
       
   378 // CreateLoadBundleNodeOperationRequestL
       
   379 // ---------------------------------------------------------------------------
       
   380 //       
       
   381 void CNcdOperationManager::CreateLoadBundleNodeOperationRequestL(
       
   382     MCatalogsBaseMessage& aMessage )
       
   383     {
       
   384         
       
   385     DLTRACEIN((""));
       
   386 
       
   387     // Get the session that will contain the handle of the node
       
   388     MCatalogsSession& requestSession( aMessage.Session() );
       
   389 
       
   390     RBuf8 nodeIdentifierData;
       
   391     nodeIdentifierData.CreateL( aMessage.InputLength() );
       
   392     CleanupClosePushL( nodeIdentifierData );
       
   393     User::LeaveIfError( aMessage.ReadInput( nodeIdentifierData ) );
       
   394 
       
   395     // Create node identifier from the stream    
       
   396     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( 
       
   397         nodeIdentifierData );
       
   398         
       
   399     if( ParallelOperationExistsForMetadataL( *identifier, aMessage.Session().Context() ) )
       
   400         {
       
   401         // Multiple simultaneous operations per one node are not supported, leave.
       
   402         User::Leave( KNcdErrorParallelOperationNotAllowed );
       
   403         }
       
   404     
       
   405     // create the operation    
       
   406     CNcdLoadBundleNodeOperation* operation = CNcdLoadBundleNodeOperation::NewL(
       
   407         *identifier, 
       
   408         iGeneralManager, 
       
   409 		HttpSessionL( aMessage.Session().Context() ), 
       
   410 		this, 
       
   411 		*this, 
       
   412 		aMessage.Session() );
       
   413     CleanupStack::PopAndDestroy( identifier );
       
   414     CleanupStack::PopAndDestroy( &nodeIdentifierData );
       
   415     
       
   416     CleanupStack::PushL( operation );
       
   417     // Add the operation to the session and get the handle.
       
   418     // If the operation already existed in the session we will still
       
   419     // get a new handle to the same object.
       
   420     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   421     
       
   422     operation->SetHandle( operationHandle );
       
   423     
       
   424     operation->Close();
       
   425     DLTRACE(("operation handle: %d", operationHandle ));
       
   426 
       
   427     // Because we created a new operation, it should be added to the
       
   428     // cache. 
       
   429     iOperationCache.AppendL( operation );
       
   430     CleanupStack::Pop( operation );    
       
   431     
       
   432     // Send the information to the client side
       
   433     TRAPD( error, 
       
   434            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   435     if( error != KErrNone )
       
   436         {        
       
   437         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   438         }
       
   439     } 
       
   440     
       
   441 // ---------------------------------------------------------------------------
       
   442 // CreateDownloadOperationL
       
   443 // ---------------------------------------------------------------------------
       
   444 //       
       
   445 void CNcdOperationManager::CreateDownloadOperationRequestL(
       
   446     MCatalogsBaseMessage& aMessage )
       
   447     {
       
   448     
       
   449     DLTRACEIN((""));
       
   450 
       
   451     RCatalogsMessageReader reader;
       
   452     reader.OpenLC( aMessage );
       
   453         
       
   454     // Read operation type    
       
   455     TNcdDownloadDataType type = static_cast<TNcdDownloadDataType>( 
       
   456         reader().ReadInt32L() );
       
   457 
       
   458     DLINFO(( "Operation type: %d", type ));
       
   459     // Create node identifier from the stream    
       
   460     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( 
       
   461         reader() );
       
   462     
       
   463     if( ParallelOperationExistsForMetadataL( *identifier, aMessage.Session().Context(),
       
   464         type == ENcdGenericFileDownload ) )
       
   465         {
       
   466         // Multiple simultaneous operations per one node are not supported, leave.
       
   467         User::Leave( KNcdErrorParallelOperationNotAllowed );
       
   468         }
       
   469   
       
   470     DLINFO(( _L("NodeId: %S::%S"), &identifier->NodeNameSpace(),
       
   471         &identifier->NodeId() ));
       
   472   
       
   473     // Read download index
       
   474     TInt downloadIndex = reader().ReadInt32L();
       
   475     DLINFO(( "Download index: %d", downloadIndex ));
       
   476     
       
   477     // Check if the download already exists, completes the message
       
   478     // if it does
       
   479     if ( DownloadExistsL( aMessage, *identifier, type, downloadIndex ) )
       
   480         {
       
   481         DLTRACE(("Download already exists"));
       
   482         CleanupStack::PopAndDestroy( 2, &reader ); // identifier, reader
       
   483         return;        
       
   484         }
       
   485     
       
   486     CleanupStack::Pop( identifier );
       
   487     CleanupStack::PopAndDestroy( &reader ); // reader
       
   488     CleanupStack::PushL( identifier );
       
   489     
       
   490     // Get current context
       
   491     MCatalogsContext& context( aMessage.Session().Context() );
       
   492   
       
   493     HBufC* clientUid = context.FamilyId().Name().AllocLC();    
       
   494   
       
   495     MNcdStorageClient* storageClient = NULL;
       
   496     // Generic file download doesn't use storage
       
   497     if ( type != ENcdGenericFileDownload ) 
       
   498         {
       
   499         
       
   500         // Quick fix: ensures that StorageManager has the client
       
   501         MNcdStorage* storage = StorageL( *clientUid, 
       
   502             identifier->NodeNameSpace() );
       
   503         
       
   504         // Find the correct storage for the client
       
   505         storageClient = 
       
   506             &iStorageManager.StorageClientL( *clientUid );
       
   507         }
       
   508         
       
   509     
       
   510     DLTRACE(("Creating the download operation"));
       
   511     
       
   512     // Try to get session handler
       
   513     MNcdSessionHandler* sessionHandler = NULL;
       
   514     TRAP_IGNORE(       
       
   515         sessionHandler = &iProtocolHandler.SessionHandlerL( context ) );
       
   516     
       
   517     CNcdBaseOperation* operation = NULL;
       
   518     if ( type != ENcdContentDownload ) 
       
   519         {        
       
   520         // Create operation according to it's type
       
   521         operation = CNcdDownloadOperation::NewL(
       
   522             *this,
       
   523             type,
       
   524             *identifier, 
       
   525             iGeneralManager,         
       
   526             HttpSessionL( context ),
       
   527             sessionHandler,
       
   528             storageClient,
       
   529             context.FamilyId(),
       
   530             downloadIndex,
       
   531             aMessage.Session() );
       
   532         }
       
   533     else
       
   534         {
       
   535         MNcdStorage* dlStorage = StorageL( *clientUid, 
       
   536             NcdProviderDefines::KDownloadNamespace );
       
   537         
       
   538         // Create operation according to it's type
       
   539         operation = CNcdContentDownloadOperation::NewL(
       
   540             *this,
       
   541             *identifier, 
       
   542             iGeneralManager,         
       
   543             HttpSessionL( context ),
       
   544             ReportManagerL( context ),
       
   545             sessionHandler,
       
   546             dlStorage->DatabaseStorageL( 
       
   547                 NcdProviderDefines::KDefaultDatabaseUid ),
       
   548             aMessage.Session(),
       
   549             downloadIndex );
       
   550         }
       
   551     DLTRACE(("Download operation created"));
       
   552     CleanupStack::PopAndDestroy( clientUid );
       
   553     CleanupStack::PopAndDestroy( identifier );    
       
   554     CleanupStack::PushL( operation );
       
   555     
       
   556     // Get the session that will contain the handle of the node
       
   557     MCatalogsSession& requestSession( aMessage.Session() );    
       
   558     
       
   559     // Add the operation to the session and get the handle.
       
   560     // If the operation already existed in the session we will still
       
   561     // get a new handle to the same object.
       
   562     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   563     operation->SetHandle( operationHandle );
       
   564     operation->Close();
       
   565     DLTRACE(("operation handle: %d", operationHandle ));
       
   566 
       
   567     // Because we created a new operation, it should be added to the
       
   568     // cache. 
       
   569     iOperationCache.AppendL( operation );
       
   570     CleanupStack::Pop( operation );    
       
   571     
       
   572     // Send the information to the client side
       
   573     TRAPD( error, 
       
   574            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   575     if( error != KErrNone )
       
   576         {        
       
   577         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   578         }
       
   579     DLTRACEOUT((""));
       
   580     }
       
   581     
       
   582 
       
   583 
       
   584 // ---------------------------------------------------------------------------
       
   585 // CreatePurchaseOperationL
       
   586 // ---------------------------------------------------------------------------
       
   587 //       
       
   588 void CNcdOperationManager::CreatePurchaseOperationRequestL(
       
   589     MCatalogsBaseMessage& aMessage )
       
   590     {
       
   591     DLTRACEIN((""));
       
   592 
       
   593     // Get the session that will contain the handle of the node
       
   594     MCatalogsSession& requestSession( aMessage.Session() );
       
   595 
       
   596     // Should use 8 bit version when client-server session supports it
       
   597     RBuf8 buf;
       
   598     buf.CreateL( aMessage.InputLength() );
       
   599     DLINFO(("input length=%d",aMessage.InputLength()));
       
   600     CleanupClosePushL( buf );
       
   601     User::LeaveIfError( aMessage.ReadInput( buf ) );
       
   602 
       
   603     RDesReadStream stream( buf );
       
   604 
       
   605     CleanupReleasePushL( stream );
       
   606 
       
   607     // Create node identifier from the stream    
       
   608     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( 
       
   609         stream );
       
   610     
       
   611     if( ParallelOperationExistsForMetadataL( *identifier, aMessage.Session().Context() ) )
       
   612         {
       
   613         // Multiple simultaneous operations per one node are not supported, leave.
       
   614         User::Leave( KNcdErrorParallelOperationNotAllowed );
       
   615         }
       
   616 
       
   617     HBufC* purchaseOptionId = NULL;
       
   618     TInt length = InternalizeDesL( purchaseOptionId, stream );
       
   619     CleanupStack::PushL( purchaseOptionId );
       
   620    
       
   621     if( length < 1 )
       
   622         {
       
   623         User::Leave( KErrArgument );
       
   624         }
       
   625 
       
   626     // create the operation
       
   627     CNcdPurchaseOperationImpl* operation = CNcdPurchaseOperationImpl::NewL(
       
   628         identifier->NodeNameSpace(), 
       
   629         identifier->NodeId(),
       
   630         identifier->ClientUid(),
       
   631         *purchaseOptionId,
       
   632         iGeneralManager, 
       
   633         HttpSessionL( aMessage.Session().Context() ),
       
   634         SmsSessionL( aMessage.Session().Context() ),
       
   635         iSubscriptionManager,
       
   636         this,
       
   637         aMessage.Session() );
       
   638 
       
   639     
       
   640     CleanupStack::PopAndDestroy( purchaseOptionId );
       
   641     CleanupStack::PopAndDestroy( identifier );
       
   642     CleanupStack::PopAndDestroy( &stream );
       
   643     CleanupStack::PopAndDestroy( &buf );
       
   644 
       
   645 
       
   646     CleanupStack::PushL( operation );
       
   647     // Add the operation to the session and get the handle.
       
   648     // If the operation already existed in the session we will still
       
   649     // get a new handle to the same object.
       
   650     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   651     operation->SetHandle( operationHandle );
       
   652     
       
   653     // AddObjectL adds reference count by 1
       
   654     operation->Close();
       
   655 
       
   656     DLTRACE(("operation handle: %d", operationHandle ));
       
   657 
       
   658     // Because we created a new operation, it should be added to the
       
   659     // cache. 
       
   660     iOperationCache.AppendL( operation );
       
   661     CleanupStack::Pop( operation );    
       
   662 
       
   663     // Send the information to the client side
       
   664     TRAPD( error, 
       
   665            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   666     if( error != KErrNone )
       
   667         {        
       
   668         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   669         }
       
   670     }
       
   671 
       
   672 
       
   673 
       
   674 // ---------------------------------------------------------------------------
       
   675 // Create install operation
       
   676 // ---------------------------------------------------------------------------
       
   677 //       
       
   678 void CNcdOperationManager::CreateInstallOperationRequestL(
       
   679     MCatalogsBaseMessage& aMessage )
       
   680     {        
       
   681     DLTRACEIN((""));
       
   682 
       
   683     // Get the session that will contain the handle of the node
       
   684     MCatalogsSession& requestSession( aMessage.Session() );
       
   685 
       
   686     
       
   687     RBuf8 nodeIdentifierData;
       
   688     nodeIdentifierData.CreateL( aMessage.InputLength() );
       
   689     CleanupClosePushL( nodeIdentifierData );
       
   690     User::LeaveIfError( aMessage.ReadInput( nodeIdentifierData ) );
       
   691 
       
   692     // Create node identifier from the stream    
       
   693     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( 
       
   694         nodeIdentifierData );
       
   695     
       
   696     if( ParallelOperationExistsForMetadataL( *identifier, aMessage.Session().Context() ) )
       
   697         {
       
   698         // Multiple simultaneous operations per one node are not supported, leave.
       
   699         User::Leave( KNcdErrorParallelOperationNotAllowed );
       
   700         }            
       
   701     
       
   702     // create the operation
       
   703     MCatalogsContext& context( requestSession.Context() );
       
   704     CNcdInstallOperation* operation = CNcdInstallOperation::NewL(
       
   705         *this,
       
   706         *identifier,
       
   707         iGeneralManager,
       
   708         HttpSessionL( context ),        
       
   709         ReportManagerL( context ),
       
   710         aMessage.Session() );
       
   711 
       
   712     CleanupStack::PopAndDestroy( identifier );
       
   713     CleanupStack::PopAndDestroy( &nodeIdentifierData );
       
   714     
       
   715     
       
   716     CleanupStack::PushL( operation );
       
   717     // Add the operation to the session and get the handle.
       
   718     // If the operation already existed in the session we will still
       
   719     // get a new handle to the same object.
       
   720     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   721     operation->SetHandle( operationHandle );
       
   722     
       
   723     // AddObjectL adds reference count by 1
       
   724     operation->Close();
       
   725 
       
   726     DLTRACE(("operation handle: %d", operationHandle ));
       
   727 
       
   728     // Because we created a new operation, it should be added to the
       
   729     // cache. 
       
   730     iOperationCache.AppendL( operation );
       
   731     CleanupStack::Pop( operation );    
       
   732     
       
   733     // Send the information to the client side
       
   734     TRAPD( error, 
       
   735            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   736     if( error != KErrNone )
       
   737         {        
       
   738         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   739         }
       
   740     DLTRACEOUT((""));
       
   741     }
       
   742 
       
   743 
       
   744 // ---------------------------------------------------------------------------
       
   745 // Create silent install operation
       
   746 // ---------------------------------------------------------------------------
       
   747 //       
       
   748 void CNcdOperationManager::CreateSilentInstallOperationRequestL(
       
   749     MCatalogsBaseMessage& aMessage )
       
   750     {        
       
   751     DLTRACEIN((""));
       
   752 
       
   753     if ( !aMessage.CheckSecurityPolicy( KSilentInstallInfoPolicy() ) )
       
   754         {
       
   755         DLTRACE(("Not enough capabilities for silent install"));
       
   756         User::Leave( KErrPermissionDenied );
       
   757         }
       
   758 
       
   759     // If there are enough capabilities, then just create a normal
       
   760     // install operation
       
   761     CreateInstallOperationRequestL( aMessage );
       
   762 
       
   763     DLTRACEOUT((""));
       
   764     }
       
   765 
       
   766 
       
   767 
       
   768 // ---------------------------------------------------------------------------
       
   769 // Create rights object download and install operation
       
   770 // ---------------------------------------------------------------------------
       
   771 //       
       
   772 void CNcdOperationManager::CreateRightsObjectOperationRequestL(
       
   773     MCatalogsBaseMessage& aMessage )
       
   774     {        
       
   775     DCHECK_CSTACK;
       
   776     DLTRACEIN((""));
       
   777 
       
   778     // Read input data buffer
       
   779     RBuf8 buf;
       
   780     buf.CreateL( aMessage.InputLength() );
       
   781     DLINFO(("input length=%d",aMessage.InputLength()));
       
   782     CleanupClosePushL( buf );
       
   783     User::LeaveIfError( aMessage.ReadInput( buf ) );
       
   784 
       
   785     // Create a stream for reading out of the buffer
       
   786     RDesReadStream stream( buf );
       
   787     CleanupClosePushL( stream );
       
   788 
       
   789     // Read uri
       
   790     HBufC* downloadUri = NULL;
       
   791     InternalizeDesL( downloadUri, stream );
       
   792     CleanupStack::PushL( downloadUri );
       
   793     DLINFO((_L("Uri %S"), downloadUri ));
       
   794 
       
   795     // Read mime type
       
   796     HBufC* mimeType = NULL;
       
   797     InternalizeDesL( mimeType, stream );
       
   798     CleanupStack::PushL( mimeType );
       
   799     DLINFO((_L("Mime type %S"), mimeType ));
       
   800 
       
   801     // Read access point id
       
   802     TNcdConnectionMethod method;
       
   803     method.InternalizeL( stream );
       
   804 
       
   805     // Get the session that will contain the handle of the node
       
   806     MCatalogsSession& requestSession( aMessage.Session() );
       
   807 
       
   808     // create the operation
       
   809     CNcdRightsObjectOperation* operation = CNcdRightsObjectOperation::NewL(
       
   810         iGeneralManager,
       
   811         *downloadUri,
       
   812         *mimeType,
       
   813         method,
       
   814         *this,
       
   815         HttpSessionL( aMessage.Session().Context() ),
       
   816         aMessage.Session() );
       
   817     CleanupStack::PushL( operation );
       
   818 
       
   819     // Add the operation to the session and get the handle.
       
   820     // If the operation already existed in the session we will still
       
   821     // get a new handle to the same object.
       
   822     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   823 
       
   824     operation->SetHandle( operationHandle );
       
   825     
       
   826     // AddObjectL adds reference count by 1
       
   827     operation->Close();
       
   828 
       
   829     DLINFO(("operation handle: %d", operationHandle ));
       
   830 
       
   831     // Because we created a new operation, it should be added to the
       
   832     // cache. 
       
   833     iOperationCache.AppendL( operation );
       
   834     CleanupStack::Pop( operation );
       
   835     
       
   836     // Send the information to the client side
       
   837     TRAPD( error,
       
   838            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   839 
       
   840     if( error != KErrNone )
       
   841         {        
       
   842         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   843         }
       
   844 
       
   845     CleanupStack::PopAndDestroy( 4 ); // mimeType, downloadUri, stream-close, buf-close
       
   846 
       
   847     DLTRACEOUT((""));
       
   848     }
       
   849 
       
   850 
       
   851 // ---------------------------------------------------------------------------
       
   852 // Create subscription operation
       
   853 // ---------------------------------------------------------------------------
       
   854 //       
       
   855 void CNcdOperationManager::CreateSubscriptionOperationRequestL(
       
   856     MCatalogsBaseMessage& aMessage )
       
   857     {
       
   858     DLTRACEIN((""));
       
   859 
       
   860     // Get the session that will contain the handle of the node
       
   861     MCatalogsSession& requestSession( aMessage.Session() );
       
   862 
       
   863     DLTRACE(("create buffer"));
       
   864 
       
   865     RBuf8 buf;
       
   866     buf.CreateL( aMessage.InputLength() );
       
   867     DLINFO(( "input length=%d", aMessage.InputLength() ));
       
   868     CleanupClosePushL( buf );
       
   869     User::LeaveIfError( aMessage.ReadInput( buf ) );
       
   870     
       
   871     RDesReadStream stream( buf );
       
   872     CleanupReleasePushL( stream );
       
   873 
       
   874     DLTRACE(("get buffer data"));
       
   875     
       
   876     MNcdSubscriptionOperation::TType subscriptionOperationType =
       
   877         (MNcdSubscriptionOperation::TType)stream.ReadInt32L();
       
   878 
       
   879     CNcdSubscriptionOperation* operation( NULL );
       
   880 
       
   881     switch ( subscriptionOperationType )
       
   882         {            
       
   883         case MNcdSubscriptionOperation::EUnsubscribe:
       
   884             {
       
   885     
       
   886             DLINFO(( "-> EUnsubscribe" ));
       
   887 
       
   888             HBufC* subscriptionPurchaseOptionId( NULL );
       
   889             HBufC* subscriptionEntityId( NULL );
       
   890             HBufC* subscriptionNamespace( NULL );
       
   891             HBufC* subscriptionServerUri( NULL );
       
   892 
       
   893             InternalizeDesL( subscriptionPurchaseOptionId, stream );
       
   894             CleanupStack::PushL( subscriptionPurchaseOptionId );
       
   895 
       
   896             InternalizeDesL( subscriptionEntityId, stream );
       
   897             CleanupStack::PushL( subscriptionEntityId );
       
   898 
       
   899             InternalizeDesL( subscriptionNamespace, stream );
       
   900             CleanupStack::PushL( subscriptionNamespace );
       
   901 
       
   902             InternalizeDesL( subscriptionServerUri, stream );
       
   903             CleanupStack::PushL( subscriptionServerUri );
       
   904             
       
   905             operation =
       
   906                 CNcdSubscriptionOperation::NewL(
       
   907                     MNcdSubscriptionOperation::EUnsubscribe,
       
   908                     *subscriptionPurchaseOptionId,
       
   909                     *subscriptionEntityId,
       
   910                     *subscriptionNamespace,
       
   911                     *subscriptionServerUri,
       
   912                     iGeneralManager,
       
   913                     iSubscriptionManager,
       
   914                     HttpSessionL( aMessage.Session().Context() ),
       
   915                     *this,
       
   916                     requestSession );
       
   917             
       
   918             CleanupStack::PopAndDestroy( subscriptionServerUri );
       
   919             CleanupStack::PopAndDestroy( subscriptionNamespace );
       
   920             CleanupStack::PopAndDestroy( subscriptionEntityId );
       
   921             CleanupStack::PopAndDestroy( subscriptionPurchaseOptionId );
       
   922 
       
   923             break;
       
   924             }
       
   925 
       
   926         case MNcdSubscriptionOperation::ERefreshSubscriptions:
       
   927             {
       
   928             DLINFO(( "-> ERefreshSubscriptions" ));
       
   929 
       
   930             operation =
       
   931                 CNcdSubscriptionOperation::NewL(
       
   932                     MNcdSubscriptionOperation::ERefreshSubscriptions,
       
   933                     iGeneralManager,
       
   934                     iSubscriptionManager,
       
   935                     HttpSessionL( aMessage.Session().Context() ),
       
   936                     *this,
       
   937                     requestSession );
       
   938 
       
   939             break;
       
   940             }
       
   941 
       
   942         default:
       
   943             {            
       
   944             User::Leave( KErrNotSupported );
       
   945 
       
   946             break;
       
   947             }
       
   948         }
       
   949 
       
   950     CleanupStack::PopAndDestroy( &stream );
       
   951     CleanupStack::PopAndDestroy( &buf );
       
   952 
       
   953     CleanupClosePushL( *operation );
       
   954 
       
   955     DLTRACE(( _L("operation created: %X"), operation ));
       
   956     
       
   957     // Add the operation to the session and get the handle.
       
   958     // If the operation already existed in the session we will still
       
   959     // get a new handle to the same object.
       
   960     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
   961     operation->SetHandle( operationHandle );
       
   962     
       
   963     // AddObjectL adds reference count by 1
       
   964     operation->Close();
       
   965     DLTRACE(( "operation handle: %d", operationHandle ));
       
   966 
       
   967     // Because we created a new operation, it should be added to the
       
   968     // cache. 
       
   969     iOperationCache.AppendL( operation );
       
   970     CleanupStack::Pop( operation );    
       
   971     
       
   972     // Send the information to the client side
       
   973     TRAPD( error, aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
   974     if( error != KErrNone )
       
   975         {        
       
   976         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
   977         // Is this ok?
       
   978         User::Leave( error );
       
   979         }
       
   980     }
       
   981 
       
   982 
       
   983 // ---------------------------------------------------------------------------
       
   984 // Create access point creation operation
       
   985 // ---------------------------------------------------------------------------
       
   986 //       
       
   987 void CNcdOperationManager::CreateCreateAccessPointOperationRequestL(
       
   988     MCatalogsBaseMessage& aMessage )
       
   989     {            
       
   990     DLTRACEIN((""));
       
   991 
       
   992     RCatalogsMessageReader reader;
       
   993     reader.OpenLC( aMessage );
       
   994 
       
   995     HBufC* accessPointData = NULL;
       
   996     InternalizeDesL( accessPointData, reader() );
       
   997 
       
   998     CleanupStack::PopAndDestroy( &reader );
       
   999     CleanupStack::PushL( accessPointData );
       
  1000     
       
  1001     DLINFO((_L("Data: %S"), accessPointData ));
       
  1002 
       
  1003     // create the operation
       
  1004     // Note that ownership of accessPointData is transferred
       
  1005     CNcdCreateAccessPointOperation* operation = CNcdCreateAccessPointOperation::NewL(
       
  1006         accessPointData,
       
  1007         *this,
       
  1008         iGeneralManager,
       
  1009         aMessage.Session() );
       
  1010     CleanupStack::Pop( accessPointData );
       
  1011     CleanupStack::PushL( operation );
       
  1012 
       
  1013     // Get the session that will contain the handle of the node
       
  1014     MCatalogsSession& requestSession( aMessage.Session() );
       
  1015 
       
  1016     // Add the operation to the session and get the handle.
       
  1017     // If the operation already existed in the session we will still
       
  1018     // get a new handle to the same object.
       
  1019     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
  1020 
       
  1021     operation->SetHandle( operationHandle );
       
  1022     
       
  1023     // AddObjectL adds reference count by 1
       
  1024     operation->Close();
       
  1025 
       
  1026     DLINFO(("operation handle: %d", operationHandle ));
       
  1027 
       
  1028     // Because we created a new operation, it should be added to the
       
  1029     // cache. 
       
  1030     iOperationCache.AppendL( operation );
       
  1031     CleanupStack::Pop( operation );
       
  1032     
       
  1033     // Send the information to the client side
       
  1034     TRAPD( error,
       
  1035            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
  1036 
       
  1037     if( error != KErrNone )
       
  1038         {        
       
  1039         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
  1040         }
       
  1041 
       
  1042     DLTRACEOUT((""));
       
  1043     }
       
  1044 
       
  1045 
       
  1046 
       
  1047 // ---------------------------------------------------------------------------
       
  1048 // Send HTTP request operation
       
  1049 // ---------------------------------------------------------------------------
       
  1050 //       
       
  1051 void CNcdOperationManager::CreateSendHttpRequestOperationRequestL(
       
  1052     MCatalogsBaseMessage& aMessage )
       
  1053     {
       
  1054     DLTRACEIN((""));
       
  1055 
       
  1056     RCatalogsMessageReader reader;
       
  1057     reader.OpenLC( aMessage );
       
  1058 
       
  1059     TNcdConnectionMethod method;
       
  1060     method.InternalizeL( reader() );
       
  1061     
       
  1062     HBufC8* uri = NULL;
       
  1063     InternalizeDesL( uri, reader() );
       
  1064     CleanupStack::PushL( uri );    
       
  1065 
       
  1066     HBufC8* request = NULL;    
       
  1067     InternalizeDesL( request, reader() );
       
  1068     
       
  1069     CleanupStack::PushL( request );
       
  1070     
       
  1071     DLINFO((_L("Data: %S"), request ));
       
  1072 
       
  1073     // Get the session that will contain the handle of the node
       
  1074     MCatalogsSession& requestSession( aMessage.Session() );
       
  1075 
       
  1076     // create the operation
       
  1077     // Note that ownership of accessPointData is transferred
       
  1078     CNcdSendHttpRequestOperation* operation = CNcdSendHttpRequestOperation::NewL(
       
  1079         uri,
       
  1080         request,
       
  1081         method,
       
  1082         iGeneralManager,
       
  1083         *this,
       
  1084         HttpSessionL( requestSession.Context() ),
       
  1085         aMessage.Session()  );
       
  1086     CleanupStack::Pop( 2, uri ); // request, uri
       
  1087     CleanupStack::PopAndDestroy( &reader );
       
  1088     CleanupStack::PushL( operation );
       
  1089 
       
  1090 
       
  1091     // Add the operation to the session and get the handle.
       
  1092     // If the operation already existed in the session we will still
       
  1093     // get a new handle to the same object.
       
  1094     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
  1095 
       
  1096     operation->SetHandle( operationHandle );
       
  1097     
       
  1098     // AddObjectL adds reference count by 1
       
  1099     operation->Close();
       
  1100 
       
  1101     DLINFO(("operation handle: %d", operationHandle ));
       
  1102 
       
  1103     // Because we created a new operation, it should be added to the
       
  1104     // cache. 
       
  1105     iOperationCache.AppendL( operation );
       
  1106     CleanupStack::Pop( operation );
       
  1107     
       
  1108     // Send the information to the client side
       
  1109     TRAPD( error,
       
  1110            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
  1111 
       
  1112     if( error != KErrNone )
       
  1113         {        
       
  1114         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
  1115         }
       
  1116 
       
  1117 
       
  1118     }
       
  1119 
       
  1120 
       
  1121 // ---------------------------------------------------------------------------
       
  1122 // Restore serialized downloads
       
  1123 // ---------------------------------------------------------------------------
       
  1124 //       
       
  1125 void CNcdOperationManager::RestoreDownloadOperationsRequestL(
       
  1126     MCatalogsBaseMessage& aMessage )
       
  1127     {
       
  1128     DLTRACEIN((""));
       
  1129     
       
  1130     // Get current context
       
  1131     MCatalogsContext& context( aMessage.Session().Context() );
       
  1132   
       
  1133     HBufC* clientUid = context.FamilyId().Name().AllocLC();    
       
  1134       
       
  1135 
       
  1136     // Get client's download storage
       
  1137     MNcdStorage* storage = StorageL( *clientUid, 
       
  1138         NcdProviderDefines::KDownloadNamespace );
       
  1139     
       
  1140         
       
  1141     CleanupStack::PopAndDestroy( clientUid );
       
  1142     DLTRACE(("Creating the download operation"));
       
  1143 
       
  1144     // Get download db
       
  1145     MNcdDatabaseStorage& db( storage->DatabaseStorageL( 
       
  1146         NcdProviderDefines::KDefaultDatabaseUid ) );
       
  1147 
       
  1148     // Write the handles of resumed operations and return 
       
  1149     // them to the client-side
       
  1150     RCatalogsBufferWriter writer;
       
  1151     writer.OpenLC();
       
  1152 
       
  1153     
       
  1154     // Get all items from the db
       
  1155     RPointerArray<MNcdStorageItem> items;
       
  1156     db.StorageItemsL( items );
       
  1157     CleanupClosePushL( items );
       
  1158     
       
  1159     DLTRACE(("Internalizing %d downloads", items.Count() ));
       
  1160 
       
  1161     MCatalogsHttpSession& httpSession( HttpSessionL( context ) );
       
  1162 
       
  1163     CNcdReportManager& reportManager( ReportManagerL( context ) );
       
  1164 
       
  1165     for ( TInt i = 0; i < items.Count(); ++i )
       
  1166         {
       
  1167         // Create operation
       
  1168         CNcdContentDownloadOperation* operation = 
       
  1169             CNcdContentDownloadOperation::NewLC( 
       
  1170                 *this, 
       
  1171                 iGeneralManager,
       
  1172                 httpSession,
       
  1173                 reportManager,
       
  1174                 db,
       
  1175                 aMessage.Session() );
       
  1176         
       
  1177         // Internalize from db
       
  1178         items[i]->SetDataItem( operation );
       
  1179         items[i]->ReadDataL();
       
  1180         
       
  1181         if ( operation->IsOk() && 
       
  1182              !ParallelOperationExistsForMetadataL( operation->NodeId(),
       
  1183                 aMessage.Session().Context() ) )
       
  1184             {
       
  1185             TInt32 operationHandle( aMessage.Session().AddObjectL( operation ) );
       
  1186             DLTRACE(("operation handle: %d", operationHandle ));
       
  1187             operation->SetHandle( operationHandle );
       
  1188             operation->Close();
       
  1189             
       
  1190             // Add to operation cache
       
  1191             iOperationCache.AppendL( operation );
       
  1192 
       
  1193             CleanupStack::Pop( operation );         
       
  1194             
       
  1195             // add object data
       
  1196             ExternalizeEnumL(
       
  1197                 NcdProviderDefines::ENcdStreamDataObject, writer() );            
       
  1198             
       
  1199             // Write handle
       
  1200             writer().WriteInt32L( operationHandle );        
       
  1201             
       
  1202             // Write type
       
  1203             writer().WriteInt32L( ENcdContentDownload );
       
  1204             
       
  1205             // Write metadata id
       
  1206             
       
  1207             operation->MetadataId().ExternalizeL( writer() );                
       
  1208             
       
  1209             writer().WriteInt32L( operation->CurrentDownload() );            
       
  1210             
       
  1211             reportManager.SetReportsAsUsedL( operation->MetadataId() );
       
  1212             DLTRACE(("Download operation created"));            
       
  1213             }    
       
  1214         else
       
  1215             {            
       
  1216             DLTRACE(("Removing failed download"));    
       
  1217             TRAP_IGNORE( items[i]->RemoveFromStorageL() );
       
  1218             DLTRACE(("Pop&Destroy"));
       
  1219             CleanupStack::PopAndDestroy( operation );
       
  1220             }        
       
  1221         }
       
  1222     
       
  1223     if ( items.Count() )
       
  1224         {
       
  1225         DLTRACE(("Commit"));
       
  1226         db.CommitL();
       
  1227         }
       
  1228     
       
  1229     // mark stream end
       
  1230     ExternalizeEnumL( NcdProviderDefines::ENcdStreamDataEnd, writer() );
       
  1231     CleanupStack::PopAndDestroy( &items );
       
  1232     
       
  1233     // Delete downloads that were not restored
       
  1234     httpSession.DeleteRestoredDownloads();
       
  1235 
       
  1236     reportManager.RemoveUnusedReportsL();
       
  1237         
       
  1238     TRAPD( error, 
       
  1239            aMessage.CompleteAndReleaseL( writer.PtrL(), KErrNone ) );
       
  1240     if( error != KErrNone )
       
  1241         {        
       
  1242         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
  1243         }
       
  1244 
       
  1245     // writer, operationHandles
       
  1246     CleanupStack::PopAndDestroy( &writer ); 
       
  1247        
       
  1248     DLTRACEOUT((""));
       
  1249 
       
  1250     }
       
  1251 
       
  1252 // ---------------------------------------------------------------------------
       
  1253 // Create server report operation
       
  1254 // ---------------------------------------------------------------------------
       
  1255 //       
       
  1256 void CNcdOperationManager::CreateServerReportOperationRequestL(
       
  1257     MCatalogsBaseMessage& aMessage )
       
  1258     {        
       
  1259     DLTRACEIN((""));
       
  1260 
       
  1261     // Get the session that will contain the handle of the node
       
  1262     MCatalogsSession& requestSession( aMessage.Session() );
       
  1263     
       
  1264     // create the operation
       
  1265     // Get current context
       
  1266     MCatalogsContext& context( aMessage.Session().Context() );
       
  1267     CNcdServerReportOperation* operation = CNcdServerReportOperation::NewL(
       
  1268         iGeneralManager,
       
  1269         *this,
       
  1270         ReportManagerL( context ),
       
  1271         aMessage.Session() );
       
  1272     
       
  1273     CleanupStack::PushL( operation );
       
  1274     // Add the operation to the session and get the handle.
       
  1275     // If the operation already existed in the session we will still
       
  1276     // get a new handle to the same object.
       
  1277     TInt32 operationHandle( requestSession.AddObjectL( operation ) );
       
  1278     operation->SetHandle( operationHandle );
       
  1279     
       
  1280     // AddObjectL adds reference count by 1
       
  1281     operation->Close();
       
  1282 
       
  1283     DLTRACE(("operation handle: %d", operationHandle ));
       
  1284 
       
  1285     // Because we created a new operation, it should be added to the
       
  1286     // cache. 
       
  1287     iOperationCache.AppendL( operation );
       
  1288     CleanupStack::Pop( operation );    
       
  1289     
       
  1290     // Send the information to the client side
       
  1291     TRAPD( error, 
       
  1292            aMessage.CompleteAndReleaseL( operationHandle, KErrNone ) );
       
  1293     if( error != KErrNone )
       
  1294         {        
       
  1295         iOperationCache.Remove( iOperationCache.Count() - 1 );
       
  1296         }
       
  1297     DLTRACEOUT((""));
       
  1298     }
       
  1299 
       
  1300 
       
  1301 MCatalogsHttpSession& CNcdOperationManager::HttpSessionL( MCatalogsContext& aContext )
       
  1302     {
       
  1303     TNcdProviderContext providerContext;
       
  1304     iProvider.GetProviderContextL( aContext, providerContext );
       
  1305     return *providerContext.iHttpSession;
       
  1306     }
       
  1307 
       
  1308 MCatalogsSmsSession& CNcdOperationManager::SmsSessionL( MCatalogsContext& aContext )
       
  1309     {
       
  1310     TNcdProviderContext providerContext;
       
  1311     iProvider.GetProviderContextL( aContext, providerContext );
       
  1312     return *providerContext.iSmsSession;
       
  1313     }
       
  1314 
       
  1315 CNcdReportManager& CNcdOperationManager::ReportManagerL( MCatalogsContext& aContext )
       
  1316     {
       
  1317     TNcdProviderContext providerContext;
       
  1318     iProvider.GetProviderContextL( aContext, providerContext );
       
  1319     return *providerContext.iReportManager;
       
  1320     }
       
  1321 
       
  1322 
       
  1323 // ---------------------------------------------------------------------------
       
  1324 // ReceiveMessage
       
  1325 // ---------------------------------------------------------------------------
       
  1326 //       
       
  1327 void CNcdOperationManager::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
  1328                                            TInt aFunctionNumber )
       
  1329     {
       
  1330     DLTRACEIN((""));
       
  1331 
       
  1332     // The message is always required.
       
  1333     if( aMessage == NULL )
       
  1334         {
       
  1335         // Do not do anything here because we can not give any
       
  1336         // feedback
       
  1337         return;
       
  1338         }
       
  1339 
       
  1340     TInt trapError( KErrNone );
       
  1341         
       
  1342     switch( aFunctionNumber )
       
  1343         {
       
  1344         case NcdNodeFunctionIds::ENcdOperationManagerCreateLoadNodeOperation:
       
  1345             DLTRACE(("Creating load node operation"));
       
  1346 
       
  1347             TRAP( trapError, CreateLoadNodeOperationRequestL( *aMessage ) );
       
  1348             break;
       
  1349 
       
  1350         case NcdNodeFunctionIds::ENcdOperationManagerCreateDownloadOperation:
       
  1351             DLTRACE(("Creating download operation"));
       
  1352 
       
  1353             TRAP( trapError, CreateDownloadOperationRequestL( *aMessage ) );
       
  1354             break;
       
  1355             
       
  1356         case NcdNodeFunctionIds::ENcdOperationManagerCreateLoadRootNodeOperation:
       
  1357             DLTRACE(("Creating load root node operation"));
       
  1358             
       
  1359             TRAP( trapError, CreateLoadRootNodeOperationRequestL( *aMessage ) );
       
  1360             break;
       
  1361             
       
  1362         case NcdNodeFunctionIds::ENcdOperationManagerCreateLoadBundleNodeOperation:
       
  1363             DLTRACE(("Creating load bundle node operation"));
       
  1364             
       
  1365             TRAP( trapError, CreateLoadBundleNodeOperationRequestL( *aMessage ) );
       
  1366             break;
       
  1367         
       
  1368         case NcdNodeFunctionIds::ENcdOperationManagerCreatePurchaseOperation:
       
  1369             DLTRACE(("Creating purchase operation"));
       
  1370             
       
  1371             TRAP( trapError, CreatePurchaseOperationRequestL( *aMessage ) );
       
  1372             break;
       
  1373             
       
  1374         case NcdNodeFunctionIds::ENcdOperationManagerCreateRightsObjectOperation:
       
  1375             DLTRACE(("Creating rights object download and install operation"));
       
  1376             
       
  1377             TRAP( trapError, CreateRightsObjectOperationRequestL( *aMessage ) );
       
  1378             break;
       
  1379 
       
  1380         case NcdNodeFunctionIds::ENcdOperationManagerCreateInstallOperation:
       
  1381             DLTRACE(("Creating install operation"));
       
  1382             
       
  1383             TRAP( trapError, CreateInstallOperationRequestL( *aMessage ) );
       
  1384             break;
       
  1385 
       
  1386         case NcdNodeFunctionIds::ENcdOperationManagerCreateSilentInstallOperation:
       
  1387             DLTRACE(("Creating install operation"));
       
  1388             
       
  1389             TRAP( trapError, CreateSilentInstallOperationRequestL( *aMessage ) );
       
  1390             break;
       
  1391 
       
  1392         case NcdNodeFunctionIds::ENcdOperationManagerCreateSubscriptionOperation:
       
  1393             DLTRACE(("Creating subscription operation"));
       
  1394             
       
  1395             TRAP( trapError, CreateSubscriptionOperationRequestL( *aMessage ) );
       
  1396             break;
       
  1397 
       
  1398         case NcdNodeFunctionIds::ENcdOperationManagerRestoreContentDownloads:
       
  1399             DLTRACE(("Restoring downloads"));
       
  1400             
       
  1401             TRAP( trapError, RestoreDownloadOperationsRequestL( *aMessage ) );
       
  1402             break;
       
  1403 
       
  1404         case NcdNodeFunctionIds::ENcdOperationManagerCreateCreateAccessPointOperation:
       
  1405             DLTRACE(("Creating create accesspoint operation"));
       
  1406             
       
  1407             TRAP( trapError, CreateCreateAccessPointOperationRequestL( *aMessage ) );
       
  1408             break;
       
  1409 
       
  1410         case NcdNodeFunctionIds::ENcdOperationManagerCreateSendHttpRequestOperation:
       
  1411             DLTRACE(("Creating HTTP request sending operation"));
       
  1412             
       
  1413             TRAP( trapError, CreateSendHttpRequestOperationRequestL( *aMessage ) );
       
  1414             break;
       
  1415 
       
  1416         case NcdNodeFunctionIds::ENcdOperationManagerCreateServerReportOperation:
       
  1417             DLTRACE(("Creating server report operation"));
       
  1418             
       
  1419             TRAP( trapError, CreateServerReportOperationRequestL( *aMessage ) );
       
  1420             break;
       
  1421             
       
  1422         case NcdNodeFunctionIds::ENcdRelease:
       
  1423             ReleaseRequest( *aMessage );
       
  1424             break;
       
  1425 
       
  1426         default:
       
  1427             DASSERT( 0 );
       
  1428             break;
       
  1429         }
       
  1430 
       
  1431     if ( trapError != KErrNone )
       
  1432         {
       
  1433         // Because something went wrong the complete has not been
       
  1434         // yet called for the message.
       
  1435         // So, inform the client about the error.
       
  1436         DLTRACE(("ERROR, Complete and release %d", trapError));
       
  1437         
       
  1438         aMessage->CompleteAndRelease( trapError );
       
  1439         }
       
  1440 
       
  1441     DLTRACEOUT((""));
       
  1442     }
       
  1443 
       
  1444 
       
  1445 // ---------------------------------------------------------------------------
       
  1446 // CounterPartLost
       
  1447 // ---------------------------------------------------------------------------
       
  1448 //       
       
  1449 void CNcdOperationManager::CounterPartLost( const MCatalogsSession& /*aSession*/ )
       
  1450     {
       
  1451     DLTRACEIN((""));
       
  1452     DLTRACEOUT((""));
       
  1453     
       
  1454     }
       
  1455     
       
  1456 
       
  1457 // ---------------------------------------------------------------------------
       
  1458 // RemoveOperation
       
  1459 // ---------------------------------------------------------------------------
       
  1460 //           
       
  1461 void CNcdOperationManager::RemoveOperation( CNcdBaseOperation& aOperation )
       
  1462     {
       
  1463     DLTRACEIN((""));
       
  1464     TInt index = iOperationCache.Find( &aOperation );
       
  1465     if ( index != KErrNotFound ) 
       
  1466         {
       
  1467         DLTRACE(("Removing operation"));
       
  1468         iOperationCache.Remove( index );
       
  1469         }
       
  1470         
       
  1471     index = iOperationQueue.Find( &aOperation );
       
  1472     if ( index != KErrNotFound )
       
  1473         {
       
  1474         // Should never come here.
       
  1475         DASSERT( EFalse );
       
  1476         iOperationQueue.Remove( index );
       
  1477         }
       
  1478     }
       
  1479     
       
  1480     
       
  1481 // ---------------------------------------------------------------------------
       
  1482 // QueueOperation
       
  1483 // ---------------------------------------------------------------------------
       
  1484 //           
       
  1485 void CNcdOperationManager::QueueOperationL( CNcdBaseOperation& aOperation )
       
  1486     {
       
  1487     DLTRACEIN(("queue size: %d", iOperationQueue.Count()));
       
  1488     iOperationQueue.AppendL( &aOperation );
       
  1489     
       
  1490     // Start the operation if it is the only one in queue, or there are no load bundle
       
  1491     // node operations which may lock the database. If the operation is a load bundle operation
       
  1492     // it should not be started if the queue is not empty since there are other operations
       
  1493     // running.
       
  1494     if ( aOperation.Type() == ELoadBundleNodeOperation )
       
  1495         {
       
  1496         if ( iOperationQueue.Count() == 1 )
       
  1497             {
       
  1498             aOperation.RunOperation();
       
  1499             }
       
  1500         }
       
  1501     else
       
  1502         {
       
  1503         if ( !QueuedLoadBundleOperationsExists() )
       
  1504             {
       
  1505             aOperation.RunOperation();
       
  1506             }
       
  1507         }
       
  1508     }
       
  1509     
       
  1510 // ---------------------------------------------------------------------------
       
  1511 // QueueOperation
       
  1512 // ---------------------------------------------------------------------------
       
  1513 //           
       
  1514 void CNcdOperationManager::QueuedOperationComplete( CNcdBaseOperation& aOperation )
       
  1515     {
       
  1516     DLTRACEIN(("operation-ptr: %x", &aOperation));
       
  1517     
       
  1518     TInt index = iOperationQueue.Find( &aOperation );
       
  1519     
       
  1520     if ( index != KErrNotFound )
       
  1521         {        
       
  1522         iOperationQueue.Remove( index );
       
  1523 
       
  1524         // Start new operations only if the completed one was the first in queue since
       
  1525         // the first one is otherwise running still.
       
  1526         if ( index == 0 && iOperationQueue.Count() ) 
       
  1527             {
       
  1528             if ( iOperationQueue[ 0 ]->Type() == ELoadBundleNodeOperation )
       
  1529                 {
       
  1530                 // If the next in queue is load bundle node, it can be started since
       
  1531                 // it is not started yet.
       
  1532                 iOperationQueue[ 0 ]->ContinueOperationL();
       
  1533                 }
       
  1534                                 
       
  1535             else if ( aOperation.Type() == ELoadBundleNodeOperation ) 
       
  1536                 {
       
  1537                 // Completed operation was a bundle load op, so the next in queue are not
       
  1538                 // started yet. Start the next operations in queue before the first load
       
  1539                 // bundle node operation.
       
  1540                 for ( TInt i = 0; i < iOperationQueue.Count(); i++ )
       
  1541                     {
       
  1542                     if ( iOperationQueue[ i ]->Type() != ELoadBundleNodeOperation )
       
  1543                         {
       
  1544                         iOperationQueue[ i ]->ContinueOperationL();
       
  1545                         }
       
  1546                     else
       
  1547                         {
       
  1548                         break;
       
  1549                         }
       
  1550                     }
       
  1551                 }
       
  1552             }
       
  1553         }
       
  1554     }
       
  1555                     
       
  1556     
       
  1557     
       
  1558 // ---------------------------------------------------------------------------
       
  1559 // Constructor
       
  1560 // ---------------------------------------------------------------------------
       
  1561 //           
       
  1562 CNcdOperationManager::CNcdOperationManager( 
       
  1563     CNcdProvider& aProvider,
       
  1564     CNcdGeneralManager& aGeneralManager,      
       
  1565     CNcdSubscriptionManager& aSubscriptionManager )
       
  1566 	: 
       
  1567     CCatalogsCommunicable(),
       
  1568     iProvider( aProvider ),
       
  1569     iGeneralManager( aGeneralManager ),
       
  1570     iStorageManager( aGeneralManager.StorageManager() ),
       
  1571     iProtocolHandler( aGeneralManager.ProtocolManager() ),
       
  1572     iNodeManager( aGeneralManager.NodeManager() ),
       
  1573     iPurchaseHistory( aGeneralManager.PurchaseHistory() ),
       
  1574     iConfigurationManager( aGeneralManager.ConfigurationManager() ),
       
  1575     iAccessPointManager( aGeneralManager.AccessPointManager() ),
       
  1576     iSubscriptionManager( aSubscriptionManager )
       
  1577     {
       
  1578     }
       
  1579 
       
  1580 
       
  1581 // ---------------------------------------------------------------------------
       
  1582 // ConstructL
       
  1583 // ---------------------------------------------------------------------------
       
  1584 //       
       
  1585 void CNcdOperationManager::ConstructL()
       
  1586     {
       
  1587     DLTRACEIN( ( "this: %X", this ) );
       
  1588     
       
  1589     DLTRACEOUT( ( "" ) );
       
  1590     }
       
  1591 
       
  1592 
       
  1593 // ---------------------------------------------------------------------------
       
  1594 // StorageL
       
  1595 // ---------------------------------------------------------------------------
       
  1596 //    
       
  1597 MNcdStorage* CNcdOperationManager::StorageL( const TDesC& aClientUid,
       
  1598     const TDesC& aNamespace ) const
       
  1599     {    
       
  1600     DLTRACEIN((""));
       
  1601     MNcdStorage* storage = NULL;
       
  1602         
       
  1603     
       
  1604     DLTRACE(( _L("Namespace: %S"), &aNamespace ));
       
  1605     TRAPD( err, storage = &iStorageManager.StorageL( aClientUid, aNamespace ) );
       
  1606     
       
  1607     if ( err == KErrNotFound ) 
       
  1608         {
       
  1609         DLTRACE(("Creating storage for the client"));
       
  1610         err = KErrNone;
       
  1611         TRAP( err, storage = &iStorageManager.CreateStorageL( aClientUid, aNamespace ) );
       
  1612         
       
  1613         if ( err == KErrAlreadyExists )
       
  1614             {
       
  1615             err = KErrNone;
       
  1616             storage = &iStorageManager.StorageL( aClientUid, aNamespace );
       
  1617             }
       
  1618         }
       
  1619 
       
  1620     if ( err != KErrNone )
       
  1621         {
       
  1622         DLTRACE(("Leaving: %i", err));
       
  1623         User::Leave( err );   
       
  1624         }
       
  1625         
       
  1626     DLTRACEOUT((""));
       
  1627     return storage;
       
  1628     }
       
  1629     
       
  1630     
       
  1631 // ---------------------------------------------------------------------------
       
  1632 // Release request
       
  1633 // ---------------------------------------------------------------------------
       
  1634 //    
       
  1635 void CNcdOperationManager::ReleaseRequest( MCatalogsBaseMessage& aMessage ) const
       
  1636     {
       
  1637     DLTRACEIN((""));
       
  1638 
       
  1639     // Decrease the reference count for this object.
       
  1640     // When the reference count reaches zero, this object will be destroyed
       
  1641     // and removed from the session.
       
  1642     MCatalogsSession& requestSession( aMessage.Session() );
       
  1643     TInt handle( aMessage.Handle() );
       
  1644     aMessage.CompleteAndRelease( KErrNone );
       
  1645     requestSession.RemoveObject( handle );
       
  1646                 
       
  1647     DLTRACEOUT((""));
       
  1648     }
       
  1649     
       
  1650 
       
  1651 // ---------------------------------------------------------------------------
       
  1652 // Checks if a download already exists
       
  1653 // ---------------------------------------------------------------------------
       
  1654 //    
       
  1655 TBool CNcdOperationManager::DownloadExistsL( MCatalogsBaseMessage& aMessage, 
       
  1656     const CNcdNodeIdentifier& aIdentifier, 
       
  1657     TNcdDownloadDataType aType, 
       
  1658     TInt aIndex )
       
  1659     {
       
  1660     DLTRACEIN(("Op cache count: %d", iOperationCache.Count()));
       
  1661     TInt32 handle = 0;
       
  1662     
       
  1663     const CNcdNodeIdentifier* metaId = &aIdentifier;
       
  1664 
       
  1665     // Use metadata id's for comparison since temp nodes have different
       
  1666     // node id's but same metadata id's as normal nodes
       
  1667     //
       
  1668     // Generic file downloads don't have node nor metadata. The given node id
       
  1669     // contains the URL and target filename
       
  1670     if ( aType != ENcdGenericFileDownload )
       
  1671         {
       
  1672         DLTRACE(("Not skin nor generic DL, getting metadata id"));        
       
  1673         
       
  1674         metaId = &iNodeManager.NodeL( aIdentifier ).NodeMetaDataL().Identifier();
       
  1675         }        
       
  1676     
       
  1677     for ( TInt i = 0; i < iOperationCache.Count(); ++i )
       
  1678         {
       
  1679         // Check other downloads but content
       
  1680         if ( aType != ENcdContentDownload && 
       
  1681              iOperationCache[i]->Type() == 
       
  1682                 EDownloadOperation )
       
  1683             {
       
  1684             CNcdDownloadOperation* op = static_cast<CNcdDownloadOperation*>(
       
  1685                 iOperationCache[i] );
       
  1686             if ( op->MatchDownload( *metaId, aType, aIndex ) )
       
  1687                 {
       
  1688                 DLTRACE(("Found a matching download"));
       
  1689                 handle = op->Handle();
       
  1690                 break;
       
  1691                 }
       
  1692             }
       
  1693         // check content downloads
       
  1694         else if ( aType == ENcdContentDownload &&
       
  1695             iOperationCache[i]->Type() ==
       
  1696                 EContentDownloadOperation )
       
  1697             {
       
  1698             CNcdContentDownloadOperation* op = static_cast<
       
  1699                 CNcdContentDownloadOperation*>(
       
  1700                 iOperationCache[i] );
       
  1701             if ( op->MatchDownload( *metaId, aType, aIndex ) )
       
  1702                 {
       
  1703                 DLTRACE(("Found a matching content download"));
       
  1704                 handle = op->Handle();
       
  1705                 break;
       
  1706                 }
       
  1707             }            
       
  1708         }
       
  1709     if ( handle ) 
       
  1710         {
       
  1711         // Send the information to the client side
       
  1712         aMessage.CompleteAndReleaseL( handle, KErrNone );
       
  1713         return ETrue;
       
  1714         }
       
  1715     DLTRACEOUT(("No matching download"));
       
  1716     return EFalse;
       
  1717     }
       
  1718 
       
  1719 
       
  1720 // ---------------------------------------------------------------------------
       
  1721 // Checks if there are load bundle node operations in operation queue.
       
  1722 // ---------------------------------------------------------------------------
       
  1723 //        
       
  1724 TBool CNcdOperationManager::QueuedLoadBundleOperationsExists() const
       
  1725     {
       
  1726     DLTRACEIN((""));
       
  1727     TInt queueSize = iOperationQueue.Count();
       
  1728     for ( TInt i = 0; i < queueSize; i++ )
       
  1729         {
       
  1730         if ( iOperationQueue[ i ]->Type() == ELoadBundleNodeOperation )
       
  1731             {
       
  1732             DLINFO(("queued load bundle op exists"));
       
  1733             return ETrue;
       
  1734             }
       
  1735         }
       
  1736         
       
  1737     DLINFO(("no queued load bundle op"));
       
  1738     return EFalse;
       
  1739     }
       
  1740 
       
  1741 // ---------------------------------------------------------------------------
       
  1742 // Checks if there are on-going operations for the metadata for another client
       
  1743 // ---------------------------------------------------------------------------
       
  1744 // 
       
  1745 TBool CNcdOperationManager::ParallelOperationExistsForMetadataL(
       
  1746     const CNcdNodeIdentifier& aNodeIdentifier,
       
  1747     const MCatalogsContext& aContext,
       
  1748     TBool aCompareIdsDirectly ) const
       
  1749     {
       
  1750     DLTRACEIN((""));
       
  1751     const CNcdNodeIdentifier* metaId = NULL;
       
  1752 
       
  1753     // If parameter suggests that ids should not be compared directly,
       
  1754     // make a safety check.
       
  1755     if ( !aCompareIdsDirectly
       
  1756          && NcdNodeIdentifierEditor::IdentifiesSomeRoot( aNodeIdentifier ) )
       
  1757         {
       
  1758         // In the case of root nodes, the metadata does not
       
  1759         // exist. So, force direct comparing of node ids.
       
  1760         DLINFO(("Force direct comparing of node ids"));
       
  1761         aCompareIdsDirectly = ETrue;
       
  1762         }
       
  1763 
       
  1764     if( !aCompareIdsDirectly )
       
  1765         {
       
  1766         // The node should always exist.
       
  1767         CNcdNode& node( iNodeManager.NodeL( aNodeIdentifier ) );
       
  1768 
       
  1769         // Above, a root node check was made to force direct comparing 
       
  1770         // of ids for root nodes because they do not have metadata. So,
       
  1771         // in root node cases we do not come here.
       
  1772         // In normal cases, the metadata should always exist. 
       
  1773         // But, to be safe in all cases, check if metadata is NULL here.  
       
  1774         // Notice, ownership is not transferred here.
       
  1775         CNcdNodeMetaData* metadata( node.NodeMetaData() );
       
  1776 
       
  1777         if ( metadata )
       
  1778             {
       
  1779             DLINFO(("Metadata existed for paralled operations checking"));
       
  1780             // Ownership is not transferred. Metadata owns its own identifier.
       
  1781             metaId = &metadata->Identifier();            
       
  1782             }
       
  1783         else
       
  1784             {
       
  1785             // Because metadata is NULL, 
       
  1786             // no operation should exist for it either.
       
  1787             DLTRACEOUT(("No metadata to compare parallel operations"));
       
  1788             return EFalse;
       
  1789             }
       
  1790         }
       
  1791         
       
  1792     // Check operation cache
       
  1793     for ( TInt i = 0; i < iOperationCache.Count(); i++ )
       
  1794         {
       
  1795         // Check is only done if the client is not the same
       
  1796         if( iOperationCache[i]->Session().Context().FamilyId() != aContext.FamilyId() ||
       
  1797             ( iOperationCache[i]->Session().Context().SecureId() == aContext.SecureId() && 
       
  1798               iOperationCache[i]->Session().Context().InstanceId() == aContext.InstanceId() ) )
       
  1799             {
       
  1800             continue;
       
  1801             }
       
  1802         // Try to get id from operation, not all operations are node specific.
       
  1803         const CNcdNodeIdentifier* id = GetNodeIdFromOperation( *iOperationCache[i] );
       
  1804         if( !id )
       
  1805             {
       
  1806             continue;
       
  1807             }
       
  1808         if( !aCompareIdsDirectly &&
       
  1809             NcdNodeIdentifierEditor::DoesMetaDataIdentifierMatchL( *metaId, *id ) )
       
  1810             {
       
  1811             return ETrue;
       
  1812             }
       
  1813         else if( aNodeIdentifier.Equals( *id ) )
       
  1814             {
       
  1815             return ETrue;
       
  1816             }
       
  1817         }
       
  1818     
       
  1819     // Check operation queue
       
  1820     for ( TInt i = 0; i < iOperationQueue.Count(); i++ )
       
  1821         {
       
  1822         // Check is only done if the client is not the same
       
  1823         if( iOperationQueue[i]->Session().Context().FamilyId() != aContext.FamilyId() ||
       
  1824             ( iOperationQueue[i]->Session().Context().SecureId() == aContext.SecureId() && 
       
  1825               iOperationQueue[i]->Session().Context().InstanceId() == aContext.InstanceId() ) )
       
  1826             {
       
  1827             continue;
       
  1828             }
       
  1829         // Try to get id from operation, not all operations are node specific.
       
  1830         const CNcdNodeIdentifier* id = GetNodeIdFromOperation( *iOperationQueue[i] );
       
  1831         if( !id )
       
  1832             {
       
  1833             continue;
       
  1834             }
       
  1835         if( !aCompareIdsDirectly &&
       
  1836             NcdNodeIdentifierEditor::DoesMetaDataIdentifierMatchL( *metaId, *id ) )
       
  1837             {
       
  1838             return ETrue;
       
  1839             }
       
  1840         else if( aNodeIdentifier.Equals( *id ) )
       
  1841             {
       
  1842             return ETrue;
       
  1843             }
       
  1844         }
       
  1845     return EFalse;
       
  1846     }
       
  1847     
       
  1848 const CNcdNodeIdentifier* CNcdOperationManager::GetNodeIdFromOperation(
       
  1849     const CNcdBaseOperation& aOperation ) const
       
  1850     {
       
  1851     DLTRACEIN((""));
       
  1852     switch( aOperation.Type() )
       
  1853         {
       
  1854         case ELoadNodeOperation:
       
  1855         case ESearchOperation:
       
  1856             {
       
  1857             const CNcdLoadNodeOperationImpl& op =
       
  1858                 static_cast<const CNcdLoadNodeOperationImpl&>( aOperation );
       
  1859             return op.NodeIdentifier();
       
  1860             }
       
  1861         case ELoadRootNodeOperation:
       
  1862             {
       
  1863             const CNcdLoadRootNodeOperation& op =
       
  1864                 static_cast<const CNcdLoadRootNodeOperation&>( aOperation );
       
  1865             return &op.NodeIdentifier();
       
  1866             }
       
  1867         case ELoadBundleNodeOperation:
       
  1868             {
       
  1869             const CNcdLoadBundleNodeOperation& op =
       
  1870                 static_cast<const CNcdLoadBundleNodeOperation&>( aOperation );
       
  1871             return &op.NodeIdentifier();
       
  1872             }
       
  1873         case EDownloadOperation:
       
  1874             {
       
  1875             const CNcdDownloadOperation& op =
       
  1876                 static_cast<const CNcdDownloadOperation&>( aOperation );
       
  1877             return &op.NodeIdentifier();
       
  1878             }
       
  1879         case EInstallOperation:
       
  1880             {
       
  1881             const CNcdInstallOperation& op =
       
  1882                 static_cast<const CNcdInstallOperation&>( aOperation );
       
  1883             return &op.NodeIdentifier();
       
  1884             }
       
  1885         case EPurchaseOperation:
       
  1886             {
       
  1887             const CNcdPurchaseOperationImpl& op =
       
  1888                 static_cast<const CNcdPurchaseOperationImpl&>( aOperation );
       
  1889             return &op.NodeIdentifier();
       
  1890             }
       
  1891         case EContentDownloadOperation:
       
  1892             {
       
  1893             const CNcdContentDownloadOperation& op =
       
  1894                 static_cast<const CNcdContentDownloadOperation&>( aOperation );
       
  1895             return &op.NodeId();
       
  1896             }
       
  1897         default:
       
  1898             {
       
  1899             return NULL;
       
  1900             }
       
  1901         // These operations are not node-specific, hence no id information can be
       
  1902         // retrieved from them:
       
  1903         /*EDownloadSubOperation,
       
  1904         EDescriptorDownloadSubOperation,
       
  1905         ESendNotificationSubOperation,
       
  1906         ERightsObjectOperation,
       
  1907         ECreateAccessPointOperation,
       
  1908         ESendHttpRequestOperation,
       
  1909         EServerReportOperation,
       
  1910         ESubscriptionOperation*/
       
  1911         }
       
  1912     }