ncdengine/provider/client/src/ncdnodemanagerproxy.cpp
changeset 0 ba25891c3a9e
equal deleted inserted replaced
-1:000000000000 0:ba25891c3a9e
       
     1 /*
       
     2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Implements CNcdNodeManagerProxy class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32err.h>
       
    20 
       
    21 #include "ncdnodemanagerproxy.h"
       
    22 #include "ncdnodeproxy.h"
       
    23 #include "ncdnodefolderproxy.h"
       
    24 #include "ncdbundlefolderproxy.h"
       
    25 #include "ncdsearchnodefolderproxy.h"
       
    26 #include "ncdnodeitemproxy.h"
       
    27 #include "ncdsearchnodeitemproxy.h"
       
    28 #include "catalogsclientserver.h"
       
    29 #include "ncdnodefunctionids.h"
       
    30 #include "ncdnodeclassids.h"
       
    31 #include "ncdproviderdefines.h"
       
    32 #include "ncdnodeidentifier.h"
       
    33 #include "ncdrootnodeproxy.h"
       
    34 #include "ncdpurchasedetails.h"
       
    35 #include "catalogsdebug.h"
       
    36 #include "ncdoperationmanagerproxy.h"
       
    37 #include "ncdsearchrootnodeproxy.h"
       
    38 #include "catalogsconstants.h"
       
    39 #include "catalogsutils.h"
       
    40 #include "ncdproviderproxy.h"
       
    41 #include "ncdexpirednode.h"
       
    42 #include "ncdnodesupplierproxy.h"
       
    43 #include "ncdnodeidentifiereditor.h"
       
    44 #include "ncdsearchnodebundleproxy.h"
       
    45 #include "ncdfavoritemanagerproxy.h"
       
    46 #include "ncdpanics.h"
       
    47 
       
    48 
       
    49 CNcdNodeManagerProxy* CNcdNodeManagerProxy::NewL(
       
    50     MCatalogsClientServer& aSession, 
       
    51     TInt aHandle,
       
    52     CNcdOperationManagerProxy& aOperationManager,
       
    53     CNcdSubscriptionManagerProxy& aSubscriptionManager,
       
    54     CNcdProviderProxy& aProvider )
       
    55     {
       
    56     CNcdNodeManagerProxy* self = 
       
    57         CNcdNodeManagerProxy::NewLC( aSession, 
       
    58                                      aHandle,
       
    59                                      aOperationManager,
       
    60                                      aSubscriptionManager,
       
    61                                      aProvider );
       
    62     CleanupStack::Pop( self );
       
    63     return self;        
       
    64     }
       
    65 
       
    66 
       
    67 CNcdNodeManagerProxy* CNcdNodeManagerProxy::NewLC(
       
    68     MCatalogsClientServer& aSession, 
       
    69     TInt aHandle,
       
    70     CNcdOperationManagerProxy& aOperationManager,
       
    71     CNcdSubscriptionManagerProxy& aSubscriptionManager,
       
    72     CNcdProviderProxy& aProvider )
       
    73     {
       
    74     CNcdNodeManagerProxy* self = 
       
    75         new( ELeave ) CNcdNodeManagerProxy( aSession,
       
    76                                             aHandle,
       
    77                                             aOperationManager,
       
    78                                             aSubscriptionManager,
       
    79                                             aProvider );
       
    80     CleanupStack::PushL( self );
       
    81     self->ConstructL();
       
    82     return self;        
       
    83     }
       
    84 
       
    85 
       
    86 CNcdNodeManagerProxy::CNcdNodeManagerProxy(
       
    87     MCatalogsClientServer& aSession, 
       
    88     TInt aHandle,
       
    89     CNcdOperationManagerProxy& aOperationManager,
       
    90     CNcdSubscriptionManagerProxy& aSubscriptionManager,
       
    91     CNcdProviderProxy& aProvider )
       
    92 : CNcdBaseProxy( aSession, aHandle ),
       
    93   iOperationManager( aOperationManager ),
       
    94   iSubscriptionManager( aSubscriptionManager ),
       
    95   iFavoriteManager( NULL ),
       
    96   iProvider( aProvider )
       
    97     {
       
    98     }
       
    99 
       
   100 
       
   101 void CNcdNodeManagerProxy::ConstructL()
       
   102     {
       
   103     iOperationManager.SetNodeManager( this );
       
   104 
       
   105     }
       
   106 
       
   107 
       
   108 CNcdNodeManagerProxy::~CNcdNodeManagerProxy()
       
   109     {
       
   110     DLTRACEIN((""));
       
   111     
       
   112     if( iSearchRootNode )
       
   113         {
       
   114         // release own reference to 
       
   115         iSearchRootNode->InternalRelease();
       
   116         }
       
   117     
       
   118     // Release all nodes without reference count. These nodes have not
       
   119     // been used after creation.
       
   120     for ( TInt i = iNodeCache.Count() - 1; i >= 0; i-- ) 
       
   121         {
       
   122         if ( iNodeCache[i]->TotalRefCount() == 0 )
       
   123             {
       
   124             // During delete, node is removed from the array automatically.
       
   125             // Notice that it is safe to call delete here instead of Release,
       
   126             // because we checked the total count above. Release implementation 
       
   127             // contains DASSERT that would assert if we called Release here.
       
   128             delete iNodeCache[i];
       
   129             }
       
   130         }
       
   131     
       
   132     // For debugging purposes check if some nodes have been left hanging.
       
   133     // All the nodes should be released before manager is deleted.
       
   134 
       
   135     DLINFO(("Cache count: %d", iNodeCache.Count()));
       
   136 
       
   137     #ifdef CATALOGS_BUILD_CONFIG_DEBUG
       
   138         DLINFO(("The following nodes have not been properly released:"));
       
   139         for ( TInt i = 0; i < iNodeCache.Count(); i++ ) 
       
   140             {
       
   141             DLINFO(( _L("MNcdNode: %x, namespace: %S, id: %S, refcount: %d"), 
       
   142                 static_cast<MNcdNode*>( iNodeCache[i] ),
       
   143                 &iNodeCache[i]->Namespace(), &iNodeCache[i]->Id(),
       
   144                 iNodeCache[i]->TotalRefCount() ));
       
   145                 
       
   146             }
       
   147         DLINFO(("release check end"));        
       
   148     #endif
       
   149 
       
   150     DASSERT( iNodeCache.Count() == 0 );           
       
   151         
       
   152     // Close the cache.
       
   153     iNodeCache.Close();
       
   154 
       
   155     // Notice that the root node is also included into the cache.
       
   156     // So, no need to delete it separately.
       
   157 
       
   158     DLTRACEOUT((""));
       
   159     }
       
   160 
       
   161 
       
   162 CNcdNodeProxy& CNcdNodeManagerProxy::NodeL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   163     {
       
   164     DLTRACEIN((_L("Node ID: %S, %S, %d"), 
       
   165                 &aNodeIdentifier.NodeId(),
       
   166                 &aNodeIdentifier.NodeNameSpace(),
       
   167                 aNodeIdentifier.ClientUid()));
       
   168 
       
   169     // Check if the node proxy already exists in the cache.
       
   170     // Every node has its own namespace and dataid.
       
   171     // If it does, do not create it.
       
   172         
       
   173     DLTRACE(("Node cache count: %d", iNodeCache.Count() ));
       
   174 
       
   175     CNcdNodeProxy* node( NodeExists( aNodeIdentifier ) );
       
   176     if ( node != NULL )
       
   177         {
       
   178         // Node was found. So, return it.
       
   179         DLTRACEOUT(("Node found"));
       
   180         return *node;
       
   181         }
       
   182     else if ( aNodeIdentifier.NodeNameSpace() 
       
   183                 == NcdProviderDefines::KRootNodeNameSpace )
       
   184         {
       
   185         DLTRACE(("RootNode"));
       
   186         // Because the node was not found from the cache,
       
   187         // create a new node.
       
   188         return RootNodeL();
       
   189         }
       
   190     else
       
   191         {
       
   192         DLTRACE(("Create a new node"));
       
   193         // Because the node was not found from the cache,
       
   194         // create a new node.
       
   195         return CreateNodeL( aNodeIdentifier );        
       
   196         }
       
   197     }
       
   198 
       
   199 
       
   200 CNcdRootNodeProxy& CNcdNodeManagerProxy::RootNodeL()
       
   201     {
       
   202     DLTRACEIN((""));
       
   203 
       
   204     if( iRootNode == NULL )
       
   205         {
       
   206         DLTRACE(("Root did not exist. Create it."));
       
   207         
       
   208         // Root does not exist. So, create it.
       
   209 
       
   210         // First get the handle to the node of the server side.
       
   211         // The handle is gotten from the server side nodemanager.
       
   212         TInt rootHandle( 0 );
       
   213         User::LeaveIfError(
       
   214                 ClientServerSession().
       
   215                     SendSync( NcdNodeFunctionIds::ENcdRootNodeHandle,
       
   216                               KNullDesC,
       
   217                               rootHandle,
       
   218                               Handle() ) );
       
   219 
       
   220         DLTRACE(("Root handle: %d", rootHandle ));
       
   221         
       
   222         // Now we have handle. So, create the actual root proxy. 
       
   223         // Notice that if the proxy object leaves during the construction
       
   224         // the destructor automatically releases the handle from the server side.               
       
   225         iRootNode = 
       
   226             CNcdRootNodeProxy::NewL( ClientServerSession(), 
       
   227                                      rootHandle,
       
   228                                      *this,
       
   229                                      iOperationManager,
       
   230                                      *iFavoriteManager );
       
   231                                       
       
   232         // Because root node is created now, it is not in the cache yet.
       
   233         // Put it into the cache. So, users can find the root then also
       
   234         // by using the NodeL function.
       
   235         iNodeCache.AppendL( iRootNode );
       
   236         }
       
   237 
       
   238     DLTRACEOUT((""));
       
   239     
       
   240     return *iRootNode;
       
   241     }
       
   242   
       
   243 CNcdSearchRootNodeProxy& CNcdNodeManagerProxy::SearchRootNodeL()
       
   244     {
       
   245     DLTRACEIN((""));
       
   246 
       
   247     if( iSearchRootNode == NULL )
       
   248         {
       
   249         DLTRACE(("Search root did not exist. Create it."));
       
   250         
       
   251         // Search root does not exist. So, create it.
       
   252 
       
   253         // First get the handle to the node of the server side.
       
   254         // The handle is gotten from the server side nodemanager.
       
   255         TInt searchRootHandle( 0 );
       
   256         User::LeaveIfError(
       
   257                 ClientServerSession().
       
   258                     SendSync( NcdNodeFunctionIds::ENcdSearchRootNodeHandle,
       
   259                               KNullDesC,
       
   260                               searchRootHandle,
       
   261                               Handle() ) );
       
   262 
       
   263         DLTRACE(("Search root handle: %d", searchRootHandle ));
       
   264         
       
   265         // Now we have handle. So, create the actual search root proxy. 
       
   266         // Notice that if the proxy object leaves during the construction
       
   267         // the destructor automatically releases the handle from the server side.               
       
   268         iSearchRootNode = 
       
   269             CNcdSearchRootNodeProxy::NewL( ClientServerSession(), 
       
   270                                      searchRootHandle,
       
   271                                      *this,
       
   272                                      iOperationManager,
       
   273                                      *iFavoriteManager );
       
   274         // call addref to keep search root alive for search ops (search root 
       
   275         // is set as observer for them)
       
   276         iSearchRootNode->InternalAddRef();
       
   277         // Because search root node is created now, it is not in the cache yet.
       
   278         // Put it into the cache. So, users can find the search root then also
       
   279         // by using the NodeL function.
       
   280         iNodeCache.AppendL( iSearchRootNode );
       
   281         }
       
   282 
       
   283     DLTRACEOUT((""));
       
   284     
       
   285     return *iSearchRootNode;
       
   286     }
       
   287 
       
   288 
       
   289 CNcdNodeProxy& CNcdNodeManagerProxy::CreateSchemeNodeL(
       
   290     const CNcdNodeIdentifier& aMetadataIdentifier,
       
   291     TNcdSchemeNodeType aType,
       
   292     TBool aRemoveOnDisconnect,
       
   293     TBool aForceCreate )
       
   294     {
       
   295     DLTRACEIN((""));
       
   296     
       
   297     CNcdNodeProxy* node( NULL );
       
   298     
       
   299     // Check the favorites for the given metadata and return the node which has
       
   300     // the metadata if one exists.
       
   301     node = iFavoriteManager->FavoriteNodeByMetaDataL( aMetadataIdentifier );
       
   302     
       
   303     if ( node )
       
   304         {
       
   305         return *node;
       
   306         }
       
   307         
       
   308     // Node was not found from favorites.
       
   309     if ( aForceCreate )
       
   310         {
       
   311         // Creation is forced, create node of correct type.
       
   312         switch ( aType )
       
   313             {
       
   314             case ENcdSchemeItem:
       
   315                 
       
   316                 node = &CreateTemporaryNodeItemL( aMetadataIdentifier, EFalse );
       
   317                 break;
       
   318                 
       
   319             case ENcdSchemeFolder:
       
   320                 node = &CreateTemporaryNodeFolderL( aMetadataIdentifier, EFalse );
       
   321                 break;
       
   322                 
       
   323             case ENcdSchemeBundleFolder:
       
   324                 node = &CreateTemporaryBundleFolderL( aMetadataIdentifier, EFalse );
       
   325                 break;
       
   326             
       
   327             default:
       
   328                 NCD_ASSERT_ALWAYS( EFalse, ENcdPanicInvalidArgument );
       
   329                 break;
       
   330             }
       
   331         }
       
   332     else 
       
   333         {
       
   334         // Creation not forced, create temporary node item if metadata exists already.
       
   335         // This leaves with KErrNotFound if metadata does not exist, thus the
       
   336         // node cannot be created.
       
   337         node = &CreateTemporaryNodeIfMetadataExistsL( aMetadataIdentifier );
       
   338         }
       
   339 
       
   340     DASSERT( node );
       
   341     
       
   342     // Scheme nodes must be added to favourites.
       
   343     node->AddToFavoritesL( aRemoveOnDisconnect );
       
   344 
       
   345     DLTRACEOUT((""));
       
   346     
       
   347     return *node;
       
   348     }
       
   349 
       
   350 
       
   351 CNcdNodeProxy& CNcdNodeManagerProxy::CreateTemporaryNodeL( 
       
   352     const MNcdPurchaseDetails& aDetails )
       
   353     {
       
   354     DLTRACEIN((""));
       
   355 
       
   356     CNcdNodeProxy* node( NULL );
       
   357 
       
   358     CNcdNodeIdentifier* identifier( 
       
   359         CNcdNodeIdentifier::NewLC( aDetails.Namespace(), 
       
   360                                    aDetails.EntityId(), 
       
   361                                    aDetails.ServerUri(),
       
   362                                    aDetails.ClientUid() ) );
       
   363 
       
   364     if ( aDetails.ItemType() == MNcdPurchaseDetails::EItem )
       
   365         {
       
   366         DLINFO(("Item from purchase history"));
       
   367         node = &CreateTemporaryNodeItemL( *identifier, ETrue );
       
   368         }
       
   369     else if ( aDetails.ItemType() == MNcdPurchaseDetails::EFolder )
       
   370         {
       
   371         DLINFO(("Folder from purchase history"));
       
   372         node = &CreateTemporaryNodeFolderL( *identifier, ETrue );
       
   373         }
       
   374     else
       
   375         {
       
   376         DLINFO(("Unknown from purchase history"));
       
   377         node = &CreateTemporaryOrSupplierNodeL( *identifier );
       
   378         }
       
   379 
       
   380     CleanupStack::PopAndDestroy( identifier );
       
   381 
       
   382     DLTRACEOUT((""));
       
   383 
       
   384     return *node;
       
   385     }
       
   386     
       
   387 CNcdNodeProxy& CNcdNodeManagerProxy::CreateTemporaryNodeFolderL( 
       
   388     const CNcdNodeIdentifier& aMetadataIdentifier, TBool aCreateMetaData )
       
   389     {
       
   390     DLTRACEIN((_L("Metadata ID: %S, %S, %S, %d"), 
       
   391                 &aMetadataIdentifier.NodeId(),
       
   392                 &aMetadataIdentifier.NodeNameSpace(),
       
   393                 &aMetadataIdentifier.ServerUri(),
       
   394                 aMetadataIdentifier.ClientUid()));        
       
   395 
       
   396     // Check if the node proxy already exists in the cache.
       
   397     // Every node has its own namespace and dataid.
       
   398     // If it does exist, do not create it.
       
   399 
       
   400     // At first, try to find the node from cache by creating the node identifier
       
   401     // from the metadata identifier.
       
   402     CNcdNodeIdentifier* tempNodeIdentifier =
       
   403         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetadataIdentifier );
       
   404     CNcdNodeProxy* node( NodeExists( *tempNodeIdentifier ) );
       
   405     
       
   406     if ( node ) 
       
   407         {
       
   408         // Node was found. So, return it.
       
   409         CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   410         DLTRACEOUT(("Node found in cache"));
       
   411         return *node;
       
   412         }
       
   413 
       
   414     // Notice that the actual node identifier is given here, instead of the
       
   415     // metadata identifier.
       
   416     HBufC8* nodeIdentifierData( tempNodeIdentifier->NodeIdentifierDataL() );
       
   417     CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   418     CleanupStack::PushL( nodeIdentifierData );
       
   419         
       
   420     DLINFO(("Get node handle"));
       
   421     // First get the handle to the node of the server side.
       
   422     // The handle is gotten from the server side nodemanager.
       
   423     
       
   424     // NOTE: The identifier may contain NULL UID here, but it will
       
   425     // be replaced by the family id in the server side. And then
       
   426     // the node proxy will contain the right UID when the created node is
       
   427     // internalized during its creation.
       
   428     TInt function = aCreateMetaData ? 
       
   429         NcdNodeFunctionIds::ENcdTemporaryNodeFolderWithMetaDataHandle : 
       
   430         NcdNodeFunctionIds::ENcdTemporaryNodeFolderHandle;
       
   431     
       
   432     TInt nodeHandle( 0 );
       
   433     User::LeaveIfError(
       
   434             ClientServerSession().
       
   435                 SendSync( function,
       
   436                           *nodeIdentifierData,
       
   437                           nodeHandle,
       
   438                           Handle() ) );
       
   439 
       
   440     DLTRACE(("Node handle: %d", nodeHandle ));
       
   441 
       
   442     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
   443 
       
   444     // No need to check the class id here, because we requested an item
       
   445     // node above.
       
   446 
       
   447     node = 
       
   448         CNcdNodeFolderProxy::NewLC( ClientServerSession(),
       
   449                                     nodeHandle,
       
   450                                     *this,
       
   451                                     iOperationManager,
       
   452                                     *iFavoriteManager );
       
   453 
       
   454     // Because we creted a new node, it should be added to the cache.
       
   455     iNodeCache.AppendL( node );
       
   456 
       
   457     CleanupStack::Pop( node );
       
   458 
       
   459     DLTRACEOUT((""));
       
   460     
       
   461     return *node;
       
   462     }
       
   463     
       
   464 CNcdNodeProxy& CNcdNodeManagerProxy::CreateTemporaryBundleFolderL(
       
   465     const CNcdNodeIdentifier& aMetadataIdentifier, TBool aCreateMetaData )
       
   466     {
       
   467     DLTRACEIN((_L("Metadata ID: %S, %S, %S, %d"), 
       
   468                 &aMetadataIdentifier.NodeId(),
       
   469                 &aMetadataIdentifier.NodeNameSpace(),
       
   470                 &aMetadataIdentifier.ServerUri(),
       
   471                 aMetadataIdentifier.ClientUid()));        
       
   472 
       
   473     // Check if the node proxy already exists in the cache.
       
   474     // Every node has its own namespace and dataid.
       
   475     // If it does exist, do not create it.
       
   476 
       
   477     // At first, try to find the node from cache by creating the node identifier
       
   478     // from the metadata identifier.
       
   479     CNcdNodeIdentifier* tempNodeIdentifier =
       
   480         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetadataIdentifier );
       
   481     CNcdNodeProxy* node( NodeExists( *tempNodeIdentifier ) );
       
   482     
       
   483     if ( node ) 
       
   484         {
       
   485         // Node was found. So, return it.
       
   486         CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   487         DLTRACEOUT(("Node found in cache"));
       
   488         return *node;
       
   489         }
       
   490 
       
   491     // Notice that the actual node identifier is given here, instead of the
       
   492     // metadata identifier.
       
   493     HBufC8* nodeIdentifierData( tempNodeIdentifier->NodeIdentifierDataL() );
       
   494     CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   495     CleanupStack::PushL( nodeIdentifierData );
       
   496         
       
   497     DLINFO(("Get node handle"));
       
   498     // First get the handle to the node of the server side.
       
   499     // The handle is gotten from the server side nodemanager.
       
   500     
       
   501     // NOTE: The identifier may contain NULL UID here, but it will
       
   502     // be replaced by the family id in the server side. And then
       
   503     // the node proxy will contain the right UID when the created node is
       
   504     // internalized during its creation.
       
   505     TInt function = aCreateMetaData ?
       
   506         NcdNodeFunctionIds::ENcdTemporaryBundleFolderWithMetaDataHandle :
       
   507         NcdNodeFunctionIds::ENcdTemporaryBundleFolderHandle;
       
   508     
       
   509     TInt nodeHandle( 0 );
       
   510     User::LeaveIfError(
       
   511             ClientServerSession().
       
   512                 SendSync( function,
       
   513                           *nodeIdentifierData,
       
   514                           nodeHandle,
       
   515                           Handle() ) );
       
   516 
       
   517     DLTRACE(("Node handle: %d", nodeHandle ));
       
   518 
       
   519     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
   520 
       
   521     // No need to check the class id here, because we requested a bundle folder
       
   522     // node above.
       
   523     node = 
       
   524         CNcdBundleFolderProxy::NewLC( ClientServerSession(),
       
   525                                       nodeHandle,
       
   526                                       *this,
       
   527                                       iOperationManager,
       
   528                                       *iFavoriteManager );
       
   529 
       
   530     // Because we creted a new node, it should be added to the cache.
       
   531     iNodeCache.AppendL( node );
       
   532 
       
   533     CleanupStack::Pop( node );
       
   534 
       
   535     DLTRACEOUT((""));
       
   536     
       
   537     return *node;
       
   538     }
       
   539 
       
   540     
       
   541 CNcdNodeProxy& CNcdNodeManagerProxy::CreateTemporaryNodeItemL(
       
   542     const CNcdNodeIdentifier& aMetadataIdentifier,
       
   543     TBool aCreateMetaData )
       
   544     {
       
   545     DLTRACEIN((_L("Metadata ID: %S, %S, %S, %d"), 
       
   546                 &aMetadataIdentifier.NodeId(),
       
   547                 &aMetadataIdentifier.NodeNameSpace(),
       
   548                 &aMetadataIdentifier.ServerUri(),
       
   549                 aMetadataIdentifier.ClientUid()));        
       
   550 
       
   551     // Check if the node proxy already exists in the cache.
       
   552     // Every node has its own namespace and dataid.
       
   553     // If it does exist, do not create it.
       
   554 
       
   555     // At first, try to find the node from cache by creating the node identifier
       
   556     // from the metadata identifier.
       
   557     CNcdNodeIdentifier* tempNodeIdentifier =
       
   558         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetadataIdentifier );
       
   559     CNcdNodeProxy* node( NodeExists( *tempNodeIdentifier ) );
       
   560     
       
   561     if ( node ) 
       
   562         {
       
   563         // Node was found. So, return it.
       
   564         CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   565         DLTRACEOUT(("Node found in cache"));
       
   566         return *node;
       
   567         }
       
   568 
       
   569     // Notice that the actual node identifier is given here, instead of the
       
   570     // metadata identifier.
       
   571     HBufC8* nodeIdentifierData( tempNodeIdentifier->NodeIdentifierDataL() );
       
   572     CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   573     CleanupStack::PushL( nodeIdentifierData );
       
   574         
       
   575     DLINFO(("Get node handle"));
       
   576     // First get the handle to the node of the server side.
       
   577     // The handle is gotten from the server side nodemanager.
       
   578     
       
   579     // NOTE: The identifier may contain NULL UID here, but it will
       
   580     // be replaced by the family id in the server side. And then
       
   581     // the node proxy will contain the right UID when the created node is
       
   582     // internalized during its creation.
       
   583     TInt function = aCreateMetaData ?
       
   584         NcdNodeFunctionIds::ENcdTemporaryNodeItemWithMetaDataHandle :
       
   585         NcdNodeFunctionIds::ENcdTemporaryNodeItemHandle;
       
   586     
       
   587     TInt nodeHandle( 0 );
       
   588     User::LeaveIfError(
       
   589             ClientServerSession().
       
   590                 SendSync( function,
       
   591                           *nodeIdentifierData,
       
   592                           nodeHandle,
       
   593                           Handle() ) );
       
   594 
       
   595     DLTRACE(("Node handle: %d", nodeHandle ));
       
   596 
       
   597     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
   598 
       
   599     // No need to check the class id here, because we requested an item
       
   600     // node above.
       
   601 
       
   602     node = 
       
   603         CNcdNodeItemProxy::NewLC( ClientServerSession(),
       
   604                                   nodeHandle,
       
   605                                   *this,
       
   606                                   iOperationManager,
       
   607                                   *iFavoriteManager );
       
   608 
       
   609     // Because we creted a new node, it should be added to the cache.
       
   610     iNodeCache.AppendL( node );
       
   611 
       
   612     CleanupStack::Pop( node );
       
   613 
       
   614     DLTRACEOUT((""));
       
   615     
       
   616     return *node;
       
   617     }
       
   618     
       
   619     
       
   620 CNcdNodeProxy& CNcdNodeManagerProxy::CreateTemporaryNodeIfMetadataExistsL(
       
   621     const CNcdNodeIdentifier& aMetadataIdentifier )
       
   622     {
       
   623     DLTRACEIN((_L("Metadata ID: %S, %S, %S, %d"), 
       
   624                 &aMetadataIdentifier.NodeId(),
       
   625                 &aMetadataIdentifier.NodeNameSpace(),
       
   626                 &aMetadataIdentifier.ServerUri(),
       
   627                 aMetadataIdentifier.ClientUid()));
       
   628                 
       
   629     CNcdNodeIdentifier* tempNodeIdentifier =
       
   630         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetadataIdentifier );
       
   631                            
       
   632     // Check if the node proxy already exists in the cache.
       
   633     // Every node has its own namespace and dataid.
       
   634     // If it does exist, do not create it.
       
   635     CNcdNodeProxy* node( NodeExists( *tempNodeIdentifier ) );    
       
   636     if ( node ) 
       
   637         {
       
   638         // Node was found. So, return it.
       
   639         CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   640         DLTRACEOUT(("Node found in cache"));
       
   641         return *node;
       
   642         }
       
   643         
       
   644     // Node was not found from the cache. So, new node proxy has to be created.
       
   645                     
       
   646     // Notice that the actual node identifier is given here for the server, instead of the
       
   647     // metadata identifier.
       
   648     HBufC8* nodeIdentifierData( tempNodeIdentifier->NodeIdentifierDataL() );
       
   649     CleanupStack::PushL( nodeIdentifierData );
       
   650         
       
   651     DLINFO(("Create temporary if metadata exists"));
       
   652 
       
   653     // This is the output value from SendSync. It tells whether the node was created in server side.
       
   654     // It will be ETrue also when the node existed there already.
       
   655     TBool isCreated( EFalse );
       
   656     
       
   657     // NOTE: The identifier may contain NULL UID here, but it will
       
   658     // be replaced by the family id in the server side. And then
       
   659     // the node proxy will contain the right UID when the created node is
       
   660     // internalized during its creation.
       
   661     // This will create the temporary node in server side if the metadata exists there already.
       
   662     // So, it can be requested next when the node proxy will be created.
       
   663     User::LeaveIfError(
       
   664             ClientServerSession().
       
   665                 SendSync( NcdNodeFunctionIds::ENcdCreateTemporaryNodeIfMetadataExists,
       
   666                           *nodeIdentifierData,
       
   667                           isCreated,
       
   668                           Handle() ) );
       
   669 
       
   670     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
   671     
       
   672     if ( isCreated ) 
       
   673         {
       
   674         // The node was created above in the server side if it did not
       
   675         // already exist. So, we can be sure that we get the node below.
       
   676         // NodeL knows how to create the correct node and inserts it to the cache. 
       
   677         // So, use that function here.
       
   678         // Notice, that there is no need to use ReplaceCacheNodeL here because the
       
   679         // supplier node can use it itself when the correct node data has been loaded
       
   680         // from the web.
       
   681         node = &NodeL( *tempNodeIdentifier );
       
   682         CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   683         }
       
   684     else 
       
   685         {
       
   686         User::Leave( KErrNotFound );
       
   687         }
       
   688 
       
   689     DLTRACEOUT(("metadata was found and temporary node created"));
       
   690     
       
   691     return *node;
       
   692     }
       
   693     
       
   694     
       
   695 CNcdNodeProxy& CNcdNodeManagerProxy::CreateTemporaryOrSupplierNodeL(
       
   696     const CNcdNodeIdentifier& aMetadataIdentifier )
       
   697     {
       
   698     DLTRACEIN((_L("Metadata ID: %S, %S, %S, %d"), 
       
   699                 &aMetadataIdentifier.NodeId(),
       
   700                 &aMetadataIdentifier.NodeNameSpace(),
       
   701                 &aMetadataIdentifier.ServerUri(),
       
   702                 aMetadataIdentifier.ClientUid()));        
       
   703 
       
   704     // Notice that the supplier node and the temporary node use same identifiers
       
   705     // but only one version should exist at a time.
       
   706 
       
   707     CNcdNodeIdentifier* tempNodeIdentifier =
       
   708         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetadataIdentifier );
       
   709 
       
   710     // Check if the node proxy already exists in the cache.
       
   711     // Every node has its own namespace and dataid.
       
   712     // If it does exist, do not create it.
       
   713     CNcdNodeProxy* node( NodeExists( *tempNodeIdentifier ) );    
       
   714     if ( node ) 
       
   715         {
       
   716         // Node was found. So, return it.
       
   717         CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   718         DLTRACEOUT(("Node found in cache"));
       
   719         return *node;
       
   720         }
       
   721 
       
   722     // Node was not found from the cache. So, new node proxy has to be created.
       
   723     
       
   724     // Notice that the actual node identifier is given here for the server, instead of the
       
   725     // metadata identifier.
       
   726     HBufC8* nodeIdentifierData( tempNodeIdentifier->NodeIdentifierDataL() );
       
   727     CleanupStack::PushL( nodeIdentifierData );
       
   728         
       
   729     DLINFO(("Create temporary or supplier node proxy"));
       
   730 
       
   731     // tmpNum is not used for anything, but give the SendSync at least some parameter.    
       
   732     TInt tmpNum( 0 );
       
   733     
       
   734     // NOTE: The identifier may contain NULL UID here, but it will
       
   735     // be replaced by the family id in the server side. And then
       
   736     // the node proxy will contain the right UID when the created node is
       
   737     // internalized during its creation.
       
   738     // This will create the supplier or temporary node in server side. So, it can be
       
   739     // requested next when the node proxy will be created.
       
   740     User::LeaveIfError(
       
   741             ClientServerSession().
       
   742                 SendSync( NcdNodeFunctionIds::ENcdCreateTemporaryOrSupplierNode,
       
   743                           *nodeIdentifierData,
       
   744                           tmpNum,
       
   745                           Handle() ) );
       
   746 
       
   747     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
   748 
       
   749     // The node was created above in the server side if it did not
       
   750     // already exist. So, we can be sure that we get the node below.
       
   751     // NodeL knows how to create the correct node and inserts it to the cache. 
       
   752     // So, use that function here.
       
   753     // Notice, that there is no need to use ReplaceCacheNodeL here because the
       
   754     // supplier node can use it itself when the correct node data has been loaded
       
   755     // from the web.
       
   756     node = &NodeL( *tempNodeIdentifier );
       
   757     
       
   758     CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   759 
       
   760     DLTRACEOUT((""));
       
   761     
       
   762     return *node;
       
   763     }
       
   764 
       
   765 
       
   766 CNcdNodeProxy& CNcdNodeManagerProxy::ReplaceCacheNodeL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   767     {
       
   768     DLTRACEIN((""))
       
   769     
       
   770     // Remove the node that has the given identifier from the cache.
       
   771     // Notice, that the node is now left hanging. And, it will be just deleted
       
   772     // when the user releases it. Also, notice that when the node is deleted,
       
   773     // CNcdNodeManager::NodeDeleted() will be called but it does not matter because the
       
   774     // comparisons in that function are done by using pointers, not identifiers.
       
   775     for ( TInt i = 0; i < iNodeCache.Count(); ++i )
       
   776         {
       
   777         // Because the UID may be set NULL for an identifier and because the
       
   778         // UID should always be same for all the nodes in this application,
       
   779         // the UID is not included when comparing node identifiers here.
       
   780         if ( iNodeCache[ i ]->NodeIdentifier().
       
   781                 Equals( aNodeIdentifier, ETrue, ETrue, EFalse, EFalse ) ) 
       
   782             {
       
   783             iNodeCache.Remove( i );
       
   784             }
       
   785         }        
       
   786 
       
   787     DLTRACEOUT((""));
       
   788 
       
   789     // This will also insert the new node into the cache.
       
   790     // Let the node call leave if something goes wrong. Actually, 
       
   791     // at least some node should be found if one version of the node with the
       
   792     // given identifier alreay exists in the server side.
       
   793     // This call may also leave if we are out of memory. In that case just leave.
       
   794     // Do not try to set the removed node back to the array. When memory is released.
       
   795     // It can be requested from the server side normally later.
       
   796     return NodeL( aNodeIdentifier );
       
   797     }
       
   798 
       
   799 
       
   800 CNcdNodeProxy* CNcdNodeManagerProxy::NodeExists( const CNcdNodeIdentifier& aNodeIdentifier ) const
       
   801     {
       
   802     DLTRACEIN((""));
       
   803     for ( TInt i = 0; i < iNodeCache.Count(); ++i )
       
   804         {
       
   805         // Because the UID may be set NULL for an identifier and because the
       
   806         // UID should always be same for all the nodes in this application,
       
   807         // the UID is not included when comparing node identifiers here.
       
   808         if ( iNodeCache[ i ]->NodeIdentifier().
       
   809                 Equals( aNodeIdentifier, ETrue, ETrue, EFalse, EFalse ) ) 
       
   810             {
       
   811             // The node has already been created 
       
   812             // because the link ids matched.
       
   813             // Return the old node.
       
   814             DLTRACE(("node found"));
       
   815             return iNodeCache[ i ];
       
   816             }
       
   817         }
       
   818     DLTRACE(("node not found"));
       
   819     return NULL;
       
   820     }
       
   821 
       
   822 
       
   823 void CNcdNodeManagerProxy::NodeDeleted( CNcdNodeProxy* aNode )
       
   824     {
       
   825     DLTRACEIN(("Node Deleted"));
       
   826 
       
   827     CNcdNodeProxy* root( iRootNode );
       
   828     CNcdNodeProxy* searchRoot( iSearchRootNode );
       
   829     if( root == aNode )
       
   830         {
       
   831         DLTRACE(("Deleted root node"));
       
   832         // Because the root node is deleted. Set the pointer value to null.
       
   833         iRootNode = NULL;        
       
   834         }
       
   835     else if( searchRoot == aNode )
       
   836         {
       
   837         DLTRACE(("Deleted search node"));
       
   838         // Because the search root node is deleted. Set the pointer value to
       
   839         // null.
       
   840         iSearchRootNode = NULL;
       
   841         }
       
   842 
       
   843     // Remove node from the cache because it will be or has been deleted.
       
   844     for ( TInt i = 0; i < iNodeCache.Count(); ++i )
       
   845         {
       
   846         if( aNode == iNodeCache[ i ] )
       
   847             {
       
   848             DLTRACE(("Removing from cache"));
       
   849             // Remove node from the array.
       
   850             iNodeCache.Remove( i );
       
   851             break;
       
   852             }
       
   853         }
       
   854     }
       
   855 
       
   856 
       
   857 void CNcdNodeManagerProxy::InternalizeRelatedNodesL( CNcdNodeProxy& aNode ) const
       
   858     {
       
   859     DLTRACEIN((""));
       
   860     
       
   861     // First internalize the given node
       
   862     aNode.InternalizeL();
       
   863     
       
   864     // Then check if there is some other nodes to internalize.
       
   865     
       
   866     // Get the metadata identifier of the given node.
       
   867     CNcdNodeIdentifier* paramMetaIdentifier( 
       
   868         NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( 
       
   869             aNode.NodeIdentifier() ) );
       
   870     CNcdNodeIdentifier* metaIdentifier( NULL );
       
   871     CNcdNodeProxy* node( NULL );
       
   872         
       
   873     // Check if related nodes are found from the cache. 
       
   874     for ( TInt i = 0; i < iNodeCache.Count(); ++i )
       
   875         {
       
   876         node = iNodeCache[ i ];
       
   877         metaIdentifier = 
       
   878             NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( 
       
   879                 node->NodeIdentifier() );
       
   880             
       
   881         // Because given node has already been internalized, there is no need to redo it
       
   882         // here. But, internalize all related nodes.
       
   883         // When identifiers are compared, compare only id and namespace. Omit comparison
       
   884         // of URI and UID. UID may be NULL if the node has not been internalized before.
       
   885         if ( &aNode != node
       
   886              && paramMetaIdentifier->Equals( *metaIdentifier, 
       
   887                                              ETrue, ETrue, EFalse, EFalse ) )
       
   888             {
       
   889             DLINFO(("Related node found. Internalize."));
       
   890             node->InternalizeL();
       
   891             }
       
   892              
       
   893         CleanupStack::PopAndDestroy( metaIdentifier );
       
   894         metaIdentifier = NULL;
       
   895         }
       
   896 
       
   897     CleanupStack::PopAndDestroy( paramMetaIdentifier );    
       
   898     DLTRACEOUT((""));
       
   899     }
       
   900 
       
   901 
       
   902 CNcdSubscriptionManagerProxy&
       
   903     CNcdNodeManagerProxy::SubscriptionManager() const
       
   904     {
       
   905     return iSubscriptionManager;
       
   906     }
       
   907     
       
   908 void CNcdNodeManagerProxy::SetFavoriteManager(
       
   909     CNcdFavoriteManagerProxy& aFavoriteManager ) 
       
   910     {
       
   911     iFavoriteManager = &aFavoriteManager;
       
   912     }
       
   913     
       
   914 void CNcdNodeManagerProxy::ClearSearchResultsL()
       
   915     {
       
   916     DLTRACEIN((""));
       
   917     TInt err = KErrNone;
       
   918     User::LeaveIfError( ClientServerSession().SendSync(
       
   919         NcdNodeFunctionIds::ENcdClearSearchResults,
       
   920         KNullDesC,
       
   921         err,
       
   922         Handle() ) );
       
   923     DLTRACEOUT(( "err = %d", err ));
       
   924     }
       
   925 
       
   926 
       
   927 TBool CNcdNodeManagerProxy::IsCapabilitySupportedL( const CNcdNodeIdentifier& aNode, 
       
   928     const TDesC& aCapability )
       
   929     {
       
   930     DLTRACEIN((""));
       
   931     CBufBase* sendBuffer = CBufFlat::NewL( KBufExpandSize );
       
   932     CleanupStack::PushL( sendBuffer );
       
   933     RBufWriteStream stream( *sendBuffer );
       
   934     CleanupClosePushL( stream );
       
   935     
       
   936     aNode.ExternalizeL( stream );
       
   937     ExternalizeDesL( aCapability, stream );
       
   938     
       
   939     TPtrC8 sendPtr( sendBuffer->Ptr( 0 ) );
       
   940     
       
   941     CleanupStack::PopAndDestroy( &stream );
       
   942     TBool isCapabilitySupported = EFalse;
       
   943     
       
   944     User::LeaveIfError( ClientServerSession().SendSync(
       
   945         NcdNodeFunctionIds::ENcdIsCapabilitySupported,
       
   946         sendPtr,
       
   947         isCapabilitySupported,
       
   948         Handle() ) );
       
   949     
       
   950     CleanupStack::PopAndDestroy( sendBuffer );
       
   951     return isCapabilitySupported;
       
   952     }
       
   953 
       
   954 
       
   955 void CNcdNodeManagerProxy::HandleExpiredNodesL(
       
   956     RPointerArray< CNcdExpiredNode >& aExpiredNodes )
       
   957     {
       
   958     DLTRACEIN((""));
       
   959     RCatalogsArray<MNcdNode> expiredNodeArray;
       
   960     CleanupClosePushL( expiredNodeArray );
       
   961     for( TInt i = 0 ; i < aExpiredNodes.Count() ; i++ )
       
   962         {
       
   963         CNcdNodeProxy* node = NodeExists( aExpiredNodes[i]->NodeIdentifier() );
       
   964         if( node )
       
   965             {
       
   966             DLTRACE(("Node existed"));
       
   967             // Perhaps errors should not be ignored?
       
   968             TRAP_IGNORE( node->InternalizeL() );
       
   969             if ( aExpiredNodes[i]->ForceUpdate() )
       
   970                 {
       
   971                 DLTRACE(("Force update set, add to array"));
       
   972                 node->AddRef();
       
   973                 expiredNodeArray.AppendL( node );
       
   974                 }
       
   975             }
       
   976         }
       
   977     if( expiredNodeArray.Count() > 0 )
       
   978         {
       
   979         DLTRACE(("Send force update nodes to provider"));
       
   980         iProvider.ExpirationCallback( expiredNodeArray );
       
   981         }
       
   982     CleanupStack::PopAndDestroy( &expiredNodeArray );
       
   983     }
       
   984 
       
   985 
       
   986 CNcdProviderProxy& CNcdNodeManagerProxy::Provider() const
       
   987     {
       
   988     return iProvider;
       
   989     }
       
   990 
       
   991 /*
       
   992 CNcdNodeProxy& CNcdNodeManagerProxy::CreateSchemeNodeL( 
       
   993     const CNcdNodeIdentifier& aMetadataIdentifier,
       
   994     TInt aFunctionId )
       
   995     {
       
   996     DLTRACEIN((_L("ID: %S, %S, %d"), 
       
   997                 &aMetadataIdentifier.NodeId(),
       
   998                 &aMetadataIdentifier.NodeNameSpace(),
       
   999                 aMetadataIdentifier.ClientUid()));        
       
  1000 
       
  1001     // Check that the root is not in an unitialized state.
       
  1002     // Scheme should be created only if the root has been initialized before.
       
  1003     // Because the root is only used here internally, there is no need to increase
       
  1004     // the reference count.
       
  1005     CNcdRootNodeProxy& root( RootNodeL() );
       
  1006     if ( root.State() == MNcdNode::EStateNotInitialized )
       
  1007         {
       
  1008         DLERROR(("Root was not initialized before creation of scheme!"));
       
  1009         DASSERT( EFalse );
       
  1010         User::Leave( KErrNotReady );
       
  1011         }
       
  1012 
       
  1013     CNcdNodeIdentifier* nodeIdentifier =
       
  1014         NcdNodeIdentifierEditor::CreateNodeIdentifierLC(
       
  1015             RootNodeL().NodeIdentifier(),
       
  1016             aMetadataIdentifier );
       
  1017 
       
  1018     // Check if the node proxy already exists in the cache.
       
  1019     // Every node has its own namespace and dataid.
       
  1020     // If it does exist, do not create it.
       
  1021         
       
  1022     CNcdNodeProxy* node( NodeExists( *nodeIdentifier ) );
       
  1023     if ( node != NULL )
       
  1024         {
       
  1025         // Node was found. So, return it.
       
  1026         CleanupStack::PopAndDestroy( nodeIdentifier );
       
  1027         DLTRACEOUT(("Node found"));
       
  1028         return *node;
       
  1029         }
       
  1030 
       
  1031     HBufC8* nodeIdentifierData( nodeIdentifier->NodeIdentifierDataL() );    
       
  1032     CleanupStack::PushL( nodeIdentifierData );
       
  1033         
       
  1034     // NOTE: The identifier may contain NULL UID here, but it will
       
  1035     // be replaced by the family id in the server side. And then
       
  1036     // the node proxy will contain the right UID when the created node is
       
  1037     // internalized during its creation.
       
  1038 
       
  1039     // tmpNum will not be used for anything. It is just given as a dummy parameter for
       
  1040     // the session request.
       
  1041     TInt tmpNum( 0 );
       
  1042     User::LeaveIfError(
       
  1043             ClientServerSession().
       
  1044                 SendSync( aFunctionId,
       
  1045                           *nodeIdentifierData,
       
  1046                           tmpNum,
       
  1047                           Handle() ) );
       
  1048 
       
  1049     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
  1050 
       
  1051     // The node was created above in the server side if it did not
       
  1052     // already exist. So, we can be sure that we get the node below.
       
  1053     // NodeL knows how to create the correct node and inserts it to the cache. 
       
  1054     // So, use that function here.
       
  1055     node = &NodeL( *nodeIdentifier );
       
  1056 
       
  1057     CleanupStack::PopAndDestroy( nodeIdentifier );
       
  1058     
       
  1059     // Update root node by calling internalization because scheme nodes will
       
  1060     // be added to the root node also.
       
  1061     RootNodeL().InternalizeL();
       
  1062 
       
  1063     DLTRACEOUT((""));
       
  1064     
       
  1065     return *node;
       
  1066     }
       
  1067 */
       
  1068 
       
  1069  CNcdNodeProxy& CNcdNodeManagerProxy::CreateNodeL( const CNcdNodeIdentifier& aNodeIdentifier )
       
  1070     {
       
  1071     DLTRACEIN((""));
       
  1072 
       
  1073     CNcdNodeProxy* node( NULL );
       
  1074 
       
  1075     HBufC8* nodeIdentifierData( aNodeIdentifier.NodeIdentifierDataL() );
       
  1076     CleanupStack::PushL( nodeIdentifierData );
       
  1077         
       
  1078     DLINFO(("Get node handle"));
       
  1079     // First get the handle to the node of the server side.
       
  1080     // The handle is gotten from the server side nodemanager.
       
  1081     
       
  1082     // NOTE: The identifier may contain NULL UID here, but it will
       
  1083     // be replaced by the family id in the server side. And then
       
  1084     // the node proxy will contain the right UID when the created node is
       
  1085     // internalized during its creation.
       
  1086     
       
  1087     TInt nodeHandle( 0 );
       
  1088     User::LeaveIfError(
       
  1089             ClientServerSession().
       
  1090                 SendSync( NcdNodeFunctionIds::ENcdNodeHandle,
       
  1091                           *nodeIdentifierData,
       
  1092                           nodeHandle,
       
  1093                           Handle() ) );
       
  1094 
       
  1095     DLTRACE(("Node handle: %d", nodeHandle ));
       
  1096 
       
  1097     CleanupStack::PopAndDestroy( nodeIdentifierData );
       
  1098 
       
  1099 
       
  1100     // Next, check the type of the node. So, we can create
       
  1101     // right type of the proxy.
       
  1102     TInt classId( 0 );    
       
  1103     TInt classIdError = 
       
  1104             ClientServerSession().
       
  1105                 SendSync( NcdNodeFunctionIds::ENcdClassId,
       
  1106                           KNullDesC,
       
  1107                           classId,
       
  1108                           nodeHandle );
       
  1109     if ( classIdError != KErrNone )
       
  1110         {
       
  1111         // Because we can not create the proxy object for some reason,
       
  1112         // release the handle.
       
  1113         TInt tmpNum( 0 );
       
  1114         ClientServerSession().
       
  1115             SendSync( NcdNodeFunctionIds::ENcdRelease,
       
  1116                       KNullDesC,
       
  1117                       tmpNum,
       
  1118                       Handle() );
       
  1119         
       
  1120         // For debuggin reasons.
       
  1121         DLERROR(("Class id error"));
       
  1122         DASSERT( EFalse );
       
  1123         
       
  1124         User::Leave( classIdError );
       
  1125         }
       
  1126 
       
  1127     // Create the node according to the class id
       
  1128     // Notice that if the proxy object leaves during the construction
       
  1129     // the destructor automatically releases the handle from the server side.               
       
  1130     switch( classId )
       
  1131         {
       
  1132         case NcdNodeClassIds::ENcdFolderNodeClassId:
       
  1133             node = 
       
  1134                 CNcdNodeFolderProxy::NewLC( ClientServerSession(), 
       
  1135                                             nodeHandle,
       
  1136                                             *this,
       
  1137                                             iOperationManager,
       
  1138                                             *iFavoriteManager );
       
  1139             break;
       
  1140 
       
  1141         case NcdNodeClassIds::ENcdTransparentFolderNodeClassId:
       
  1142             // The transparent folder is handled in the proxy
       
  1143             // side as a normal folder.
       
  1144             node = 
       
  1145                 CNcdNodeFolderProxy::NewLC( ClientServerSession(), 
       
  1146                                             nodeHandle,
       
  1147                                             *this,
       
  1148                                             iOperationManager,
       
  1149                                             *iFavoriteManager );
       
  1150             break;
       
  1151             
       
  1152         case NcdNodeClassIds::ENcdBundleFolderNodeClassId:
       
  1153             node =
       
  1154                 CNcdBundleFolderProxy::NewLC( ClientServerSession(),
       
  1155                                               nodeHandle,
       
  1156                                               *this,
       
  1157                                               iOperationManager,
       
  1158                                               *iFavoriteManager );
       
  1159             break;
       
  1160         
       
  1161         case NcdNodeClassIds::ENcdSearchFolderNodeClassId:
       
  1162             node = 
       
  1163                 CNcdSearchNodeFolderProxy::NewLC( ClientServerSession(), 
       
  1164                                             nodeHandle,
       
  1165                                             *this,
       
  1166                                             iOperationManager,
       
  1167                                             *iFavoriteManager );
       
  1168             break;
       
  1169 
       
  1170         case NcdNodeClassIds::ENcdItemNodeClassId:
       
  1171             node = 
       
  1172                 CNcdNodeItemProxy::NewLC( ClientServerSession(),
       
  1173                                           nodeHandle,
       
  1174                                           *this,
       
  1175                                           iOperationManager,
       
  1176                                           *iFavoriteManager );
       
  1177             break;
       
  1178         
       
  1179         case NcdNodeClassIds::ENcdSearchItemNodeClassId:
       
  1180             node = 
       
  1181                 CNcdSearchNodeItemProxy::NewLC( ClientServerSession(),
       
  1182                                           nodeHandle,
       
  1183                                           *this,
       
  1184                                           iOperationManager,
       
  1185                                           *iFavoriteManager );
       
  1186             break;
       
  1187             
       
  1188         case NcdNodeClassIds::ENcdSearchRootNodeClassId:
       
  1189             node = 
       
  1190                 CNcdSearchRootNodeProxy::NewLC( ClientServerSession(),
       
  1191                                           nodeHandle,
       
  1192                                           *this,
       
  1193                                           iOperationManager,
       
  1194                                           *iFavoriteManager );
       
  1195             break;
       
  1196             
       
  1197 
       
  1198         case NcdNodeClassIds::ENcdSupplierNodeClassId:
       
  1199             {
       
  1200             node = CNcdNodeSupplierProxy::NewLC( ClientServerSession(),
       
  1201                                                  nodeHandle,
       
  1202                                                  *this,
       
  1203                                                  iOperationManager,
       
  1204                                                  *iFavoriteManager );
       
  1205 
       
  1206             break;
       
  1207             }
       
  1208             
       
  1209         case NcdNodeClassIds::ENcdSearchBundleNodeClassId:
       
  1210             {
       
  1211             node = 
       
  1212                 CNcdSearchNodeBundleProxy::NewLC( ClientServerSession(), 
       
  1213                                             nodeHandle,
       
  1214                                             *this,
       
  1215                                             iOperationManager,
       
  1216                                             *iFavoriteManager );
       
  1217             break;
       
  1218             }            
       
  1219             
       
  1220         default:
       
  1221             // classId is not recognized
       
  1222             // So, node is left NULL
       
  1223             DLERROR(("Node class type was not recognized!"));
       
  1224             // For testing purposes assert here
       
  1225             DASSERT( EFalse );
       
  1226             break;
       
  1227         }
       
  1228 
       
  1229     // Because we creted a new node, it should be added to the cache.
       
  1230     iNodeCache.AppendL( node );
       
  1231 
       
  1232     CleanupStack::Pop( node );
       
  1233     DLTRACEOUT((""));
       
  1234     return *node;
       
  1235     }