ncdengine/provider/server/src/ncdloadbundlenodeoperationimpl.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:  
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdloadbundlenodeoperationimpl.h"
       
    20 #include "ncdoperationfunctionids.h"
       
    21 #include "catalogsbasemessage.h"
       
    22 #include "catalogshttpsession.h"
       
    23 #include "catalogshttpoperation.h"
       
    24 #include "catalogshttpconfig.h"
       
    25 #include "catalogsbigdes.h"
       
    26 #include "catalogsaccesspointmanagerimpl.h"
       
    27 #include "ncdrequestgenerator.h"
       
    28 
       
    29 #include "ncdrequestbase.h"
       
    30 #include "ncdrequestbrowsesearch.h"
       
    31 #include "ncdrequestconfiguration.h"
       
    32 #include "ncd_pp_itemref.h"
       
    33 #include "ncd_pp_folderref.h"
       
    34 #include "ncd_pp_dataentity.h"
       
    35 #include "ncd_cp_query.h"
       
    36 #include "ncd_cp_queryelement.h"
       
    37 #include "ncd_cp_queryoption.h"
       
    38 
       
    39 #include "ncdprotocolutils.h"
       
    40 #include "ncdprotocol.h"
       
    41 #include "ncdprotocolimpl.h"
       
    42 #include "ncdparser.h"
       
    43 #include "ncdnodemanager.h"
       
    44 #include "ncdproviderdefines.h"
       
    45 #include "ncdnodeidentifier.h"
       
    46 #include "ncdnodeclassids.h"
       
    47 #include "ncdnodefolder.h"
       
    48 #include "ncdrootnode.h"
       
    49 #include "ncdbundlefolder.h"
       
    50 #include "ncdloadnodeoperationimpl.h"
       
    51 #include "ncd_cp_detail.h"
       
    52 #include "ncd_cp_clientconfiguration.h"
       
    53 #include "ncd_cp_error.h"
       
    54 #include "catalogscontext.h"
       
    55 #include "ncd_cp_serverdetails.h"
       
    56 #include "ncdqueryimpl.h"
       
    57 #include "ncdnodelink.h"
       
    58 #include "ncd_cp_queryresponseimpl.h"
       
    59 #include "catalogsutils.h"
       
    60 #include "ncderrors.h"
       
    61 #include "ncdconfigurationmanager.h"
       
    62 #include "ncdoperationremovehandler.h"
       
    63 #include "ncdnodemetadataimpl.h"
       
    64 #include "ncdnodeiconimpl.h"
       
    65 #include "ncdsessionhandler.h"
       
    66 #include "ncd_pp_error.h"
       
    67 #include "ncdconfigurationkeys.h"
       
    68 #include "ncdutils.h"
       
    69 #include "ncdnodeidentifiereditor.h"
       
    70 #include "ncdnodeidentifier.h"
       
    71 #include "ncdprotocolstrings.h"
       
    72 #include "ncdnodeseeninfo.h"
       
    73 #include "ncdchildentitymap.h"
       
    74 #include "ncdproviderutils.h"
       
    75 #include "ncdhttputils.h"
       
    76 #include "ncdoperationqueue.h"
       
    77 #include "ncdgeneralmanager.h"
       
    78 #include "ncd_cp_queryimpl.h"
       
    79 #include "ncdstring.h"
       
    80 #include "ncdnodedisclaimer.h"
       
    81 
       
    82 #include "catalogsdebug.h"
       
    83 
       
    84 
       
    85 // ---------------------------------------------------------------------------
       
    86 // ?description_if_needed
       
    87 // ---------------------------------------------------------------------------
       
    88 //
       
    89 CNcdLoadBundleNodeOperation* CNcdLoadBundleNodeOperation::NewL(
       
    90     const CNcdNodeIdentifier& aNodeIdentifier,
       
    91     CNcdGeneralManager& aGeneralManager,
       
    92     MCatalogsHttpSession& aHttpSession,
       
    93     MNcdOperationRemoveHandler* aRemoveHandler,
       
    94     MNcdOperationQueue& aOperationQueue,
       
    95     MCatalogsSession& aSession )
       
    96     {
       
    97     CNcdLoadBundleNodeOperation* self = CNcdLoadBundleNodeOperation::NewLC(
       
    98         aNodeIdentifier,
       
    99         aGeneralManager,
       
   100         aHttpSession,
       
   101         aRemoveHandler,
       
   102         aOperationQueue,
       
   103         aSession );
       
   104     CleanupStack::Pop( self );
       
   105     return self;
       
   106     }
       
   107 
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // ?description_if_needed
       
   111 // ---------------------------------------------------------------------------
       
   112 //
       
   113 CNcdLoadBundleNodeOperation* CNcdLoadBundleNodeOperation::NewLC(
       
   114     const CNcdNodeIdentifier& aNodeIdentifier,
       
   115     CNcdGeneralManager& aGeneralManager,
       
   116     MCatalogsHttpSession& aHttpSession,
       
   117     MNcdOperationRemoveHandler* aRemoveHandler,
       
   118     MNcdOperationQueue& aOperationQueue,
       
   119     MCatalogsSession& aSession )
       
   120     {
       
   121     CNcdLoadBundleNodeOperation* self =
       
   122         new( ELeave ) CNcdLoadBundleNodeOperation( 
       
   123             aGeneralManager,
       
   124             aHttpSession, 
       
   125             aRemoveHandler, 
       
   126             aOperationQueue, 
       
   127             aSession );
       
   128     CleanupClosePushL( *self );
       
   129     self->ConstructL( aNodeIdentifier );
       
   130     return self;
       
   131     }
       
   132 
       
   133 // ---------------------------------------------------------------------------
       
   134 // ?description_if_needed
       
   135 // ---------------------------------------------------------------------------
       
   136 //
       
   137 CNcdLoadBundleNodeOperation::~CNcdLoadBundleNodeOperation()
       
   138     {
       
   139     DLTRACEIN((""));
       
   140     DASSERT( !iNodeDbLocked );
       
   141     iConfigManager.RemoveObserver( *this );
       
   142     
       
   143     iLoadedNodes.ResetAndDestroy();
       
   144     
       
   145     DLTRACE(("Delete id, buffer"));
       
   146     delete iNodeIdentifier;
       
   147     
       
   148     DLTRACE(("Delete parser"));
       
   149     delete iParser;
       
   150     if ( iTransaction )
       
   151         {
       
   152         DLTRACE(("Releasing transaction"));
       
   153         iTransaction->Release();
       
   154         }
       
   155     DLTRACE(("Delete loaded nodes"));
       
   156     iLoadedNodes.ResetAndDestroy();
       
   157         
       
   158     DLTRACE(("Closing suboperations"));
       
   159     // Close operations
       
   160     for ( TInt i = 0; i < iSubOps.Count(); ++i )
       
   161         {
       
   162         iSubOps[i]->Close();        
       
   163         }
       
   164     DLTRACE(("Suboperations closed"));
       
   165     iSubOps.Reset();
       
   166     iFailedSubOps.Reset();
       
   167     iCompletedSubOps.Reset();
       
   168     
       
   169     DLTRACE(("Deleting content sources"));
       
   170     delete iContentSourceMap;
       
   171     
       
   172     DLTRACE(("Delete conf response buffer"));
       
   173     delete iConfigResponseBuf;
       
   174         
       
   175     if( iConfQuery )
       
   176         {
       
   177         iConfQuery->InternalRelease();
       
   178         }
       
   179 
       
   180     iSubOpQuerys.Close();
       
   181     
       
   182     delete iServerUri;
       
   183     
       
   184     iChildEntityMaps.ResetAndDestroy();
       
   185     
       
   186     DLTRACEOUT((""));
       
   187     }
       
   188 
       
   189 const CNcdNodeIdentifier& CNcdLoadBundleNodeOperation::NodeIdentifier() const
       
   190     {
       
   191     return *iNodeIdentifier;
       
   192     }
       
   193 
       
   194 // ---------------------------------------------------------------------------
       
   195 // ?implementation_description
       
   196 // ---------------------------------------------------------------------------
       
   197 //
       
   198 void CNcdLoadBundleNodeOperation::HandleCancelMessage( MCatalogsBaseMessage* aMessage ) 
       
   199     {
       
   200     DLTRACEIN((""));
       
   201     Cancel();
       
   202     CNcdBaseOperation::HandleCancelMessage( aMessage );
       
   203     iOperationQueue.QueuedOperationComplete( *this );
       
   204     }
       
   205 
       
   206 // ---------------------------------------------------------------------------
       
   207 // ?implementation_description
       
   208 // ---------------------------------------------------------------------------
       
   209 //    
       
   210 TInt CNcdLoadBundleNodeOperation::CompleteMessage(
       
   211     MCatalogsBaseMessage* & aMessage,
       
   212     TNcdOperationMessageCompletionId aId,
       
   213     const MNcdSendable& aSendableObject,
       
   214     TInt aStatus ) 
       
   215     {
       
   216     DLTRACEIN((""));    
       
   217     NotifyCompletionOfQueuedOperation( aId );
       
   218     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aSendableObject, aStatus );
       
   219     }
       
   220     
       
   221 
       
   222 // ---------------------------------------------------------------------------
       
   223 // ?implementation_description
       
   224 // ---------------------------------------------------------------------------
       
   225 //    
       
   226 TInt CNcdLoadBundleNodeOperation::CompleteMessage(
       
   227     MCatalogsBaseMessage* & aMessage,
       
   228     TNcdOperationMessageCompletionId aId,
       
   229     TInt aStatus )
       
   230     {
       
   231     DLTRACEIN((""));
       
   232     NotifyCompletionOfQueuedOperation( aId );
       
   233     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aStatus );
       
   234     }
       
   235     
       
   236 // ---------------------------------------------------------------------------
       
   237 // ?implementation_description
       
   238 // ---------------------------------------------------------------------------
       
   239 //    
       
   240 TInt CNcdLoadBundleNodeOperation::CompleteMessage(
       
   241     MCatalogsBaseMessage*& aMessage,
       
   242     TNcdOperationMessageCompletionId aId,
       
   243     const MNcdSendable& aSendableObject,
       
   244     RPointerArray<CNcdNodeIdentifier>& aNodes,
       
   245     TInt aStatus )
       
   246     {
       
   247     DLTRACEIN((""));
       
   248     NotifyCompletionOfQueuedOperation( aId );
       
   249     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aSendableObject, aNodes, aStatus );
       
   250     }
       
   251     
       
   252 // ---------------------------------------------------------------------------
       
   253 // ?implementation_description
       
   254 // ---------------------------------------------------------------------------
       
   255 //    
       
   256 TInt CNcdLoadBundleNodeOperation::CompleteMessage(
       
   257     MCatalogsBaseMessage*& aMessage,
       
   258     TNcdOperationMessageCompletionId aId,
       
   259     RPointerArray<CNcdExpiredNode>& aExpiredNodes,
       
   260     TInt aStatus )
       
   261     {
       
   262     DLTRACEIN((""));
       
   263     NotifyCompletionOfQueuedOperation( aId );
       
   264     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aExpiredNodes, aStatus );
       
   265     }
       
   266     
       
   267 
       
   268 // ---------------------------------------------------------------------------
       
   269 // ?implementation_description
       
   270 // ---------------------------------------------------------------------------
       
   271 //
       
   272 TInt CNcdLoadBundleNodeOperation::Start()
       
   273     {
       
   274     DLTRACEIN((""));
       
   275     if ( iOperationState == EStateStopped )
       
   276         {
       
   277         // Op not yet running, queue it
       
   278         iOperationState = EStateRunning;                
       
   279         TRAPD( err, iOperationQueue.QueueOperationL( *this ) );        
       
   280         return err;
       
   281         }
       
   282     else
       
   283         {
       
   284         return KErrInUse;
       
   285         }
       
   286     }    
       
   287     
       
   288     
       
   289 // ---------------------------------------------------------------------------
       
   290 // ?implementation_description
       
   291 // ---------------------------------------------------------------------------
       
   292 //
       
   293 void CNcdLoadBundleNodeOperation::Cancel()
       
   294     {
       
   295     DLTRACEIN( ( "" ) );
       
   296     if ( iTransaction )
       
   297         {
       
   298         iTransaction->Cancel();        
       
   299         iTransaction = NULL;
       
   300         }
       
   301     if ( iParser )
       
   302         {
       
   303         iParser->CancelParsing();
       
   304         }    
       
   305     for ( TInt i = 0 ; i < iSubOps.Count() ; i++ )
       
   306         {
       
   307         iSubOps[i]->Cancel();
       
   308         iSubOps[i]->Close();
       
   309         }
       
   310     iSubOps.Reset();
       
   311     if ( iNodeDbLocked ) 
       
   312         {        
       
   313         iNodeManager->UnlockNodeDb( iNodeIdentifier->ClientUid() );
       
   314         iNodeDbLocked = EFalse;
       
   315         TRAP_IGNORE( iNodeManager->RevertNodeCacheL( *iNodeIdentifier ) );
       
   316         }
       
   317     }
       
   318 
       
   319 // ---------------------------------------------------------------------------
       
   320 // ?implementation_description
       
   321 // ---------------------------------------------------------------------------
       
   322 //
       
   323 void CNcdLoadBundleNodeOperation::HandleHttpEventL( 
       
   324         MCatalogsHttpOperation& aOperation, 
       
   325         TCatalogsHttpEvent aEvent )
       
   326     {
       
   327     DLTRACEIN((""));
       
   328     DASSERT( &aOperation == iTransaction );
       
   329     DASSERT( aOperation.OperationType() == ECatalogsHttpTransaction );
       
   330 
       
   331     TCatalogsTransportProgress progress( iTransaction->Progress() );
       
   332     
       
   333     // Are state and id needed?
       
   334     iProgress = TNcdSendableProgress( iBundleNodeState,
       
   335         iTransaction->OperationId().Id(), progress.iProgress,
       
   336         progress.iMaxProgress );
       
   337 
       
   338     switch( aEvent.iOperationState ) 
       
   339         {
       
   340         // Handle completed operation
       
   341         case ECatalogsHttpOpCompleted:
       
   342             {
       
   343             
       
   344             iTransaction->Release();
       
   345             iTransaction = NULL;
       
   346             // Inform parser that no more data will be sent
       
   347             iParser->EndL();
       
   348             break;
       
   349             }     
       
   350                
       
   351         // Handle operation in progress
       
   352         case ECatalogsHttpOpInProgress:
       
   353             {
       
   354             if( aEvent.iProgressState == ECatalogsHttpResponseBodyReceived )
       
   355                 {
       
   356                 // If config response, append the contents to the buffer.
       
   357                 if ( iBundleNodeState == EReceiveConf ) 
       
   358                     {
       
   359                     iConfigResponseBuf->InsertL(
       
   360                         iConfigResponseBuf->Size(), aOperation.Body() );                        
       
   361                     }               
       
   362 
       
   363                 // send received data to parser
       
   364                 iParser->ParseL( aOperation.Body() );
       
   365                 }
       
   366             break;
       
   367             }
       
   368                     
       
   369         default:
       
   370             {
       
   371             break;
       
   372             }
       
   373         }
       
   374     }
       
   375     
       
   376     
       
   377 TBool CNcdLoadBundleNodeOperation::HandleHttpError( 
       
   378     MCatalogsHttpOperation& aOperation, 
       
   379     TCatalogsHttpError aError )    
       
   380     {
       
   381     DLTRACEIN(("Error type: %d, code: %d", aError.iType, aError.iError ));    
       
   382     DASSERT( &aOperation == iTransaction );
       
   383     
       
   384     aOperation.Release();
       
   385     iTransaction = NULL;
       
   386 
       
   387     if ( iMasterServerRedirectionState == ERedirecting ) 
       
   388         {
       
   389         // Return back to original master server uri.
       
   390         iConfigManager.RemoveObserver( *this );
       
   391         TRAPD(err, iConfigManager.ResetMasterServerAddressL(
       
   392             iPendingMessage->Session().Context() ));
       
   393         if( err != KErrNone )
       
   394             {
       
   395             iError = err;
       
   396             iBundleNodeState = EFailed;
       
   397             }
       
   398         else
       
   399             {
       
   400             iMasterServerRedirectionState = EReverted;
       
   401             iBundleNodeState = EConfRequest;
       
   402             }
       
   403         }
       
   404     else
       
   405         {
       
   406         iError = aError.iError;
       
   407         iBundleNodeState = EFailed;
       
   408         }
       
   409     RunOperation();
       
   410     return ETrue;
       
   411     }
       
   412 
       
   413 void CNcdLoadBundleNodeOperation::ParseError( TInt aErrorCode )
       
   414     {
       
   415     DLTRACEIN(("error:%d", aErrorCode ));
       
   416     
       
   417     // Handle error only if not handling an error already
       
   418     // (cancellation of parsing may cause an unnecessary call to this function).
       
   419     if ( iError == KErrNone )
       
   420         {
       
   421         if ( iMasterServerRedirectionState == ERedirecting ) 
       
   422             {
       
   423             // Return back to original master server uri.
       
   424             iConfigManager.RemoveObserver( *this );
       
   425             TRAPD(err, iConfigManager.ResetMasterServerAddressL(
       
   426                 iPendingMessage->Session().Context() ));
       
   427             if( err != KErrNone )
       
   428                 {
       
   429                 iError = err;
       
   430                 iBundleNodeState = EFailed;
       
   431                 }
       
   432             else
       
   433                 {
       
   434                 iMasterServerRedirectionState = EReverted;
       
   435                 iBundleNodeState = EConfRequest;
       
   436                 }
       
   437             }
       
   438         else 
       
   439             {            
       
   440             iBundleNodeState = EFailed;
       
   441             iError = aErrorCode;
       
   442             }
       
   443             
       
   444         if ( iTransaction )
       
   445             {
       
   446             iTransaction->Cancel();
       
   447             iTransaction = NULL;
       
   448             }
       
   449         if ( iParser )
       
   450             {
       
   451             iParser->CancelParsing();
       
   452             }
       
   453         
       
   454         RunOperation();
       
   455         }
       
   456     }
       
   457 
       
   458 // ---------------------------------------------------------------------------
       
   459 // ?implementation_description
       
   460 // ---------------------------------------------------------------------------
       
   461 //
       
   462 void CNcdLoadBundleNodeOperation::ParseCompleteL( TInt aError )
       
   463     {
       
   464     DLTRACEIN((_L("error:%d"), aError ));
       
   465     
       
   466     if ( iParser )
       
   467         {
       
   468         delete iParser;
       
   469         iParser = NULL;
       
   470         }
       
   471     if ( aError != KErrNone )
       
   472         {
       
   473         DLTRACE(("Parsing error, stop operation!"))
       
   474         iError = aError;
       
   475         iBundleNodeState = EFailed;
       
   476         RunOperation();
       
   477         }
       
   478     else
       
   479         {
       
   480         DASSERT( iBundleNodeState == EReceiveConf || iBundleNodeState == EConfRequest );
       
   481         if ( iConfQuery )
       
   482             {
       
   483             DLTRACE(("Query received, let base op handle it"));
       
   484             iBundleNodeState = EConfQuery;
       
   485             // let base op handle the query
       
   486             TRAPD( err, CNcdBaseOperation::QueryReceivedL( iConfQuery ) );
       
   487             if ( err != KErrNone ) 
       
   488                 {
       
   489                 iError = err;
       
   490                 iBundleNodeState = EFailed;
       
   491                 RunOperation();
       
   492                 }
       
   493             }
       
   494         else if ( iBundleNodeState == EConfRequest )
       
   495             {
       
   496             DASSERT( iMasterServerRedirectionState == ERedirecting );
       
   497             RunOperation();
       
   498             }
       
   499         else if ( iContentSourceMap->ContentSourceCount() < 1 ) 
       
   500             {
       
   501             iError = KNcdErrorNoContentSources;
       
   502             iBundleNodeState = EFailed;
       
   503             DLINFO(("No content sources received, stop operation!"))
       
   504             RunOperation();
       
   505             }
       
   506         else
       
   507             {            
       
   508             iBundleNodeState = EBrowseRequest;
       
   509             RunOperation();
       
   510             }
       
   511         }
       
   512     DLTRACEOUT((""));
       
   513     }
       
   514 
       
   515 void CNcdLoadBundleNodeOperation::ConfigurationBeginL( const TDesC& aVersion, 
       
   516                                                      TInt aExpirationDelta )
       
   517     {
       
   518     DLTRACEIN((""));
       
   519 
       
   520     // set expiration delta for the bundle node
       
   521     iNodeManager->NodeL( *iNodeIdentifier ).
       
   522         CreateAndSetLinkL().SetValidUntilDelta( aExpirationDelta );
       
   523     // Pass to default observer.
       
   524     DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   525     iDefaultConfigurationProtocolObserver->ConfigurationBeginL( aVersion, aExpirationDelta );
       
   526     DLTRACEOUT((""));
       
   527     }
       
   528     
       
   529 void CNcdLoadBundleNodeOperation::ConfigurationQueryL(
       
   530     MNcdConfigurationProtocolQuery* aQuery )
       
   531     {
       
   532     DLTRACEIN(("Query received"));
       
   533     DASSERT( !iConfQuery );
       
   534     CleanupDeletePushL( aQuery );
       
   535     // create a query object form the protocol entity
       
   536     iConfQuery = CNcdQuery::NewL( *aQuery, IsHttpsUri( *iServerUri ) );
       
   537     CleanupStack::Pop( aQuery );    
       
   538     
       
   539 	// Pass ownership to default observer.
       
   540 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   541     iDefaultConfigurationProtocolObserver->ConfigurationQueryL( aQuery );
       
   542     DLTRACEOUT((""));
       
   543     }
       
   544 
       
   545 void CNcdLoadBundleNodeOperation::ClientConfigurationL(
       
   546     MNcdConfigurationProtocolClientConfiguration* aConfiguration )
       
   547     {
       
   548     DLTRACEIN((""));
       
   549     
       
   550     CleanupDeletePushL( aConfiguration );
       
   551     if ( !iNodeDbLocked )
       
   552         {        
       
   553         iNodeManager->LockNodeDbL( iNodeIdentifier->ClientUid() );
       
   554         iNodeDbLocked = ETrue;
       
   555         }
       
   556     DLINFO(("detail count:%d", aConfiguration->DetailCount()));
       
   557 
       
   558     // Parse access point data from client configuration response.
       
   559     iAccessPointManager.ParseAccessPointDataFromClientConfL(
       
   560         *aConfiguration, iPendingMessage->Session().Context().FamilyId() );
       
   561     
       
   562     for( TInt i = 0 ; i < aConfiguration->DetailCount() ; i++ )
       
   563         {
       
   564         const MNcdConfigurationProtocolDetail& detail = aConfiguration->DetailL( i );
       
   565         DLINFO((_L("detail: id=%S value=%S"), &detail.Id(), &detail.Value() ));
       
   566         
       
   567         if ( detail.Id() != KContentSources )
       
   568             {
       
   569             continue;
       
   570             }
       
   571         const RPointerArray<MNcdConfigurationProtocolDetail>& csDetails =
       
   572             detail.Details();
       
   573         DLINFO(("csDetails count=%d", csDetails.Count()));
       
   574         for ( TInt j = 0 ; j < csDetails.Count() ; j++ )
       
   575             {            
       
   576             MNcdConfigurationProtocolDetail* csDetail = csDetails[j];
       
   577             DLINFO((_L("csDetail: id=%S value=%S"), &csDetail->Id(), &csDetail->Value() ));
       
   578             if ( csDetail->Id() != KNameSpace )
       
   579                 {
       
   580                 continue;
       
   581                 }
       
   582             
       
   583             if ( csDetail->GroupId() == KCatalogBundle ) 
       
   584                 {
       
   585                 ParseCatalogBundleL( *csDetail );
       
   586                 continue;
       
   587                 }
       
   588 
       
   589             }           
       
   590         }
       
   591     if ( iContentSourceMap->ContentSourceCount() < 1 &&
       
   592               iMasterServerRedirectionState == EReverted )
       
   593         {
       
   594         iError = KNcdErrorNoContentSources;
       
   595         iBundleNodeState = EFailed;
       
   596         DLINFO(("No content sources received, stop operation!"))
       
   597         RunOperation();
       
   598         // Leave so that parsing is not continued.
       
   599         User::Leave( iError );
       
   600         }
       
   601     CleanupStack::Pop( aConfiguration );
       
   602 	// Pass ownership to default observer.
       
   603 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   604     iDefaultConfigurationProtocolObserver->ClientConfigurationL( aConfiguration );
       
   605     DLTRACEOUT((""));
       
   606     }
       
   607     
       
   608 void CNcdLoadBundleNodeOperation::ConfigurationDetailsL(
       
   609     CArrayPtr<MNcdConfigurationProtocolDetail>* aDetails )
       
   610     {
       
   611     DLTRACEIN((""));
       
   612     
       
   613     // Pass ownership to default observer.
       
   614 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   615 	iDefaultConfigurationProtocolObserver->ConfigurationDetailsL( aDetails );
       
   616 	
       
   617 	DLTRACEOUT((""));
       
   618     }
       
   619     
       
   620 void CNcdLoadBundleNodeOperation::ConfigurationActionRequestL(
       
   621     MNcdConfigurationProtocolActionRequest* aActionRequest )
       
   622     {
       
   623     DLTRACEIN((""));
       
   624 	// Pass ownership to default observer.
       
   625 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   626     iDefaultConfigurationProtocolObserver->ConfigurationActionRequestL( aActionRequest );
       
   627     DLTRACEOUT((""));
       
   628     }
       
   629 
       
   630 void CNcdLoadBundleNodeOperation::ConfigurationServerDetailsL( MNcdConfigurationProtocolServerDetails* aServerDetails )
       
   631     {
       
   632     DLTRACEIN((""));
       
   633 	// Pass ownership to default observer.
       
   634 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   635     iDefaultConfigurationProtocolObserver->ConfigurationServerDetailsL( aServerDetails );
       
   636     DLTRACEOUT((""));
       
   637     }
       
   638 
       
   639 void CNcdLoadBundleNodeOperation::ConfigurationErrorL( MNcdConfigurationProtocolError* aError )
       
   640     {
       
   641     DLTRACEIN((""));
       
   642     iBundleNodeState = EFailed;
       
   643     iError = aError->Code();
       
   644 
       
   645 	// Pass ownership to default observer.
       
   646 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   647     iDefaultConfigurationProtocolObserver->ConfigurationErrorL( aError );
       
   648    
       
   649     RunOperation();
       
   650 
       
   651     DLTRACEOUT((""));
       
   652     }
       
   653     
       
   654 void CNcdLoadBundleNodeOperation::ConfigurationEndL()
       
   655     {
       
   656     DLTRACEIN((""));
       
   657 	// Pass to default observer.
       
   658 	DASSERT( iDefaultConfigurationProtocolObserver != NULL );
       
   659     iDefaultConfigurationProtocolObserver->ConfigurationEndL();
       
   660     DLTRACEOUT((""));
       
   661     }
       
   662 
       
   663 
       
   664 void CNcdLoadBundleNodeOperation::Progress( CNcdBaseOperation& aOperation )
       
   665     {
       
   666     (void) aOperation; // suppresses compiler warning
       
   667     DASSERT( iBundleNodeState == EReceiveBrowse )
       
   668     DASSERT( aOperation.Type() == ELoadNodeOperation )
       
   669     }
       
   670     
       
   671 void CNcdLoadBundleNodeOperation::QueryReceived( CNcdBaseOperation& /*aOperation*/,
       
   672     CNcdQuery* aQuery )
       
   673     {
       
   674     DASSERT( iBundleNodeState == EReceiveBrowse )
       
   675     TRAPD( err, iSubOpQuerys.AppendL( aQuery ) );
       
   676     aQuery->InternalAddRef();
       
   677     if( err != KErrNone )
       
   678         {
       
   679         iError = err;
       
   680         iBundleNodeState = EFailed;
       
   681         }
       
   682     RunOperation();
       
   683     }
       
   684     
       
   685 void CNcdLoadBundleNodeOperation::OperationComplete( CNcdBaseOperation* aOperation,
       
   686                                                    TInt aError )
       
   687     {
       
   688     DLTRACEIN(("error=%d", aError));
       
   689     DLINFO((("iBundleNodeState = %d"), iBundleNodeState ));
       
   690     (void) aError; // suppresses compiler warning
       
   691 
       
   692     DASSERT( iBundleNodeState == EReceiveBrowse || 
       
   693              iBundleNodeState == EBrowseRequest )
       
   694     DASSERT( aOperation->Type() == ELoadNodeOperation )
       
   695     
       
   696     DLINFO(("subop count: failed:%d completed:%d total:%d",
       
   697                 iFailedSubOps.Count(), iCompletedSubOps.Count(), iSubOps.Count() ));
       
   698     
       
   699     TRAPD(err, 
       
   700     CNcdLoadNodeOperationImpl* loadOp =
       
   701         static_cast<CNcdLoadNodeOperationImpl*>( aOperation );
       
   702     DASSERT( loadOp->State() == CNcdLoadNodeOperationImpl::EFailed ||
       
   703         loadOp->State() == CNcdLoadNodeOperationImpl::EComplete )
       
   704     if ( loadOp->State() == CNcdLoadNodeOperationImpl::EFailed )
       
   705         {
       
   706         iFailedSubOps.AppendL( loadOp );
       
   707         }
       
   708     else if ( loadOp->State() == CNcdLoadNodeOperationImpl::EComplete )
       
   709         {
       
   710         iCompletedSubOps.AppendL( loadOp );
       
   711         const RPointerArray<CNcdNodeIdentifier>& loadedNodes = loadOp->LoadedNodes();
       
   712 
       
   713         // add loaded nodes from child op to our own array
       
   714         for ( TInt i = 0 ; i < loadedNodes.Count() ; i++ )
       
   715             {
       
   716             CNcdNodeIdentifier* id = CNcdNodeIdentifier::NewLC( *loadedNodes[i] );
       
   717             iLoadedNodes.AppendL( id );
       
   718             CleanupStack::Pop( id );
       
   719             }
       
   720         }
       
   721     
       
   722     if ( iBundleNodeState ==  EReceiveBrowse )
       
   723         {
       
   724         // call RunOperation only in this state,
       
   725         // otherwise RunOperation could call itself immediately
       
   726         // after starting a sub op
       
   727         // (sub-op start -> error -> complete callback -> run op )
       
   728         RunOperation();
       
   729         }); //TRAPD    
       
   730     if ( err != KErrNone )
       
   731         {
       
   732         iError = err;
       
   733         iBundleNodeState = EFailed;
       
   734         RunOperation();
       
   735         }
       
   736     }
       
   737     
       
   738 void CNcdLoadBundleNodeOperation::ConfigurationChangedL() 
       
   739     {
       
   740     DLTRACEIN((( "iBundleNodeState: %d"), iBundleNodeState ));
       
   741     DASSERT( iBundleNodeState == EReceiveConf )    
       
   742     // Master server address changed. Restart operation.
       
   743     iBundleNodeState = EConfRequest;
       
   744     iMasterServerRedirectionState = ERedirecting;    
       
   745     }
       
   746     
       
   747 void CNcdLoadBundleNodeOperation::ReceiveMessage(
       
   748     MCatalogsBaseMessage* aMessage,
       
   749     TInt aFunctionNumber ) 
       
   750     {    
       
   751     DLTRACEIN((_L("Handle: %i, aFunctionNumber=%d"), aMessage->Handle(),
       
   752     aFunctionNumber));
       
   753 
       
   754     switch ( aFunctionNumber ) 
       
   755         {
       
   756         case ENCDOperationFunctionGetData:
       
   757             {
       
   758             HandleConfigurationDataRequestMessage( *aMessage );
       
   759             break;
       
   760             }
       
   761         default:
       
   762             {
       
   763             CNcdBaseOperation::ReceiveMessage( aMessage, aFunctionNumber );
       
   764             break;
       
   765             }
       
   766         }
       
   767     }
       
   768 
       
   769 void CNcdLoadBundleNodeOperation::ErrorL( MNcdPreminetProtocolError* aData )
       
   770     {
       
   771     DLTRACEIN((""));    
       
   772     // Default observer deletes aData
       
   773     iParser->DefaultObserver().ErrorL( aData );
       
   774     }
       
   775 
       
   776 // ---------------------------------------------------------------------------
       
   777 // ?description_if_needed
       
   778 // ---------------------------------------------------------------------------
       
   779 //
       
   780 CNcdLoadBundleNodeOperation::CNcdLoadBundleNodeOperation(
       
   781     CNcdGeneralManager& aGeneralManager, 
       
   782     MCatalogsHttpSession& aHttpSession,  
       
   783     MNcdOperationRemoveHandler* aRemoveHandler,
       
   784     MNcdOperationQueue& aOperationQueue,
       
   785     MCatalogsSession& aSession )
       
   786     : CNcdBaseOperation( aGeneralManager, aRemoveHandler, ELoadBundleNodeOperation,
       
   787         aSession ), 
       
   788       iAccessPointManager( aGeneralManager.AccessPointManager() ),
       
   789       iHttpSession( aHttpSession ),
       
   790       iProtocol( aGeneralManager.ProtocolManager() ),
       
   791       iConfigManager( aGeneralManager.ConfigurationManager() ),
       
   792       iNodeDbLocked( EFalse ),
       
   793       iOperationQueue( aOperationQueue ),
       
   794       iFirstConfRequest( ETrue )
       
   795     {
       
   796     iBundleNodeState = EConfRequest;
       
   797     iMasterServerRedirectionState = EBegin;
       
   798     iProgress.iState = 0;
       
   799     iProgress.iOperationId = 0;
       
   800     iProgress.iProgress = 0;
       
   801     iProgress.iMaxProgress = 100;
       
   802     }
       
   803 
       
   804 
       
   805 // ---------------------------------------------------------------------------
       
   806 // ?description_if_needed
       
   807 // ---------------------------------------------------------------------------
       
   808 //
       
   809 void CNcdLoadBundleNodeOperation::ConstructL(
       
   810     const CNcdNodeIdentifier& aNodeIdentifier )
       
   811     {
       
   812     DLTRACEIN((""));
       
   813     CNcdBaseOperation::ConstructL();
       
   814     
       
   815     iConfigResponseBuf = CBufFlat::NewL( 100 );
       
   816     iNodeIdentifier = CNcdNodeIdentifier::NewL( aNodeIdentifier );
       
   817     }
       
   818 
       
   819 // ---------------------------------------------------------------------------
       
   820 // ?implementation_description
       
   821 // ---------------------------------------------------------------------------
       
   822 //
       
   823 HBufC8* CNcdLoadBundleNodeOperation::CreateConfRequestLC( CNcdQuery* aQuery )
       
   824     {
       
   825     DLTRACEIN((""));
       
   826     CNcdRequestConfiguration* req =
       
   827         NcdRequestGenerator::CreateConfigurationRequestLC();
       
   828     CNcdNode& bundleNode = iNodeManager->NodeL( *iNodeIdentifier );
       
   829     
       
   830     CNcdNodeIdentifier* metadataIdentifier = 
       
   831         NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *iNodeIdentifier );
       
   832             
       
   833     RBuf8 buf;
       
   834     CleanupClosePushL( buf );
       
   835     buf.CreateL( metadataIdentifier->NodeId().Length() );
       
   836     buf.Copy( metadataIdentifier->NodeId() );
       
   837     
       
   838     req->AddCatalogBundleRequestL( buf );
       
   839     CleanupStack::PopAndDestroy( &buf );
       
   840     
       
   841     CleanupStack::PopAndDestroy( metadataIdentifier );
       
   842     
       
   843     if( aQuery )
       
   844         {
       
   845         DASSERT(( aQuery->Response() == MNcdQuery::EAccepted ));
       
   846         
       
   847         MNcdConfigurationProtocolQueryResponse* queryResponse =
       
   848             CreateResponseL( *aQuery );
       
   849         CleanupStack::PushL( queryResponse );
       
   850         req->AddQueryResponseL( queryResponse );
       
   851         CleanupStack::Pop( queryResponse );
       
   852         }
       
   853         
       
   854     HBufC8* data = iProtocol.ProcessConfigurationRequestL(
       
   855         iPendingMessage->Session().Context(), *req );
       
   856     CleanupStack::PopAndDestroy( req );
       
   857     CleanupStack::PushL( data );    
       
   858     return data;
       
   859     }
       
   860 
       
   861 
       
   862 void CNcdLoadBundleNodeOperation::RevertNodesOfBrokenSourcesToCacheL() 
       
   863     {
       
   864     DLTRACEIN((""));
       
   865     // Revert the nodes from broken content sources
       
   866     CNcdRootNode* rootNode( NULL );
       
   867     TRAPD( err, rootNode = &iNodeManager->RootNodeL( iNodeIdentifier->ClientUid() ) );
       
   868     
       
   869     if ( err != KErrNone )
       
   870         {
       
   871         // Root node has not been created, so there is no old content source map.
       
   872         // There is no need to revert anything.
       
   873         return;
       
   874         }
       
   875         
       
   876     DASSERT( rootNode );
       
   877     
       
   878     CNcdContentSourceMap& oldContentSourceMap = rootNode->ContentSourceMap();
       
   879     DLINFO(("old content source count=%d", oldContentSourceMap.ContentSourceCount() ));
       
   880     for ( TInt i = 0; i < oldContentSourceMap.ContentSourceCount(); i++ ) 
       
   881         {
       
   882         CNcdContentSource& oldSource = oldContentSourceMap.ContentSource( i );
       
   883 
       
   884         // Note that the content sources contain node identifiers, 
       
   885         // not metadata identifiers.        
       
   886         RPointerArray<CNcdNodeIdentifier>& oldNodes = 
       
   887             oldContentSourceMap.NodesL( oldSource );
       
   888             
       
   889         if ( iContentSourceMap->HasContentSource( oldSource ) )
       
   890             {           
       
   891             DLINFO(("same content source")); 
       
   892             CNcdContentSource& source = 
       
   893                 iContentSourceMap->ContentSourceL( oldSource );
       
   894             if ( source.IsBroken() ) 
       
   895                 {
       
   896                 // Broken content source, revert the nodes belonging to this source                                             
       
   897                 for ( TInt i = 0; i < oldNodes.Count(); i++ ) 
       
   898                     {
       
   899                     RevertNodeL( *oldNodes[i], source );
       
   900                     }
       
   901                 }
       
   902             }
       
   903         else if ( oldSource.ParentIdentifier().Equals( *iNodeIdentifier ) )
       
   904             {
       
   905             DLINFO(("content source disappeared"));
       
   906             for ( TInt i = 0; i < oldNodes.Count(); i++ ) 
       
   907                 {                
       
   908                 iNodeManager->RemoveNodeL( *oldNodes[i] );
       
   909                 }
       
   910             }            
       
   911         }
       
   912     }
       
   913         
       
   914     
       
   915 void CNcdLoadBundleNodeOperation::RevertNodeL(
       
   916     const CNcdNodeIdentifier& aNodeIdentifier,
       
   917     const CNcdContentSource& aContentSource ) 
       
   918     {
       
   919     DLTRACEIN((_L("node ns: %S, id: %S"), 
       
   920         &aNodeIdentifier.NodeNameSpace(), 
       
   921         &aNodeIdentifier.NodeId() ));
       
   922         
       
   923     iNodeManager->RevertNodeFromTempCacheL( aNodeIdentifier );
       
   924     CNcdNode* node = iNodeManager->NodePtrL( aNodeIdentifier );
       
   925     DASSERT( node );
       
   926     
       
   927     // If the node is bundle's child, it must be added as a child since it was removed from the 
       
   928     // child list as it was moved to temp cache.
       
   929     CNcdNodeIdentifier* parentId = NcdNodeIdentifierEditor::ParentOfLC( aNodeIdentifier );
       
   930     if ( parentId->Equals( *iNodeIdentifier ) ) 
       
   931         {
       
   932         DLINFO(("Child of bundle"));
       
   933         CNcdNode& bundleNode = 
       
   934             iNodeManager->NodeL( *iNodeIdentifier );
       
   935         CNcdNodeIdentifier* metaOfChild = 
       
   936             NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( aNodeIdentifier );
       
   937         iNodeManager->AddToParentL(
       
   938             *parentId, *metaOfChild, CNcdNodeFactory::ENcdNodeFolder, CNcdNodeFactory::ENcdBundleNode,
       
   939             CNcdNodeFactory::NodePurposeL( *node ), CNcdNodeManager::EInsert,
       
   940             iContentSourceMap->GetInsertIndexL( aContentSource, *parentId ) );
       
   941         CleanupStack::PopAndDestroy( metaOfChild );
       
   942         }
       
   943     CleanupStack::PopAndDestroy( parentId );        
       
   944     }
       
   945     
       
   946     
       
   947 void CNcdLoadBundleNodeOperation::RemoveOldNodesL() 
       
   948     {
       
   949     DLTRACEIN((""));
       
   950     CNcdRootNode& rootNode = 
       
   951         iNodeManager->RootNodeL( iNodeIdentifier->ClientUid() );
       
   952     CNcdContentSourceMap& oldContentSourceMap = rootNode.ContentSourceMap();
       
   953     DLINFO(("old content source count=%d", oldContentSourceMap.ContentSourceCount() ));
       
   954     for ( TInt i = 0; i < oldContentSourceMap.ContentSourceCount(); i++ ) 
       
   955         {
       
   956         CNcdContentSource& oldSource = oldContentSourceMap.ContentSource( i );
       
   957 
       
   958         // Note that the content sources contain node identifiers, 
       
   959         // not metadata identifiers.        
       
   960         RPointerArray<CNcdNodeIdentifier>& oldNodes = 
       
   961             oldContentSourceMap.NodesL( oldSource );
       
   962             
       
   963         if ( iContentSourceMap->HasContentSource( oldSource ) )
       
   964             {           
       
   965             DLINFO(("same content source")); 
       
   966             CNcdContentSource& source = 
       
   967                 iContentSourceMap->ContentSourceL( oldSource );
       
   968             if ( !source.IsBroken() ) 
       
   969                 {                
       
   970                 RPointerArray<CNcdNodeIdentifier>& nodes = 
       
   971                     iContentSourceMap->NodesL( source );
       
   972                 for ( TInt i = 0; i < oldNodes.Count(); i++ ) 
       
   973                     {
       
   974                     if ( !ContainsNode( nodes, *oldNodes[i] ) ) 
       
   975                         {                        
       
   976                         // Note that the content sources contain node identifiers, 
       
   977                         // not metadata identifiers.
       
   978                         iNodeManager->RemoveNodeL( *oldNodes[i] );
       
   979                         }
       
   980                     }
       
   981                 }
       
   982             }
       
   983         else if ( oldSource.ParentIdentifier().Equals( *iNodeIdentifier ) )
       
   984             {
       
   985             DLINFO(("content source disappeared"));
       
   986             for ( TInt i = 0; i < oldNodes.Count(); i++ ) 
       
   987                 {                
       
   988                 iNodeManager->RemoveNodeL( *oldNodes[i] );
       
   989                 }
       
   990             }
       
   991         }
       
   992     }
       
   993     
       
   994 void CNcdLoadBundleNodeOperation::AddBundleToLoadedNodesL() 
       
   995     {
       
   996     DLTRACEIN((""));
       
   997     CNcdNodeIdentifier* bundleId = CNcdNodeIdentifier::NewLC( *iNodeIdentifier );
       
   998     iLoadedNodes.AppendL( bundleId );
       
   999     CleanupStack::Pop( bundleId );    
       
  1000     }
       
  1001     
       
  1002 void CNcdLoadBundleNodeOperation::SetAlwaysVisibleFlagsL() 
       
  1003     {
       
  1004     DLTRACEIN((""));
       
  1005     for ( TInt i = 0; i < iContentSourceMap->ContentSourceCount(); i++ ) 
       
  1006         {
       
  1007         CNcdContentSource& contentSource = iContentSourceMap->ContentSource( i );
       
  1008         if ( !contentSource.AlwaysVisible() ) 
       
  1009             {
       
  1010             continue;
       
  1011             }
       
  1012         // Get the reference. So, no need to close this array.
       
  1013         RPointerArray<CNcdNodeIdentifier>& nodes = iContentSourceMap->NodesL( contentSource );
       
  1014         TRAPD( err, 
       
  1015             {            
       
  1016             for ( TInt i = 0; i < nodes.Count(); i++ ) 
       
  1017                 {
       
  1018                 // Because content sources use node id 
       
  1019                 CNcdNodeIdentifier* nodeId = nodes[i];
       
  1020                 
       
  1021                 // Check whether the node is loaded completely
       
  1022                 for ( TInt i = 0; i < iLoadedNodes.Count(); i++ ) 
       
  1023                     {
       
  1024                     if ( iLoadedNodes[i]->Equals( *nodeId ) ) 
       
  1025                         {                        
       
  1026                         CNcdNode& node = iNodeManager->NodeL( *nodeId );
       
  1027                         CNcdNodeMetaData& metadata = node.NodeMetaDataL();                
       
  1028                         metadata.SetAlwaysVisible( ETrue );
       
  1029                         
       
  1030                         // DLMAIN-523, "Always visible information is not 
       
  1031                         // persisted to disk"
       
  1032                         iNodeManager->DbSaveNodeMetaDataL( metadata );
       
  1033                         break;
       
  1034                         }
       
  1035                     }
       
  1036                 }
       
  1037             }); // TRAP
       
  1038 
       
  1039 
       
  1040         if ( err == KErrNotFound ) 
       
  1041             {
       
  1042             DASSERT( EFalse );
       
  1043             }
       
  1044         else if ( err != KErrNone )
       
  1045             {
       
  1046             User::Leave( err );
       
  1047             }
       
  1048 
       
  1049         }
       
  1050     DLTRACEOUT(("Ok."));
       
  1051     }
       
  1052     
       
  1053 void CNcdLoadBundleNodeOperation::UpdateCsMapToRootNodeL() 
       
  1054     {
       
  1055     DLTRACEIN((""));
       
  1056     CNcdRootNode& rootNode = iNodeManager->CreateRootL( iNodeIdentifier->ClientUid() );
       
  1057     CNcdContentSourceMap& oldMap = rootNode.ContentSourceMap();
       
  1058     
       
  1059     // Find the bundle from old map
       
  1060     TInt folderIndex = oldMap.FindFolder( *iNodeIdentifier );
       
  1061     if ( folderIndex == KErrNotFound ) 
       
  1062         {
       
  1063         // This bundle folder is not in root node's content source map.
       
  1064         // Can happen for example when cache has been cleared and favorite view opened
       
  1065         // if there is a bundle folder in favorites.
       
  1066         for ( TInt i = 0; i < iContentSourceMap->ContentSourceCount(); i++ ) 
       
  1067             {
       
  1068             CNcdContentSource& cs = iContentSourceMap->ContentSource( i );
       
  1069             CNcdContentSource* copy = cs.CopyL();
       
  1070             CleanupStack::PushL( copy );
       
  1071             oldMap.AppendContentSourceL( copy );
       
  1072             CleanupStack::Pop( copy );
       
  1073             }
       
  1074         }
       
  1075     else 
       
  1076         {
       
  1077         // Root node's content source map contains this bundle folder already. Clear
       
  1078         // the old content sources from the bundle and add the new ones.
       
  1079         CNcdFolderContent& content = oldMap.FolderContent( folderIndex );
       
  1080         content.ClearContentSources();
       
  1081         for ( TInt i = 0; i < iContentSourceMap->ContentSourceCount(); i++ ) 
       
  1082             {
       
  1083             CNcdContentSource& cs = iContentSourceMap->ContentSource( i );
       
  1084             CNcdContentSource* copy = cs.CopyL();
       
  1085             CleanupStack::PushL( copy );
       
  1086             content.AppendContentSourceL( copy );    
       
  1087             CleanupStack::Pop( copy );
       
  1088             }
       
  1089         }
       
  1090         
       
  1091     DASSERT( !iNodeDbLocked );        
       
  1092     // Root node's content source map updated, save root node to db
       
  1093     iNodeManager->DbSaveNodeL( rootNode );
       
  1094     }
       
  1095 
       
  1096      
       
  1097 void CNcdLoadBundleNodeOperation::ParseCatalogBundleL(
       
  1098     const MNcdConfigurationProtocolDetail& aDetail ) 
       
  1099     {  
       
  1100     DLTRACEIN((""));
       
  1101     DASSERT( aDetail.GroupId() == KCatalogBundle );
       
  1102     DASSERT( aDetail.Id() == KNameSpace );
       
  1103     
       
  1104     // The bundle node should already exist.
       
  1105     CNcdNode& bundleFolder = iNodeManager->NodeL( *iNodeIdentifier );
       
  1106     CNcdNodeLink& link = bundleFolder.NodeLinkL();
       
  1107 
       
  1108     CNcdNodeIdentifier* metaDataId =
       
  1109         NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *iNodeIdentifier );
       
  1110     
       
  1111     const RPointerArray<MNcdConfigurationProtocolContent>& bundleContents = 
       
  1112         aDetail.Contents();
       
  1113 
       
  1114 #ifdef CATALOGS_BUILD_CONFIG_DEBUG    
       
  1115     const TDesC* bundleId = NULL;
       
  1116     for ( TInt i = 0; i < bundleContents.Count(); i++ ) 
       
  1117         {
       
  1118         const MNcdConfigurationProtocolContent* content = bundleContents[i];
       
  1119         if ( content->Key() == KId ) 
       
  1120             {
       
  1121             bundleId = &content->Value();
       
  1122             break;
       
  1123             }
       
  1124         }
       
  1125         
       
  1126     DASSERT( bundleId );
       
  1127     DASSERT( *bundleId == metaDataId->NodeId() );
       
  1128     DASSERT( aDetail.Value() == metaDataId->NodeNameSpace() );    
       
  1129 #endif  
       
  1130     
       
  1131     // Also, notice that it is essential to insert the metadata identifier into the
       
  1132     // link info. So, the right metadata will be found when the bundle is opened
       
  1133     // from the database. For example when application has been started.
       
  1134     link.SetMetaDataIdentifierL( *metaDataId );
       
  1135     
       
  1136     // Create meta data for bundle folder.
       
  1137     CNcdNodeMetaData& bundleMetaData = 
       
  1138         iNodeManager->CreateNodeMetaDataL( *metaDataId, CNcdNodeFactory::ENcdNodeFolder );
       
  1139     
       
  1140     for ( TInt i = 0; i < bundleContents.Count(); i++ )
       
  1141         {
       
  1142         const MNcdConfigurationProtocolContent* content = bundleContents[i];
       
  1143         if ( content->Key() == KName ) 
       
  1144             {
       
  1145             bundleMetaData.SetNodeNameL( content->Value() );
       
  1146             }
       
  1147         else if ( content->Key() == KDescription ) 
       
  1148             {
       
  1149             bundleMetaData.SetDescriptionL( content->Value() );
       
  1150             }
       
  1151         else if ( content->Key() == KValidUntil ) 
       
  1152             {
       
  1153             link.SetValidUntilDelta(
       
  1154                 NcdProtocolUtils::DesDecToIntL( content->Value() ) );
       
  1155             }
       
  1156         else if ( content->Key() == KViewType ) 
       
  1157             {
       
  1158             static_cast<CNcdBundleFolder&>( bundleFolder ).SetViewTypeL( 
       
  1159                 content->Value() );
       
  1160             }
       
  1161         else if ( content->Key() == KDisclaimer )
       
  1162             {
       
  1163             HandleBundleDisclaimerL( bundleMetaData, content->Value() );
       
  1164             }
       
  1165         }
       
  1166             
       
  1167     const RPointerArray<MNcdConfigurationProtocolDetail>& subCatalogs = 
       
  1168         aDetail.Details();
       
  1169 
       
  1170     // Parse icon data.
       
  1171     for ( TInt i = 0; i < subCatalogs.Count(); i++ ) 
       
  1172         {
       
  1173         MNcdConfigurationProtocolDetail* detail = subCatalogs[i];
       
  1174         if ( detail->Id() != KIcon ) 
       
  1175             {
       
  1176             continue;
       
  1177             }
       
  1178         const RPointerArray<MNcdConfigurationProtocolContent> iconContents = 
       
  1179             detail->Contents();
       
  1180         CNcdNodeIcon* icon = CNcdNodeIcon::NewL( *iNodeManager, bundleMetaData );
       
  1181         bundleMetaData.SetIcon( icon );
       
  1182         
       
  1183         for ( TInt i = 0; i < iconContents.Count(); i++ ) 
       
  1184             {
       
  1185             MNcdConfigurationProtocolContent* content = iconContents[i];
       
  1186             if ( content->Key() == KId ) 
       
  1187                 {
       
  1188                 icon->SetIconIdL( content->Value() );
       
  1189                 }
       
  1190             else if ( content->Key() == KData ) 
       
  1191                 {
       
  1192                 const TDesC& iconData = content->Content();
       
  1193                 HBufC8* iconData8 = HBufC8::NewLC( iconData.Length() );
       
  1194                 iconData8->Des().Copy( iconData );
       
  1195                 HBufC8* decodedData = 
       
  1196                     NcdProtocolUtils::DecodeBase64LC( *iconData8 );
       
  1197                 
       
  1198                 // Save the icon data to database.
       
  1199                 CNcdNodeIdentifier* iconId = CNcdNodeIdentifier::NewLC(
       
  1200                     metaDataId->NodeNameSpace(), icon->IconId(), 
       
  1201                     icon->Uri(), metaDataId->ClientUid() );
       
  1202                 iNodeManager->DbSaveIconDataL( *iconId, *decodedData );
       
  1203                 CleanupStack::PopAndDestroy( iconId );
       
  1204                 CleanupStack::PopAndDestroy( decodedData );
       
  1205                 CleanupStack::PopAndDestroy( iconData8 );
       
  1206                 }
       
  1207             else if ( content->Key() == KUri && content->Value() != KNullDesC )
       
  1208                 {
       
  1209                 DLTRACE((_L("Setting bundle icon uri: %S"), &content->Value() ));
       
  1210                 icon->SetUriL( content->Value() );
       
  1211                 }
       
  1212             }
       
  1213         }
       
  1214         
       
  1215     CleanupStack::PopAndDestroy( metaDataId );
       
  1216     
       
  1217     iNodeManager->DbSaveNodeMetaDataL( bundleMetaData );          
       
  1218 
       
  1219     // Set the metadata to the bundle folder because it was not set during creation.
       
  1220     bundleFolder.SetNodeMetaDataL( bundleMetaData );
       
  1221     
       
  1222     iNodeManager->DbSaveNodeL( bundleFolder );        
       
  1223 
       
  1224     // Parse sub catalogs.            
       
  1225     for ( TInt i = 0; i < subCatalogs.Count(); i++ ) 
       
  1226         {
       
  1227         MNcdConfigurationProtocolDetail* subCatalog = subCatalogs[i];
       
  1228         if ( subCatalog->GroupId() != KSubCatalogs ) 
       
  1229             {
       
  1230             continue;
       
  1231             }
       
  1232             
       
  1233         DASSERT( subCatalog->Id() == KNameSpace );
       
  1234         // The parameter is the parent node identifier.
       
  1235         CNcdContentSource* contentSource = CNcdContentSource::NewLC( bundleFolder.Identifier() );
       
  1236         contentSource->SetNameSpaceL( subCatalog->Value() );
       
  1237 
       
  1238         DLINFO((_L("Bundle subcatalog ns(/value): %S"), 
       
  1239                 &subCatalog->Value()));
       
  1240         
       
  1241         const RPointerArray<MNcdConfigurationProtocolDetail>& subCatalogDetails =
       
  1242             subCatalog->Details();
       
  1243         for ( TInt i = 0; i < subCatalogDetails.Count(); i++ ) 
       
  1244             {
       
  1245             const MNcdConfigurationProtocolDetail* detail = subCatalogDetails[i];
       
  1246             if ( detail->Id() == KUri ) 
       
  1247                 {
       
  1248                 contentSource->SetUriL( detail->Value() );
       
  1249                 DLINFO((_L("Bundle subcatalog detail uri(/value): %S"), 
       
  1250                         &detail->Value()));
       
  1251                 }
       
  1252             }
       
  1253         
       
  1254         const RPointerArray<MNcdConfigurationProtocolContent>& subCatalogContents =
       
  1255             subCatalog->Contents();
       
  1256         for ( TInt i = 0; i < subCatalogContents.Count(); i++ ) 
       
  1257             {
       
  1258             const MNcdConfigurationProtocolContent* content = subCatalogContents[i];
       
  1259             if ( content->Key() == KId ) 
       
  1260                 {
       
  1261                 // Notice that the the content source ids should be node identifiers.
       
  1262                 // Not the actual metadata identifiers. So, append the root info
       
  1263                 // in front of the value gotten from the server.
       
  1264                 CNcdNodeIdentifier* contentIdentifier =
       
  1265                     CNcdNodeIdentifier::NewLC( contentSource->NameSpace(),
       
  1266                                                content->Value(),
       
  1267                                                contentSource->Uri(),
       
  1268                                                bundleFolder.Identifier().ClientUid() );
       
  1269 
       
  1270                 CNcdNodeIdentifier* actualNodeIdentifier =
       
  1271                     NcdNodeIdentifierEditor::CreateNodeIdentifierLC( bundleFolder.Identifier(),
       
  1272                                                                       *contentIdentifier );
       
  1273                                                               
       
  1274                 contentSource->SetNodeIdL( actualNodeIdentifier->NodeId() );
       
  1275                 
       
  1276                 DLINFO((_L("Bundle subcatalog content set node id(/value): %S"), 
       
  1277                         &actualNodeIdentifier->NodeId()));
       
  1278                         
       
  1279                 CleanupStack::PopAndDestroy( actualNodeIdentifier );
       
  1280                 CleanupStack::PopAndDestroy( contentIdentifier );
       
  1281                 }
       
  1282             else if ( content->Key() == KProvider ) 
       
  1283                 {
       
  1284                 contentSource->SetProviderL( content->Value() );
       
  1285                 DLINFO((_L("Bundle subcatalog content set provider (/value): %S"), 
       
  1286                         &content->Value()));
       
  1287                 }
       
  1288             else if ( content->Key() == KTransparent ) 
       
  1289                 {
       
  1290                 TBool transparent = EFalse;
       
  1291                 NcdProtocolUtils::DesToBool( transparent, content->Value() );
       
  1292                 contentSource->SetTransparent( transparent );
       
  1293                 }
       
  1294             }
       
  1295             
       
  1296         // add the content source to content source map
       
  1297         iContentSourceMap->AppendContentSourceL( contentSource );
       
  1298         CleanupStack::Pop( contentSource );
       
  1299         }
       
  1300     }
       
  1301     
       
  1302     
       
  1303 void CNcdLoadBundleNodeOperation::NotifyCompletionOfQueuedOperation(
       
  1304     TNcdOperationMessageCompletionId aId )
       
  1305     {
       
  1306     DLTRACEIN((""));
       
  1307     if ( aId == ENCDOperationMessageCompletionComplete ||
       
  1308          aId == ENCDOperationMessageCompletionError )
       
  1309         {
       
  1310         iOperationQueue.QueuedOperationComplete( *this );
       
  1311         }
       
  1312     }
       
  1313     
       
  1314     
       
  1315 TBool CNcdLoadBundleNodeOperation::ContainsNode(
       
  1316     const RPointerArray<CNcdNodeIdentifier>& aNodes,
       
  1317     const CNcdNodeIdentifier& aNode) 
       
  1318     {
       
  1319     for ( TInt i = 0; i < aNodes.Count(); i++ ) 
       
  1320         {
       
  1321         CNcdNodeIdentifier* nodeId = aNodes[i];
       
  1322         DASSERT( nodeId->ClientUid() == aNode.ClientUid() );
       
  1323         if ( nodeId->Equals( aNode ) ) 
       
  1324             {
       
  1325             return ETrue;
       
  1326             }
       
  1327         }
       
  1328     return EFalse;
       
  1329     }
       
  1330 
       
  1331 
       
  1332 void CNcdLoadBundleNodeOperation::HandleBundleDisclaimerL(
       
  1333     CNcdNodeMetaData& aMetadata, 
       
  1334     const TDesC& aDisclaimer )
       
  1335     {
       
  1336     DLTRACEIN((""));
       
  1337     // Create a temp query that is initialized with the disclaimer data
       
  1338     // and internalize the disclaimer-object with the query. This
       
  1339     // way we don't have to add new setters to CNcdNodeDisclaimer
       
  1340     CNcdConfigurationProtocolQueryImpl* tempQuery = 
       
  1341         CNcdConfigurationProtocolQueryImpl::NewLC();
       
  1342     tempQuery->iBodyText->SetDataL( aDisclaimer );
       
  1343     tempQuery->iSemantics = MNcdQuery::ESemanticsDisclaimer;
       
  1344     
       
  1345     CNcdNodeDisclaimer* disclaimer = CNcdNodeDisclaimer::NewLC();
       
  1346     disclaimer->InternalizeL( *tempQuery );
       
  1347     aMetadata.SetDisclaimer( disclaimer );
       
  1348     
       
  1349     CleanupStack::Pop( disclaimer );
       
  1350     CleanupStack::PopAndDestroy( tempQuery );
       
  1351     }
       
  1352 
       
  1353     
       
  1354 void CNcdLoadBundleNodeOperation::HandleConfigurationDataRequestMessage(
       
  1355     MCatalogsBaseMessage& aMessage ) 
       
  1356     {
       
  1357     DLTRACEIN((""));
       
  1358     TPtr8 data = iConfigResponseBuf->Ptr( 0 );
       
  1359     
       
  1360     TRAPD( err, aMessage.CompleteAndReleaseL( data, KErrNone ) );
       
  1361     if ( err != KErrNone ) 
       
  1362         {
       
  1363         aMessage.CompleteAndRelease( err );
       
  1364         }        
       
  1365     }    
       
  1366 // ---------------------------------------------------------------------------
       
  1367 // From class CNcdBaseOperation.
       
  1368 // ?implementation_description
       
  1369 // ---------------------------------------------------------------------------
       
  1370 //
       
  1371 TInt CNcdLoadBundleNodeOperation::RunOperation()
       
  1372     {
       
  1373     DLTRACEIN((("this-ptr: %x"), this ));
       
  1374   
       
  1375     TRAPD( err, DoRunOperationL() ); 
       
  1376      
       
  1377      if ( err != KErrNone )
       
  1378         {
       
  1379         DLTRACE(("error: %d", err));
       
  1380         Cancel();
       
  1381         iBundleNodeState = EFailed;
       
  1382         iError = err;
       
  1383         if ( iPendingMessage )
       
  1384             {
       
  1385             // ignoring error because operation already failed
       
  1386             CompleteMessage( iPendingMessage,
       
  1387                 ENCDOperationMessageCompletionError, iError );
       
  1388             }
       
  1389         }
       
  1390 
       
  1391     DLTRACEOUT(("err: %d", err));
       
  1392     return err;    
       
  1393     }
       
  1394 
       
  1395 void CNcdLoadBundleNodeOperation::DoRunOperationL()
       
  1396     {
       
  1397     DLTRACEIN((""));
       
  1398     switch ( iBundleNodeState )
       
  1399         {
       
  1400         case EConfRequest:
       
  1401             {            
       
  1402             DLTRACE((_L("->EConfRequest")));
       
  1403             DASSERT ( iPendingMessage );
       
  1404                                     
       
  1405             // remove old content sources
       
  1406             delete iContentSourceMap;
       
  1407             iContentSourceMap = NULL;
       
  1408             iContentSourceMap = CNcdContentSourceMap::NewL();
       
  1409             
       
  1410             delete iServerUri;
       
  1411             iServerUri = NULL;
       
  1412             
       
  1413             // Use the server uri from bundle node's node link, if it exists.
       
  1414             // This way we use the correct uri in case of scheme bundle folder.
       
  1415             CNcdNodeFolder& bundleNode = iNodeManager->FolderL( *iNodeIdentifier );
       
  1416             if ( bundleNode.CreateAndSetLinkL().ServerUri() != KNullDesC ) 
       
  1417                 {
       
  1418                 iServerUri = bundleNode.NodeLinkL().ServerUri().AllocL();
       
  1419                 }
       
  1420             else 
       
  1421                 {
       
  1422                 iServerUri = iConfigManager.MasterServerAddressL(
       
  1423                     iPendingMessage->Session().Context() ).AllocL();
       
  1424                 }
       
  1425             DLINFO((_L("server uri: %S"), iServerUri ));
       
  1426                         
       
  1427             
       
  1428             if ( iFirstConfRequest )
       
  1429                 {
       
  1430                 // Store previous list only if some children have been previously loaded.
       
  1431                 if( bundleNode.ChildrenPreviouslyLoaded() )
       
  1432                     {
       
  1433                     bundleNode.StoreChildrenToPreviousListL();
       
  1434                     }
       
  1435                 
       
  1436                 // Create previous lists of children for new checking.
       
  1437                 iChildEntityMaps.ResetAndDestroy();
       
  1438                 iNodeManager->SeenInfo().CreatePreviousListsForChildrenL( bundleNode, iChildEntityMaps );
       
  1439 
       
  1440                 // Backup node RAM cache to temp cache.
       
  1441                 iNodeManager->BackupAndClearCacheL( *iNodeIdentifier );
       
  1442                 iNodeManager->LockNodeDbL( iNodeIdentifier->ClientUid() );
       
  1443                 iNodeDbLocked = ETrue;                                  
       
  1444                 }
       
  1445             
       
  1446             HBufC8* request = CreateConfRequestLC( iConfQuery );
       
  1447             
       
  1448             if ( iConfQuery )
       
  1449                 {
       
  1450                 iConfQuery->InternalRelease();
       
  1451                 iConfQuery = NULL;
       
  1452                 }
       
  1453                         
       
  1454             DLINFO(( "request= %S", request ));
       
  1455             
       
  1456             // create transaction
       
  1457             iGeneralManager.HttpUtils().CreateTransactionL( 
       
  1458                 iHttpSession,
       
  1459                 iTransaction,
       
  1460                 *iServerUri,
       
  1461                 *this,
       
  1462                 *request );
       
  1463 
       
  1464             
       
  1465             // create parser
       
  1466             delete iParser;
       
  1467             iParser = NULL;
       
  1468             iParser = iProtocol.CreateParserL( 
       
  1469                 iPendingMessage->Session().Context(), *iServerUri );
       
  1470             MNcdParserObserverBundle& observers = iParser->Observers();
       
  1471             observers.SetParserObserver( this );
       
  1472             iDefaultConfigurationProtocolObserver =
       
  1473                 observers.ConfigurationProtocolObserver();
       
  1474             observers.SetConfigurationProtocolObserver( this );
       
  1475             observers.SetInformationObserver( this );
       
  1476             
       
  1477             iConfigManager.AddObserverL( *this, iPendingMessage->Session().Context() );
       
  1478             
       
  1479             iParser->BeginAsyncL();
       
  1480   
       
  1481             // start transaction
       
  1482             User::LeaveIfError( iTransaction->Start() );            
       
  1483             CleanupStack::PopAndDestroy( request );
       
  1484             
       
  1485             iFirstConfRequest = EFalse;
       
  1486             iBundleNodeState = EReceiveConf;
       
  1487             DLTRACE((_L("->EConfRequest done")));
       
  1488             break;
       
  1489             }
       
  1490             
       
  1491         case EReceiveConf:
       
  1492             {
       
  1493             DLTRACE((_L("->EReceiveConf")));
       
  1494             // Should send progress only if progress is made
       
  1495             
       
  1496             if ( iPendingMessage && iSendProgress )
       
  1497                 {
       
  1498                 User::LeaveIfError( CompleteMessage( iPendingMessage,
       
  1499                     ENCDOperationMessageCompletionProgress,
       
  1500                     iProgress, KErrNone ) );
       
  1501                 iSendProgress = EFalse;
       
  1502                 }
       
  1503             DLTRACE((_L("->EReceiveConf done")));
       
  1504             break;
       
  1505             }
       
  1506             
       
  1507         case EConfQuery:
       
  1508             {
       
  1509             DLTRACE(("->EConfQuery"));
       
  1510             DASSERT( iConfQuery );
       
  1511             DASSERT( iConfQuery->Response() == MNcdQuery::EAccepted ||
       
  1512                 iConfQuery->Response() == MNcdQuery::ERejected )
       
  1513             if ( iConfQuery->Response() == MNcdQuery::EAccepted)
       
  1514                 {
       
  1515                 DLTRACE(("Query accepted"));
       
  1516                 if ( iConfQuery->ItemCount() == 0 )
       
  1517                     {
       
  1518                     // SPECIAL CASE:
       
  1519                     // querys with no items don't need responding to
       
  1520                     // e.g. a server message
       
  1521                     if( iContentSourceMap->ContentSourceCount() > 0 )
       
  1522                         {
       
  1523                         // content sources received in the earlier response,
       
  1524                         // start loading them
       
  1525                         iBundleNodeState = EBrowseRequest;
       
  1526                         }
       
  1527                     else if ( iMasterServerRedirectionState == ERedirecting )
       
  1528                         {
       
  1529                         // Redirect. Delete conf query since it does not need
       
  1530                         // responding to new master server.
       
  1531                         DLINFO(("Redirect"));
       
  1532                         iConfQuery->InternalRelease();
       
  1533                         iConfQuery = NULL;                       
       
  1534                         iBundleNodeState = EConfRequest;
       
  1535                         }                        
       
  1536                     else
       
  1537                         {
       
  1538                         // no content sources received
       
  1539                         // e.g. server didn't give any content sources 
       
  1540                         // with the set provisioning, only a 
       
  1541                         // "service not available..." message is received
       
  1542                         iBundleNodeState = EComplete;
       
  1543                         }                                
       
  1544                     }
       
  1545                 else
       
  1546                     {
       
  1547                     // NORMAL CASE:
       
  1548                     // Respond to the query in a new request
       
  1549                     iBundleNodeState = EConfRequest;
       
  1550                     }            
       
  1551                 }            
       
  1552             else
       
  1553                 {
       
  1554                 DLTRACE(("Query rejected"));
       
  1555                 if ( iConfQuery->IsOptional() )
       
  1556                     {
       
  1557                     DLTRACE(("Query is optional"));
       
  1558                     if( iContentSourceMap->ContentSourceCount() > 0 )
       
  1559                         {
       
  1560                         DLTRACE(("Content sources received previously, start loading"));
       
  1561                         // content sources received in the earlier response,
       
  1562                         // start loading them
       
  1563                         iBundleNodeState = EBrowseRequest;
       
  1564                         }
       
  1565                     else if ( iMasterServerRedirectionState == ERedirecting )
       
  1566                         {
       
  1567                         // Redirect. Delete conf query since it does not need
       
  1568                         // responding to new master server.
       
  1569                         DLINFO(("Redirect"));
       
  1570                         iConfQuery->InternalRelease();
       
  1571                         iConfQuery = NULL;                       
       
  1572                         iBundleNodeState = EConfRequest;
       
  1573                         }                                                
       
  1574                     else
       
  1575                         {
       
  1576                         DLTRACE(("No sources received!"));
       
  1577                         // no content sources received with an optional query
       
  1578                         // this should never happen!                        
       
  1579                         iError = KNcdErrorNoContentSources;
       
  1580                         iBundleNodeState = EFailed;
       
  1581                         }                            
       
  1582                     }
       
  1583                 else
       
  1584                     {
       
  1585                     DLTRACE(("Query not optional, operation will stop!"));
       
  1586                     iBundleNodeState = EComplete;
       
  1587                     }
       
  1588                 }
       
  1589                             
       
  1590             RunOperation();            
       
  1591             DLTRACE(("->EConfQuery done"));
       
  1592             break;
       
  1593             }
       
  1594             
       
  1595         case EBrowseRequest:
       
  1596             {
       
  1597             DLTRACE((_L("->EBrowseRequest")));
       
  1598                         
       
  1599             iSubOps.ResetAndDestroy();
       
  1600 
       
  1601             // Create load node op for each content source.
       
  1602             DLINFO((("Content source count=%d"), iContentSourceMap->ContentSourceCount()));
       
  1603             for ( TInt i = 0 ; i < iContentSourceMap->ContentSourceCount() ; i++ )
       
  1604                 {
       
  1605                 CNcdContentSource& contentSource =
       
  1606                     iContentSourceMap->ContentSource( i );
       
  1607                 DLINFO((_L("content source: namespace=%S, uri=%S, id=%S"),
       
  1608                     &contentSource.NameSpace(), &contentSource.Uri(), &contentSource.NodeId()));
       
  1609                 
       
  1610                 CNcdLoadNodeOperationImpl* loadOp =
       
  1611                     CNcdLoadNodeOperationImpl::NewLC(
       
  1612                         contentSource,
       
  1613                         iContentSourceMap,
       
  1614                         contentSource.ParentIdentifier(),
       
  1615                         iGeneralManager,                        
       
  1616                         iHttpSession,                        
       
  1617                         iRemoveHandler,
       
  1618                         iSession );
       
  1619                 
       
  1620                 loadOp->AddObserverL( this );
       
  1621                 iSubOps.AppendL( loadOp );
       
  1622                 CleanupStack::Pop( loadOp );
       
  1623                 // error code ignored, errors handled via callback
       
  1624                 loadOp->Start();
       
  1625                 }
       
  1626             
       
  1627             iBundleNodeState = EReceiveBrowse;
       
  1628             DLINFO(("subop count: failed:%d completed:%d total:%d",
       
  1629                 iFailedSubOps.Count(), iCompletedSubOps.Count(), iSubOps.Count() ));
       
  1630             if ( iFailedSubOps.Count() + iCompletedSubOps.Count() ==
       
  1631                  iSubOps.Count() )
       
  1632                 {
       
  1633                 // all sub ops have either completed or failed
       
  1634                 // -> this operation is now complete
       
  1635                 iBundleNodeState = EComplete;
       
  1636                 if ( iFailedSubOps.Count() > 0 ) 
       
  1637                     {
       
  1638                     DLINFO(("Some catalogs failed to load"));
       
  1639                     iError = KNcdErrorSomeCatalogsFailedToLoad;
       
  1640                     }
       
  1641                 RunOperation();
       
  1642                 }
       
  1643                 
       
  1644             DLTRACE((_L("->EBrowseRequest done")));
       
  1645             
       
  1646             break;
       
  1647             }
       
  1648             
       
  1649         case EReceiveBrowse:
       
  1650             {
       
  1651             DLTRACE((_L("->EReceiveBrowse")));
       
  1652             if( iSubOpQuerys.Count() > 0 )
       
  1653                 {
       
  1654                 // send sub op query to proxy
       
  1655                 CNcdBaseOperation::QueryReceivedL( iSubOpQuerys[0] );
       
  1656                 iSubOpQuerys.Remove( 0 );
       
  1657                 }                
       
  1658             else if ( iPendingMessage && iLoadedNodes.Count() > 0 )
       
  1659                 {
       
  1660                 SetAlwaysVisibleFlagsL();
       
  1661                 
       
  1662                 // send updated nodes identifiers to proxy
       
  1663                 User::LeaveIfError( CompleteMessage( iPendingMessage,
       
  1664                     ENCDOperationMessageCompletionNodesUpdated,
       
  1665                     iProgress,
       
  1666                     iLoadedNodes,
       
  1667                     KErrNone ) );
       
  1668                 
       
  1669                 iLoadedNodes.ResetAndDestroy();
       
  1670                 }
       
  1671             else if ( iFailedSubOps.Count() + iCompletedSubOps.Count() ==
       
  1672                  iSubOps.Count() )
       
  1673                 {
       
  1674                 // all sub ops have either completed or failed
       
  1675                 // -> this operation is now complete
       
  1676                 iBundleNodeState = EComplete;
       
  1677                 if ( iFailedSubOps.Count() > 0 ) 
       
  1678                     {
       
  1679                     DLINFO(("Some catalogs failed to load"));
       
  1680                     iError = KNcdErrorSomeCatalogsFailedToLoad;
       
  1681                     }
       
  1682                 RunOperation();
       
  1683                 }
       
  1684                 
       
  1685             DLTRACE((_L("->EReceiveBrowse done")));
       
  1686             break;
       
  1687             }
       
  1688             
       
  1689         case EComplete:
       
  1690             {
       
  1691             DLTRACE((_L("->EComplete")));
       
  1692             
       
  1693             // Compare the ContentSourceMaps of previous root node load and this
       
  1694             // load and delete the nodes that were removed from server.
       
  1695             if ( iContentSourceMap && iContentSourceMap->ContentSourceCount() > 0 ) 
       
  1696                 {
       
  1697                 DLINFO(("Content source map count"));
       
  1698                 RevertNodesOfBrokenSourcesToCacheL();                                            
       
  1699                 AddBundleToLoadedNodesL();
       
  1700                 SetAlwaysVisibleFlagsL();
       
  1701 
       
  1702                 // Now the RAM node cache should be updated correctly, save it to database.
       
  1703                 iNodeManager->UnlockNodeDb( iNodeIdentifier->ClientUid() );
       
  1704                 iNodeDbLocked = EFalse;
       
  1705 
       
  1706                 UpdateCsMapToRootNodeL();
       
  1707                 
       
  1708                 delete iContentSourceMap;
       
  1709                 iContentSourceMap = NULL;
       
  1710 
       
  1711                 iNodeManager->DbSaveNodesL( *iNodeIdentifier );                                
       
  1712                 }
       
  1713                 
       
  1714             if( iNodeDbLocked )
       
  1715                 {
       
  1716                 iNodeManager->UnlockNodeDb( iNodeIdentifier->ClientUid() );
       
  1717                 iNodeDbLocked = EFalse;
       
  1718                 }
       
  1719             
       
  1720             iNodeManager->ClearTempCacheL( *iNodeIdentifier );
       
  1721                             
       
  1722             CNcdNodeFolder& bundleNode = 
       
  1723                 iNodeManager->FolderL( *iNodeIdentifier );
       
  1724                 
       
  1725             // Set the children loaded flag so that next refresh stores
       
  1726             // previous child list (needed for new checking)
       
  1727             if( bundleNode.ChildCount() )
       
  1728                 {
       
  1729                 bundleNode.SetChildrenPreviouslyLoaded();
       
  1730                 iNodeManager->DbSaveNodeL( bundleNode );
       
  1731                 }
       
  1732                 
       
  1733             // Check new status
       
  1734             iNodeManager->SeenInfo().StorePreviousListsToExistingChildrenL(
       
  1735                 bundleNode,
       
  1736                 iChildEntityMaps );
       
  1737                 
       
  1738             iChildEntityMaps.ResetAndDestroy();
       
  1739             
       
  1740             // Check new status for transparent folders (transparent folders are
       
  1741             // loaded during bundle op so they need to be checked here)
       
  1742             iNodeManager->SeenInfo().DoNewCheckForTransparentChildrenL(
       
  1743                 bundleNode );
       
  1744             
       
  1745             iNodeManager->SeenInfo().RefreshFolderSeenStatusL( *iNodeIdentifier );
       
  1746             
       
  1747             if ( iPendingMessage && iLoadedNodes.Count() > 0 )
       
  1748                 {
       
  1749                 DLINFO(("Pending message loaded nodes"));
       
  1750                 // send updated nodes identifiers to proxy
       
  1751                 User::LeaveIfError( CompleteMessage( iPendingMessage,
       
  1752                     ENCDOperationMessageCompletionNodesUpdated,
       
  1753                     iProgress,
       
  1754                     iLoadedNodes,
       
  1755                     KErrNone ) );
       
  1756                 
       
  1757                 iLoadedNodes.ResetAndDestroy();                
       
  1758                 }
       
  1759             else if ( iPendingMessage )
       
  1760                 {
       
  1761                 DLINFO(("Pending message"));
       
  1762                 if ( iError == KErrNone ) 
       
  1763                     {                    
       
  1764                     // Send complete message to proxy.
       
  1765                     User::LeaveIfError( CompleteMessage( iPendingMessage,
       
  1766                         ENCDOperationMessageCompletionComplete,
       
  1767                         iProgress,
       
  1768                         KErrNone ) );
       
  1769                                         
       
  1770                     iOperationState = EStateComplete;
       
  1771                     }
       
  1772                 else 
       
  1773                     {
       
  1774                     iBundleNodeState = EFailed;
       
  1775                     RunOperation();
       
  1776                     }
       
  1777                 }
       
  1778             DLTRACE((_L("->EComplete done")));
       
  1779             break;
       
  1780             }
       
  1781             
       
  1782         case EFailed:
       
  1783             {
       
  1784             DLTRACE((_L("->EFailed")));
       
  1785             Cancel();
       
  1786             // Send error message in case didn't have any pending
       
  1787             // messages when the operation actually failed
       
  1788             if( iPendingMessage )
       
  1789                 {
       
  1790                 DLINFO(("Pending"));
       
  1791                 // ignoring error because operation already failed
       
  1792                 CompleteMessage( iPendingMessage,
       
  1793                     ENCDOperationMessageCompletionError, iError );
       
  1794                 }
       
  1795             DLTRACE((_L("->EFailed done")));
       
  1796             break;
       
  1797             }
       
  1798             
       
  1799         default:
       
  1800             {
       
  1801             DLTRACE(("default"));
       
  1802             DASSERT(0);
       
  1803             break;
       
  1804             }
       
  1805         }
       
  1806     }
       
  1807     
       
  1808 void CNcdLoadBundleNodeOperation::ChangeToPreviousStateL()
       
  1809     {
       
  1810     DLTRACEIN(("no implementation needed"));
       
  1811     }
       
  1812 
       
  1813 TBool CNcdLoadBundleNodeOperation::QueryCompletedL( CNcdQuery* aQuery )
       
  1814     {    
       
  1815     DLTRACEIN((""));
       
  1816     TBool handled = EFalse;
       
  1817  
       
  1818     if ( aQuery == iConfQuery )
       
  1819         {
       
  1820         // handle conf query
       
  1821         DASSERT( iBundleNodeState == EConfQuery );
       
  1822         if ( aQuery->Response() == MNcdQuery::ERejected )
       
  1823             {
       
  1824             Cancel();
       
  1825             }
       
  1826         handled = ETrue;
       
  1827         }
       
  1828     else
       
  1829         {
       
  1830         // handle child ops's querys
       
  1831         TBool found = EFalse;
       
  1832         for( TInt i = 0 ; i < iSubOps.Count() ; i++ )
       
  1833             {
       
  1834             CNcdQuery* query = iSubOps[i]->ActiveQuery();
       
  1835             if ( aQuery == query )
       
  1836                 {
       
  1837                 iSubOps[i]->QueryHandledL( aQuery );
       
  1838                 TInt index = iSubOpQuerys.Find( aQuery );
       
  1839                 if ( index != KErrNotFound )
       
  1840                     {
       
  1841                     // remove reference
       
  1842                     iSubOpQuerys[index]->InternalRelease();
       
  1843                     iSubOpQuerys.Remove( index );
       
  1844                     }
       
  1845                 query->InternalRelease();
       
  1846                 query = NULL;
       
  1847                 found = ETrue;
       
  1848                 break;
       
  1849                 }
       
  1850             if ( query )
       
  1851                 {
       
  1852                 query->InternalRelease();
       
  1853                 }
       
  1854             }
       
  1855         if ( !found )
       
  1856             {
       
  1857             DLINFO(("Query doesn't belong to any sub op! ERROR!"))
       
  1858             DASSERT( 0 );
       
  1859             User::Leave( KErrArgument );
       
  1860             }
       
  1861         else
       
  1862             {
       
  1863             handled = ETrue;
       
  1864             }
       
  1865         }
       
  1866 
       
  1867     return handled;
       
  1868     }