ncdengine/provider/server/src/ncdloadnodeoperationimpl.cpp
changeset 0 ba25891c3a9e
child 25 7333d7932ef7
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 #include <limits.h>
       
    22 
       
    23 #include "ncdloadnodeoperationimpl.h"
       
    24 #include "ncdoperationfunctionids.h"
       
    25 #include "catalogsbasemessage.h"
       
    26 #include "catalogsbigdes.h"
       
    27 #include "ncdrequestgenerator.h"
       
    28 
       
    29 #include "ncdrequestbase.h"
       
    30 #include "ncdrequestbrowsesearch.h"
       
    31 #include "ncdrequestconfiguration.h"
       
    32 #include "ncd_pp_itemref.h"
       
    33 #include "ncd_pp_folderref.h"
       
    34 #include "ncd_pp_dataentity.h"
       
    35 #include "ncd_pp_error.h"
       
    36 #include "ncd_pp_datablock.h"
       
    37 #include "ncd_pp_icon.h"
       
    38 #include "ncdprotocolutils.h"
       
    39 #include "ncdprotocol.h"
       
    40 #include "ncdprotocolimpl.h"
       
    41 #include "ncdparser.h"
       
    42 #include "ncdnodemanager.h"
       
    43 #include "ncdproviderdefines.h"
       
    44 #include "ncdnodeidentifier.h"
       
    45 #include "ncdnodeclassids.h"
       
    46 #include "ncdnodefolder.h"
       
    47 #include "ncdoperationobserver.h"
       
    48 #include "catalogssession.h"
       
    49 #include "ncdnodeimpl.h"
       
    50 #include "ncdnodelink.h"
       
    51 #include "ncdqueryimpl.h"
       
    52 #include "catalogsutils.h"
       
    53 #include "ncd_cp_query.h"
       
    54 #include "ncdnodemetadata.h"
       
    55 #include "ncdnodemetadataimpl.h"
       
    56 #include "ncderrors.h"
       
    57 #include "ncdoperationremovehandler.h"
       
    58 #include "ncdnodeiconimpl.h"
       
    59 #include "ncdsessionhandler.h"
       
    60 #include "ncdnodefactory.h"
       
    61 #include "ncdnodeidentifiereditor.h"
       
    62 #include "ncdexpirednode.h"
       
    63 #include "ncdhttputils.h"
       
    64 #include "ncdproviderutils.h"
       
    65 #include "catalogshttpincludes.h"
       
    66 #include "ncdnodeseeninfo.h"
       
    67 #include "ncdchildentity.h"
       
    68 #include "ncdoperationqueue.h"
       
    69 #include "ncdgeneralmanager.h"
       
    70 
       
    71 #include "catalogsdebug.h"
       
    72 
       
    73 // ======== MEMBER FUNCTIONS ========
       
    74 
       
    75 
       
    76 // ---------------------------------------------------------------------------
       
    77 // ?description_if_needed
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 CNcdLoadNodeOperationImpl* CNcdLoadNodeOperationImpl::NewL(
       
    81     const CNcdNodeIdentifier& aNodeIdentifier,
       
    82     const CNcdNodeIdentifier& aParentIdentifier,
       
    83     CNcdNodeFactory::TNcdNodePurpose aParentNodePurpose,
       
    84     TNcdResponseFilterParams aFilterParams,
       
    85     CNcdGeneralManager& aGeneralManager,
       
    86     MCatalogsHttpSession& aHttpSession,
       
    87     MNcdOperationRemoveHandler* aRemoveHandler,
       
    88     MNcdOperationQueue* aOperationQueue,
       
    89     MCatalogsSession& aSession,
       
    90     TBool aLoadChildren,
       
    91     TNcdChildLoadMode aMode,
       
    92     TBool aIsSubOperation,
       
    93     TBool aCreateParent )
       
    94     {
       
    95     CNcdLoadNodeOperationImpl* self = CNcdLoadNodeOperationImpl::NewLC(
       
    96         aNodeIdentifier,
       
    97         aParentIdentifier,
       
    98         aParentNodePurpose,
       
    99         aFilterParams,        
       
   100         aGeneralManager,
       
   101         aHttpSession,
       
   102         aRemoveHandler,
       
   103         aOperationQueue,
       
   104         aSession,
       
   105         aLoadChildren,
       
   106         aMode,
       
   107         aIsSubOperation,
       
   108         aCreateParent );
       
   109     CleanupStack::Pop( self );
       
   110     return self;
       
   111     }
       
   112 
       
   113 
       
   114 // ---------------------------------------------------------------------------
       
   115 // ?description_if_needed
       
   116 // ---------------------------------------------------------------------------
       
   117 //
       
   118 CNcdLoadNodeOperationImpl* CNcdLoadNodeOperationImpl::NewLC(
       
   119     const CNcdNodeIdentifier& aNodeIdentifier,
       
   120     const CNcdNodeIdentifier& aParentIdentifier,
       
   121     CNcdNodeFactory::TNcdNodePurpose aParentNodePurpose,
       
   122     TNcdResponseFilterParams aFilterParams,
       
   123     CNcdGeneralManager& aGeneralManager,
       
   124     MCatalogsHttpSession& aHttpSession,
       
   125     MNcdOperationRemoveHandler* aRemoveHandler,
       
   126     MNcdOperationQueue* aOperationQueue,
       
   127     MCatalogsSession& aSession,
       
   128     TBool aLoadChildren,
       
   129     TNcdChildLoadMode aMode,
       
   130     TBool aIsSubOperation,
       
   131     TBool aCreateParent )
       
   132     {
       
   133     CNcdLoadNodeOperationImpl* self =
       
   134         new( ELeave ) CNcdLoadNodeOperationImpl( 
       
   135             aParentNodePurpose, 
       
   136             aFilterParams,
       
   137             aMode, 
       
   138             aLoadChildren, 
       
   139             aGeneralManager, 
       
   140             aHttpSession,
       
   141             aRemoveHandler, 
       
   142             aOperationQueue, 
       
   143             aSession, 
       
   144             aIsSubOperation, 
       
   145             aCreateParent );
       
   146     CleanupClosePushL( *self );
       
   147     self->ConstructL( aNodeIdentifier, aParentIdentifier );
       
   148     return self;
       
   149     }
       
   150     
       
   151 CNcdLoadNodeOperationImpl* CNcdLoadNodeOperationImpl::NewLC(
       
   152     CNcdContentSource& aContentSource,
       
   153     CNcdContentSourceMap* aContentSourceMap,
       
   154     const CNcdNodeIdentifier& aParentIdentifier,
       
   155     CNcdGeneralManager& aGeneralManager,
       
   156     MCatalogsHttpSession& aHttpSession,
       
   157     MNcdOperationRemoveHandler* aRemoveHandler,
       
   158     MCatalogsSession& aSession )
       
   159     {
       
   160     CNcdLoadNodeOperationImpl* self =
       
   161         new( ELeave ) CNcdLoadNodeOperationImpl( 
       
   162             aGeneralManager, 
       
   163             aHttpSession, 
       
   164 			aRemoveHandler, 
       
   165 			aSession );
       
   166     CleanupClosePushL( *self );
       
   167     self->ConstructL( aContentSource, aContentSourceMap, aParentIdentifier );
       
   168     return self;
       
   169     }
       
   170 
       
   171 // ---------------------------------------------------------------------------
       
   172 // ?description_if_needed
       
   173 // ---------------------------------------------------------------------------
       
   174 //
       
   175 CNcdLoadNodeOperationImpl::~CNcdLoadNodeOperationImpl()
       
   176     {
       
   177     DLTRACEIN(( "this-ptr: %X", this ));
       
   178 
       
   179     // If the operation proxy is released without cancelling, eg. UI exits 
       
   180     // while node loading is going on, then the operation is not removed
       
   181     // from the operation queue.
       
   182     //
       
   183     // HandleReleaseMessage() would be a bit better place for this but I
       
   184     // don't want to implement it just for this :)
       
   185     NotifyCompletionOfQueuedOperation( ENCDOperationMessageCompletionComplete );
       
   186     
       
   187     delete iNodeIdentifier;
       
   188     delete iServerUri;
       
   189     delete iParentIdentifier;
       
   190     
       
   191     DLTRACE(("Closing suboperations"));
       
   192     // Close operations
       
   193     for ( TInt i = 0; i < iSubOps.Count(); ++i )
       
   194         {
       
   195         iSubOps[i]->Close();        
       
   196         }
       
   197     DLTRACE(("Suboperations closed"));
       
   198     iSubOps.Reset();
       
   199     iFailedSubOps.Reset();
       
   200     iCompletedSubOps.Reset();
       
   201     
       
   202     if( iLoadNodeQuery )
       
   203         {
       
   204         iLoadNodeQuery->InternalRelease();
       
   205         }
       
   206     
       
   207     iSubOpQuerys.Close();
       
   208     
       
   209     DLTRACE(("Deleting iLoadedNodes"));
       
   210     iLoadedNodes.ResetAndDestroy();
       
   211     
       
   212     DLTRACE(("Deleting iParser"));
       
   213     delete iParser;
       
   214     
       
   215     DLTRACE(("Releasing iTransaction"));
       
   216     if ( iTransaction )
       
   217         {
       
   218         iTransaction->Release();
       
   219         }
       
   220     
       
   221     DLTRACE(("Releasing iHttpSession"));
       
   222     iHttpSession.Release();
       
   223     
       
   224     iRemoteFolders.ResetAndDestroy();
       
   225     iTransparentChildFolders.ResetAndDestroy();
       
   226     iTransparentChildItems.ResetAndDestroy();
       
   227     
       
   228     iNodeIconMaps.ResetAndDestroy();
       
   229 
       
   230     DLTRACEOUT((""));  
       
   231     }
       
   232 
       
   233 CNcdLoadNodeOperationImpl::TLoadNodeOperationState
       
   234     CNcdLoadNodeOperationImpl::State()
       
   235     {
       
   236     return iLoadNodeState;
       
   237     }
       
   238     
       
   239 const RPointerArray<CNcdNodeIdentifier>&
       
   240     CNcdLoadNodeOperationImpl::LoadedNodes()
       
   241     {
       
   242     return iLoadedNodes;
       
   243     }
       
   244 
       
   245 const CNcdNodeIdentifier* CNcdLoadNodeOperationImpl::NodeIdentifier() const
       
   246     {
       
   247     return iNodeIdentifier;
       
   248     }
       
   249 
       
   250 // ---------------------------------------------------------------------------
       
   251 // ?implementation_description
       
   252 // ---------------------------------------------------------------------------
       
   253 //
       
   254 TInt CNcdLoadNodeOperationImpl::Start()
       
   255     {
       
   256     DLTRACEIN((""));
       
   257     if ( iOperationState == EStateStopped )
       
   258         {
       
   259         // Op not yet running, queue it
       
   260         iOperationState = EStateRunning;
       
   261         TInt err;
       
   262         // Do not add sub operations to queue, since the parent operation will jam then.
       
   263         if ( IsSubOperation() )
       
   264             {
       
   265             err = RunOperation();
       
   266             }
       
   267         else
       
   268             {
       
   269             DASSERT( iOperationQueue );            
       
   270             TRAP( err, iOperationQueue->QueueOperationL( *this ) );        
       
   271             }
       
   272         return err;
       
   273         }
       
   274     else
       
   275         {
       
   276         return KErrInUse;
       
   277         }
       
   278     }
       
   279 
       
   280 
       
   281 // ---------------------------------------------------------------------------
       
   282 // ?implementation_description
       
   283 // ---------------------------------------------------------------------------
       
   284 //
       
   285 void CNcdLoadNodeOperationImpl::Cancel()
       
   286     {
       
   287     DLTRACEIN(( "this-ptr: %X", this ));
       
   288 
       
   289     if ( iTransaction )
       
   290         {
       
   291         iTransaction->Cancel();
       
   292         iTransaction = NULL;
       
   293         }
       
   294 
       
   295     if ( iParser )
       
   296         {
       
   297         iParser->CancelParsing();
       
   298         }
       
   299         
       
   300     for ( TInt i = 0; i < iSubOps.Count(); i++ ) 
       
   301         {
       
   302         CNcdLoadNodeOperationImpl* operation = iSubOps[i];
       
   303         if ( iCompletedSubOps.Find( operation ) == KErrNotFound &&
       
   304              iFailedSubOps.Find( operation ) == KErrNotFound ) 
       
   305             {
       
   306             operation->Cancel();
       
   307             }
       
   308         } 
       
   309     
       
   310     DLTRACEOUT((""));
       
   311     }
       
   312     
       
   313 
       
   314 // ---------------------------------------------------------------------------
       
   315 // ?implementation_description
       
   316 // ---------------------------------------------------------------------------
       
   317 //
       
   318 void CNcdLoadNodeOperationImpl::HandleCancelMessage( MCatalogsBaseMessage* aMessage ) 
       
   319     {
       
   320     DLTRACEIN((""));
       
   321     CNcdBaseOperation::HandleCancelMessage( aMessage );
       
   322     if ( !IsSubOperation() )
       
   323         {
       
   324         DASSERT( iOperationQueue );    
       
   325         iOperationQueue->QueuedOperationComplete( *this );
       
   326         }
       
   327     }
       
   328     
       
   329     
       
   330 // ---------------------------------------------------------------------------
       
   331 // ?implementation_description
       
   332 // ---------------------------------------------------------------------------
       
   333 //    
       
   334 TInt CNcdLoadNodeOperationImpl::CompleteMessage(
       
   335     MCatalogsBaseMessage* & aMessage,
       
   336     TNcdOperationMessageCompletionId aId,
       
   337     const MNcdSendable& aSendableObject,
       
   338     TInt aStatus ) 
       
   339     {
       
   340     DLTRACEIN((""));    
       
   341     NotifyCompletionOfQueuedOperation( aId );
       
   342     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aSendableObject, aStatus );
       
   343     }
       
   344     
       
   345 
       
   346 // ---------------------------------------------------------------------------
       
   347 // ?implementation_description
       
   348 // ---------------------------------------------------------------------------
       
   349 //    
       
   350 TInt CNcdLoadNodeOperationImpl::CompleteMessage(
       
   351     MCatalogsBaseMessage* & aMessage,
       
   352     TNcdOperationMessageCompletionId aId,
       
   353     TInt aStatus )
       
   354     {
       
   355     DLTRACEIN((""));
       
   356     NotifyCompletionOfQueuedOperation( aId );
       
   357     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aStatus );
       
   358     }
       
   359     
       
   360 // ---------------------------------------------------------------------------
       
   361 // ?implementation_description
       
   362 // ---------------------------------------------------------------------------
       
   363 //    
       
   364 TInt CNcdLoadNodeOperationImpl::CompleteMessage(
       
   365     MCatalogsBaseMessage*& aMessage,
       
   366     TNcdOperationMessageCompletionId aId,
       
   367     const MNcdSendable& aSendableObject,
       
   368     RPointerArray<CNcdNodeIdentifier>& aNodes,
       
   369     TInt aStatus )
       
   370     {
       
   371     DLTRACEIN((""));
       
   372     NotifyCompletionOfQueuedOperation( aId );
       
   373     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aSendableObject, aNodes, aStatus );
       
   374     }
       
   375     
       
   376 // ---------------------------------------------------------------------------
       
   377 // ?implementation_description
       
   378 // ---------------------------------------------------------------------------
       
   379 //    
       
   380 TInt CNcdLoadNodeOperationImpl::CompleteMessage(
       
   381     MCatalogsBaseMessage*& aMessage,
       
   382     TNcdOperationMessageCompletionId aId,
       
   383     RPointerArray<CNcdExpiredNode>& aExpiredNodes,
       
   384     TInt aStatus )
       
   385     {
       
   386     DLTRACEIN((""));
       
   387     NotifyCompletionOfQueuedOperation( aId );
       
   388     return CNcdBaseOperation::CompleteMessage( aMessage, aId, aExpiredNodes, aStatus );
       
   389     }
       
   390     
       
   391 // ---------------------------------------------------------------------------
       
   392 // ?implementation_description
       
   393 // ---------------------------------------------------------------------------
       
   394 //
       
   395 void CNcdLoadNodeOperationImpl::HandleHttpEventL( 
       
   396         MCatalogsHttpOperation& aOperation, 
       
   397         TCatalogsHttpEvent aEvent )
       
   398     {
       
   399     DLTRACEIN(( "this-ptr: %X", this ));
       
   400        
       
   401     DASSERT( &aOperation == iTransaction );
       
   402     DASSERT( aOperation.OperationType() == ECatalogsHttpTransaction );
       
   403 
       
   404     TCatalogsTransportProgress progress( iTransaction->Progress() );
       
   405     
       
   406     // Are state and id needed?
       
   407     iProgress = TNcdSendableProgress( iLoadNodeState,
       
   408         iTransaction->OperationId().Id(), progress.iProgress,
       
   409         progress.iMaxProgress );
       
   410 
       
   411     switch( aEvent.iOperationState ) 
       
   412         {
       
   413         // Handle completed operation
       
   414         case ECatalogsHttpOpCompleted:
       
   415             {
       
   416             ReleasePtr( iTransaction );
       
   417             // Inform parser that no more data will be sent
       
   418             iParser->EndL();
       
   419             break;
       
   420             }        
       
   421         // Handle operation in progress
       
   422         case ECatalogsHttpOpInProgress:
       
   423             {
       
   424             if ( aEvent.iProgressState == ECatalogsHttpResponseBodyReceived )
       
   425                 {
       
   426                 // send received data to parser
       
   427                 iParser->ParseL( aOperation.Body() );
       
   428                 }
       
   429             break;
       
   430             }
       
   431                     
       
   432         default:
       
   433             {
       
   434             break;
       
   435             }
       
   436         }
       
   437         
       
   438     DLTRACEOUT((""));    
       
   439     }
       
   440     
       
   441     
       
   442 TBool CNcdLoadNodeOperationImpl::HandleHttpError( 
       
   443     MCatalogsHttpOperation& aOperation, 
       
   444     TCatalogsHttpError aError )    
       
   445     {
       
   446     DLTRACEIN(("Error type: %d, code: %d", aError.iType, aError.iError ));    
       
   447     
       
   448     DLINFO(( "this-ptr: %X", this ));
       
   449 
       
   450     DASSERT( &aOperation == iTransaction );
       
   451     
       
   452     if ( iLoadMode == EContentSource )
       
   453         {
       
   454         iContentSource->SetBroken( ETrue );
       
   455         }
       
   456     
       
   457     aOperation.Release();
       
   458     iTransaction = NULL;
       
   459     iError = aError.iError;
       
   460     iLoadNodeState = EFailed;
       
   461     RunOperation();
       
   462         
       
   463     DLTRACEOUT((""));
       
   464     return ETrue;
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // ?implementation_description
       
   469 // ---------------------------------------------------------------------------
       
   470 //
       
   471 void CNcdLoadNodeOperationImpl::ParseError( TInt aErrorCode )
       
   472     {
       
   473     DLTRACEIN(("error:%d", aErrorCode ));
       
   474     DLINFO(( "this-ptr: %X", this ));
       
   475     // Hanlde only if this operation isn't already handling an error.
       
   476     // Canceling parsing may lead to such a situation.
       
   477     if( iLoadNodeState == EReceive && iError == KErrNone )
       
   478         {
       
   479         iLoadNodeState = EFailed;
       
   480         iError = aErrorCode;
       
   481 
       
   482         if ( iTransaction )
       
   483             {
       
   484             iTransaction->Cancel();        
       
   485             iTransaction = NULL;
       
   486             }
       
   487         
       
   488         // There's nothing we can do for errors here
       
   489         TRAP_IGNORE( ContinueOperationL() );
       
   490         }
       
   491     }
       
   492 
       
   493 // ---------------------------------------------------------------------------
       
   494 // ?implementation_description
       
   495 // ---------------------------------------------------------------------------
       
   496 //
       
   497 void CNcdLoadNodeOperationImpl::ParseCompleteL( TInt aError )
       
   498     {
       
   499     DLTRACEIN((_L("error:%d, this: %x"), aError, this ));
       
   500                
       
   501     DLINFO(( "this-ptr: %X", this ));   
       
   502 
       
   503 
       
   504     if ( aError != KErrNone )
       
   505         {
       
   506         iError = aError;
       
   507         iLoadNodeState = EFailed;        
       
   508         ContinueOperationL();
       
   509         }
       
   510     // if iError != KErrNone, the error has already been handled
       
   511     else if ( iError == KErrNone )
       
   512         {
       
   513         DASSERT( iLoadNodeState == EReceive );
       
   514         // Completed queries have been responded to successfully, remove them.
       
   515         ClearCompletedQueries();
       
   516         if ( QueriesPending() )
       
   517             {
       
   518             HandleQuerysL();
       
   519             }
       
   520         else if ( RemoteFolderCount() )
       
   521             {
       
   522             // remote folders need to be loaded next
       
   523             iLoadNodeState = ERemote;
       
   524             ContinueOperationL();            
       
   525             }
       
   526         else
       
   527             {
       
   528             // no querys received, go to next state
       
   529             iLoadNodeState = EComplete;
       
   530             ContinueOperationL();
       
   531             }
       
   532         }
       
   533     DLTRACEOUT((""));
       
   534     }
       
   535 
       
   536 // ---------------------------------------------------------------------------
       
   537 // ?implementation_description
       
   538 // ---------------------------------------------------------------------------
       
   539 //
       
   540 void CNcdLoadNodeOperationImpl::FolderRefL(
       
   541     MNcdPreminetProtocolFolderRef* aData )
       
   542     {
       
   543     DLTRACEIN(("%X",aData));
       
   544     DLINFO(( "this-ptr: %X", this ));
       
   545 
       
   546     // Normal PushL causes USER 42
       
   547     CleanupDeletePushL( aData );
       
   548     
       
   549     DLTRACE((_L("folder id=%S"),&aData->Id()));
       
   550         
       
   551     switch ( iLoadMode )
       
   552         {
       
   553         case EContentSource:
       
   554             {
       
   555                 
       
   556             DLINFO((_L("Cs: id=%S"), &iContentSource->NodeId() ));
       
   557             //PrintNodeChildren();
       
   558             CNcdNodeManager::TNcdRefHandleMode insertMode = 
       
   559                 aData->ParentId() == KNullDesC ? 
       
   560                     CNcdNodeManager::EInsert : CNcdNodeManager::EAppend;
       
   561             
       
   562             CNcdNode* node( NULL );                    
       
   563             if ( iContentSource->IsTransparent() && aData->ParentId() == KNullDesC ) 
       
   564                 {
       
   565                 DLINFO(("Transparent node"));
       
   566                 // Check if the parent is actually bundle or root node
       
   567                 if ( iContentSourceMap->HasBundleFolder( *iParentIdentifier ) ) 
       
   568                     {
       
   569                     // Child of bundle folder.
       
   570                     node = 
       
   571                         &iNodeManager->RefHandlerL(
       
   572                             *iParentIdentifier, *aData, iClientUid, insertMode,
       
   573                             iContentSourceMap->GetInsertIndexL(*iContentSource, *iParentIdentifier ),
       
   574                             CNcdNodeFactory::ENcdNodeFolder, CNcdNodeFactory::ENcdBundleNode,
       
   575                             CNcdNodeFactory::ENcdTransparentNode );
       
   576                     }
       
   577                 else
       
   578                     {                        
       
   579                     // Child of root node.
       
   580                 	node =
       
   581                     	&iNodeManager->RefHandlerL(
       
   582                         	*iParentIdentifier, *aData, iClientUid, insertMode,
       
   583                         	iContentSourceMap->GetInsertIndexL(*iContentSource, *iParentIdentifier ),
       
   584                         	CNcdNodeFactory::ENcdNodeRoot, CNcdNodeFactory::ENcdNormalNode,
       
   585                         	CNcdNodeFactory::ENcdTransparentNode );
       
   586 					}
       
   587                         
       
   588                 // The content sources are thought to be remote.
       
   589                 node->NodeLinkL().SetRemoteFlag( ETrue );
       
   590                 }
       
   591             else if ( iContentSource->IsTransparent() ) 
       
   592                 {
       
   593                 DLINFO(("Transparent child"));
       
   594                 // Because we have the transparent content source and the parent id was set
       
   595                 // it means that we have loaded the child of the transparent folder.
       
   596                 CNcdNodeIdentifier* metaDataParentIdentifier =
       
   597                     CNcdNodeIdentifier::NewLC( aData->ParentNamespace(),
       
   598                                                aData->ParentId(),
       
   599                                                aData->ServerUri(),
       
   600                                                iClientUid );
       
   601                 CNcdNodeIdentifier* actualParentIdentifier =
       
   602                     NcdNodeIdentifierEditor::CreateNodeIdentifierLC( *iParentIdentifier,
       
   603                                                                      *metaDataParentIdentifier );
       
   604                 node = 
       
   605                     &iNodeManager->RefHandlerL(
       
   606                         *actualParentIdentifier, *aData, iClientUid, insertMode,
       
   607                         0, CNcdNodeFactory::ENcdNodeFolder,
       
   608                         CNcdNodeFactory::ENcdTransparentNode,
       
   609                         CNcdNodeFactory::ENcdChildOfTransparentNode );
       
   610                         
       
   611                 CleanupStack::PopAndDestroy( actualParentIdentifier );
       
   612                 CleanupStack::PopAndDestroy( metaDataParentIdentifier );
       
   613                 CNcdNodeIdentifier* nodeId = 
       
   614                     CNcdNodeIdentifier::NewLC( node->Identifier() );
       
   615                 
       
   616                 if ( aData->RemoteUri() != KNullDesC ) 
       
   617                     {
       
   618                     DASSERT( node->NodeLinkL().RemoteUri() == aData->RemoteUri() );
       
   619 
       
   620                     // Set the remote flag value just in case server has changed its settings
       
   621                     // from before.
       
   622                     node->NodeLinkL().SetRemoteFlag( ETrue );
       
   623                     iRemoteFolders.AppendL( nodeId );
       
   624                     }
       
   625                 else
       
   626                     {
       
   627                     iTransparentChildFolders.AppendL( nodeId );
       
   628                     }
       
   629                     
       
   630                 CleanupStack::Pop( nodeId );
       
   631                 }
       
   632             else if ( aData->ParentId() == KNullDesC )
       
   633                 {
       
   634                 // Check if the parent is actually bundle or a real content source
       
   635                 if ( iContentSourceMap->HasBundleFolder( *iParentIdentifier ) )
       
   636                     {
       
   637                     DLINFO(("Bundle content source"));
       
   638                     node = 
       
   639                         &iNodeManager->RefHandlerL(
       
   640                             *iParentIdentifier, *aData, iClientUid, insertMode,
       
   641                             iContentSourceMap->GetInsertIndexL( *iContentSource, *iParentIdentifier ),
       
   642                             CNcdNodeFactory::ENcdNodeFolder, CNcdNodeFactory::ENcdBundleNode,
       
   643                             CNcdNodeFactory::ENcdNormalNode );
       
   644                             
       
   645                     // The node is thought as a remote because it is direct child of bundle
       
   646                     node->NodeLinkL().SetRemoteFlag( ETrue );
       
   647                     }
       
   648                 else
       
   649                     {
       
   650                     DLINFO(("Normal content source"));
       
   651                     node =
       
   652                         &iNodeManager->RefHandlerL(
       
   653                             *iParentIdentifier, *aData, iClientUid, insertMode,
       
   654                             iContentSourceMap->GetInsertIndexL( *iContentSource, *iParentIdentifier ),
       
   655                             CNcdNodeFactory::ENcdNodeRoot, CNcdNodeFactory::ENcdNormalNode,
       
   656                             CNcdNodeFactory::ENcdNormalNode );                        
       
   657                     // All the content sources are thought as a remote nodes because they are
       
   658                     // catalogs.                        
       
   659                     node->NodeLinkL().SetRemoteFlag( ETrue );
       
   660                     }
       
   661                     
       
   662                 if( aData->RemoteUri() != KNullDesC )
       
   663                     {
       
   664                     // empty browse req. may give remote folders
       
   665                     CNcdNodeIdentifier* nodeId = 
       
   666                         CNcdNodeIdentifier::NewLC( node->Identifier() );
       
   667                     DASSERT( node->NodeLinkL().RemoteUri() == aData->RemoteUri() );
       
   668                     // Because this is remote node make sure that the flag is correct.
       
   669                     // No need the node here, because it will be saved again when remote
       
   670                     // folders are loaded.
       
   671                     node->NodeLinkL().SetRemoteFlag( ETrue );
       
   672                     iRemoteFolders.AppendL( nodeId );
       
   673                     CleanupStack::Pop( nodeId );
       
   674                     }
       
   675                 }
       
   676 
       
   677             // Notice that we do not need to handle the children of the content sources here
       
   678             // even if they would be loaded for some reason. So, all the necessary situations
       
   679             // have been handled above.
       
   680                 
       
   681             if ( node != NULL )
       
   682                 {                    
       
   683                 node->CreateAndSetLinkL().
       
   684                     SetCatalogsSourceNameL( iContentSource->Provider() );
       
   685                 iNodeManager->DbSaveNodeL( *node );
       
   686 
       
   687                 // Notice that the content source contains the node identifier, not
       
   688                 // metadata identifier.
       
   689                 if ( aData->ParentId() == KNullDesC ) 
       
   690                     {                    
       
   691                     CNcdNodeIdentifier* contentIdentifier =
       
   692                         CNcdNodeIdentifier::NewLC( node->Identifier() );
       
   693                     // Note that ownership of the identifier is transferred.
       
   694                     iContentSourceMap->AddNodeToContentSourceL( 
       
   695                         contentIdentifier, *iContentSource );
       
   696                     CleanupStack::Pop( contentIdentifier );
       
   697                     }
       
   698                 }
       
   699 
       
   700             break;
       
   701             }
       
   702             
       
   703         case ESingleNode:
       
   704             {
       
   705             DLINFO(("Single node"));
       
   706             DASSERT( iNodeIdentifier );
       
   707             DLINFO(("iNodeIdentifier: ns= %S, id= %S, aData: ns= %S, id= %S",
       
   708                 &iNodeIdentifier->NodeNameSpace(), &iNodeIdentifier->NodeId(),
       
   709                 &aData->Namespace(), &aData->Id() ));
       
   710             
       
   711             // Because aData contains metadata ids, we have to get
       
   712             // the metadata id from the iNodeIdentifier
       
   713             CNcdNodeIdentifier* metaIdentifier =
       
   714                 NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *iNodeIdentifier );
       
   715             CNcdNode& currentNode = iNodeManager->NodeL( *iNodeIdentifier );
       
   716             // Structure is added only for the node that is being loaded,
       
   717             // everything else is dumped.
       
   718             if ( aData->Id() == metaIdentifier->NodeId() && 
       
   719                 aData->Namespace() == metaIdentifier->NodeNameSpace() )
       
   720                 {
       
   721                 DLINFO(("ESingleNode, adding parent"));
       
   722                     
       
   723                 iNodeManager->RefHandlerL( *iParentIdentifier,
       
   724                     *aData,
       
   725                     iClientUid,
       
   726                     CNcdNodeManager::EUpdate,
       
   727                     0,
       
   728                     iParentType,
       
   729                     iParentPurpose,
       
   730 					CNcdNodeFactory::NodePurposeL( currentNode ),
       
   731 				    iCreateParent );
       
   732                     
       
   733                 }
       
   734             CleanupStack::PopAndDestroy( metaIdentifier );
       
   735             break;
       
   736             }
       
   737         case EChildren:
       
   738             {
       
   739             DLINFO(("Children"));
       
   740             DASSERT( iNodeIdentifier );
       
   741             
       
   742             // The comparison has to be made here between the metadata infos
       
   743             // So, get the parent node from the manager. So, the node metadata info
       
   744             // can be gotten. Notice that the parent already has the link info where
       
   745             // we can get its metadata identifier.
       
   746             CNcdNode& currentNode = iNodeManager->NodeL( *iNodeIdentifier );
       
   747             if ( aData->Id() == currentNode.NodeLinkL().MetaDataIdentifier().NodeId() && 
       
   748                  aData->Namespace() == currentNode.NodeLinkL().MetaDataIdentifier().NodeNameSpace() )
       
   749                 {
       
   750                 DLINFO(("EChildren Add parent"));
       
   751                 
       
   752                 // add parent
       
   753                 iNodeManager->RefHandlerL( *iParentIdentifier,
       
   754                     *aData,
       
   755                     iClientUid,
       
   756                     CNcdNodeManager::EUpdate,
       
   757                     0,
       
   758                     iParentType,
       
   759                     iParentPurpose,
       
   760                     CNcdNodeFactory::NodePurposeL( currentNode ),
       
   761                     iCreateParent );
       
   762                 // Structure loaded for parent -> send update notification
       
   763                 // for parent node so that it gets internalized.
       
   764                 CNcdNodeIdentifier* loadedNodeId = 
       
   765                     CNcdNodeIdentifier::NewLC( currentNode.Identifier() );
       
   766                 iLoadedNodes.AppendL( loadedNodeId );
       
   767                 CleanupStack::Pop( loadedNodeId );
       
   768                 }
       
   769             else
       
   770                 {
       
   771                 DLINFO(("EChildren add child"));
       
   772                 // add child
       
   773                 // Because aData item did not match the currentNode it means that
       
   774                 // we are loading the child of the current node.
       
   775                 // The iNodeIdentifier identifies the parent whose children should be loaded.
       
   776                 CNcdNode& node = 
       
   777                     iNodeManager->RefHandlerL( *iNodeIdentifier,
       
   778                                                *aData,
       
   779                                                iClientUid,
       
   780                                                CNcdNodeManager::EReplace,
       
   781                                                iNodeIndex++,
       
   782                                                CNcdNodeFactory::NodeTypeL( currentNode ),
       
   783                                                CNcdNodeFactory::NodePurposeL( currentNode ) );
       
   784 
       
   785                 // Before saving the node information make sure that the node remote info is
       
   786                 // set correctly.
       
   787                 if ( aData->RemoteUri() != KNullDesC )
       
   788                     {
       
   789                     DLINFO((_L("Remote node: %S"), &node.Identifier().NodeId()));
       
   790                     node.NodeLinkL().SetRemoteFlag( ETrue );
       
   791                     CNcdNodeIdentifier* identifier = CNcdNodeIdentifier::NewLC( node.Identifier() );
       
   792                     iRemoteFolders.AppendL( identifier );
       
   793                     CleanupStack::Pop( identifier );
       
   794                     }
       
   795                 else
       
   796                     {
       
   797                     DLINFO((_L("Normal node: %S"), &node.Identifier().NodeId()));
       
   798                     node.NodeLinkL().SetRemoteFlag( EFalse );
       
   799                     }
       
   800                 iNodeManager->DbSaveNodeL( node );
       
   801                 }
       
   802             break;
       
   803             }
       
   804         default:
       
   805             {
       
   806             DASSERT(0)
       
   807             User::Leave( KErrGeneral );
       
   808             break;
       
   809             }
       
   810         }
       
   811     
       
   812     // Delete data because ownership has been transferred.
       
   813     CleanupStack::PopAndDestroy( aData );
       
   814     
       
   815     RunOperation();        
       
   816     DLTRACEOUT((""));
       
   817     }
       
   818     
       
   819 // ---------------------------------------------------------------------------
       
   820 // ?implementation_description
       
   821 // ---------------------------------------------------------------------------
       
   822 //    
       
   823 void CNcdLoadNodeOperationImpl::FolderDataL(
       
   824     MNcdPreminetProtocolDataEntity* aData )
       
   825     {
       
   826     DLTRACEIN(( "this-ptr: %X", this ));
       
   827     
       
   828     // Normal PushL causes USER 42
       
   829     CleanupDeletePushL( aData );
       
   830     
       
   831     // This node will contain the metadata that is updated by calling
       
   832     // the handler function.
       
   833     // Notice that after this the metadata has also been created.
       
   834     // So, metadata can be directly used.
       
   835     CNcdNodeIdentifier* parentIdentifier( NULL );
       
   836     TBool addMetaData = ETrue;
       
   837     if( iLoadMode == EChildren || iLoadMode == ESingleNode )
       
   838         {
       
   839         DLINFO(("EChildren"));
       
   840         DASSERT( iNodeIdentifier );
       
   841         CNcdNodeIdentifier* metaIdentifier = 
       
   842             NcdNodeIdentifierEditor::CreateMetaDataIdentifierL( *iNodeIdentifier );
       
   843         if ( aData->Id() != metaIdentifier->NodeId() || 
       
   844              aData->Namespace() != metaIdentifier->NodeNameSpace() )
       
   845             {
       
   846             // aData must be child of iNodeIdentifier
       
   847             delete metaIdentifier;
       
   848             metaIdentifier = NULL;
       
   849             if( iLoadMode == EChildren )
       
   850                 {
       
   851                 parentIdentifier = CNcdNodeIdentifier::NewLC( *iNodeIdentifier );
       
   852                 }
       
   853             else
       
   854                 {
       
   855                 // Don't add child metadata in ESingleNode mode.
       
   856                 addMetaData = EFalse;
       
   857                 }
       
   858             }
       
   859         else 
       
   860             {
       
   861             delete metaIdentifier;
       
   862             metaIdentifier = NULL;
       
   863             }                
       
   864         }
       
   865     else if ( iLoadMode == EContentSource && iContentSource->IsTransparent() ) 
       
   866         {
       
   867         DLINFO(("EContentSource and transparent"));
       
   868         // We have to check if the folder data belongs to a folder inside a transparent
       
   869         // folder.
       
   870         CNcdNodeIdentifier* metaIdentifier = CNcdNodeIdentifier::NewLC(
       
   871             aData->Namespace(), aData->Id(), aData->ServerUri(), iClientUid );
       
   872         for ( TInt i = 0; i < iTransparentChildFolders.Count(); i++ ) 
       
   873             {
       
   874             CNcdNodeIdentifier* childOfTransparent = iTransparentChildFolders[i];
       
   875             CNcdNodeIdentifier* metaOfChild =
       
   876                 NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *childOfTransparent );
       
   877             DASSERT( metaOfChild != NULL );
       
   878             if ( metaOfChild->Equals( *metaIdentifier ) ) 
       
   879                 {
       
   880                 parentIdentifier = NcdNodeIdentifierEditor::ParentOfLC( *childOfTransparent );
       
   881                 CleanupStack::Pop( parentIdentifier );
       
   882                 CleanupStack::PopAndDestroy( metaOfChild );
       
   883                 break;
       
   884                 }
       
   885             CleanupStack::PopAndDestroy( metaOfChild );                
       
   886             }
       
   887         CleanupStack::PopAndDestroy( metaIdentifier );
       
   888         if ( parentIdentifier ) 
       
   889             {                
       
   890             CleanupStack::PushL( parentIdentifier );
       
   891             }
       
   892         }
       
   893     else if ( iLoadMode == EContentSource )
       
   894         {
       
   895         DLINFO(("EContentSource"));
       
   896         DLTRACE(("Check that node ref already exists."));
       
   897         TBool nodeFound = EFalse;
       
   898         RPointerArray<CNcdNodeIdentifier>& csNodes = iContentSourceMap->NodesL( *iContentSource );
       
   899         for( TInt i = 0 ; i < csNodes.Count() ; i++ )
       
   900             {
       
   901             CNcdNodeIdentifier* metaIdentifier =
       
   902                 NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *csNodes[i] );
       
   903             if( metaIdentifier->NodeNameSpace() == aData->Namespace() &&
       
   904                 metaIdentifier->NodeId() == aData->Id() )
       
   905                 {
       
   906                 DLTRACE(("Node ref has been added, proceed with metadata adding."));
       
   907                 nodeFound = ETrue;
       
   908                 CleanupStack::PopAndDestroy( metaIdentifier );
       
   909                 break;
       
   910                 }
       
   911             CleanupStack::PopAndDestroy( metaIdentifier );
       
   912             }
       
   913         if ( !nodeFound )
       
   914             {
       
   915             DLTRACE(("Node ref has NOT been added, don't add metadata either."));
       
   916             addMetaData = EFalse;
       
   917             }
       
   918         }
       
   919         
       
   920         
       
   921     if( addMetaData )
       
   922         {
       
   923         // set iParentIdentifier as parent if not set otherwise, this would be the case of a
       
   924         // normal top-level node from a content source
       
   925         if ( ! parentIdentifier ) 
       
   926             {
       
   927             parentIdentifier = CNcdNodeIdentifier::NewLC( *iParentIdentifier );
       
   928             }
       
   929             
       
   930         CNcdNode& node = 
       
   931             iNodeManager->DataHandlerL( *parentIdentifier, *aData, iClientUid );
       
   932             
       
   933         CleanupStack::PopAndDestroy( parentIdentifier );
       
   934         
       
   935         // Notice that the loaded nodes should contain the actual node identifier
       
   936         // instead of metadata identifier, because the identifiers are returned to
       
   937         // the proxy side after operation completes.
       
   938         CNcdNodeIdentifier* loadedNodeId = 
       
   939             CNcdNodeIdentifier::NewLC( node.Identifier() );
       
   940         iLoadedNodes.AppendL( loadedNodeId );
       
   941         CleanupStack::Pop( loadedNodeId );
       
   942         
       
   943         DLINFO(( _L("node loaded, id: %S"), &node.Identifier().NodeId() ));
       
   944 
       
   945         // If the data contains icon id and datablock id, they are stored until
       
   946         // the datablock arrives later (in DataBlocksL method).
       
   947         const MNcdPreminetProtocolIcon* icon = aData->Icon();
       
   948         if ( icon != NULL ) 
       
   949             {
       
   950             const TDesC& iconId = icon->Id();
       
   951             const TDesC& dataBlockId = icon->DataBlock();
       
   952             if ( iconId != KNullDesC && dataBlockId != KNullDesC ) 
       
   953                 {
       
   954                 // Icon id may be mapped to the metadata id here
       
   955                 MapIconIdForDataBlockL( iconId, dataBlockId, 
       
   956                                         node.NodeMetaDataL().Identifier() );
       
   957                 // Notice that here we need to get the node by using the
       
   958                 // parent identifier and metadata id, because the metadata
       
   959                 // identifier itself is not enough to identify the node.
       
   960                 node.NodeMetaDataL().IconL().SetIconDataReady( EFalse );
       
   961                 }
       
   962             }
       
   963         }
       
   964     else if ( parentIdentifier )
       
   965         {
       
   966         CleanupStack::PopAndDestroy( parentIdentifier );
       
   967         }
       
   968 
       
   969     // Delete data because ownership has been transferred.
       
   970     CleanupStack::PopAndDestroy( aData );
       
   971     
       
   972     RunOperation();
       
   973     DLTRACEOUT((""));
       
   974     }
       
   975     
       
   976 // ---------------------------------------------------------------------------
       
   977 // ?implementation_description
       
   978 // ---------------------------------------------------------------------------
       
   979 //
       
   980 void CNcdLoadNodeOperationImpl::ItemRefL( MNcdPreminetProtocolItemRef* aData )
       
   981     {
       
   982     DLTRACEIN(( "this-ptr: %X", this ));
       
   983     
       
   984     
       
   985     // Normal PushL causes USER 42
       
   986     CleanupDeletePushL( aData );
       
   987     
       
   988     switch ( iLoadMode )
       
   989         {
       
   990         case EContentSource:
       
   991             {
       
   992             DLINFO(("EContentSource"));
       
   993             DASSERT( aData->ParentId() != KNullDesC );
       
   994            
       
   995             // The iParentIdentifier is not correct for items since they cannot be in root
       
   996             // level. We have to create the actual parent identifier and use it.
       
   997             CNcdNodeIdentifier* metaDataParentIdentifier =
       
   998                 CNcdNodeIdentifier::NewLC(
       
   999                     aData->ParentNamespace(), aData->ParentId(),
       
  1000                     aData->ServerUri(), iClientUid );
       
  1001             CNcdNodeIdentifier* actualParentIdentifier =
       
  1002                 NcdNodeIdentifierEditor::CreateNodeIdentifierLC(
       
  1003                     *iParentIdentifier, *metaDataParentIdentifier );
       
  1004             
       
  1005             // Check if the parent is actually transparent, scheme, bundle or a real content source
       
  1006             if ( iContentSource->IsTransparent() ) 
       
  1007                 {
       
  1008                 DLINFO(("Content source transparent"));
       
  1009                 CNcdNode& node = iNodeManager->RefHandlerL( *actualParentIdentifier,
       
  1010                                                             *aData,
       
  1011                                                             iClientUid,
       
  1012                                                             CNcdNodeManager::EAppend,
       
  1013                                                             0,
       
  1014                                                             CNcdNodeFactory::ENcdNodeFolder,
       
  1015                                                             CNcdNodeFactory::ENcdTransparentNode,
       
  1016                                                             CNcdNodeFactory::ENcdChildOfTransparentNode );
       
  1017                 CNcdNodeIdentifier* nodeId = 
       
  1018                     CNcdNodeIdentifier::NewLC( node.Identifier() );
       
  1019                 iTransparentChildItems.AppendL( nodeId );
       
  1020                 CleanupStack::Pop( nodeId );                    
       
  1021                 }
       
  1022             else if ( iContentSourceMap->HasBundleFolder( *iParentIdentifier ) )
       
  1023                 {
       
  1024                 DLINFO(("Bundle content source"));
       
  1025                 iNodeManager->RefHandlerL(  *actualParentIdentifier,
       
  1026                                             *aData,
       
  1027                                             iClientUid,
       
  1028                                             CNcdNodeManager::EAppend,
       
  1029                                             0,
       
  1030                                             CNcdNodeFactory::ENcdNodeFolder,
       
  1031                                             CNcdNodeFactory::ENcdBundleNode );
       
  1032                 }
       
  1033             else if ( aData->ParentId() == KNullDesC )
       
  1034                 {
       
  1035                 DLINFO(("Normal content source"));
       
  1036                 iNodeManager->RefHandlerL(  *actualParentIdentifier,
       
  1037                                             *aData,
       
  1038                                             iClientUid,
       
  1039                                             CNcdNodeManager::EAppend,
       
  1040                                             0,
       
  1041                                             CNcdNodeFactory::ENcdNodeFolder );
       
  1042                 }
       
  1043             
       
  1044             CleanupStack::PopAndDestroy( actualParentIdentifier );
       
  1045             CleanupStack::PopAndDestroy( metaDataParentIdentifier );
       
  1046             break;
       
  1047             }
       
  1048         case ESingleNode:
       
  1049             {
       
  1050             DLINFO(("Single node"));
       
  1051             DASSERT( iNodeIdentifier );
       
  1052             DLINFO(("iNodeIdentifier: ns= %S, id= %S, aData: ns= %S, id= %S",
       
  1053                 &iNodeIdentifier->NodeNameSpace(), &iNodeIdentifier->NodeId(),
       
  1054                 &aData->Namespace(), &aData->Id() ));
       
  1055             
       
  1056             // Because aData contains metadata ids, we have to get
       
  1057             // the metadata id from the iNodeIdentifier
       
  1058             CNcdNodeIdentifier* metaIdentifier =
       
  1059                 NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *iNodeIdentifier );
       
  1060             CNcdNode& currentNode = iNodeManager->NodeL( *iNodeIdentifier );
       
  1061             if ( aData->Id() == metaIdentifier->NodeId() && 
       
  1062                 aData->Namespace() == metaIdentifier->NodeNameSpace() )
       
  1063                 {
       
  1064                 DLINFO(("ESingleNode, adding parent"));
       
  1065                     
       
  1066                 iNodeManager->RefHandlerL( *iParentIdentifier,
       
  1067                     *aData,
       
  1068                     iClientUid,
       
  1069                     CNcdNodeManager::EUpdate,
       
  1070                     0,
       
  1071                     iParentType,
       
  1072                     iParentPurpose,
       
  1073                     CNcdNodeFactory::NodePurposeL( currentNode ) );
       
  1074                 }
       
  1075             CleanupStack::PopAndDestroy( metaIdentifier );
       
  1076             break;
       
  1077             }
       
  1078         case EChildren:
       
  1079             {
       
  1080             DLINFO(("Children"));
       
  1081             // Get the parent node. So, we can use its link to get the metadataidentifier.
       
  1082             // The parent always has the link information set here.    
       
  1083             CNcdNode& parentNode = iNodeManager->NodeL( *iNodeIdentifier );
       
  1084             if ( aData->Id() == parentNode.NodeLinkL().MetaDataIdentifier().NodeId() && 
       
  1085                 aData->Namespace() == parentNode.NodeLinkL().MetaDataIdentifier().NodeNameSpace() )
       
  1086                 {
       
  1087                 // add parent
       
  1088                 iNodeManager->RefHandlerL( *iParentIdentifier,
       
  1089                                             *aData,
       
  1090                                             iClientUid,
       
  1091                                             CNcdNodeManager::EUpdate,
       
  1092                                             0,
       
  1093                                             iParentType,
       
  1094                                             iParentPurpose );
       
  1095                 }
       
  1096             else
       
  1097                 {
       
  1098                 // add child
       
  1099                 // The iNodeIdentifier identifies the parent whose children should be loaded.
       
  1100                 iNodeManager->RefHandlerL( *iNodeIdentifier,
       
  1101                                             *aData,
       
  1102                                             iClientUid,
       
  1103                                             CNcdNodeManager::EReplace,
       
  1104                                             iNodeIndex++,
       
  1105                                             CNcdNodeFactory::ENcdNodeFolder,
       
  1106                                             CNcdNodeFactory::NodePurposeL( parentNode ) );
       
  1107                 }
       
  1108             break;
       
  1109             }
       
  1110         default:
       
  1111             {
       
  1112             DASSERT(0)
       
  1113             User::Leave( KErrGeneral );
       
  1114             break;
       
  1115             }
       
  1116         }
       
  1117     
       
  1118     // Delete data because ownership has been transferred.
       
  1119     CleanupStack::PopAndDestroy( aData ); 
       
  1120     
       
  1121     RunOperation();
       
  1122     DLTRACEOUT((""));
       
  1123     }
       
  1124     
       
  1125 // ---------------------------------------------------------------------------
       
  1126 // ?implementation_description
       
  1127 // ---------------------------------------------------------------------------
       
  1128 //
       
  1129 void CNcdLoadNodeOperationImpl::ItemDataL(
       
  1130     MNcdPreminetProtocolDataEntity* aData )
       
  1131     {
       
  1132     DLTRACEIN(( "this-ptr: %X", this ));
       
  1133 
       
  1134     
       
  1135    
       
  1136         // Normal PushL causes USER 42
       
  1137     CleanupDeletePushL( aData );
       
  1138     TBool addMetaData = ETrue;
       
  1139     CNcdNodeIdentifier* parentIdentifier( NULL );
       
  1140     if( iLoadMode == EChildren || iLoadMode == ESingleNode )
       
  1141         {
       
  1142         DLINFO(("EChildren or ESingleNode"));
       
  1143         DASSERT( iNodeIdentifier );
       
  1144         CNcdNodeIdentifier* metaIdentifier = 
       
  1145             NcdNodeIdentifierEditor::CreateMetaDataIdentifierL( *iNodeIdentifier );
       
  1146         if ( aData->Id() != metaIdentifier->NodeId() || 
       
  1147              aData->Namespace() != metaIdentifier->NodeNameSpace() )
       
  1148             {
       
  1149             // aData must be child of iNodeIdentifier
       
  1150             delete metaIdentifier;
       
  1151             metaIdentifier = NULL;
       
  1152             if( iLoadMode == EChildren )
       
  1153                 {
       
  1154                 parentIdentifier = CNcdNodeIdentifier::NewLC( *iNodeIdentifier );
       
  1155                 }
       
  1156             else
       
  1157                 {
       
  1158                 // Don't add child metadata in ESingleNode mode.
       
  1159                 addMetaData = EFalse;
       
  1160                 }
       
  1161             }
       
  1162         else 
       
  1163             {
       
  1164             delete metaIdentifier;
       
  1165             metaIdentifier = NULL;
       
  1166             }                
       
  1167         }
       
  1168     else if ( iLoadMode == EContentSource && iContentSource->IsTransparent() ) 
       
  1169         {
       
  1170         // parent is actually the transparent folder, 
       
  1171         // not iParentIdentifier ( which is root node )
       
  1172         CNcdNodeIdentifier* metaIdentifier = CNcdNodeIdentifier::NewLC(
       
  1173             aData->Namespace(), aData->Id(), aData->ServerUri(), iClientUid );
       
  1174         for ( TInt i = 0; i < iTransparentChildItems.Count(); i++ ) 
       
  1175             {
       
  1176             CNcdNodeIdentifier* childOfTransparent = iTransparentChildItems[i];
       
  1177             CNcdNodeIdentifier* metaOfChild =
       
  1178                 NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *childOfTransparent );
       
  1179             DASSERT( metaOfChild != NULL );
       
  1180             if ( metaOfChild->Equals( *metaIdentifier ) ) 
       
  1181                 {
       
  1182                 parentIdentifier = NcdNodeIdentifierEditor::ParentOfLC( *childOfTransparent );
       
  1183                 CleanupStack::Pop( parentIdentifier );
       
  1184                 CleanupStack::PopAndDestroy( metaOfChild );
       
  1185                 break;
       
  1186                 }
       
  1187             CleanupStack::PopAndDestroy( metaOfChild );
       
  1188             }
       
  1189         CleanupStack::PopAndDestroy( metaIdentifier );
       
  1190         if ( parentIdentifier )
       
  1191             {
       
  1192             CleanupStack::PushL( parentIdentifier );
       
  1193             }
       
  1194         }
       
  1195     else if ( iLoadMode == EContentSource )
       
  1196         {
       
  1197         DLINFO(("EContentSource"));
       
  1198         DLTRACE(("Check that node ref already exists."));
       
  1199         TBool nodeFound = EFalse;
       
  1200         RPointerArray<CNcdNodeIdentifier>& csNodes = iContentSourceMap->NodesL( *iContentSource );
       
  1201         for( TInt i = 0 ; i < csNodes.Count() ; i++ )
       
  1202             {
       
  1203             CNcdNodeIdentifier* metaIdentifier =
       
  1204                 NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *csNodes[i] );
       
  1205             if( metaIdentifier->NodeNameSpace() == aData->Namespace() &&
       
  1206                 metaIdentifier->NodeId() == aData->Id() )
       
  1207                 {
       
  1208                 DLTRACE(("Node ref has been added, proceed with metadata adding."));
       
  1209                 nodeFound = ETrue;
       
  1210                 CleanupStack::PopAndDestroy( metaIdentifier );
       
  1211                 break;
       
  1212                 }
       
  1213             CleanupStack::PopAndDestroy( metaIdentifier );
       
  1214             }
       
  1215         if ( !nodeFound )
       
  1216             {
       
  1217             DLTRACE(("Node ref has NOT been added, don't add metadata either."));
       
  1218             addMetaData = EFalse;
       
  1219             }
       
  1220         }
       
  1221     
       
  1222     if( addMetaData )
       
  1223         {
       
  1224         // set iParentIdentifier as parent if not set otherwise, this would be the case of a
       
  1225         // normal top-level node from a content source
       
  1226         if ( ! parentIdentifier ) 
       
  1227             {
       
  1228             parentIdentifier = CNcdNodeIdentifier::NewLC( *iParentIdentifier );
       
  1229             }
       
  1230         
       
  1231         // Get the node reference from the data handler.
       
  1232         // The node has the given parent and its metadata
       
  1233         // will be internalized with the given data.
       
  1234         CNcdNode& node =
       
  1235             iNodeManager->DataHandlerL( *parentIdentifier, *aData, iClientUid );
       
  1236             
       
  1237         CleanupStack::PopAndDestroy( parentIdentifier );
       
  1238 
       
  1239         // Notice that the loaded nodes should contain the actual node identifier
       
  1240         // instead of metadata identifier, because the identifiers are returned to
       
  1241         // the proxy side after operation completes.
       
  1242         CNcdNodeIdentifier* loadedNodeId = 
       
  1243             CNcdNodeIdentifier::NewLC( node.Identifier() );
       
  1244         iLoadedNodes.AppendL( loadedNodeId );
       
  1245         CleanupStack::Pop( loadedNodeId );        
       
  1246 
       
  1247         // If the data contains icon id and datablock id, they are stored until
       
  1248         // the datablock arrives later.
       
  1249         const MNcdPreminetProtocolIcon* icon = aData->Icon();
       
  1250         if ( icon != NULL ) 
       
  1251             {
       
  1252             const TDesC& iconId = icon->Id();
       
  1253             const TDesC& dataBlockId = icon->DataBlock();
       
  1254             if ( iconId != KNullDesC && dataBlockId != KNullDesC ) 
       
  1255                 {
       
  1256                 // The node metadata was created by using the DataHandlerL
       
  1257                 // and inserted for the node.
       
  1258                 // So, the metadata can be asked from the node now.
       
  1259                 MapIconIdForDataBlockL(iconId, dataBlockId, 
       
  1260                                        node.NodeMetaDataL().Identifier() );
       
  1261                 node.NodeMetaDataL().IconL().SetIconDataReady( EFalse );
       
  1262                 }
       
  1263             }
       
  1264         }
       
  1265     else if ( parentIdentifier )
       
  1266         {
       
  1267         CleanupStack::PopAndDestroy( parentIdentifier );
       
  1268         }
       
  1269         
       
  1270     // Delete data because ownership has been transferred.
       
  1271     CleanupStack::PopAndDestroy( aData );
       
  1272     
       
  1273     RunOperation();
       
  1274     DLTRACEOUT((""));
       
  1275     }
       
  1276     
       
  1277 void CNcdLoadNodeOperationImpl::Progress( CNcdBaseOperation& /*aOperation*/ )
       
  1278     {
       
  1279     
       
  1280     }
       
  1281     
       
  1282 void CNcdLoadNodeOperationImpl::QueryReceived( CNcdBaseOperation& /*aOperation*/,
       
  1283     CNcdQuery* aQuery )
       
  1284     {
       
  1285     DLTRACEIN(( "this-ptr: %X", this ));
       
  1286     DASSERT( iLoadNodeState == EReceiveRemote )
       
  1287     TRAPD( err, iSubOpQuerys.AppendL( aQuery ) );
       
  1288     if( err != KErrNone )
       
  1289         {
       
  1290         iError = err;
       
  1291         iLoadNodeState = EFailed;
       
  1292         }
       
  1293     aQuery->InternalAddRef();
       
  1294     RunOperation();
       
  1295     }
       
  1296     
       
  1297 void CNcdLoadNodeOperationImpl::OperationComplete( CNcdBaseOperation* aOperation,
       
  1298     TInt aError )
       
  1299     {
       
  1300     DLTRACEIN(("error=%d, iLoadNodeState=%d, operation=%x", 
       
  1301         aError, iLoadNodeState, aOperation ));
       
  1302     (void) aError; // suppresses compiler warning
       
  1303     DLINFO(( "this-ptr: %X", this ));
       
  1304 
       
  1305     DASSERT( iLoadNodeState == EReceiveRemote || 
       
  1306         iLoadNodeState == ERemote || 
       
  1307         iLoadNodeState == EFailed );
       
  1308     
       
  1309     // Operation type can be ESearchOperation because CNcdSearchOperation
       
  1310     // inherits from CNcdLoadNodeOperationImpl
       
  1311     DASSERT( aOperation->Type() == ELoadNodeOperation ||
       
  1312              aOperation->Type() == ESearchOperation );
       
  1313 
       
  1314     DLTRACE(("Failed subops: %d, completed: %d, total: %d", 
       
  1315         iFailedSubOps.Count(), 
       
  1316         iCompletedSubOps.Count(),
       
  1317         iSubOps.Count() ));
       
  1318     
       
  1319     TRAPD(err, 
       
  1320     CNcdLoadNodeOperationImpl* loadOp =
       
  1321         static_cast<CNcdLoadNodeOperationImpl*>( aOperation );
       
  1322         
       
  1323     if ( loadOp->State() == CNcdLoadNodeOperationImpl::EFailed )
       
  1324         {
       
  1325         iFailedSubOps.AppendL( loadOp );
       
  1326         }
       
  1327     else if ( loadOp->State() == CNcdLoadNodeOperationImpl::EComplete )
       
  1328         {
       
  1329         DLTRACE(("Op was complete"));
       
  1330         iCompletedSubOps.AppendL( loadOp );
       
  1331         const RPointerArray<CNcdNodeIdentifier>& loadedNodes = loadOp->LoadedNodes();
       
  1332         // add loaded nodes from child op to our own array
       
  1333         for ( TInt i = 0 ; i < loadedNodes.Count() ; i++ )
       
  1334             {
       
  1335             CNcdNodeIdentifier* id = CNcdNodeIdentifier::NewLC( *loadedNodes[i] );
       
  1336             iLoadedNodes.AppendL( id );
       
  1337             CleanupStack::Pop( id );
       
  1338             }
       
  1339         }
       
  1340     
       
  1341     if ( iLoadNodeState == EReceiveRemote )
       
  1342         {
       
  1343         // call RunOperation only in this state,
       
  1344         // otherwise RunOperation could call itself immediately
       
  1345         // after starting a sub op
       
  1346         // (sub-op start -> error -> complete callback -> run op )
       
  1347         RunOperation();
       
  1348         }
       
  1349     ); //TRAPD
       
  1350     
       
  1351     DLTRACE(("Failed subops: %d, completed: %d, total: %d", 
       
  1352         iFailedSubOps.Count(), 
       
  1353         iCompletedSubOps.Count(),
       
  1354         iSubOps.Count() ));
       
  1355         
       
  1356     if ( err != KErrNone )
       
  1357         {
       
  1358         iError = err;
       
  1359         iLoadNodeState = EFailed;
       
  1360         RunOperation();
       
  1361         }
       
  1362 
       
  1363     DLTRACEOUT((""));
       
  1364     }
       
  1365     
       
  1366 void CNcdLoadNodeOperationImpl::DataBlocksL(
       
  1367     CArrayPtr<MNcdPreminetProtocolDataBlock>* aData ) 
       
  1368     {
       
  1369     DLTRACEIN(( "this-ptr: %X", this ));
       
  1370     CleanupResetAndDestroyPushL( *aData );
       
  1371     
       
  1372     // Save the data blocks having icon data to database, taking advance of 
       
  1373     // the mapping of icon IDs and datablock IDs.
       
  1374     
       
  1375     for ( TInt i = 0; i < aData->Count(); i++ ) 
       
  1376         {
       
  1377         MNcdPreminetProtocolDataBlock* dataBlock = (*aData)[i];
       
  1378         DLINFO(( "datablock number: %d", i ));
       
  1379         RPointerArray<CNcdNodeIconMap> icons = IconsForDataBlockL( dataBlock->Id() );
       
  1380         CleanupResetAndDestroyPushL( icons );
       
  1381         
       
  1382         for ( TInt iconIndex = 0; iconIndex < icons.Count(); iconIndex++ )
       
  1383             {
       
  1384             DLINFO(( "icon number: %d", iconIndex ));
       
  1385             CNcdNodeIconMap* map = icons[iconIndex];
       
  1386             CNcdNodeIdentifier* metaDataId = map->iMetadataId;
       
  1387             
       
  1388             // Metadata should always exist if we are trying to handle the icon data.
       
  1389             const CNcdNodeMetaData& metaData = 
       
  1390                 iNodeManager->NodeMetaDataL( *metaDataId );
       
  1391             CNcdNodeIdentifier* iconIdentifier = CNcdNodeIdentifier::NewLC(
       
  1392                 metaData.Identifier().NodeNameSpace(), *map->iIconId,
       
  1393                 metaData.Identifier().ServerUri(), metaData.Identifier().ClientUid() );
       
  1394             DLTRACE(("Saving icon data"));
       
  1395             iNodeManager->DbSaveIconDataL( *iconIdentifier, dataBlock->Content() );
       
  1396             DLTRACE(("Icon data saved"));
       
  1397             CleanupStack::PopAndDestroy( iconIdentifier );
       
  1398             iconIdentifier = NULL;                
       
  1399             DLTRACE(("Marking icon data as ready"));
       
  1400             // mark the icon data is ready
       
  1401             metaData.IconL().SetIconDataReady( ETrue );                
       
  1402             DLTRACE(("Icon data marked ready"));
       
  1403             }         
       
  1404             
       
  1405         CleanupStack::PopAndDestroy( &icons );              
       
  1406         }
       
  1407     
       
  1408     DLTRACE(("Calling default observer"));
       
  1409     // aData is deleted by default observer
       
  1410     iParser->DefaultObserver().DataBlocksL( aData );
       
  1411     CleanupStack::Pop( aData );
       
  1412     }
       
  1413     
       
  1414 // ---------------------------------------------------------------------------
       
  1415 // ?description_if_needed
       
  1416 // ---------------------------------------------------------------------------
       
  1417 //
       
  1418 CNcdLoadNodeOperationImpl::CNcdLoadNodeOperationImpl(
       
  1419     CNcdNodeFactory::TNcdNodePurpose aParentNodePurpose,
       
  1420     TNcdResponseFilterParams aFilterParams,
       
  1421     TNcdChildLoadMode aMode,
       
  1422     TBool aLoadChildren,
       
  1423     CNcdGeneralManager& aGeneralManager,    
       
  1424     MCatalogsHttpSession& aHttpSession,    
       
  1425     MNcdOperationRemoveHandler* aRemoveHandler,
       
  1426     MNcdOperationQueue* aOperationQueue,
       
  1427     MCatalogsSession& aSession,
       
  1428     TBool aIsSubOperation,
       
  1429     TBool aCreateParent )
       
  1430     : CNcdBaseOperation( aGeneralManager, aRemoveHandler, ELoadNodeOperation, 
       
  1431         aSession, aIsSubOperation ),
       
  1432       iAccessPointManager( aGeneralManager.AccessPointManager() ),
       
  1433       iProtocol( aGeneralManager.ProtocolManager() ),
       
  1434       iHttpSession( aHttpSession ),
       
  1435       iFilterParams( aFilterParams ),
       
  1436       iChildLoadMode( aMode ),
       
  1437       iNodeIndex( aFilterParams.iPageStart ),
       
  1438       iParentType( CNcdNodeFactory::ENcdNodeFolder ),
       
  1439       iParentPurpose( aParentNodePurpose ),
       
  1440       iCreateParent( aCreateParent ),
       
  1441       iOperationQueue( aOperationQueue )
       
  1442     {
       
  1443     if ( aLoadChildren )
       
  1444         {
       
  1445         iLoadMode = EChildren;
       
  1446         }
       
  1447     else
       
  1448         {
       
  1449         iLoadMode = ESingleNode;
       
  1450         }
       
  1451     iLoadNodeState = ESendRequest;
       
  1452     iProgress.iState = 0;
       
  1453     iProgress.iOperationId = 0;
       
  1454     iProgress.iProgress = 0;
       
  1455     iProgress.iMaxProgress = 100;
       
  1456     iHttpSession.AddRef();
       
  1457     }
       
  1458 
       
  1459 CNcdLoadNodeOperationImpl::CNcdLoadNodeOperationImpl(
       
  1460     CNcdGeneralManager& aGeneralManager,    
       
  1461     MCatalogsHttpSession& aHttpSession,    
       
  1462     MNcdOperationRemoveHandler* aRemoveHandler,
       
  1463     MCatalogsSession& aSession )
       
  1464     : CNcdBaseOperation( aGeneralManager, aRemoveHandler, ELoadNodeOperation,
       
  1465         aSession, ETrue ),
       
  1466       iAccessPointManager( aGeneralManager.AccessPointManager() ),
       
  1467       iProtocol( aGeneralManager.ProtocolManager() ),
       
  1468       iHttpSession( aHttpSession ),
       
  1469       iLoadMode( EContentSource ),
       
  1470       iParentType( CNcdNodeFactory::ENcdNodeFolder )
       
  1471     {
       
  1472     iLoadNodeState = ESendRequest;
       
  1473     iProgress.iState = 0;
       
  1474     iProgress.iOperationId = 0;
       
  1475     iProgress.iProgress = 0;
       
  1476     iProgress.iMaxProgress = 100;
       
  1477     iHttpSession.AddRef();
       
  1478     }
       
  1479 
       
  1480 // ---------------------------------------------------------------------------
       
  1481 // ?description_if_needed
       
  1482 // ---------------------------------------------------------------------------
       
  1483 //
       
  1484 void CNcdLoadNodeOperationImpl::ConstructL(
       
  1485     const CNcdNodeIdentifier& aNodeIdentifier,
       
  1486     const CNcdNodeIdentifier& aParentIdentifier )
       
  1487     {
       
  1488     DLTRACEIN(( "this-ptr: %X", this ));
       
  1489 
       
  1490     CNcdBaseOperation::ConstructL();
       
  1491     
       
  1492     iNodeIdentifier = 
       
  1493         CNcdNodeIdentifier::NewL( aNodeIdentifier );        
       
  1494     iParentIdentifier = 
       
  1495         CNcdNodeIdentifier::NewL( aParentIdentifier );
       
  1496     iClientUid = aNodeIdentifier.ClientUid();
       
  1497        
       
  1498     DetermineParentTypeL( iClientUid );   
       
  1499     DLTRACEOUT((""));
       
  1500     }
       
  1501 
       
  1502 void CNcdLoadNodeOperationImpl::ConstructL(
       
  1503     CNcdContentSource& aContentSource,
       
  1504     CNcdContentSourceMap* aContentSourceMap,
       
  1505     const CNcdNodeIdentifier& aParentIdentifier )
       
  1506     {
       
  1507     DLTRACEIN((""));
       
  1508     CNcdBaseOperation::ConstructL();
       
  1509     iContentSourceMap = aContentSourceMap;
       
  1510     iContentSource = &aContentSource;
       
  1511     iParentIdentifier = CNcdNodeIdentifier::NewL( aParentIdentifier );
       
  1512     iClientUid = aParentIdentifier.ClientUid();
       
  1513        
       
  1514     DetermineParentTypeL( iClientUid );
       
  1515     DLTRACEOUT((""));
       
  1516     }
       
  1517 
       
  1518 // ---------------------------------------------------------------------------
       
  1519 // ?implementation_description
       
  1520 // ---------------------------------------------------------------------------
       
  1521 //
       
  1522 HBufC8* CNcdLoadNodeOperationImpl::CreateRequestLC(
       
  1523     CNcdNodeIdentifier* aNodeIdentifier,    
       
  1524     TNcdResponseFilterParams aFilterParams,
       
  1525     const TDesC& aUri )
       
  1526     {
       
  1527     DLTRACEIN(( "this-ptr: %X", this ));
       
  1528     
       
  1529     CNcdRequestBrowseSearch* req =
       
  1530         NcdRequestGenerator::CreateBrowseRequestLC();
       
  1531         
       
  1532     switch ( iLoadMode )
       
  1533         {
       
  1534         case EContentSource:
       
  1535             {
       
  1536             DLTRACE(("EContentSource"));
       
  1537             DASSERT( iContentSource )
       
  1538             req->SetNamespaceL( iContentSource->NameSpace() );
       
  1539             CDesC16ArrayFlat* elements = new (ELeave) CDesC16ArrayFlat(1);
       
  1540             CleanupStack::PushL( elements );
       
  1541             if ( iContentSource->NodeId() != KNullDesC() )
       
  1542                 {                
       
  1543                 DLTRACE((_L("Id found: %S, use it in the request"), &iContentSource->NodeId() ));
       
  1544                 CNcdNodeIdentifier* nodeId = CNcdNodeIdentifier::NewLC(
       
  1545                     iContentSource->NameSpace(), iContentSource->NodeId(), 
       
  1546                     iContentSource->Uri(), iClientUid );
       
  1547                 CNcdNodeIdentifier* metaId = NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *nodeId );
       
  1548 
       
  1549                 CNcdNode* node( NULL );
       
  1550                 // Node can tried by using the nodeId which is the identifier included in
       
  1551                 // the content source.
       
  1552                 TRAPD( err, node = &iNodeManager->NodeL( *nodeId ));
       
  1553                 CNcdNodeLink* link( NULL );
       
  1554                 if( err == KErrNone )
       
  1555                     {
       
  1556                     DLINFO(("EContentSource Node was found"));
       
  1557                     link = node->NodeLink();
       
  1558                     if ( link ) 
       
  1559                         {                        
       
  1560                         DLINFO(("node link was found"));
       
  1561                         // node found, use timestamp
       
  1562                         // Notice that the content source contains the node id.
       
  1563                         // Request needs the meta id, so use it here.
       
  1564                         req->AddEntityL( metaId->NodeId(),
       
  1565                                          link->Timestamp(),
       
  1566                                          ETrue );
       
  1567                         }
       
  1568                     }
       
  1569                     
       
  1570                 if ( !link ) 
       
  1571                     {
       
  1572                     DLINFO(("EContentSource Node or link not found"));
       
  1573                     // Notice that the content source contains the node id.
       
  1574                     // Request needs the meta id, so use it here.
       
  1575                     // node not found, no timestamp
       
  1576                     req->AddEntityL( metaId->NodeId(), ETrue );
       
  1577                     }
       
  1578                 CleanupStack::PopAndDestroy( metaId );
       
  1579                 CleanupStack::PopAndDestroy( nodeId );
       
  1580                 }
       
  1581 
       
  1582             if ( iContentSource->IsTransparent() ) 
       
  1583                 {
       
  1584                 // If content source is transparent, we need to get all the children of the
       
  1585                 // transparent folder too.
       
  1586                 req->AddResponseFilterL(
       
  1587                     INT_MAX, // pageSize: get all children
       
  1588                     0, // pageStart: start from the first child
       
  1589                     1, // structureDepth: load child structure
       
  1590                     1, // metaDataDepth: load child metadata
       
  1591                     INT_MAX, // metaDataPerLevel: get all metadata
       
  1592                     *elements,
       
  1593                     *elements );
       
  1594                 }
       
  1595             else
       
  1596                 {
       
  1597                 // Normal case, load the first child's structure to get the child count.
       
  1598                 req->AddResponseFilterL(
       
  1599                     1, // pageSize: load one child
       
  1600                     0, // pageStart: load the first child
       
  1601                     1, // structureDepth: load child structure
       
  1602                     0, // metaDataDepth: don't load child metadata
       
  1603                     1, // metaDataPerLevel: only load one metadata per level
       
  1604                     *elements,
       
  1605                     *elements );
       
  1606                 }
       
  1607             CleanupStack::PopAndDestroy( elements );
       
  1608             DLTRACE(("EContentSource done"))
       
  1609             break;
       
  1610             }
       
  1611         case ESingleNode:
       
  1612             {
       
  1613             DLTRACE(("ESingleNode"));
       
  1614             DASSERT( aNodeIdentifier );
       
  1615             // loading just one node, don't use filter params 
       
  1616             // The parameter identifier means the actual node. So,
       
  1617             // the id may be used to get the node from the manager.
       
  1618             CNcdNode& node = iNodeManager->NodeL( *aNodeIdentifier );
       
  1619             CDesC16ArrayFlat* elements = new (ELeave) CDesC16ArrayFlat(1);
       
  1620             CleanupStack::PushL( elements );
       
  1621             // Request uses the metadata information not the node information.
       
  1622             req->SetNamespaceL( node.NodeLinkL().MetaDataIdentifier().NodeNameSpace() );
       
  1623             req->AddEntityL( node.NodeLinkL().MetaDataIdentifier().NodeId(),
       
  1624                              node.NodeLinkL().Timestamp(),
       
  1625                              ETrue ); // Include metadata.
       
  1626                         
       
  1627             // We don't want to use a response filter with items because then
       
  1628             // metadata won't be included in the response unless the filter has
       
  1629             // metaDataDepth > 0. 
       
  1630             if ( CNcdNodeFactory::NodeTypeL( node ) != CNcdNodeFactory::ENcdNodeItem ) 
       
  1631                 {
       
  1632                 req->AddResponseFilterL(
       
  1633                     1, // pageSize: load one child, needed to get child count from Jamba backend
       
  1634                     0, // pageStart: load the first child
       
  1635                     1, // structureDepth: load child structure
       
  1636                     0, // metaDataDepth: don't load metadata
       
  1637                     0, // metaDataPerLevel: don't load metadata
       
  1638                     *elements,
       
  1639                     *elements );
       
  1640                 }
       
  1641             CleanupStack::PopAndDestroy( elements );
       
  1642             DLTRACE(("ESingleNode done"))
       
  1643             break;
       
  1644             }
       
  1645         case EChildren:
       
  1646             {
       
  1647             DLTRACE(("EChildren"));
       
  1648             DASSERT( aNodeIdentifier );
       
  1649             // loading children, use filter params
       
  1650             // The parameter identifier means the actual node. So,
       
  1651             // the id may be used to get the node from the manager.
       
  1652             CNcdNodeFolder& folder = iNodeManager->FolderL( *aNodeIdentifier );
       
  1653             req->SetNamespaceL( folder.NodeLinkL().MetaDataIdentifier().NodeNameSpace() );
       
  1654             CDesC16ArrayFlat* elements = new (ELeave) CDesC16ArrayFlat(1);
       
  1655             CleanupStack::PushL( elements );
       
  1656             
       
  1657             // Add the parent folder to the request.
       
  1658             req->AddEntityL( folder.NodeLinkL().MetaDataIdentifier().NodeId(),
       
  1659                              folder.NodeLinkL().Timestamp(),
       
  1660                              EFalse ); // No metadata for parent
       
  1661             
       
  1662             switch ( iChildLoadMode )
       
  1663                 {
       
  1664                 case ELoadStructure:
       
  1665                     {
       
  1666                     DLTRACE(("ELoadStructure"));
       
  1667                     // Calculate correct pagesize.
       
  1668                     TInt pageSize = CalculateStructPageSize(aFilterParams.iPageStart,
       
  1669                         aFilterParams.iPageSize,
       
  1670                         folder,
       
  1671                         iChildLoadMode );
       
  1672                     // Add response filter to get only the desired amount of children.
       
  1673                     req->AddResponseFilterL(
       
  1674                         pageSize, // pageSize
       
  1675                         aFilterParams.iPageStart, // pageStart
       
  1676                         1, // structureDepth: load child structure
       
  1677                         0, // metaDataDepth:  don't load child metadata
       
  1678                         0, // metaDataPerLevel: don't load child metadata
       
  1679                         *elements,
       
  1680                         *elements );
       
  1681                     DLTRACE(("ELoadStructure done"));
       
  1682                     break;
       
  1683                     }
       
  1684                 case ELoadMetadata:
       
  1685                     {
       
  1686                     DLTRACE(("ELoadMetadata"));
       
  1687                     CNcdNodeFolder& folder = iNodeManager->FolderL( *aNodeIdentifier );
       
  1688                     // Special handling for bundle folders.
       
  1689                     if ( folder.ClassId() == NcdNodeClassIds::ENcdBundleFolderNodeClassId )
       
  1690                         {
       
  1691                         DLTRACE(("Bundle folder -> load children in sub ops."));
       
  1692                         for ( TInt i = aFilterParams.iPageStart ;
       
  1693                              i < aFilterParams.iPageStart + aFilterParams.iPageSize ;
       
  1694                              i++ )
       
  1695                             {
       
  1696                             CNcdNode& childNode = iNodeManager->NodeL( folder.ChildByServerIndexL( i ) );
       
  1697                             
       
  1698                             if ( !childNode.NodeMetaData() || childNode.NodeLinkL().IsExpired() )
       
  1699                                 {
       
  1700                                 // load node only if it has no metadata or if it's expired
       
  1701                             
       
  1702                                 CNcdNodeIdentifier* remoteFolderId =
       
  1703                                     CNcdNodeIdentifier::NewLC( childNode.Identifier() );
       
  1704                                 // Remote folderlist contains actual node ids.
       
  1705                                 iRemoteFolders.AppendL( remoteFolderId );
       
  1706                                 CleanupStack::Pop( remoteFolderId );
       
  1707                                 }
       
  1708                             }
       
  1709                         if( iRemoteFolders.Count() > 0 )
       
  1710                             {
       
  1711                             DLTRACE(("Only remote folders to load"));
       
  1712                             User::Leave( KNcdLoadNodeErrRemoteOnly );
       
  1713                             }
       
  1714                         else
       
  1715                             {
       
  1716                             DLTRACE(("Nothing to do -> complete operation"));
       
  1717                             User::Leave( KNcdLoadNodeErrNothingToDo );
       
  1718                             }
       
  1719                         }
       
  1720                     else
       
  1721                         {
       
  1722                         DLTRACE(("Normal folder"));
       
  1723                         // Calculate correct pagesize.
       
  1724                         TInt pageSize = CalculateStructPageSize(aFilterParams.iPageStart,
       
  1725                             aFilterParams.iPageSize,
       
  1726                             folder,
       
  1727                             iChildLoadMode );
       
  1728                         // Add response filter to get only the desired amount of children.                      
       
  1729                         req->AddResponseFilterL(
       
  1730                             pageSize, // pageSize: 
       
  1731                             aFilterParams.iPageStart, // pageStart: not applicable in this case as pageSize is 0
       
  1732                             1, // structureDepth: load child structure
       
  1733                             1, // metaDataDepth: load child metadata
       
  1734                             aFilterParams.iPageSize,// metaDataPerLevel: load metadata only for the requested page
       
  1735                             *elements,
       
  1736                             *elements );
       
  1737                         }
       
  1738                     DLTRACE(("ELoadMetadata done"));
       
  1739                     break;
       
  1740                     }
       
  1741                 default:
       
  1742                     {
       
  1743                     // For debugging purposes
       
  1744                     DLERROR(("Unidentified case"));
       
  1745                     DASSERT( EFalse );
       
  1746                     break;                        
       
  1747                     }
       
  1748                 }
       
  1749             CleanupStack::PopAndDestroy( elements );
       
  1750             DLTRACE(("EChildren done"));
       
  1751             break;
       
  1752             }
       
  1753         default:
       
  1754             {
       
  1755             // For debugging purposes
       
  1756             DLERROR(("Unidentified case"));
       
  1757             DASSERT( EFalse );
       
  1758             break;                        
       
  1759             }
       
  1760         }
       
  1761     
       
  1762     HBufC8* data = NULL;
       
  1763     
       
  1764     AddQueryResponsesL( req );
       
  1765     
       
  1766     data = iProtocol.ProcessPreminetRequestL(
       
  1767         iSession.Context(), *req, aUri );
       
  1768     
       
  1769     CleanupStack::PopAndDestroy( req );
       
  1770     CleanupStack::PushL( data );
       
  1771     return data;
       
  1772     }
       
  1773 
       
  1774 void CNcdLoadNodeOperationImpl::MapIconIdForDataBlockL(
       
  1775     const TDesC& aIconId, const TDesC& aDataBlockId,
       
  1776     const CNcdNodeIdentifier& aNodeId ) 
       
  1777     {
       
  1778     DLTRACEIN(( "this-ptr: %X", this ));
       
  1779     // Hold node updates until the datablocks have been received
       
  1780     iHoldNodeUpdates = ETrue;
       
  1781     
       
  1782     // Notice that actually here we use the metadata ids and not
       
  1783     // the node ids.
       
  1784     CNcdNodeIconMap* newMap = CNcdNodeIconMap::NewLC( aNodeId, aIconId, aDataBlockId );
       
  1785     iNodeIconMaps.AppendL( newMap );
       
  1786     CleanupStack::Pop( newMap );    
       
  1787     }
       
  1788     
       
  1789 RPointerArray<CNcdLoadNodeOperationImpl::CNcdNodeIconMap> CNcdLoadNodeOperationImpl::IconsForDataBlockL(
       
  1790     const TDesC& aDataBlockId ) 
       
  1791     {
       
  1792     DLTRACEIN(( "this-ptr: %X", this ));
       
  1793     RPointerArray<CNcdNodeIconMap> maps;
       
  1794     CleanupClosePushL( maps );
       
  1795     
       
  1796     TInt i = iNodeIconMaps.Count() - 1;
       
  1797     while ( i > -1 )
       
  1798         {
       
  1799         if ( *iNodeIconMaps[i]->iDataBlockId == aDataBlockId ) 
       
  1800             {
       
  1801             maps.AppendL( iNodeIconMaps[i] );
       
  1802             iNodeIconMaps.Remove( i );
       
  1803             }
       
  1804         
       
  1805         i--;
       
  1806         }
       
  1807         
       
  1808     // zero the flag if no more mapped icons exist    
       
  1809     iHoldNodeUpdates = iNodeIconMaps.Count();        
       
  1810         
       
  1811     CleanupStack::Pop( &maps );
       
  1812     return maps;
       
  1813     }
       
  1814     
       
  1815 void CNcdLoadNodeOperationImpl::CreateSubOperationsL()
       
  1816     {
       
  1817     DLTRACEIN((("Remote folder count: %d"), iRemoteFolders.Count() ));
       
  1818     DLINFO(( "this-ptr: %X", this ));
       
  1819     for ( TInt i = 0 ; i < iRemoteFolders.Count() ; i++ )
       
  1820         {
       
  1821         // Note that the remote folder contain the actual node ids.
       
  1822         CNcdNode& remoteFolder = iNodeManager->NodeL( *iRemoteFolders[i] );        
       
  1823         CNcdNode& parentNode = iNodeManager->NodeL( remoteFolder.NodeLinkL().ParentIdentifier() );
       
  1824         CNcdLoadNodeOperationImpl* loadOp =
       
  1825             CNcdLoadNodeOperationImpl::NewLC(
       
  1826                 *iRemoteFolders[i],
       
  1827                 remoteFolder.NodeLinkL().ParentIdentifier(),
       
  1828                 CNcdNodeFactory::NodePurposeL( parentNode ),
       
  1829                 TNcdResponseFilterParams(),
       
  1830                 iGeneralManager,
       
  1831                 iHttpSession,
       
  1832                 iRemoveHandler,
       
  1833                 iOperationQueue,
       
  1834                 iSession,
       
  1835                 EFalse,
       
  1836                 ELoadStructure,
       
  1837                 ETrue );
       
  1838         
       
  1839         loadOp->AddObserverL( this );
       
  1840         iSubOps.AppendL( loadOp );
       
  1841         CleanupStack::Pop( loadOp );
       
  1842         // error code ignored, errors handled via callback
       
  1843         loadOp->Start();
       
  1844         }
       
  1845     }
       
  1846     
       
  1847 TBool CNcdLoadNodeOperationImpl::IsLoadingNecessaryL()
       
  1848     {
       
  1849     DLTRACEIN(( "this-ptr: %X", this ));
       
  1850     if( iLoadMode == EContentSource )
       
  1851         {
       
  1852         DLTRACE(("Content source -> always load"))
       
  1853         return ETrue;
       
  1854         }
       
  1855     DASSERT( iNodeIdentifier );
       
  1856     CNcdNode& node = iNodeManager->NodeL( *iNodeIdentifier );
       
  1857     
       
  1858     // If metadata is loaded for children, it can also be done for the
       
  1859     // root children. This has been also handled in CreateRequestL.
       
  1860     // Root loading should only be allowed for root children.
       
  1861     if ( CNcdNodeFactory::NodeTypeL( node ) == CNcdNodeFactory::ENcdNodeRoot ) 
       
  1862         {
       
  1863         DLTRACE(("Root or search root-> never load"))
       
  1864         return EFalse;
       
  1865         }
       
  1866         
       
  1867     DLTRACE(("load"));
       
  1868     return ETrue;
       
  1869     }
       
  1870     
       
  1871     
       
  1872 TBool CNcdLoadNodeOperationImpl::IsChildClearingNecessaryL()
       
  1873     {
       
  1874     DLTRACEIN(( "this-ptr: %X", this ));
       
  1875     return iLoadMode == ESingleNode && 
       
  1876         CNcdNodeFactory::NodeTypeL(
       
  1877             iNodeManager->NodeL( *iNodeIdentifier ) ) == 
       
  1878         CNcdNodeFactory::ENcdNodeFolder;
       
  1879     }
       
  1880 
       
  1881 // ---------------------------------------------------------------------------
       
  1882 // From class CNcdBaseOperation.
       
  1883 // ?implementation_description
       
  1884 // ---------------------------------------------------------------------------
       
  1885 //
       
  1886 TInt CNcdLoadNodeOperationImpl::RunOperation()
       
  1887     {
       
  1888     DLTRACEIN(( "this-ptr: %X", this ));
       
  1889     
       
  1890     TInt err( KErrNone );
       
  1891     TRAP( err, DoRunOperationL() );
       
  1892     
       
  1893     if ( err != KErrNone )
       
  1894         {
       
  1895         DLTRACE(("error: %d", err));
       
  1896         Cancel();
       
  1897         iLoadNodeState = EFailed;
       
  1898         iError = err;
       
  1899         if ( iPendingMessage )
       
  1900             {
       
  1901             // error ignored because operation already failed
       
  1902             CompleteMessage( iPendingMessage,
       
  1903                 ENCDOperationMessageCompletionError, iError );
       
  1904             }
       
  1905         // call observers
       
  1906         CompleteCallback();
       
  1907         }
       
  1908         
       
  1909     DLTRACEOUT(("err: %d", err));
       
  1910     return err;    
       
  1911     
       
  1912     }
       
  1913         
       
  1914 
       
  1915 // ---------------------------------------------------------------------------
       
  1916 // 
       
  1917 // 
       
  1918 // ---------------------------------------------------------------------------
       
  1919 //
       
  1920 void CNcdLoadNodeOperationImpl::DoRunOperationL()
       
  1921     {
       
  1922     DLTRACEIN(("this: %x", this ));
       
  1923     TInt err = KErrNone;
       
  1924     switch ( iLoadNodeState )
       
  1925         {
       
  1926         case ESendRequest:
       
  1927             {
       
  1928             DLTRACE((_L("->ESendRequest")));
       
  1929             
       
  1930             // check that is loading really necessary
       
  1931             if ( !IsLoadingNecessaryL() )
       
  1932                 {
       
  1933                 // complete operation
       
  1934                 iLoadNodeState = EComplete;
       
  1935                 RunOperation();
       
  1936                 break;
       
  1937                 }
       
  1938             
       
  1939             switch ( iLoadMode )
       
  1940                 {
       
  1941                 case EContentSource:
       
  1942                     {
       
  1943                     // loading from a content source, get uri from it
       
  1944                     DASSERT( iContentSource );
       
  1945                     AssignDesL( iServerUri, iContentSource->Uri() );
       
  1946                     break;
       
  1947                     }
       
  1948                 case ESingleNode:
       
  1949                 case EChildren:
       
  1950                     {
       
  1951                     // loading from a node, get uri from it
       
  1952                     DASSERT( iNodeIdentifier );
       
  1953                     // The member variable contains the actual node identifier.
       
  1954                     // So, it can be used directly. No need for the parent info.
       
  1955                     CNcdNode& node = iNodeManager->NodeL( *iNodeIdentifier );                    
       
  1956                     if ( node.NodeLinkL().RemoteUri() != KNullDesC() )
       
  1957                         {
       
  1958                         DLTRACE((_L("Node has remote uri: %S, use it"),
       
  1959                             &node.NodeLinkL().RemoteUri() ));
       
  1960                         AssignDesL( iServerUri, node.NodeLinkL().RemoteUri() );
       
  1961                         }
       
  1962                     else
       
  1963                         {
       
  1964                         AssignDesL( iServerUri, node.NodeLinkL().ServerUri() );
       
  1965                         }            
       
  1966                     break;
       
  1967                     }
       
  1968                 }
       
  1969             
       
  1970             
       
  1971             if ( iNodeIdentifier &&
       
  1972                  CNcdNodeFactory::NodeTypeL(
       
  1973                     iNodeManager->NodeL( *iNodeIdentifier ) ) == 
       
  1974                         CNcdNodeFactory::ENcdNodeFolder )
       
  1975                 {
       
  1976                 CNcdNodeFolder& folder = iNodeManager->FolderL( *iNodeIdentifier );
       
  1977                 // Store previous list only if some children have been previously loaded.
       
  1978                 if( folder.ChildrenPreviouslyLoaded() )
       
  1979                     {
       
  1980                     folder.StoreChildrenToPreviousListL();
       
  1981                     }
       
  1982                 if( IsChildClearingNecessaryL() )
       
  1983                     {                
       
  1984                     DLTRACE(("clear children"));
       
  1985                     RemoveChildrenL( folder );
       
  1986                     }
       
  1987                 }
       
  1988             
       
  1989             DLINFO(( _L("URI: %S"), iServerUri ));
       
  1990             
       
  1991             // create a browse request
       
  1992             HBufC8* request = NULL;
       
  1993             TRAPD( reqErr,
       
  1994                 {
       
  1995                 request = CreateRequestLC( iNodeIdentifier,
       
  1996                     iFilterParams, *iServerUri );
       
  1997                 CleanupStack::Pop( request );
       
  1998                 });
       
  1999             if( reqErr != KErrNone )
       
  2000                 {
       
  2001                 if( reqErr == KNcdLoadNodeErrRemoteOnly )
       
  2002                     {
       
  2003                     iLoadNodeState = ERemote;
       
  2004                     RunOperation();
       
  2005                     break;
       
  2006                     }
       
  2007                 else if ( reqErr == KNcdLoadNodeErrNothingToDo )
       
  2008                     {
       
  2009                     iLoadNodeState = EComplete;
       
  2010                     RunOperation();
       
  2011                     break;
       
  2012                     }
       
  2013                 else
       
  2014                     {
       
  2015                     User::Leave( reqErr );
       
  2016                     }
       
  2017                 }
       
  2018             CleanupStack::PushL( request );
       
  2019             
       
  2020             
       
  2021             DLINFO(( "request= %S", request ));
       
  2022             
       
  2023             // create transaction
       
  2024             if ( iLoadMode == EContentSource ) 
       
  2025                 {
       
  2026                 DASSERT( iContentSource );
       
  2027                 if ( iContentSource->NodeId() == KNullDesC ) 
       
  2028                     {
       
  2029                     // Note that iTransaction is released & set as null
       
  2030                     // before new transaction is created. If iTransaction is
       
  2031                     // not null, then it obviously is not released
       
  2032                     // Correct accesspoint is set if found, otherwise default
       
  2033                     // is used
       
  2034                     iGeneralManager.HttpUtils().CreateTransactionL(
       
  2035                         iHttpSession,
       
  2036                         iTransaction,
       
  2037                         *iServerUri,
       
  2038                         *this,
       
  2039                         *request,
       
  2040                         iContentSource->NameSpace(), 
       
  2041                         MCatalogsAccessPointManager::EBrowse, 
       
  2042                         iClientUid );
       
  2043 
       
  2044                     }
       
  2045                 else
       
  2046                     {
       
  2047                     // iNodeIdentifier may be NULL here. So, we have to use the information
       
  2048                     // from the content source. Because the accesspoint requires the node id
       
  2049                     // we can use the content source that contains the actual node id.
       
  2050                     CNcdNodeIdentifier* contentIdentifier =
       
  2051                         CNcdNodeIdentifier::NewLC( iContentSource->NameSpace(), 
       
  2052                                                    iContentSource->NodeId(), 
       
  2053                                                    iContentSource->Uri(), 
       
  2054                                                    iClientUid );
       
  2055 
       
  2056                     
       
  2057                     iGeneralManager.HttpUtils().CreateTransactionL(
       
  2058                         iHttpSession,
       
  2059                         iTransaction,
       
  2060                         *iServerUri,
       
  2061                         *this,
       
  2062                         *request,
       
  2063                         contentIdentifier->NodeNameSpace(),
       
  2064                         contentIdentifier->NodeId(),
       
  2065                         MCatalogsAccessPointManager::EBrowse, 
       
  2066                         iClientUid );
       
  2067                         
       
  2068                     CleanupStack::PopAndDestroy( contentIdentifier );                    
       
  2069                     }
       
  2070                 }
       
  2071             else
       
  2072                 {
       
  2073                 DASSERT( iNodeIdentifier )
       
  2074                 DLTRACE((_L("Finding AP: namespace=%S, clientUid=%d"), &iNodeIdentifier->NodeNameSpace(), iClientUid.iUid));
       
  2075                 
       
  2076                 CNcdNodeIdentifier* originIdentifier = NULL;
       
  2077                 if ( NcdNodeIdentifierEditor::IdentifiesTemporaryNodeL( *iNodeIdentifier ) )
       
  2078                     {
       
  2079                     // Temporary nodes can be created for already purchased nodes when cache is empty,
       
  2080                     // therefore we should try to get their origin identifier from purchase history for ap searching.
       
  2081                     DLTRACE(("Temporary node, try to get origin identifier for it"));
       
  2082                     originIdentifier =
       
  2083                         iNodeManager->GetOriginIdentifierL( *iNodeIdentifier );
       
  2084                     }
       
  2085                 
       
  2086                 if ( originIdentifier ) 
       
  2087                     {
       
  2088                     CleanupStack::PushL( originIdentifier );
       
  2089                     
       
  2090                     // First try originIdentifier, if it fails, try iNodeIdentifier
       
  2091                     DLTRACE(("Origin identifier found, trying to get ap with it."));
       
  2092                     iGeneralManager.HttpUtils().CreateTransactionL(
       
  2093                         iHttpSession,
       
  2094                         iTransaction,
       
  2095                         *iServerUri,
       
  2096                         *this,
       
  2097                         *request,
       
  2098                         *originIdentifier,
       
  2099                         *iNodeIdentifier,
       
  2100                         MCatalogsAccessPointManager::EBrowse, 
       
  2101                         iClientUid );
       
  2102                         
       
  2103                     CleanupStack::PopAndDestroy( originIdentifier ); 
       
  2104                     originIdentifier = NULL;                   
       
  2105                     }
       
  2106                 else
       
  2107                     {
       
  2108                     DLTRACE(("No origin id, just try iNodeIdentifier"));
       
  2109                     iGeneralManager.HttpUtils().CreateTransactionL(
       
  2110                         iHttpSession,
       
  2111                         iTransaction,
       
  2112                         *iServerUri,
       
  2113                         *this,
       
  2114                         *request,
       
  2115                         *iNodeIdentifier,
       
  2116                         MCatalogsAccessPointManager::EBrowse, 
       
  2117                         iClientUid );
       
  2118                     }
       
  2119                 }
       
  2120             CleanupStack::PopAndDestroy( request );    
       
  2121 
       
  2122             // create parser  
       
  2123             if( !iParser )
       
  2124                 {
       
  2125                 iParser = iProtocol.CreateParserL( 
       
  2126                 iSession.Context(), *iServerUri );
       
  2127                 }
       
  2128             
       
  2129             // set observers
       
  2130             MNcdParserObserverBundle& observers = iParser->Observers();
       
  2131             observers.SetParserObserver( this );
       
  2132             observers.SetEntityObserver( this );
       
  2133             observers.SetInformationObserver( this );
       
  2134             observers.SetDataBlocksObserver( this );
       
  2135             observers.SetErrorObserver( this );
       
  2136             observers.SetQueryObserver( this );
       
  2137             iParser->BeginAsyncL();  
       
  2138             
       
  2139             iTransparentChildFolders.ResetAndDestroy();
       
  2140             // start transaction
       
  2141             User::LeaveIfError( iTransaction->Start() );
       
  2142             
       
  2143             iLoadNodeState = EReceive;
       
  2144             DLTRACE((_L("->ESendRequest done")));
       
  2145             break;
       
  2146             }
       
  2147             
       
  2148         case EReceive:
       
  2149             {
       
  2150             DLTRACE(("->EReceive, iPendingMessage: %x, nodes: %d", 
       
  2151                  iPendingMessage,
       
  2152                  iLoadedNodes.Count() ));
       
  2153             if ( iPendingMessage && 
       
  2154                  !iHoldNodeUpdates && 
       
  2155                  iLoadedNodes.Count() > 0 )
       
  2156                 {
       
  2157                 // send updated nodes identifiers to proxy
       
  2158                 err = CompleteMessage( iPendingMessage,
       
  2159                     ENCDOperationMessageCompletionNodesUpdated,
       
  2160                     iProgress,
       
  2161                     iLoadedNodes,
       
  2162                     KErrNone );
       
  2163                 User::LeaveIfError( err );
       
  2164                 iLoadedNodes.ResetAndDestroy();
       
  2165                 }
       
  2166             DLTRACE((_L("->EReceive done")));
       
  2167             break;
       
  2168             }
       
  2169         
       
  2170         
       
  2171         case ERemote:
       
  2172             {
       
  2173             DLTRACE((_L("->ERemote")));
       
  2174             
       
  2175             // create load node op for each remote folder
       
  2176             iSubOps.ResetAndDestroy();
       
  2177 
       
  2178             // create sub ops for remote folders
       
  2179             CreateSubOperationsL();
       
  2180             
       
  2181             iLoadNodeState = EReceiveRemote;
       
  2182             
       
  2183             if ( iFailedSubOps.Count() + iCompletedSubOps.Count() ==
       
  2184                  iSubOps.Count() )
       
  2185                 {
       
  2186                 // all sub ops have either completed or failed
       
  2187                 // -> go to next state
       
  2188                 iLoadNodeState = EComplete;
       
  2189                 if ( iFailedSubOps.Count() > 0 )
       
  2190                     {
       
  2191                     iError = KNcdErrorSomeCatalogsFailedToLoad;
       
  2192                     }
       
  2193                 RunOperation();
       
  2194                 }
       
  2195                 
       
  2196             DLTRACE((_L("->ERemote done")));
       
  2197             break;
       
  2198             }
       
  2199         
       
  2200          case EReceiveRemote:
       
  2201             {
       
  2202             DLTRACE((_L("->EReceiveRemote")));
       
  2203             if( iSubOpQuerys.Count() > 0 )
       
  2204                 {
       
  2205                 // send sub op query to proxy
       
  2206                 CNcdBaseOperation::QueryReceivedL( iSubOpQuerys[0] );
       
  2207                 // release own reference and remove
       
  2208                 iSubOpQuerys[0]->InternalRelease();
       
  2209                 iSubOpQuerys.Remove( 0 );
       
  2210                 }
       
  2211             else if ( iPendingMessage && 
       
  2212                       !iHoldNodeUpdates &&
       
  2213                       iLoadedNodes.Count() > 0 )
       
  2214                 {
       
  2215                 // send updated nodes's identifiers to proxy
       
  2216                 err = CompleteMessage( iPendingMessage,
       
  2217                     ENCDOperationMessageCompletionNodesUpdated,
       
  2218                     iProgress,
       
  2219                     iLoadedNodes,
       
  2220                     KErrNone );
       
  2221                 User::LeaveIfError( err );
       
  2222                 iLoadedNodes.ResetAndDestroy();
       
  2223                 }
       
  2224             else if ( iFailedSubOps.Count() + iCompletedSubOps.Count() ==
       
  2225                  iSubOps.Count() )
       
  2226                 {
       
  2227                 DLTRACE(("Sub ops complete"));
       
  2228                 // all sub ops have either completed or failed
       
  2229                 // -> go to next state
       
  2230                 if ( iFailedSubOps.Count() > 0 ) 
       
  2231                     {
       
  2232                     iError = KNcdErrorSomeCatalogsFailedToLoad;
       
  2233                     }
       
  2234                 iLoadNodeState = EComplete;
       
  2235                 // Continue operation asynchronously, to prevent problems when
       
  2236                 // potentially deleting sub ops in next state
       
  2237                 ContinueOperationL();
       
  2238                 }
       
  2239                 
       
  2240             DLTRACE((_L("->EReceiveRemote done")));
       
  2241             break;
       
  2242             }
       
  2243             
       
  2244         
       
  2245         case EComplete:
       
  2246             {
       
  2247             DLTRACE((_L("->EComplete")));
       
  2248                         
       
  2249             // Set the children loaded flag so that next refresh stores
       
  2250             // previous child list (needed for new checking)
       
  2251             SetChildrenLoadedFlagL();
       
  2252             
       
  2253             RefreshSeenStatusL();
       
  2254             
       
  2255             if ( IsSubOperation() )
       
  2256                 {
       
  2257                 if( iError == KErrNone )
       
  2258                     {
       
  2259                     // call observers 
       
  2260                     CompleteCallback();
       
  2261                     }
       
  2262                 else
       
  2263                     {
       
  2264                     DLINFO(("Error has occurred, fail operation"));
       
  2265                     iLoadNodeState = EFailed;
       
  2266                     RunOperation();
       
  2267                     break;
       
  2268                     }
       
  2269                 }
       
  2270             else
       
  2271                 {
       
  2272                 DLTRACE(("iPendingMessage: %x, loaded nodes: %d", 
       
  2273                     iPendingMessage, iLoadedNodes.Count() ));
       
  2274                 
       
  2275                 // NOTE: The operation will not complete until it gets a message from proxy
       
  2276                 if ( iPendingMessage && iLoadedNodes.Count() > 0 )
       
  2277                     {
       
  2278                     // Send remaining loaded node info to proxy before completing op.
       
  2279                     DLTRACE(("Sending remaining loaded node info to proxy."));
       
  2280                     TInt err = CompleteMessage( iPendingMessage,
       
  2281                         ENCDOperationMessageCompletionNodesUpdated,
       
  2282                         iProgress,
       
  2283                         iLoadedNodes,
       
  2284                         KErrNone );
       
  2285                     User::LeaveIfError( err );
       
  2286                     iLoadedNodes.ResetAndDestroy();
       
  2287                     iHoldNodeUpdates = EFalse;
       
  2288                     }
       
  2289                 else if ( iPendingMessage )
       
  2290                     {
       
  2291                     DLTRACE(("No loaded node info left, complete op."));
       
  2292                     if( iError == KErrNone )
       
  2293                         {
       
  2294                         // Send complete message to proxy.                
       
  2295                         err = CompleteMessage( iPendingMessage,
       
  2296                             ENCDOperationMessageCompletionComplete,
       
  2297                             iProgress,
       
  2298                             KErrNone );
       
  2299                         User::LeaveIfError( err );
       
  2300                         iOperationState = EStateComplete;
       
  2301                         // call observers 
       
  2302                         CompleteCallback();
       
  2303                         }
       
  2304                     else
       
  2305                         {
       
  2306                         DLINFO(("Error has occurred, fail operation"));
       
  2307                         iLoadNodeState = EFailed;
       
  2308                         RunOperation();
       
  2309                         break;
       
  2310                         }
       
  2311                     }
       
  2312                 }
       
  2313                             
       
  2314             DLTRACE((_L("->EComplete done")));
       
  2315             break;
       
  2316             }
       
  2317             
       
  2318         case EFailed:
       
  2319             {
       
  2320             DLTRACE((_L("->EFailed")));
       
  2321             // Operation failed, send error message
       
  2322             Cancel();
       
  2323             if ( iPendingMessage )
       
  2324                 {
       
  2325                 // error ignored because operation has already failed
       
  2326                 CompleteMessage( iPendingMessage,
       
  2327                     ENCDOperationMessageCompletionError, iError );
       
  2328                 }
       
  2329             // call observers
       
  2330             CompleteCallback();
       
  2331             DLTRACE((_L("->EFailed done")));
       
  2332             break;            
       
  2333             }
       
  2334         default:
       
  2335             {
       
  2336             DLERROR(("default case, should never come here!"));
       
  2337             DASSERT(0);
       
  2338             User::Leave( KErrArgument );
       
  2339             break;
       
  2340             }
       
  2341         }
       
  2342     DLTRACEOUT((""));        
       
  2343     }
       
  2344     
       
  2345 
       
  2346 void CNcdLoadNodeOperationImpl::ChangeToPreviousStateL()
       
  2347     {
       
  2348     DLTRACEIN(( "this-ptr: %X", this ));
       
  2349     switch ( iLoadNodeState )
       
  2350         {
       
  2351         case EReceive:
       
  2352             {
       
  2353             // can only go back from this state
       
  2354             iLoadNodeState = ESendRequest;
       
  2355             break;
       
  2356             }
       
  2357         default:
       
  2358             {
       
  2359             DLTRACE(("CAN'T GO BACK FROM THIS STATE, ERROR!"));
       
  2360             DASSERT(0);
       
  2361             User::Leave( KErrArgument );
       
  2362             }
       
  2363         }
       
  2364     }
       
  2365 
       
  2366 TBool CNcdLoadNodeOperationImpl::QueryCompletedL( CNcdQuery* aQuery )
       
  2367     {    
       
  2368     DLTRACEIN(("aQuery=%08x", aQuery));
       
  2369     DLINFO(( "this-ptr: %X", this ));
       
  2370 
       
  2371     // handle child ops' querys
       
  2372     for( TInt i = 0 ; i < iSubOps.Count() ; i++ )
       
  2373         {
       
  2374         CNcdQuery* query = iSubOps[i]->ActiveQuery();
       
  2375         if ( aQuery == query )
       
  2376             {
       
  2377             // send to subop
       
  2378             iSubOps[i]->QueryHandledL( aQuery );
       
  2379             TInt index = iSubOpQuerys.Find( aQuery );
       
  2380             if ( index != KErrNotFound )
       
  2381                 {
       
  2382                 // remove own reference
       
  2383                 iSubOpQuerys[index]->InternalRelease();
       
  2384                 iSubOpQuerys.Remove( index );
       
  2385                 }
       
  2386             query->InternalRelease();
       
  2387             query = NULL;
       
  2388             return ETrue;
       
  2389             }
       
  2390         else if ( query )
       
  2391             {
       
  2392             query->InternalRelease();
       
  2393             }
       
  2394         }
       
  2395     
       
  2396     // own query
       
  2397     return EFalse;
       
  2398     }
       
  2399     
       
  2400 void CNcdLoadNodeOperationImpl::ErrorL( MNcdPreminetProtocolError* aData )
       
  2401     {
       
  2402     DLTRACEIN(( "this-ptr: %X", this ));
       
  2403     CleanupDeletePushL( aData );
       
  2404     switch ( aData->Code() )
       
  2405         {
       
  2406         case 404:
       
  2407             {
       
  2408             // requested node not found on server
       
  2409             if ( iNodeIdentifier && aData->Id() != KNullDesC ) 
       
  2410                 {
       
  2411                 CNcdNode& node = iNodeManager->NodeL( *iNodeIdentifier );
       
  2412                 CNcdNodeLink& nodeLink( node.NodeLinkL() );
       
  2413                     
       
  2414                 // Checking for empty parent identifier also because of scheme nodes                    
       
  2415                 if( nodeLink.MetaDataIdentifier().NodeId() == aData->Id() &&
       
  2416                     ( nodeLink.ParentIdentifier().ContainsEmptyFields() ||
       
  2417                       iNodeManager->NodeL( nodeLink.ParentIdentifier() )
       
  2418                         .ClassId() == NcdNodeClassIds::ENcdRootNodeClassId ) )
       
  2419                     {
       
  2420                     // parent node not found
       
  2421                     // grandparent is root node -> remove parent
       
  2422                     iNodeManager->RemoveNodeL( *iNodeIdentifier );
       
  2423                     }
       
  2424                 else
       
  2425                     {
       
  2426                     RPointerArray<CNcdExpiredNode> expiredNodes;
       
  2427                     CleanupResetAndDestroyPushL( expiredNodes );
       
  2428                     if( node.NodeLinkL().MetaDataIdentifier().NodeId() == aData->Id() )
       
  2429                         {
       
  2430                         // parent node not found
       
  2431                         // expire grandparent
       
  2432                         CNcdNode& parent = iNodeManager->NodeL( node.NodeLinkL().ParentIdentifier() );
       
  2433                         iNodeManager->SetNodeExpiredL( parent, EFalse, EFalse, expiredNodes );
       
  2434                         }
       
  2435                     else
       
  2436                         {                    
       
  2437                         // child node not found  
       
  2438                         // expire parent
       
  2439                         iNodeManager->SetNodeExpiredL( node, EFalse, EFalse, expiredNodes );
       
  2440                         }
       
  2441                     ExpirationInfoReceived( this, expiredNodes );
       
  2442                     CleanupStack::PopAndDestroy( &expiredNodes );
       
  2443                     }
       
  2444                 iError = KNcdErrorNodeWasRemoved;
       
  2445                 }
       
  2446             else 
       
  2447                 {
       
  2448                 // something else was not found
       
  2449                 iError = KNcdProtocolErrorBase - aData->Code();
       
  2450                 }
       
  2451             iLoadNodeState = EFailed;
       
  2452             CleanupStack::Pop( aData );
       
  2453             // Default observer deletes aData
       
  2454             iParser->DefaultObserver().ErrorL( aData );            
       
  2455             break;
       
  2456             }
       
  2457             
       
  2458         case 416:
       
  2459             {
       
  2460             DLTRACE(("session expired"));
       
  2461             Cancel();
       
  2462             RemoveServerSessionL();
       
  2463             DLINFO(("Start operation from initial state"))
       
  2464             iLoadNodeState = ESendRequest;
       
  2465             CleanupStack::Pop( aData );
       
  2466             // Default observer deletes aData
       
  2467             iParser->DefaultObserver().ErrorL( aData );
       
  2468             break;
       
  2469             }
       
  2470             
       
  2471         case 401:
       
  2472             {
       
  2473             //special case check if we have rejected an auth. query earlier
       
  2474             for ( TInt i = 0 ; i < iCompletedQuerys.Count() ; i++ )
       
  2475                 {
       
  2476                 if( iCompletedQuerys[i]->Semantics() == MNcdQuery::ESemanticsAuthenticationQuery &&
       
  2477                     iCompletedQuerys[i]->Response() == MNcdQuery::ERejected )
       
  2478                     {
       
  2479                     DLTRACE(("Auth. query was rejected before -> remove session so that we get a new query when this node is requested again"));
       
  2480                     RemoveServerSessionL();
       
  2481                     break;
       
  2482                     }
       
  2483                 }
       
  2484             // fall trough to default case
       
  2485             }
       
  2486             
       
  2487         default:
       
  2488             {
       
  2489             iError = KNcdProtocolErrorBase - aData->Code();
       
  2490             iLoadNodeState = EFailed;
       
  2491             CleanupStack::Pop( aData );
       
  2492             // Default observer deletes aData
       
  2493             iParser->DefaultObserver().ErrorL( aData );    
       
  2494             break;
       
  2495             }
       
  2496         }    
       
  2497     
       
  2498     // continue operation asynchronously to prevent problems with parser
       
  2499     ContinueOperationL();
       
  2500     }
       
  2501 
       
  2502 void CNcdLoadNodeOperationImpl::DetermineParentTypeL( const TUid& aUid )
       
  2503     {
       
  2504     DLTRACEIN(( "this-ptr: %X", this ));
       
  2505     CNcdNodeIdentifier* root = 
       
  2506         NcdNodeIdentifierEditor::CreateRootIdentifierForClientLC( aUid );
       
  2507     DASSERT( iParentIdentifier );
       
  2508     if ( root->Equals( *iParentIdentifier ) ) 
       
  2509         {
       
  2510         DLTRACE(("Parent is root"));
       
  2511         iParentType = CNcdNodeFactory::ENcdNodeRoot;
       
  2512         }
       
  2513     CleanupStack::PopAndDestroy( root );
       
  2514     }
       
  2515 
       
  2516 
       
  2517 //////////////////////////////////////////////////////////////////////////////////////////////
       
  2518 // CNcdLoadNodeOperationImpl::CNcdNodeIconMap
       
  2519 //////////////////////////////////////////////////////////////////////////////////////////////
       
  2520 
       
  2521 CNcdLoadNodeOperationImpl::CNcdNodeIconMap* CNcdLoadNodeOperationImpl::CNcdNodeIconMap::NewLC(
       
  2522     const CNcdNodeIdentifier& aMetadataId,
       
  2523     const TDesC& aIconId,
       
  2524     const TDesC& aDataBlockId ) 
       
  2525     {
       
  2526     CNcdNodeIconMap* self = new ( ELeave ) CNcdNodeIconMap;
       
  2527     CleanupStack::PushL( self );
       
  2528     self->ConstructL( aMetadataId, aIconId, aDataBlockId );
       
  2529     return self;
       
  2530     }
       
  2531     
       
  2532 void CNcdLoadNodeOperationImpl::CNcdNodeIconMap::ConstructL(
       
  2533     const CNcdNodeIdentifier& aMetadataId,
       
  2534     const TDesC& aIconId,
       
  2535     const TDesC& aDataBlockId )
       
  2536     {
       
  2537     iDataBlockId = aDataBlockId.AllocL();
       
  2538     iIconId = aIconId.AllocL();
       
  2539     iMetadataId = CNcdNodeIdentifier::NewL( aMetadataId );
       
  2540     }
       
  2541     
       
  2542 CNcdLoadNodeOperationImpl::CNcdNodeIconMap::CNcdNodeIconMap() 
       
  2543     {
       
  2544     }
       
  2545     
       
  2546 CNcdLoadNodeOperationImpl::CNcdNodeIconMap::~CNcdNodeIconMap() 
       
  2547     {
       
  2548     delete iDataBlockId;
       
  2549     delete iIconId;
       
  2550     delete iMetadataId;
       
  2551     }
       
  2552     
       
  2553 void CNcdLoadNodeOperationImpl::RemoveServerSessionL()
       
  2554     {
       
  2555     DLTRACEIN((""));
       
  2556     if( iLoadMode == EContentSource )
       
  2557         {
       
  2558         DASSERT( iContentSource );
       
  2559         iProtocol.SessionHandlerL( iSession.Context() )
       
  2560             .RemoveSession( *iServerUri, iContentSource->NameSpace() );
       
  2561         }
       
  2562     else
       
  2563         {
       
  2564         DASSERT( iNodeIdentifier );
       
  2565         iProtocol.SessionHandlerL( iSession.Context() )
       
  2566             .RemoveSession( *iServerUri, iNodeIdentifier->NodeNameSpace() );
       
  2567         }
       
  2568     }
       
  2569 
       
  2570 void CNcdLoadNodeOperationImpl::SetChildrenLoadedFlagL()
       
  2571     {
       
  2572     DLTRACEIN((""));
       
  2573     // Set children loaded flag.
       
  2574     if( iLoadMode == EChildren )
       
  2575         {
       
  2576         CNcdNodeFolder& folder = iNodeManager->FolderL( *iNodeIdentifier );
       
  2577         folder.SetChildrenPreviouslyLoaded();
       
  2578         iNodeManager->DbSaveNodeL( folder );
       
  2579         }
       
  2580     else if( iLoadMode == EContentSource
       
  2581         && iContentSource->IsTransparent() )
       
  2582         {
       
  2583         RPointerArray<CNcdNodeIdentifier> nodes =
       
  2584             iContentSourceMap->NodesL( *iContentSource );
       
  2585         for( TInt i = 0 ; i < nodes.Count() ; i++ )
       
  2586             {
       
  2587             CNcdNodeFolder& folder = iNodeManager->FolderL( *nodes[i] );
       
  2588             folder.SetChildrenPreviouslyLoaded();
       
  2589             iNodeManager->DbSaveNodeL( folder );
       
  2590             }
       
  2591         }
       
  2592     }
       
  2593     
       
  2594 void CNcdLoadNodeOperationImpl::RefreshSeenStatusL()
       
  2595     {
       
  2596     DLTRACEIN((""));
       
  2597     if( iLoadMode == EChildren )
       
  2598         {
       
  2599         iNodeManager->SeenInfo().RefreshFolderSeenStatusL(  *iNodeIdentifier );
       
  2600         }
       
  2601     else if( iLoadMode == EContentSource
       
  2602         && iContentSource->IsTransparent() )
       
  2603         {
       
  2604         RPointerArray<CNcdNodeIdentifier> nodes =
       
  2605             iContentSourceMap->NodesL( *iContentSource );
       
  2606         for( TInt i = 0 ; i < nodes.Count() ; i++ )
       
  2607             {
       
  2608             iNodeManager->SeenInfo().RefreshFolderSeenStatusL( *nodes[i] );
       
  2609             }
       
  2610         }
       
  2611     }
       
  2612 
       
  2613 TInt CNcdLoadNodeOperationImpl::CalculateStructPageSize(
       
  2614     TInt aPageStart,
       
  2615     TInt aPageSize,
       
  2616     CNcdNodeFolder& aNodeFolder,
       
  2617     TNcdChildLoadMode aChildLoadMode )
       
  2618     {
       
  2619     DLTRACEIN((""));
       
  2620     if( aChildLoadMode == ELoadMetadata )
       
  2621         {
       
  2622         DLTRACE(("ELoadMetadata"));
       
  2623         // Check that how much struct is already loaded.
       
  2624         TInt count = aNodeFolder.ChildArray().Count();
       
  2625         if( count > 0 )
       
  2626             {
       
  2627             TInt lastLoadedChildIndex = aNodeFolder.ChildArray()[count-1]->Index();
       
  2628             if( lastLoadedChildIndex >= aPageStart + aPageSize - 1 )
       
  2629                 {
       
  2630                 DLTRACE(("Structure already loaded for this page -> use original page size"));
       
  2631                 return aPageSize;
       
  2632                 }
       
  2633             }
       
  2634         }
       
  2635     DLTRACE((""));
       
  2636     return KNcdStructPageSize > aPageSize
       
  2637             ? KNcdStructPageSize : aPageSize; 
       
  2638     }
       
  2639 
       
  2640 TInt CNcdLoadNodeOperationImpl::RemoteFolderCount() const
       
  2641     {
       
  2642     DLTRACEIN((""));
       
  2643     return iRemoteFolders.Count();
       
  2644     }
       
  2645 
       
  2646 
       
  2647 void CNcdLoadNodeOperationImpl::RemoveChildrenL( CNcdNodeFolder& aFolder ) 
       
  2648     {
       
  2649     DLTRACEIN((""));
       
  2650     aFolder.ExpireAndRemoveChildrenL();
       
  2651     }
       
  2652     
       
  2653 
       
  2654 void CNcdLoadNodeOperationImpl::NotifyCompletionOfQueuedOperation(
       
  2655     TNcdOperationMessageCompletionId aId )
       
  2656     {
       
  2657     DLTRACEIN((""));
       
  2658     if ( IsSubOperation() )
       
  2659         {
       
  2660         return;
       
  2661         }
       
  2662         
       
  2663     DASSERT( iOperationQueue );        
       
  2664     if ( aId == ENCDOperationMessageCompletionComplete ||
       
  2665          aId == ENCDOperationMessageCompletionError )
       
  2666         {
       
  2667         iOperationQueue->QueuedOperationComplete( *this );
       
  2668         }
       
  2669     }
       
  2670