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