ncdengine/provider/server/src/ncdnodemanager.cpp
changeset 0 ba25891c3a9e
child 5 aba6b8104af3
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 CNcdNodeManager class
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "ncdnodemanager.h"
       
    20 
       
    21 #include <e32err.h>
       
    22 #include <s32mem.h>
       
    23 #include <badesca.h>
       
    24 
       
    25 #include "ncdnodedbmanager.h"
       
    26 #include "ncdnodecachecleaner.h"
       
    27 #include "ncdnodecachecleanermanager.h"
       
    28 #include "ncdnodeidentifier.h"
       
    29 #include "ncdnodeidentifiereditor.h"
       
    30 #include "ncdnodeclassids.h"
       
    31 #include "ncdnodeimpl.h"
       
    32 #include "ncdnodeitem.h"
       
    33 #include "ncdnodefolder.h"
       
    34 #include "ncdbundlefolder.h"
       
    35 #include "ncdnodetransparentfolder.h"
       
    36 #include "ncdrootnode.h"
       
    37 #include "ncdsearchnodefolder.h"
       
    38 #include "ncdnodelink.h"
       
    39 #include "ncdnodemetadataimpl.h"
       
    40 #include "ncdnodeitemmetadata.h"
       
    41 #include "ncdnodefoldermetadata.h"
       
    42 #include "ncdsearchnodeitem.h"
       
    43 #include "ncdsearchnodefolder.h"
       
    44 #include "ncdsearchrootnode.h"
       
    45 #include "ncdexpirednode.h"
       
    46 #include "ncdchildentity.h"
       
    47 #include "ncdpurchasehistorydbimpl.h"
       
    48 #include "ncdnodepreviewimpl.h"
       
    49 #include "ncdstoragedescriptordataitem.h"
       
    50 #include "catalogsbasemessage.h"
       
    51 #include "catalogssession.h"
       
    52 #include "ncd_pp_folderref.h"
       
    53 #include "ncd_pp_itemref.h"
       
    54 #include "ncd_pp_dataentity.h"
       
    55 #include "ncd_pp_download.h"
       
    56 #include "ncdpreviewmanager.h"
       
    57 #include "ncdstoragemanagerimpl.h"
       
    58 #include "ncdconfigurationmanager.h"
       
    59 #include "ncdnodefunctionids.h"
       
    60 #include "ncdproviderdefines.h"
       
    61 #include "ncdserverdetails.h"
       
    62 #include "catalogscontext.h"
       
    63 #include "catalogsutils.h"
       
    64 #include "catalogsconstants.h"
       
    65 #include "ncd_pp_expiredcacheddata.h"
       
    66 #include "ncdproviderutils.h"
       
    67 #include "ncdutils.h"
       
    68 #include "ncdsearchnodebundle.h"
       
    69 #include "ncdfavoritemanagerimpl.h"
       
    70 #include "ncdnodeseeninfo.h"
       
    71 #include "ncdnodeiconimpl.h"
       
    72 #include "ncderrors.h"
       
    73 #include "ncdsearchablenode.h"
       
    74 #include "ncdnodeidentifierutils.h"
       
    75 #include "ncdgeneralmanager.h"
       
    76 
       
    77 #include "catalogsdebug.h"
       
    78 
       
    79 // If the values from the provider are given in kilos and other classes
       
    80 // require them in bytes, this value can be used for conversion.
       
    81 const TInt KBytesToKilos( 1024 );
       
    82 
       
    83 const TInt KNodeCacheGranularity = 256;
       
    84 
       
    85 CNcdNodeManager::CNcdNodeManager( CNcdGeneralManager& aGeneralManager )
       
    86 : CCatalogsCommunicable(),
       
    87   iPurchaseHistory( aGeneralManager.PurchaseHistory() ),  
       
    88   iNodeCache( KNodeCacheGranularity ),
       
    89   iNodeMetaDataCache( KNodeCacheGranularity ),
       
    90   iTempNodeCache( KNodeCacheGranularity ),
       
    91   iConfigurationManager( aGeneralManager.ConfigurationManager() ),
       
    92   iNodeOrder( CNcdNode::Compare ),
       
    93   iGeneralManager( aGeneralManager )
       
    94     {
       
    95     DLTRACEIN((""));    
       
    96     }
       
    97 
       
    98 
       
    99 void CNcdNodeManager::ConstructL()
       
   100     {
       
   101     DLTRACEIN((""));
       
   102     iGeneralManager.SetNodeManager( *this );
       
   103     iDbManager = CNcdNodeDbManager::NewL( iGeneralManager.StorageManager() );
       
   104     
       
   105     // Make sure that db manager is created before factory is created.
       
   106     iNodeFactory = CNcdNodeFactory::NewL( *this );
       
   107     
       
   108     // Notice that this function uses the objects created above.
       
   109     // So, if the creation is moved somewhere else, make sure that
       
   110     // NodeDbManager and NodeFactory are also created.
       
   111     iNodeCacheCleanerManager = 
       
   112         CNcdNodeCacheCleanerManager::NewL( iGeneralManager, 
       
   113                                            NodeDbManager(),
       
   114                                            NcdProviderDefines::KDbDefaultMaxByteSize,
       
   115                                            NodeFactory() );
       
   116 
       
   117     iPreviewManager = CNcdPreviewManager::NewL( iGeneralManager, 
       
   118                                           NcdProviderDefines::KMaxClientPreviews );
       
   119     iPreviewManager->LoadDataL();
       
   120     iGeneralManager.SetNodeManager( *this );
       
   121     
       
   122     iSeenInfo = CNcdNodeSeenInfo::NewL( iGeneralManager );
       
   123 
       
   124     iSearchableNode = new ( ELeave ) CNcdSearchableNode( *this );
       
   125     DLTRACEOUT((""));
       
   126     }
       
   127 
       
   128 
       
   129 CNcdNodeManager::~CNcdNodeManager()
       
   130     {
       
   131     DLTRACEIN((""));
       
   132     
       
   133     // Ensure that all cached objects are closed
       
   134     FullCacheCleanup();
       
   135 
       
   136 
       
   137     if ( iSearchableNode ) 
       
   138         {
       
   139         iSearchableNode->Close();        
       
   140         }
       
   141         
       
   142     // Delete member variables in reverse order when comparing
       
   143     // to the creation order.
       
   144 
       
   145     delete iPreviewManager;
       
   146     
       
   147     // Delete node cache cleaner.
       
   148     delete iNodeCacheCleanerManager;   
       
   149 
       
   150     // Delete node factory.
       
   151     delete iNodeFactory;
       
   152 
       
   153     // Delete the db manager.
       
   154     delete iDbManager;
       
   155     
       
   156     // Delete the seen info.
       
   157     delete iSeenInfo;
       
   158 
       
   159     iClientDatabaseLocks.Close();
       
   160     
       
   161     DLTRACEOUT((""));
       
   162     }
       
   163 
       
   164 
       
   165 CNcdNodeManager* CNcdNodeManager::NewL( CNcdGeneralManager& aGeneralManager )
       
   166     {
       
   167     CNcdNodeManager* self =
       
   168         new( ELeave ) CNcdNodeManager( aGeneralManager );
       
   169     CleanupClosePushL( *self );
       
   170     self->ConstructL();
       
   171     CleanupStack::Pop( self );
       
   172     return self;
       
   173     }
       
   174 
       
   175 
       
   176 // ---------------------------------------------------------------------------
       
   177 // General getter functions
       
   178 // ---------------------------------------------------------------------------
       
   179 
       
   180 CNcdPurchaseHistoryDb& CNcdNodeManager::PurchaseHistory() const
       
   181     {
       
   182     return iPurchaseHistory;
       
   183     }
       
   184 
       
   185 CNcdPreviewManager& CNcdNodeManager::PreviewManager()  const
       
   186     {
       
   187     return *iPreviewManager;
       
   188     }
       
   189 
       
   190 
       
   191 
       
   192 // ---------------------------------------------------------------------------
       
   193 // Functions to get node objects from caches or from db. 
       
   194 // And, functions to create node objects.
       
   195 // ---------------------------------------------------------------------------
       
   196 
       
   197 CNcdNode& CNcdNodeManager::NodeL( const CNcdNodeIdentifier& aIdentifier )
       
   198     {
       
   199     DLTRACEIN((""));
       
   200     
       
   201     CNcdNode* node = NodePtrL( aIdentifier );
       
   202     if ( node == NULL )
       
   203         {
       
   204         User::Leave( KErrNotFound );
       
   205         }
       
   206 
       
   207     DLTRACEOUT((""));
       
   208     return *node;
       
   209     }
       
   210 
       
   211 CNcdNode& CNcdNodeManager::NodeL( const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   212                                   const CNcdNodeIdentifier& aNodeMetaDataIdentifier )
       
   213     {
       
   214     DLTRACEIN((""));
       
   215     
       
   216     CNcdNodeIdentifier* identifier =
       
   217         NcdNodeIdentifierEditor::CreateNodeIdentifierLC( aParentNodeIdentifier, 
       
   218                                                          aNodeMetaDataIdentifier );
       
   219     CNcdNode& node = NodeL( *identifier );
       
   220 
       
   221     CleanupStack::PopAndDestroy( identifier );
       
   222 
       
   223     DLTRACEOUT((""));
       
   224 
       
   225     return node;
       
   226     }
       
   227 
       
   228 
       
   229 CNcdNode* CNcdNodeManager::NodePtrL( const CNcdNodeIdentifier& aIdentifier )
       
   230     {
       
   231     DLTRACEIN(( _L("Node id: %S, %S, %d"), 
       
   232                 &aIdentifier.NodeNameSpace(),
       
   233                 &aIdentifier.NodeId(),
       
   234                 aIdentifier.ClientUid().iUid ));
       
   235 
       
   236     CNcdNode* node( FindNodeFromCacheL( aIdentifier ) );
       
   237     if ( node != NULL )
       
   238         {
       
   239         DLTRACEOUT(("Found node"));
       
   240         return node;
       
   241         }
       
   242 
       
   243     DLINFO(("Start loading the node from storage"));
       
   244     // Check if the node can be found from the db because it was not found
       
   245     // from the cache.
       
   246     // This function leaves with KErrNotFound if the data was not found from
       
   247     // the database. If this is the case then the data should be loaded from
       
   248     // internet. But it is not job of this function. Let it leave.
       
   249     TRAPD( trapError, node = &DbNodeL( aIdentifier ) );
       
   250     if ( trapError == KErrNotFound )
       
   251         {
       
   252         // Node was not found from db. So, return NULL value.
       
   253         DLTRACEOUT(("Node was not found anywhere. Return NULL."));
       
   254         return NULL;
       
   255         }
       
   256     // Leave if some other error occurred.
       
   257     User::LeaveIfError( trapError );
       
   258 
       
   259     DLTRACEOUT(("Node found from db"));
       
   260     return node;
       
   261     }
       
   262 
       
   263 
       
   264 CNcdNode* CNcdNodeManager::NodePtrL( const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   265                                      const CNcdNodeIdentifier& aNodeMetaDataIdentifier )
       
   266     {
       
   267     DLTRACEIN((""));
       
   268     
       
   269     CNcdNodeIdentifier* identifier =
       
   270         NcdNodeIdentifierEditor::CreateNodeIdentifierLC( aParentNodeIdentifier, 
       
   271                                                          aNodeMetaDataIdentifier );
       
   272     CNcdNode* node = NodePtrL( *identifier );
       
   273 
       
   274     CleanupStack::PopAndDestroy( identifier );
       
   275 
       
   276     DLTRACEOUT((""));
       
   277 
       
   278     return node;
       
   279     }
       
   280 
       
   281 
       
   282 CNcdNodeFolder& CNcdNodeManager::FolderL( const CNcdNodeIdentifier& aIdentifier )
       
   283     {
       
   284     DLTRACEIN(( _L("Node id: %S, %S, %d"), 
       
   285                 &aIdentifier.NodeNameSpace(),
       
   286                 &aIdentifier.NodeId(),
       
   287                 aIdentifier.ClientUid().iUid ));
       
   288 
       
   289     CNcdNode& node( NodeL( aIdentifier ) );
       
   290     CNcdNodeFactory::TNcdNodeType nodeType( NodeFactory().NodeTypeL( node ) );
       
   291     if ( nodeType != CNcdNodeFactory::ENcdNodeFolder &&
       
   292         nodeType != CNcdNodeFactory::ENcdNodeSearchBundle
       
   293          && nodeType != CNcdNodeFactory::ENcdNodeRoot )
       
   294         {
       
   295         // The node was not of the right type
       
   296         DLERROR(("Wrong type of node: %d. Should be folder: %d or %d or %d",
       
   297                  nodeType, 
       
   298                  CNcdNodeFactory::ENcdNodeFolder,
       
   299                  CNcdNodeFactory::ENcdNodeSearchBundle,
       
   300                  CNcdNodeFactory::ENcdNodeRoot));
       
   301 
       
   302         // For debug purposes
       
   303         DASSERT( EFalse );
       
   304                 
       
   305         User::Leave( KErrArgument );
       
   306         }
       
   307 
       
   308     DLTRACEOUT((""));
       
   309 
       
   310     return static_cast<CNcdNodeFolder&>( node );
       
   311     }
       
   312 
       
   313 
       
   314 CNcdRootNode& CNcdNodeManager::RootNodeL( const TUid& aClientUid )
       
   315     {
       
   316     DLTRACEIN((""));
       
   317 
       
   318     // All the search roots have the same namespace, but their ids are
       
   319     // the client UIDs.
       
   320     CNcdNodeIdentifier* identifier = 
       
   321         NcdNodeIdentifierEditor::CreateRootIdentifierForClientLC( aClientUid );
       
   322 
       
   323     CNcdNode& node( NodeL( *identifier ) );
       
   324 
       
   325     CleanupStack::PopAndDestroy( identifier );
       
   326 
       
   327     // Check the type to make sure that the casting is ok in the end.
       
   328     CNcdNodeFactory::TNcdNodeType nodeType( NodeFactory().NodeTypeL( node ) );
       
   329     if ( nodeType != CNcdNodeFactory::ENcdNodeRoot )
       
   330         {
       
   331         // The node was not right
       
   332         DLERROR(("Wrong node type. Should be root"));
       
   333 
       
   334         // For debug purposes
       
   335         DASSERT( EFalse );
       
   336                 
       
   337         User::Leave( KErrArgument );
       
   338         }
       
   339 
       
   340     DLTRACEOUT((""));
       
   341 
       
   342     return static_cast<CNcdRootNode&>( node );            
       
   343     }
       
   344 
       
   345 
       
   346 CNcdSearchNodeFolder& CNcdNodeManager::SearchFolderL( const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   347                                                       const CNcdNodeIdentifier& aNodeMetaDataIdentifier )
       
   348     {
       
   349     DLTRACEIN((""));
       
   350 
       
   351     CNcdNode& node( NodeL( aParentNodeIdentifier, aNodeMetaDataIdentifier ) );
       
   352     
       
   353     // Check the type and purpose to make sure that the casting is ok in the end.
       
   354     CNcdNodeFactory::TNcdNodeType nodeType( NodeFactory().NodeTypeL( node ) );
       
   355     CNcdNodeFactory::TNcdNodePurpose nodePurpose( NodeFactory().NodePurposeL( node ) );
       
   356     if ( nodeType != CNcdNodeFactory::ENcdNodeFolder
       
   357          && nodeType != CNcdNodeFactory::ENcdNodeRoot
       
   358          || nodePurpose != CNcdNodeFactory::ENcdSearchNode )
       
   359         {
       
   360         // The node was not right
       
   361         DLERROR(("Wrong node class."));
       
   362 
       
   363         DASSERT( EFalse );
       
   364 
       
   365         // The node was not of the right type
       
   366         User::Leave( KErrArgument );
       
   367         }
       
   368 
       
   369     DLTRACEOUT((""));
       
   370 
       
   371     return static_cast<CNcdSearchNodeFolder&>( node );
       
   372     }
       
   373 
       
   374 
       
   375 CNcdSearchNodeFolder& CNcdNodeManager::SearchFolderL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   376     {
       
   377     DLTRACEIN((""));
       
   378 
       
   379     CNcdNode& node( NodeL( aNodeIdentifier ));
       
   380     
       
   381     // Check the type and purpose to make sure that the casting is ok in the end.
       
   382     CNcdNodeFactory::TNcdNodeType nodeType( NodeFactory().NodeTypeL( node ) );
       
   383     CNcdNodeFactory::TNcdNodePurpose nodePurpose( NodeFactory().NodePurposeL( node ) );
       
   384     if ( nodeType != CNcdNodeFactory::ENcdNodeFolder
       
   385          && nodeType != CNcdNodeFactory::ENcdNodeRoot
       
   386          && nodeType != CNcdNodeFactory::ENcdNodeSearchBundle
       
   387          || nodePurpose != CNcdNodeFactory::ENcdSearchNode )
       
   388         {
       
   389         // The node was not right
       
   390         DLERROR(("Wrong node class."));
       
   391 
       
   392         DASSERT( EFalse );
       
   393 
       
   394         // The node was not of the right type
       
   395         User::Leave( KErrArgument );
       
   396         }
       
   397 
       
   398     DLTRACEOUT((""));
       
   399 
       
   400     return static_cast<CNcdSearchNodeFolder&>( node );
       
   401     }
       
   402     
       
   403     
       
   404 CNcdSearchNodeItem& CNcdNodeManager::SearchNodeItemL( const CNcdNodeIdentifier& aNodeIdentifier )
       
   405     {
       
   406     DLTRACEIN((""));
       
   407 
       
   408     CNcdNode& node( NodeL( aNodeIdentifier ));
       
   409     
       
   410     if ( node.ClassId() != NcdNodeClassIds::ENcdSearchItemNodeClassId )
       
   411         {
       
   412         // The node was not right
       
   413         DLERROR(("Wrong node class."));
       
   414 
       
   415         DASSERT( EFalse );
       
   416 
       
   417         // The node was not of the right type
       
   418         User::Leave( KErrArgument );
       
   419         }
       
   420 
       
   421     DLTRACEOUT((""));
       
   422 
       
   423     return static_cast<CNcdSearchNodeItem&>( node );
       
   424     }
       
   425 
       
   426 
       
   427 CNcdNode& CNcdNodeManager::CreateNodeL( CNcdNodeFactory::TNcdNodeType aNodeType,
       
   428                                         CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   429                                         const CNcdNodeIdentifier& aNodeIdentifier )
       
   430     {
       
   431     DLTRACEIN(("Nodetype: %d, nodepurpose: %d", aNodeType, aNodePurpose));
       
   432     DLINFO((_L("Identifier ns: %S, id: %S"), 
       
   433             &aNodeIdentifier.NodeNameSpace(),
       
   434             &aNodeIdentifier.NodeId()));
       
   435 
       
   436     // The node identifier can not be empty
       
   437     DASSERT( !aNodeIdentifier.ContainsEmptyFields() );
       
   438 
       
   439     // Get the class id of the node that has the given purpose.
       
   440     // The data type parameter informs if an item or a folder should be created.
       
   441     // Set the class id to be some item as a default.
       
   442     NcdNodeClassIds::TNcdNodeClassId classId =
       
   443             NodeFactory().NodeClassIdL( aNodeType, aNodePurpose );
       
   444 
       
   445     DLINFO(("classid of node: %d", classId));
       
   446 
       
   447     CNcdNode* node( NodePtrL( aNodeIdentifier ) );
       
   448        
       
   449     if ( node == NULL )
       
   450         {
       
   451         DLINFO(("Create node"));
       
   452         // Create the node according to the class id
       
   453         node = NodeFactory().CreateNodeLC( aNodeIdentifier,
       
   454                                            classId );
       
   455 
       
   456         DASSERT( node );
       
   457         
       
   458         // and insert node to the cache.
       
   459         AppendNodeToCacheL( node );
       
   460         
       
   461         // cache takes ownership of the node
       
   462         CleanupStack::Pop( node );
       
   463         
       
   464         // NodePtr inserts the metadata if node was found there.
       
   465         // There is no reason to insert the metadata here, because the
       
   466         // node has been just created, and it does not contains the
       
   467         // link data where the metadata id info is inserted.
       
   468         }
       
   469     else if ( NodeFactory().NodeTypeL( *node ) != aNodeType
       
   470               || NodeFactory().NodePurposeL( *node  ) != aNodePurpose )
       
   471         {
       
   472         // Node was already in the list. But, the node is not
       
   473         // of the expected type or purpose.
       
   474         // Notice, that if the requested node purpose was scheme node and the
       
   475         // node that already exists is of the different purpose, then we use the
       
   476         // original node. So, schemes do not require this checking.
       
   477         DLINFO(("classid of real node: %d", node->ClassId() ));
       
   478         DLERROR(("Wrong node type or purpose."));
       
   479         DLERROR(("Type: %d, should be: %d",
       
   480                  NodeFactory().NodeTypeL( *node ), 
       
   481                  aNodeType));
       
   482         DLERROR(("Purpose: %d, should be: %d",
       
   483                  NodeFactory().NodePurposeL( *node ), 
       
   484                  aNodePurpose));
       
   485         DASSERT( EFalse );
       
   486         User::Leave( KErrArgument );
       
   487         }
       
   488 
       
   489     DLTRACEOUT((""));
       
   490 
       
   491     return *node;     
       
   492     }
       
   493 
       
   494 
       
   495 CNcdNode& CNcdNodeManager::CreateNodeL( CNcdNodeFactory::TNcdNodeType aNodeType,
       
   496                                         CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   497                                         const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   498                                         const CNcdNodeIdentifier& aMetaDataIdentifier )
       
   499     {
       
   500     DLTRACEIN((""));
       
   501 
       
   502     // Check the metadata identifier because it has to contain values. These values
       
   503     // are used when the node is created. The parent node may contain empty values.
       
   504     // because the root does not have parent.
       
   505     if ( aMetaDataIdentifier.ContainsEmptyFields() )
       
   506         {
       
   507         DLERROR(("Cannot create node with empty identifier meta values"));
       
   508         
       
   509         // For debug purposes
       
   510         DASSERT( EFalse );
       
   511         
       
   512         User::Leave( KErrArgument );
       
   513         }
       
   514 
       
   515     // Try to find the node before creating it.
       
   516     // Use the correct form of identifier by asking it from the factory
       
   517     CNcdNodeIdentifier* identifier =
       
   518         NcdNodeIdentifierEditor::CreateNodeIdentifierLC( aParentNodeIdentifier, 
       
   519                                                          aMetaDataIdentifier );
       
   520     CNcdNode& node( CreateNodeL( aNodeType, aNodePurpose, *identifier ) );
       
   521     CleanupStack::PopAndDestroy( identifier );
       
   522 
       
   523     DLTRACEOUT((""));
       
   524 
       
   525     return node; 
       
   526     }
       
   527 
       
   528 
       
   529 CNcdNodeItem& CNcdNodeManager::CreateNodeItemL( CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   530                                                 const CNcdNodeIdentifier& aNodeIdentifier )
       
   531     {
       
   532     DLTRACEIN((""));
       
   533 
       
   534     CNcdNode& node =
       
   535         CreateNodeL( CNcdNodeFactory::ENcdNodeItem, aNodePurpose, 
       
   536                      aNodeIdentifier );
       
   537     
       
   538     // Now it is safe to do casting.
       
   539 
       
   540     DLTRACEOUT((""));
       
   541 
       
   542     return static_cast<CNcdNodeItem&>(node);    
       
   543     }
       
   544 
       
   545 CNcdNodeItem& CNcdNodeManager::CreateNodeItemL( CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   546                                                 const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   547                                                 const CNcdNodeIdentifier& aMetaDataIdentifier )
       
   548     {
       
   549     DLTRACEIN((""));
       
   550 
       
   551     CNcdNode& node =
       
   552         CreateNodeL( CNcdNodeFactory::ENcdNodeItem, aNodePurpose, 
       
   553                      aParentNodeIdentifier, aMetaDataIdentifier );
       
   554     
       
   555     // Now it is safe to do casting.
       
   556 
       
   557     DLTRACEOUT((""));
       
   558 
       
   559     return static_cast<CNcdNodeItem&>(node);   
       
   560     }
       
   561 
       
   562 
       
   563 CNcdNodeFolder& CNcdNodeManager::CreateNodeFolderL( CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   564                                                     const CNcdNodeIdentifier& aNodeIdentifier,
       
   565                                                     CNcdNodeFactory::TNcdNodeType aFolderType )
       
   566     {
       
   567     DLTRACEIN((""));
       
   568 
       
   569     CNcdNode& node =
       
   570         CreateNodeL( aFolderType, aNodePurpose, 
       
   571                      aNodeIdentifier );
       
   572     
       
   573     // Now it is safe to do casting.
       
   574 
       
   575     DLTRACEOUT((""));
       
   576 
       
   577     return static_cast<CNcdNodeFolder&>(node);    
       
   578     }
       
   579     
       
   580 CNcdNodeFolder& CNcdNodeManager::CreateNodeFolderL( CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   581                                                     const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   582                                                     const CNcdNodeIdentifier& aMetaDataIdentifier,
       
   583                                                     CNcdNodeFactory::TNcdNodeType aFolderType )
       
   584     {
       
   585     DLTRACEIN((""));
       
   586 
       
   587     CNcdNode& node =
       
   588         CreateNodeL( aFolderType, aNodePurpose, 
       
   589                      aParentNodeIdentifier, aMetaDataIdentifier );
       
   590     
       
   591     // Now it is safe to do casting.
       
   592 
       
   593     DLTRACEOUT((""));
       
   594 
       
   595     return static_cast<CNcdNodeFolder&>(node);    
       
   596     }    
       
   597 
       
   598 
       
   599 CNcdRootNode& CNcdNodeManager::CreateRootL( const TUid& aClientUid )
       
   600     {
       
   601     DLTRACEIN((""));
       
   602     
       
   603     CNcdNodeIdentifier* rootIdentifier( 
       
   604         NcdNodeIdentifierEditor::CreateRootIdentifierForClientLC( aClientUid ) );
       
   605         
       
   606     CNcdNode& node( CreateNodeL( CNcdNodeFactory::ENcdNodeRoot,
       
   607                                  CNcdNodeFactory::ENcdNormalNode,
       
   608                                  *rootIdentifier ) );
       
   609 
       
   610     CleanupStack::PopAndDestroy( rootIdentifier );
       
   611 
       
   612     DLTRACEOUT((""));
       
   613 
       
   614     return static_cast<CNcdRootNode&>( node );            
       
   615     }
       
   616 
       
   617 
       
   618 CNcdRootNode& CNcdNodeManager::CreateRootL( const MCatalogsContext& aContext )
       
   619     {
       
   620     DLTRACEIN((""));
       
   621     return CreateRootL( aContext.FamilyId() );
       
   622     }
       
   623     
       
   624     
       
   625 CNcdNodeFolder& CNcdNodeManager::CreateSearchRootL( const MCatalogsContext& aContext )
       
   626     {
       
   627     DLTRACEIN((""));
       
   628     
       
   629     CNcdNodeIdentifier* rootIdentifier( 
       
   630         NcdNodeIdentifierEditor::CreateSearchRootIdentifierForClientLC( aContext.FamilyId() ) );
       
   631         
       
   632     CNcdNode& node( CreateNodeL( CNcdNodeFactory::ENcdNodeRoot,
       
   633                                  CNcdNodeFactory::ENcdSearchNode,
       
   634                                  *rootIdentifier ) );
       
   635 
       
   636     CleanupStack::PopAndDestroy( rootIdentifier );
       
   637 
       
   638     DLTRACEOUT((""));
       
   639 
       
   640     return static_cast<CNcdNodeFolder&>( node );
       
   641     }
       
   642 
       
   643 
       
   644 CNcdNodeFolder& CNcdNodeManager::CreateBundleFolderL( const CNcdNodeIdentifier& aMetaDataIdentifier )
       
   645     {
       
   646     DLTRACEIN((""));
       
   647     // The parent of the bundle is always the root folder
       
   648     CNcdNodeIdentifier* rootIdentifier = 
       
   649         NcdNodeIdentifierEditor::CreateRootIdentifierForClientLC( aMetaDataIdentifier.ClientUid() );
       
   650 
       
   651     CNcdNodeFolder& folder =
       
   652         CreateNodeFolderL( CNcdNodeFactory::ENcdBundleNode, 
       
   653                            *rootIdentifier, 
       
   654                            aMetaDataIdentifier );
       
   655                            
       
   656     CleanupStack::PopAndDestroy( rootIdentifier );
       
   657 
       
   658     DLTRACEOUT((""));
       
   659     
       
   660     return folder;
       
   661     }
       
   662 
       
   663 
       
   664 CNcdNode& CNcdNodeManager::CreateTemporaryNodeOrSupplierL( const CNcdNodeIdentifier& aMetaDataIdentifier )
       
   665     {
       
   666     DLTRACEIN((""));
       
   667 
       
   668     CNcdNode* node( NULL );
       
   669 
       
   670     // First check if the given temporary node already exists in RAM or in databse.
       
   671     // We can use NodeL also for this operation.
       
   672     CNcdNodeIdentifier* tempNodeIdentifier =
       
   673         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetaDataIdentifier );
       
   674         
       
   675     // Note that if the node is found it is also inserted into the node cache
       
   676     // but it is not saved into the database.
       
   677     TRAP_IGNORE( node = &NodeL( *tempNodeIdentifier ) );
       
   678 
       
   679     // If the temporary node did not exist. Then create supplier, which also checks
       
   680     // if the corresponding node already exists in RAM or in database.
       
   681     // CreateNodeL can handle this.
       
   682     // If it does not exist then there is still possibility that the corresponding
       
   683     // metadata exists. If metadata exists, then it can be used to create the correct
       
   684     // temporary node
       
   685     if ( node == NULL )
       
   686         {
       
   687         // First check the metadata.
       
   688         // The ownership of the meta will be in cache.
       
   689         CNcdNodeMetaData* meta( NULL );
       
   690         TRAP_IGNORE( meta = &NodeMetaDataL( aMetaDataIdentifier ) );
       
   691         
       
   692         if ( meta != NULL )
       
   693             {
       
   694             DLINFO(("Meta was found for the temp node"));
       
   695             
       
   696             // Metadata was found. So, create right type temporary node.
       
   697             if ( meta->ClassId() 
       
   698                     == NcdNodeClassIds::ENcdFolderNodeMetaDataClassId )
       
   699                 {
       
   700                 DLINFO(("Create temp folder"));
       
   701                 node = &CreateNodeFolderL( CNcdNodeFactory::ENcdNormalNode,
       
   702                                            *tempNodeIdentifier );
       
   703                 }
       
   704             else if ( meta->ClassId() 
       
   705                         == NcdNodeClassIds::ENcdItemNodeMetaDataClassId )
       
   706                 {
       
   707                 DLINFO(("Create temp item"));
       
   708                 node = &CreateNodeItemL( CNcdNodeFactory::ENcdNormalNode,
       
   709                                          *tempNodeIdentifier );                
       
   710                 }
       
   711             else
       
   712                 {
       
   713                 DLINFO(("Unknown meta type"));
       
   714                 DASSERT( EFalse );
       
   715                 User::Leave( KErrUnknown );
       
   716                 }
       
   717             
       
   718             DLINFO(("Setting node metadata"))
       
   719             node->SetNodeMetaDataL( *meta );
       
   720             }
       
   721         else
       
   722             {
       
   723             DLINFO(("Create node supplier"));
       
   724             node = &CreateNodeL( CNcdNodeFactory::ENcdNodeSupplier,
       
   725                                  CNcdNodeFactory::ENcdNormalNode,
       
   726                                  *tempNodeIdentifier );
       
   727             }
       
   728         }
       
   729     // Notice that if the node creation worked correctly, it will
       
   730     // be added to the cache list. So the ownership is in cache, so
       
   731     // no need to keep the node in cleanup stack.
       
   732     
       
   733     // Now that we have the node, make sure that all the necessary information
       
   734     // is inserted to its link. This includes metadata identifier and the
       
   735     // server uri.
       
   736     CNcdNodeLink& link( node->CreateAndSetLinkL() );
       
   737     link.SetMetaDataIdentifierL( aMetaDataIdentifier );
       
   738     link.SetServerUriL( aMetaDataIdentifier.ServerUri() );
       
   739     
       
   740     CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   741 
       
   742     // Now that everything is ok, save the node into the db.
       
   743     DbSaveNodeL( *node );
       
   744     
       
   745     DLTRACEOUT((""));
       
   746     
       
   747     return *node;
       
   748     }
       
   749     
       
   750 
       
   751 CNcdNode* CNcdNodeManager::CreateTemporaryNodeIfMetadataExistsL(
       
   752     const CNcdNodeIdentifier& aMetadataIdentifier ) 
       
   753     {
       
   754     DLTRACEIN((""));
       
   755     
       
   756     // Check if the metadata exists.
       
   757     CNcdNodeMetaData* metadata( NULL );
       
   758     TRAPD( err, metadata = &NodeMetaDataL( aMetadataIdentifier ) );
       
   759     if ( err == KErrNotFound ) 
       
   760         {
       
   761         // Metadata not found, cannot do anything.
       
   762         return NULL;
       
   763         }
       
   764     
       
   765     User::LeaveIfError( err );
       
   766     DASSERT( metadata );
       
   767     
       
   768     // Metadata exists, create temporary node of correct type.   
       
   769 
       
   770     // First check if the given temporary node already exists in RAM or in databse.
       
   771     // We can use NodeL also for this operation.
       
   772     CNcdNodeIdentifier* tempNodeIdentifier =
       
   773         NcdNodeIdentifierEditor::CreateTemporaryNodeIdentifierLC( aMetadataIdentifier );
       
   774 
       
   775     CNcdNode* node( NULL );
       
   776     TRAP( err, node = &NodeL( *tempNodeIdentifier ) );
       
   777     LeaveIfNotErrorL( err, KErrNotFound );
       
   778     
       
   779     if ( node == NULL )
       
   780         {
       
   781         // If the temporary node did not exist. Create one according to the type of
       
   782         // the metadata.            
       
   783         if ( metadata->ClassId() == NcdNodeClassIds::ENcdFolderNodeMetaDataClassId )
       
   784             {
       
   785             DLINFO(("Create temp folder"));
       
   786             node = &CreateNodeFolderL( CNcdNodeFactory::ENcdNormalNode,
       
   787                                        *tempNodeIdentifier );
       
   788             }
       
   789         else if ( metadata->ClassId() 
       
   790                     == NcdNodeClassIds::ENcdItemNodeMetaDataClassId )
       
   791             {
       
   792             DLINFO(("Create temp item"));
       
   793             node = &CreateNodeItemL( CNcdNodeFactory::ENcdNormalNode,
       
   794                                      *tempNodeIdentifier );                
       
   795             }
       
   796         else
       
   797             {
       
   798             DLINFO(("Unknown meta type"));
       
   799             DASSERT( EFalse );
       
   800             User::Leave( KErrUnknown );
       
   801             }
       
   802         
       
   803         DLINFO(("Setting node metadata"))
       
   804         node->SetNodeMetaDataL( *metadata );
       
   805         }
       
   806     else
       
   807         {
       
   808         // Temporary node exists. Check that it has the metadata.
       
   809         CNcdNodeMetaData* existingMeta = node->NodeMetaData();
       
   810         if ( existingMeta )
       
   811             {
       
   812             DASSERT( existingMeta == metadata );
       
   813             }
       
   814         else 
       
   815             {
       
   816             // Temporary node did not have metadata, install it.
       
   817             node->SetNodeMetaDataL( *metadata );
       
   818             }
       
   819         }
       
   820         
       
   821     DASSERT( node );
       
   822     DASSERT( node->NodeMetaData() );
       
   823     
       
   824     // Notice that if the node creation worked correctly, it will
       
   825     // be added to the cache list. So the ownership is in cache, so
       
   826     // no need to keep the node in cleanup stack.
       
   827     
       
   828     // Now that we have the node, make sure that all the necessary information
       
   829     // is inserted to its link. This includes metadata identifier and the
       
   830     // server uri.
       
   831     CNcdNodeLink& link( node->CreateAndSetLinkL() );
       
   832     link.SetMetaDataIdentifierL( aMetadataIdentifier );
       
   833     link.SetServerUriL( aMetadataIdentifier.ServerUri() );
       
   834     
       
   835     CleanupStack::PopAndDestroy( tempNodeIdentifier );
       
   836 
       
   837     // Now that everything is ok, save the node into the db.
       
   838     DbSaveNodeL( *node );
       
   839     
       
   840     DLTRACEOUT((""));
       
   841     
       
   842     return node;
       
   843     }
       
   844     
       
   845     
       
   846 CNcdSearchNodeBundle& CNcdNodeManager::CreateSearchBundleL( const CNcdNodeIdentifier& aMetaDataIdentifier,
       
   847     const CNcdNodeIdentifier& aParentIdentifier )
       
   848     {
       
   849     DLTRACEIN((""));
       
   850     
       
   851 
       
   852     CNcdNodeFolder& folder =
       
   853         CreateNodeFolderL( CNcdNodeFactory::ENcdSearchNode, 
       
   854                            aParentIdentifier, 
       
   855                            aMetaDataIdentifier,
       
   856                            CNcdNodeFactory::ENcdNodeSearchBundle );
       
   857                            
       
   858     // Now it is safe to do casting.
       
   859 
       
   860     DLTRACEOUT((""));
       
   861 
       
   862     return static_cast<CNcdSearchNodeBundle&>(folder);
       
   863     }
       
   864 
       
   865 CNcdSearchNodeFolder& CNcdNodeManager::CreateSearchFolderL( const CNcdNodeIdentifier& aMetaDataIdentifier,
       
   866     const CNcdNodeIdentifier& aParentIdentifier )
       
   867     {
       
   868     DLTRACEIN((""));
       
   869     
       
   870 
       
   871     CNcdNodeFolder& folder =
       
   872         CreateNodeFolderL( CNcdNodeFactory::ENcdSearchNode, 
       
   873                            aParentIdentifier, 
       
   874                            aMetaDataIdentifier,
       
   875                            CNcdNodeFactory::ENcdNodeFolder );
       
   876                            
       
   877     // Now it is safe to do casting.
       
   878 
       
   879     DLTRACEOUT((""));
       
   880 
       
   881     return static_cast<CNcdSearchNodeBundle&>(folder);
       
   882     }
       
   883 
       
   884 
       
   885 CNcdNodeMetaData& CNcdNodeManager::NodeMetaDataL(  
       
   886     const CNcdNodeIdentifier& aIdentifier )
       
   887     {
       
   888     DLTRACEIN(( _L("Metadata id: %S, %S, %d"), 
       
   889                 &aIdentifier.NodeNameSpace(),
       
   890                 &aIdentifier.NodeId(),
       
   891                 aIdentifier.ClientUid().iUid ));
       
   892 
       
   893     CNcdNodeMetaData* metaData( 
       
   894         FindNodeMetaDataFromCache( aIdentifier ) );
       
   895 
       
   896     if ( metaData == NULL )
       
   897         {
       
   898         // Check if the node can be found from the db because it was not found
       
   899         // from the cache.
       
   900         // This function leaves with KErrNotFound if the data was not found from
       
   901         // the database. If this is the case then the data should be loaded from
       
   902         // internet. But it is not job of this function. Let it leave.
       
   903         metaData = &DbMetaDataL( aIdentifier );        
       
   904         }
       
   905 
       
   906     DLTRACEOUT((""));
       
   907     
       
   908     return *metaData;
       
   909     }
       
   910 
       
   911 
       
   912 CNcdNodeMetaData& CNcdNodeManager::CreateNodeMetaDataL(
       
   913     const CNcdNodeIdentifier& aMetaDataIdentifier,
       
   914     CNcdNodeFactory::TNcdNodeType aMetaType ) 
       
   915     {
       
   916     
       
   917     DLTRACEIN(( _L("Metadata id: %S, %S, %d"), 
       
   918                 &aMetaDataIdentifier.NodeNameSpace(),
       
   919                 &aMetaDataIdentifier.NodeId(),
       
   920                 aMetaDataIdentifier.ClientUid().iUid ));
       
   921     
       
   922     CNcdNodeMetaData* metaData( NULL );
       
   923     TRAPD( err, metaData = &NodeMetaDataL( aMetaDataIdentifier ) );
       
   924     if ( err != KErrNone ) 
       
   925         {
       
   926         if ( err == KErrNotFound ) 
       
   927             {
       
   928             metaData = NodeFactory().CreateMetaDataLC( aMetaDataIdentifier, aMetaType );
       
   929             iNodeMetaDataCache.AppendL( metaData );
       
   930             // Cache takes ownership of the metadata
       
   931             CleanupStack::Pop( metaData );
       
   932             }
       
   933         else 
       
   934             {
       
   935             User::Leave( err );
       
   936             }
       
   937         }
       
   938     
       
   939     return *metaData;
       
   940     }
       
   941 
       
   942 
       
   943 
       
   944 // ---------------------------------------------------------------------------
       
   945 // Functions that are used to insert data information
       
   946 // gotten from the data parsers into the correct node
       
   947 // objects. These functions are provided for operations.
       
   948 // The updated information may also be inserted from the 
       
   949 // purchase history.
       
   950 // ---------------------------------------------------------------------------
       
   951 
       
   952 CNcdNode& CNcdNodeManager::RefHandlerL( 
       
   953     const CNcdNodeIdentifier& aParentNodeIdentifier,
       
   954     MNcdPreminetProtocolEntityRef& aData,
       
   955     const TUid& aClientUid,
       
   956     TNcdRefHandleMode aMode,
       
   957     TInt aIndex,
       
   958     CNcdNodeFactory::TNcdNodeType aParentNodeType,
       
   959     CNcdNodeFactory::TNcdNodePurpose aParentNodePurpose,
       
   960     CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
   961     TBool aCreateParent )
       
   962     {
       
   963     DLTRACEIN(("aData: %X, nodepurpose: %d, aCreateParent: %d", &aData, aNodePurpose, aCreateParent));
       
   964     
       
   965     DLINFO((_L("parent node ns: %S, id: %S"), 
       
   966 
       
   967             &aParentNodeIdentifier.NodeNameSpace(), &aParentNodeIdentifier.NodeId()));
       
   968     DLINFO((_L("parent node from entity ns: %S, id: %S"), 
       
   969             &aData.ParentNamespace(), &aData.ParentId()));
       
   970 
       
   971     DLINFO((_L("data ns: %S, id: %S"), 
       
   972             &aData.Namespace(), &aData.Id()));
       
   973             
       
   974     DLINFO((_L("insert index: %d, mode: %d"), aIndex, aMode ));
       
   975     DPROFILING_BEGIN( x );
       
   976 
       
   977     // Get the type of the node -- folder or item.
       
   978     CNcdNodeFactory::TNcdNodeType nodeType = CNcdNodeFactory::ENcdNodeItem;
       
   979     if ( aData.Type() == MNcdPreminetProtocolEntityRef::EFolderRef )
       
   980         {
       
   981         nodeType = CNcdNodeFactory::ENcdNodeFolder;
       
   982         }
       
   983     else if ( aData.Type() != MNcdPreminetProtocolEntityRef::EItemRef )
       
   984         {                
       
   985         // Wrong type
       
   986         DLINFO(( "Wrong node data type: %d", aData.Type() ));
       
   987         DASSERT( EFalse );
       
   988         User::Leave( KErrArgument );
       
   989         }   
       
   990 
       
   991     // Notice that the aClientUid is used here instead of the parent identifier uid,
       
   992     // because the parent identifier may be empty in some cases.
       
   993     CNcdNodeIdentifier* metaIdentifier = 
       
   994         CNcdNodeIdentifier::NewLC( aData.Namespace(), 
       
   995                                    aData.Id(),
       
   996                                    aData.ServerUri(), 
       
   997                                    aClientUid );
       
   998 
       
   999         
       
  1000     // Check if the node already exists in RAM cache or in the db.
       
  1001     // Also, check the node type. This function replaces old node
       
  1002     // in RAM cache (not in db) if the node type and purpose do
       
  1003     // not match with the ones gotten from the parser.
       
  1004     CNcdNode& node( CheckAndCreateNodeL( nodeType, 
       
  1005                                          aNodePurpose,
       
  1006                                          aParentNodeIdentifier,
       
  1007                                          *metaIdentifier ) );
       
  1008 
       
  1009 
       
  1010 
       
  1011     if ( aCreateParent ||
       
  1012          !aParentNodeIdentifier.ContainsEmptyFields() &&
       
  1013          NodePtrL( aParentNodeIdentifier ) ) 
       
  1014         {        
       
  1015         // Insert the node to the parent if it does not already exist there.
       
  1016         // Note that here we insert it into the actual parent. Not into the parent
       
  1017         // that is set for the proxy parent.
       
  1018         // Note that the node link is internalized after the node has been inserted into the
       
  1019         // parent. This way, the link will finally contain the correct info, for example
       
  1020         // the correct parent info.
       
  1021         // Make sure that the parent node type is correct in case root is used
       
  1022         AddToParentL( aParentNodeIdentifier, 
       
  1023                       *metaIdentifier, 
       
  1024                       aParentNodeType, 
       
  1025                       aParentNodePurpose, 
       
  1026                       aNodePurpose, 
       
  1027                       aMode, 
       
  1028                       aIndex );
       
  1029         DLINFO(("AddToParentL done, aData: %X", &aData));
       
  1030         }
       
  1031 
       
  1032     // Metaid is not needed anymore. So, delete it.
       
  1033     CleanupStack::PopAndDestroy( metaIdentifier );
       
  1034     metaIdentifier = NULL;
       
  1035 
       
  1036     // Internalize data to the link of the node
       
  1037     DLINFO(("Internalize link data"));
       
  1038     
       
  1039     // Note that the parent identifier should be checked if the parent is transparent in
       
  1040     // other words if this node should be child of transparent.
       
  1041     // Then the actual parent for the proxy transmission should be set to be the
       
  1042     // grand parent node.
       
  1043     if ( aNodePurpose == CNcdNodeFactory::ENcdChildOfTransparentNode )
       
  1044         {
       
  1045         DLINFO(("Transparent child. Get parent of parent"));
       
  1046         // Parse the correct grandparent identifier because the proxy side will get
       
  1047         // the grandparent identifier for the parent identifier info in case of transparent
       
  1048         // nodes.
       
  1049         CNcdNodeIdentifier* grandParentIdentifier( 
       
  1050             NcdNodeIdentifierEditor::ParentOfLC( aParentNodeIdentifier ) );
       
  1051         node.InternalizeLinkL( 
       
  1052             aData, aParentNodeIdentifier, *grandParentIdentifier, aClientUid );
       
  1053         CleanupStack::PopAndDestroy( grandParentIdentifier );
       
  1054         }
       
  1055     else 
       
  1056         {
       
  1057         node.InternalizeLinkL( 
       
  1058             aData, aParentNodeIdentifier, aParentNodeIdentifier, aClientUid );
       
  1059         }
       
  1060 
       
  1061     // Metadata of the node may exists in cache at this point already, but it is not
       
  1062     // installed to the node, because otherwise the state of the node would be
       
  1063     // "initialized" and UI would not reload the metadata. This is a problem if
       
  1064     // user wants to force refresh level3 view.
       
  1065     
       
  1066     // Save the node now after it has been inserted into its parent.
       
  1067     // Because the node has been updated and contains at least new
       
  1068     // link data, we should save the new data to the database.
       
  1069     DLINFO(("Save node"));
       
  1070 
       
  1071     DbSaveNodeL( node );
       
  1072     DPROFILING_END( x );
       
  1073     DLTRACEOUT((""));
       
  1074     
       
  1075     return node;
       
  1076     }
       
  1077 
       
  1078 
       
  1079 CNcdNode& CNcdNodeManager::DataHandlerL( 
       
  1080     const CNcdNodeIdentifier& aParentNodeIdentifier,
       
  1081     MNcdPreminetProtocolDataEntity& aData,
       
  1082     const TUid& aClientUid )
       
  1083     {
       
  1084     DLTRACEIN((_L("parent ns: %S, id: %S, data ns: %S, id: %S, name: %S"), 
       
  1085                 &aParentNodeIdentifier.NodeNameSpace(), &aParentNodeIdentifier.NodeId(), 
       
  1086                 &aData.Namespace(), &aData.Id(),&aData.Name()));
       
  1087     DPROFILING_BEGIN( x );
       
  1088     // Create the metadata according to the entity information
       
  1089     
       
  1090     // Notice:
       
  1091     // The data entity namespace information is conditional accroding to the protocol. 
       
  1092     // But the parser should always set the correct namespace. The parent node namespace
       
  1093     // can not be used here because the parent may be in different namespace than
       
  1094     // the child. At least if the root is used.
       
  1095 
       
  1096     // Notice that if the parent is for example root,
       
  1097     // then the parent server uri is KNullDesC which is not the right server.
       
  1098     // Use the serveruri that is gotten from the aData interface object.
       
  1099     // Also, notice that aClientUid is used here. Because in some special cases,
       
  1100     // the parent node identifier may be empty.
       
  1101     CNcdNodeIdentifier* metaId = 
       
  1102         CNcdNodeIdentifier::NewLC( aData.Namespace(), 
       
  1103                                    aData.Id(), 
       
  1104                                    aData.ServerUri(),
       
  1105                                    aClientUid );
       
  1106 
       
  1107     // The node should always exist in the database if metadata exist.
       
  1108     CNcdNode& node( NodeL( aParentNodeIdentifier, *metaId ) );
       
  1109 
       
  1110 
       
  1111     DLINFO(("Create metadata"));
       
  1112     CNcdNodeFactory::TNcdNodeType metaType( CNcdNodeFactory::ENcdNodeItem );
       
  1113     if ( aData.Type() == EFolderEntity )
       
  1114         {
       
  1115         metaType = CNcdNodeFactory::ENcdNodeFolder;
       
  1116         }
       
  1117     else if ( aData.Type() != EItemEntity )
       
  1118         {
       
  1119         DLERROR(("Wrong entity type"));
       
  1120         DASSERT( EFalse );
       
  1121         User::Leave( KErrArgument );
       
  1122         }
       
  1123     
       
  1124     // Checks that the old metadata is of the right type if it already
       
  1125     // exists. If the types do not match, then the old metadata in 
       
  1126     // RAM cache is replaced by the new metadata object that is of the
       
  1127     // correct type. Notice, that the db is not updated by this function call.    
       
  1128     CNcdNodeMetaData& metaData( 
       
  1129         CheckAndCreateMetaDataL( *metaId, metaType ) );    
       
  1130     
       
  1131     CleanupStack::PopAndDestroy( metaId );
       
  1132 
       
  1133     DLINFO(("Internalize meta"));
       
  1134 
       
  1135     // Set all the data from the entity to the metadata itself
       
  1136     metaData.InternalizeL( aData );
       
  1137 
       
  1138     DLINFO(( "Set meta for the node"));
       
  1139 
       
  1140     // Insert the metadata information to the node. Metadata's timestamp
       
  1141     // is also updated to link in here
       
  1142     node.SetNodeMetaDataL( metaData );
       
  1143     
       
  1144     DLINFO(("Save meta to db"));        
       
  1145     
       
  1146     // Do not save the node here, because it already contains uptodate info
       
  1147     // or if it was just created, then nothing worth saving.
       
  1148     // Just save the metadata to the database,
       
  1149     // because it contains new info.
       
  1150     DbSaveNodeMetaDataL( metaData );
       
  1151     DPROFILING_END( x );
       
  1152     DLTRACEOUT((""));
       
  1153     
       
  1154     return node;
       
  1155     }
       
  1156 
       
  1157 
       
  1158 void CNcdNodeManager::PreviewHandlerL( const CNcdNodeIdentifier& aNodeIdentifier,
       
  1159                                        const TDesC& aFileName,
       
  1160                                        TInt aIndex,
       
  1161                                        const TDesC& aMimeType )
       
  1162     {
       
  1163     DLTRACEIN(("Check old meta from the cache"));
       
  1164     
       
  1165     CNcdNode& node( NodeL( aNodeIdentifier ) );    
       
  1166     CNcdNodeMetaData& metadata( node.NodeMetaDataL() );
       
  1167     CNcdNodePreview& preview( metadata.PreviewL() );
       
  1168 
       
  1169     iPreviewManager->AddPreviewL( metadata.Identifier(), 
       
  1170                                   preview.Uri( aIndex ), 
       
  1171                                   aFileName,
       
  1172                                   aMimeType );
       
  1173 
       
  1174     // Updates aMimeType to CNcdNodePreview if the MIME type
       
  1175     // was not received in protocol responses
       
  1176     preview.UpdateMimesFromPreviewManagerL();
       
  1177     
       
  1178     // Notice that the metadata does not need to be saved after this
       
  1179     // because the preview manager handles all the necessary info.
       
  1180     
       
  1181     DLTRACEOUT((""));
       
  1182     }
       
  1183 
       
  1184 
       
  1185 void CNcdNodeManager::PurchaseHandlerL( const CNcdNodeIdentifier& aNodeIdentifier )
       
  1186     {
       
  1187     DLTRACEIN(("Update installation information to the node"));
       
  1188     
       
  1189     CNcdNode& node( NodeL( aNodeIdentifier ) );
       
  1190     CNcdNodeMetaData& metadata( node.NodeMetaDataL() );
       
  1191 
       
  1192     CNcdPurchaseDetails* details = metadata.PurchaseDetailsLC();
       
  1193 
       
  1194     // Try to internalize URI content from purchase history
       
  1195     metadata.InternalizeUriContentL( *details );                    
       
  1196      
       
  1197     // Try to internalize node download from purchase history.
       
  1198     metadata.InternalizeDownloadL( *details );
       
  1199     
       
  1200     metadata.InternalizeInstallFromContentInfoL();
       
  1201     
       
  1202     // Try to internalize node install from purchase history
       
  1203     metadata.InternalizeInstallL( *details );    
       
  1204     
       
  1205     CleanupStack::PopAndDestroy( details );
       
  1206 
       
  1207 
       
  1208     // Notice that the metadata does not need to be saved after this
       
  1209     // because the purchase history contains all the necessary info.
       
  1210             
       
  1211     DLTRACEOUT((""));
       
  1212     }
       
  1213 
       
  1214 
       
  1215 void CNcdNodeManager::DownloadDataHandlerL( const CNcdNodeIdentifier& aNodeIdentifier )
       
  1216     {
       
  1217     DLTRACEIN((""));
       
  1218 
       
  1219     CNcdNode& node( NodeL( aNodeIdentifier ) );
       
  1220     CNcdNodeMetaData& metadata( node.NodeMetaDataL() );
       
  1221 
       
  1222 
       
  1223     CNcdPurchaseDetails* details = metadata.PurchaseDetailsLC();
       
  1224         
       
  1225     metadata.InternalizeDependencyL( *details );
       
  1226      
       
  1227     // Try to internalize node download from purchase history.
       
  1228     metadata.InternalizeDownloadL( *details );
       
  1229     
       
  1230     metadata.InternalizeInstallFromContentInfoL();
       
  1231     
       
  1232     // Try to internalize node install from purchase history
       
  1233     metadata.InternalizeInstallL( *details );    
       
  1234     
       
  1235     CleanupStack::PopAndDestroy( details );
       
  1236 
       
  1237     // Notice that the metadata does not need to be saved after this
       
  1238     // because the purchase history contains all the necessary info.
       
  1239             
       
  1240     DLTRACEOUT((""));
       
  1241     }
       
  1242 
       
  1243 
       
  1244 void CNcdNodeManager::InstallHandlerL( const CNcdNodeIdentifier& aNodeIdentifier )
       
  1245     {
       
  1246     DLTRACEIN(("Update installation information to the node"));
       
  1247     
       
  1248     CNcdNode& node( NodeL( aNodeIdentifier ) );
       
  1249     CNcdNodeMetaData& metadata( node.NodeMetaDataL() );
       
  1250         
       
  1251     CNcdPurchaseDetails* details = metadata.PurchaseDetailsLC();
       
  1252         
       
  1253     metadata.InternalizeDependencyL( *details );
       
  1254     
       
  1255     // Try to internalize node download from purchase history.
       
  1256     metadata.InternalizeDownloadL( *details );
       
  1257     
       
  1258     metadata.InternalizeInstallFromContentInfoL();
       
  1259     
       
  1260     // Try to internalize node install from purchase history
       
  1261     metadata.InternalizeInstallL( *details );    
       
  1262     
       
  1263     metadata.HandleContentUpgradeL();
       
  1264     
       
  1265     CleanupStack::PopAndDestroy( details );
       
  1266 
       
  1267     // Notice that the metadata does not need to be saved after this
       
  1268     // because the purchase history contains all the necessary info.
       
  1269             
       
  1270     DLTRACEOUT((""));
       
  1271     }
       
  1272 
       
  1273 
       
  1274 void CNcdNodeManager::SetNodeExpiredL(
       
  1275     const CNcdNodeIdentifier& aNodeIdentifier,
       
  1276     TBool aRecursive,
       
  1277     TBool aForceUpdate,
       
  1278     RPointerArray<CNcdExpiredNode>& aFoundNodes )
       
  1279     {
       
  1280     DLTRACEIN((""));
       
  1281 
       
  1282     CNcdNode* node( NULL );
       
  1283     TRAPD( err, node = &NodeL( aNodeIdentifier ) );
       
  1284     if ( err == KErrNotFound )
       
  1285         {
       
  1286         // No need to do anything if node was not found.
       
  1287         return;
       
  1288         }
       
  1289     else if ( err != KErrNone )
       
  1290         {
       
  1291         User::Leave( err );
       
  1292         }
       
  1293         
       
  1294     SetNodeExpiredL( *node, aRecursive, aForceUpdate, aFoundNodes );
       
  1295     DLTRACEOUT((""));
       
  1296     }
       
  1297 
       
  1298 void CNcdNodeManager::SetNodeExpiredL(
       
  1299     CNcdNode& aNode,
       
  1300     TBool aRecursive,
       
  1301     TBool aForceUpdate,
       
  1302     RPointerArray<CNcdExpiredNode>& aFoundNodes )
       
  1303     {
       
  1304     DLTRACEIN((""));
       
  1305     CNcdNodeLink& nodeLink = aNode.CreateAndSetLinkL();
       
  1306     nodeLink.SetValidUntilDelta( 0 );
       
  1307     DASSERT( nodeLink.IsExpired() );
       
  1308     DbSaveNodeL( aNode );
       
  1309     aFoundNodes.AppendL( CNcdExpiredNode::NewL( aNode.Identifier(), aForceUpdate ) );
       
  1310     
       
  1311     if ( aRecursive 
       
  1312          && ( aNode.ClassId() == NcdNodeClassIds::ENcdFolderNodeClassId
       
  1313               || aNode.ClassId() == NcdNodeClassIds::ENcdSearchFolderNodeClassId
       
  1314               || aNode.ClassId() == NcdNodeClassIds::ENcdRootNodeClassId
       
  1315               || aNode.ClassId() == NcdNodeClassIds::ENcdBundleFolderNodeClassId 
       
  1316               || aNode.ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId 
       
  1317               || aNode.ClassId() == NcdNodeClassIds::ENcdSearchBundleNodeClassId ) ) 
       
  1318         {
       
  1319         CNcdNodeFolder& folder = static_cast<CNcdNodeFolder&>( aNode );
       
  1320         const RPointerArray<CNcdChildEntity>& children = folder.ChildArray();
       
  1321         for ( TInt i = 0; i < children.Count(); i++ )
       
  1322             {
       
  1323             SetNodeExpiredL( children[i]->Identifier(), ETrue, aForceUpdate, aFoundNodes );
       
  1324             }
       
  1325         }
       
  1326     DLTRACEOUT((""));
       
  1327     }
       
  1328 
       
  1329 void CNcdNodeManager::SetNodesExpiredByMetadataL(
       
  1330     const MNcdPreminetProtocolExpiredCachedData& aData,
       
  1331     const TUid& aClientUid,
       
  1332     const TDesC& aNameSpace,
       
  1333     RPointerArray<CNcdExpiredNode>& aFoundNodes )
       
  1334     {
       
  1335     DLTRACEIN((""));
       
  1336     
       
  1337     RPointerArray<CNcdNodeIdentifier> identifiers;
       
  1338     CleanupResetAndDestroyPushL( identifiers );
       
  1339     CDesCArrayFlat* nameSpaces = new (ELeave) CDesCArrayFlat( KListGranularity );
       
  1340     CleanupStack::PushL( nameSpaces );
       
  1341     RArray<NcdNodeClassIds::TNcdNodeClassType> types;
       
  1342     CleanupClosePushL( types );
       
  1343     types.AppendL( NcdNodeClassIds::ENcdNode );
       
  1344     iDbManager->GetAllClientItemIdentifiersL( identifiers, aClientUid,
       
  1345         *nameSpaces, types );
       
  1346         
       
  1347     for ( TInt i = 0 ; i < identifiers.Count() ; i++ )
       
  1348         {
       
  1349         for ( TInt j = 0 ; j < aData.ExpiredEntityCount() ; j++ )
       
  1350             {
       
  1351             if ( NcdNodeIdentifierEditor::DoesMetaDataIdentifierMatchL(
       
  1352                 *identifiers[i],
       
  1353                 aData.ExpiredEntityL( j ).EntityId(),
       
  1354                 aNameSpace,
       
  1355                 aClientUid ) )
       
  1356                 {
       
  1357                 // need to create a temp identifier because identifiers
       
  1358                 // from db have encoded namespace
       
  1359                 CNcdNodeIdentifier* realIdentifier = CNcdNodeIdentifier::NewLC(
       
  1360                     aNameSpace,
       
  1361                     identifiers[i]->NodeId(),
       
  1362                     identifiers[i]->ClientUid() );
       
  1363                 SetNodeExpiredL( *realIdentifier,
       
  1364                     aData.ExpiredEntityL( j ).Recursive(),
       
  1365                     aData.ExpiredEntityL( j ).ForceUpdate(),
       
  1366                     aFoundNodes );
       
  1367                 CleanupStack::PopAndDestroy( realIdentifier );
       
  1368                 break;
       
  1369                 }
       
  1370             }
       
  1371         }
       
  1372         
       
  1373     CleanupStack::PopAndDestroy( &types );
       
  1374     CleanupStack::PopAndDestroy( nameSpaces );
       
  1375     CleanupStack::PopAndDestroy( &identifiers );
       
  1376     }
       
  1377 
       
  1378 
       
  1379 void CNcdNodeManager::RemoveNodeL( const CNcdNodeIdentifier& aParentIdentifier,
       
  1380                                    const CNcdNodeIdentifier& aNodeMetaDataIdentifier ) 
       
  1381     {
       
  1382     DLTRACEIN((""));
       
  1383     CNcdNodeIdentifier* identifier =
       
  1384         NcdNodeIdentifierEditor::CreateNodeIdentifierLC( aParentIdentifier,
       
  1385                                                          aNodeMetaDataIdentifier );
       
  1386     RemoveNodeL( *identifier );
       
  1387     CleanupStack::PopAndDestroy( identifier );
       
  1388     }
       
  1389 
       
  1390 void CNcdNodeManager::RemoveNodeL( const CNcdNodeIdentifier& aIdentifier ) 
       
  1391     {
       
  1392     DLTRACEIN((""));
       
  1393     CNcdNode* node = NodePtrL( aIdentifier );
       
  1394     if ( node == NULL ) 
       
  1395         {
       
  1396         DLINFO(("Node did not exist"));
       
  1397         return;
       
  1398         }
       
  1399             
       
  1400     CNcdNodeLink& nodeLink = node->CreateAndSetLinkL();
       
  1401     const CNcdNodeIdentifier& parentId = nodeLink.ParentIdentifier();
       
  1402     
       
  1403     CNcdNodeFolder* parentFolder = NULL;
       
  1404     // Parent node doesn't necessarily exists, eg. "floating" favorite nodes
       
  1405     // If the parent node identifier is empty, then FolderL will leave
       
  1406     // with KErrArgument
       
  1407     TRAPD( err, parentFolder = &FolderL( parentId ) );
       
  1408     LeaveIfNotErrorL( err, KErrNotFound, KErrArgument );
       
  1409     
       
  1410     NodeCacheCleanerManager().
       
  1411         CacheCleanerL( 
       
  1412             aIdentifier.ClientUid() ).
       
  1413                 AddCleanupIdentifierL( aIdentifier );
       
  1414     
       
  1415     if ( parentFolder ) 
       
  1416         {
       
  1417         DLTRACE(("Removing from parent"));
       
  1418         // NOTE: After next function aIdentifier may not be valid anymore as
       
  1419         // node owning it has been deleted.
       
  1420         parentFolder->RemoveChild( aIdentifier );
       
  1421         DbSaveNodeL( *parentFolder );
       
  1422         }
       
  1423     }
       
  1424     
       
  1425 
       
  1426 void CNcdNodeManager::ClearSearchResultsL( const MCatalogsContext& aContext )
       
  1427     {
       
  1428     DLTRACEIN((""));
       
  1429     
       
  1430     CNcdNodeFolder& searchRoot = CreateSearchRootL( aContext );
       
  1431     
       
  1432     // Maybe this should be recursive?
       
  1433     const RPointerArray<CNcdChildEntity>& children = searchRoot.ChildArray();
       
  1434     for (TInt i = 0 ; i < children.Count() ; i++ )
       
  1435         {
       
  1436         const CNcdNodeIdentifier& child = children[i]->Identifier();
       
  1437         CNcdNodeFolder* childFolder = NULL;
       
  1438         TRAPD(err, childFolder = &FolderL( child ) );
       
  1439         if( err == KErrNone )
       
  1440             {
       
  1441             childFolder->RemoveChildrenL();            
       
  1442             }
       
  1443         }
       
  1444     searchRoot.RemoveChildrenL();  
       
  1445          
       
  1446     }
       
  1447     
       
  1448     
       
  1449 void CNcdNodeManager::BackupAndClearCacheL(
       
  1450     const CNcdNodeIdentifier& aRootNode )
       
  1451     {
       
  1452     DLTRACEIN((_L("aRootNode ns: %S, id: %S"), &aRootNode.NodeNameSpace(), &aRootNode.NodeId()));
       
  1453 
       
  1454     CNcdNode* root = NodePtrL( aRootNode );
       
  1455    
       
  1456     // Remove children from the list of root node.
       
  1457     if ( root ) 
       
  1458         {
       
  1459         CNcdNodeFolder* rootFolder = static_cast<CNcdNodeFolder*>( root );
       
  1460         // Note that RemoveChildren() doesn't remove nodes from the database like
       
  1461         // RemoveChildrenL()        
       
  1462         rootFolder->RemoveChildren();
       
  1463         }    
       
  1464     
       
  1465     
       
  1466     // Move all the children of the root node ( recursively ).
       
  1467     for ( TInt i = iNodeCache.Count() - 1; i >= 0; i-- ) 
       
  1468         {
       
  1469         CNcdNode* node = iNodeCache[i];
       
  1470         if ( NcdNodeIdentifierEditor::ParentOf( aRootNode, node->Identifier() ) ) 
       
  1471             {
       
  1472 
       
  1473             if ( CNcdNodeFactory::NodeTypeL( *node ) == CNcdNodeFactory::ENcdNodeFolder )
       
  1474                 {
       
  1475                 DLTRACE(("Clearing child list"));
       
  1476                 
       
  1477                 CNcdNodeFolder* folder = static_cast<CNcdNodeFolder*>( node );
       
  1478                 // Do not use RemoveChildrenL method, since it saves the parent node to
       
  1479                 // db --> original child list is lost, reverting is impossible
       
  1480                 folder->RemoveChildren();
       
  1481                 }
       
  1482                 
       
  1483             User::LeaveIfError( InsertNodeInOrder( node, iTempNodeCache ) );
       
  1484             DLINFO((_L("Moved node: %S, %S"), &node->Identifier().NodeNameSpace(), &node->Identifier().NodeId() ));                
       
  1485             iNodeCache.Remove( i );
       
  1486             }
       
  1487         }          
       
  1488         
       
  1489     }
       
  1490 
       
  1491     
       
  1492 void CNcdNodeManager::RevertNodeCacheL(
       
  1493     const CNcdNodeIdentifier& aRootNode ) 
       
  1494     {
       
  1495     DLTRACEIN((""));
       
  1496     
       
  1497     RPointerArray<CNcdNode> schemeNodes;
       
  1498     
       
  1499     // Remove all the children of the given root from the main cache.
       
  1500     for ( TInt i = iNodeCache.Count() - 1; i >= 0; i-- ) 
       
  1501         {
       
  1502         CNcdNode* node = iNodeCache[i];
       
  1503         if ( NcdNodeIdentifierEditor::ParentOf( aRootNode, node->Identifier() ) ) 
       
  1504             {
       
  1505             node->Close();
       
  1506             iNodeCache.Remove( i );
       
  1507             }
       
  1508         }
       
  1509         
       
  1510     // Move the nodes from temp cache to main RAM cache
       
  1511     for ( TInt i = iTempNodeCache.Count() - 1; i >= 0; i-- ) 
       
  1512         {
       
  1513         CNcdNode* node = iTempNodeCache[i];
       
  1514         if ( NcdNodeIdentifierEditor::ParentOf( aRootNode, node->Identifier() ) ) 
       
  1515             {
       
  1516             User::LeaveIfError( InsertNodeInOrder( node, iNodeCache ) );
       
  1517             iTempNodeCache.Remove( i );
       
  1518             }
       
  1519         }
       
  1520         
       
  1521     // Internalize the root and its children from database to get correct child lists.
       
  1522     for ( TInt i = 0; i < iNodeCache.Count(); i++ ) 
       
  1523         {
       
  1524         CNcdNode* node = iNodeCache[ i ];
       
  1525         if ( NcdNodeIdentifierEditor::ParentOf( aRootNode, node->Identifier() ) ||
       
  1526              node->Identifier().Equals( aRootNode ) ) 
       
  1527             {
       
  1528             HBufC8* data( 
       
  1529                 NodeDbManager().ReadDataFromDatabaseLC(
       
  1530                     node->Identifier(), NcdNodeClassIds::ENcdNode ) );
       
  1531             if ( data != NULL && data->Length() > 0 ) 
       
  1532                 {
       
  1533                 NodeFactory().InternalizeNodeL( *node, *data );
       
  1534                 }
       
  1535             else 
       
  1536                 {
       
  1537                 // Data was not in database, clear the child list.
       
  1538                 CNcdNodeFactory::TNcdNodeType nodeType = CNcdNodeFactory::NodeTypeL( *node );
       
  1539                 if ( nodeType == CNcdNodeFactory::ENcdNodeFolder || 
       
  1540                      nodeType == CNcdNodeFactory::ENcdNodeRoot ) 
       
  1541                     {
       
  1542                     CNcdNodeFolder* folder = static_cast<CNcdNodeFolder*>( node );
       
  1543                     folder->RemoveChildrenL();
       
  1544                     }                                
       
  1545                 }
       
  1546             CleanupStack::PopAndDestroy( data );
       
  1547             }
       
  1548         }
       
  1549     }        
       
  1550 
       
  1551 void CNcdNodeManager::RevertNodeFromTempCacheL( const CNcdNodeIdentifier& aNodeIdentifier ) 
       
  1552     {
       
  1553     DLTRACEIN((""));
       
  1554     // Find the node from temp cache
       
  1555     TInt index = FindNodeFromArray( aNodeIdentifier, iTempNodeCache );
       
  1556     
       
  1557     if ( index != KErrNotFound ) 
       
  1558         {
       
  1559         CNcdNode* nodeFromMainCache = FindNodeFromMainCache( aNodeIdentifier );
       
  1560         if ( nodeFromMainCache ) 
       
  1561             {
       
  1562             DASSERT( nodeFromMainCache == iTempNodeCache[ index ] );
       
  1563             DLINFO(("No need to revert, the node was in main cache already"));            
       
  1564             iTempNodeCache[ index ]->Close();
       
  1565             }
       
  1566         else 
       
  1567             {            
       
  1568             User::LeaveIfError( InsertNodeInOrder( iTempNodeCache[ index ], iNodeCache ) );            
       
  1569             }
       
  1570             
       
  1571         iTempNodeCache.Remove( index );
       
  1572         }
       
  1573     }
       
  1574     
       
  1575 void CNcdNodeManager::ClearTempCacheL( const CNcdNodeIdentifier& aRootNode ) 
       
  1576     {
       
  1577     DLTRACEIN((""));
       
  1578     for ( TInt i = iTempNodeCache.Count() - 1; i >= 0; i-- ) 
       
  1579         {
       
  1580         CNcdNode* node = iTempNodeCache[i];
       
  1581         if ( NcdNodeIdentifierEditor::ParentOf( aRootNode, node->Identifier() ) ) 
       
  1582             {
       
  1583             
       
  1584             // Also remove from db if not present in main cache.
       
  1585             if ( FindNodeFromMainCache( node->Identifier() ) == NULL ) 
       
  1586                 {
       
  1587                 RemoveNodeL( node->Identifier() );
       
  1588                 }
       
  1589                 
       
  1590             iTempNodeCache.Remove( i );
       
  1591             node->Close();
       
  1592             }
       
  1593         }
       
  1594     }
       
  1595 
       
  1596 // ---------------------------------------------------------------------------
       
  1597 // Cache cleanup functions.
       
  1598 // These functions are called by the node objects when
       
  1599 // they are released by the corresponding proxy object.
       
  1600 // ---------------------------------------------------------------------------
       
  1601 
       
  1602 void CNcdNodeManager::NodeReleased( CNcdNode& aNode )
       
  1603     {
       
  1604     if ( aNode.AccessCount() == 1 )
       
  1605         {
       
  1606         // We need to release the node immediately if its metadata needs to be
       
  1607         // released as soon as possible
       
  1608         CNcdNodeMetaData* metadata = aNode.NodeMetaData();
       
  1609         if ( metadata && 
       
  1610              metadata->DeleteSoon() )
       
  1611             {
       
  1612             DLTRACE(( _L("Remove node from cache: %S"), 
       
  1613                 &aNode.Identifier().NodeId() ));
       
  1614             
       
  1615             if ( iClientDatabaseLocks.Find(
       
  1616                 aNode.Identifier().ClientUid().iUid ) == KErrNotFound )
       
  1617                 {                
       
  1618                 // Because this node will not be in the cache anymore, we can remove
       
  1619                 // it from the block list of the cleaner if it exists there. 
       
  1620                 TRAP_IGNORE(
       
  1621                     NodeCacheCleanerManager().
       
  1622                         CacheCleanerL( aNode.Identifier().ClientUid() ).
       
  1623                             RemoveDoNotRemoveIdentifierL( aNode.Identifier() ) );        
       
  1624                 }
       
  1625                 
       
  1626             TInt index = iNodeCache.Find( &aNode );
       
  1627             if ( index != KErrNotFound ) 
       
  1628                 {                
       
  1629                 // Remove unreferenced node from the cache and destroy it.
       
  1630                 iNodeCache.Remove( index );
       
  1631                 }
       
  1632             
       
  1633             aNode.Close();
       
  1634             
       
  1635             // Ensure that metadata is released if possible
       
  1636             MetaDataReleased( *metadata );
       
  1637             }
       
  1638             
       
  1639         // Node is ready for closing.
       
  1640         NodeCacheCleanup();
       
  1641         }
       
  1642     }
       
  1643     
       
  1644     
       
  1645 void CNcdNodeManager::MetaDataReleased( CNcdNodeMetaData& aMetaData )
       
  1646     {
       
  1647     DLTRACEIN((""));
       
  1648     if ( aMetaData.AccessCount() == 1 )
       
  1649         {
       
  1650         if ( aMetaData.DeleteSoon() && !IsMetadataUsed( &aMetaData ) ) 
       
  1651             {            
       
  1652             DLTRACE(("Metadata wants to be released as soon as possible"));
       
  1653             TInt index = iNodeMetaDataCache.Find( &aMetaData );
       
  1654             DASSERT( index != KErrNotFound );
       
  1655             aMetaData.Close();            
       
  1656 
       
  1657             iNodeMetaDataCache.Remove( index );            
       
  1658             }
       
  1659             
       
  1660         // Metadata is ready for closing.
       
  1661         MetaDataCacheCleanup();
       
  1662         }
       
  1663     }
       
  1664 
       
  1665 
       
  1666 void CNcdNodeManager::ClearClientCacheL( 
       
  1667     const MCatalogsContext& aContext,
       
  1668     TBool aClearDownloads )
       
  1669     {    
       
  1670     DLTRACEIN(("Clearing previews"));        
       
  1671     
       
  1672     TRAP_IGNORE( iPreviewManager->RemoveAllPreviewsL() );
       
  1673         
       
  1674     DLTRACE(("Close cached objects"));
       
  1675     FullCacheCleanup();
       
  1676         
       
  1677     DLTRACE(("Clearing nodes and icons"));
       
  1678     
       
  1679     // Clear namespaces that contain favorites so that favorites are
       
  1680     // left intact. Also checks that favorite nodes can be loaded from db
       
  1681     TRAPD( err, ClearNamespacesWithFavoritesL( aContext.FamilyId() ) );
       
  1682             
       
  1683     // Now clear rest of the namespaces (except subscriptions)
       
  1684     // Favorites are deleted if they are corrupted
       
  1685     ClearClientNamespacesL( 
       
  1686         aContext.FamilyId(), 
       
  1687         err != KErrNone, 
       
  1688         aClearDownloads );
       
  1689     
       
  1690     // Clear seen info.
       
  1691     iSeenInfo->ClearInfoL( aContext.FamilyId() );
       
  1692     
       
  1693     // Unset previously loaded flag to prevent all children from being interpreted
       
  1694     // as new on next refresh.
       
  1695     CreateRootL( aContext.FamilyId() ).SetChildrenPreviouslyLoaded( EFalse );
       
  1696     
       
  1697     DLTRACEOUT(("All cleared"));
       
  1698     }
       
  1699 
       
  1700 
       
  1701 void CNcdNodeManager::ClearClientNamespacesL( 
       
  1702     const TUid& aClientUid, 
       
  1703     TBool aClearFavorites,
       
  1704     TBool aClearDownloads )
       
  1705     {
       
  1706     DLTRACEIN((""));
       
  1707     // Insert the subscription namespace into the skip array. Because
       
  1708     // subscriptions should not be deleted from the db.
       
  1709     CPtrCArray* doNotCleanNameSpaces = 
       
  1710         new(ELeave) CPtrCArray( KListGranularity );
       
  1711     CleanupStack::PushL( doNotCleanNameSpaces );
       
  1712     
       
  1713     doNotCleanNameSpaces->AppendL( 
       
  1714         NcdProviderDefines::KSubscriptionNamespace() );
       
  1715     
       
  1716     doNotCleanNameSpaces->AppendL(
       
  1717         NcdProviderDefines::KProviderStorageNamespace() );
       
  1718     
       
  1719     if ( !aClearDownloads )
       
  1720         {
       
  1721         DLTRACE(("Do not delete downloads"));
       
  1722         doNotCleanNameSpaces->AppendL( 
       
  1723             NcdProviderDefines::KDownloadNamespace() );
       
  1724         
       
  1725         doNotCleanNameSpaces->AppendL( 
       
  1726             NcdProviderDefines::KDataNamespace() );
       
  1727         }
       
  1728     
       
  1729     if ( !aClearFavorites ) 
       
  1730         {        
       
  1731         // Insert the namespaces from which nodes are in 
       
  1732         // favorites list to skip list.
       
  1733         const RPointerArray<CNcdNodeIdentifier>& favorites = 
       
  1734             iFavoriteManager->FavoriteNodesL( aClientUid );
       
  1735         TInt favoriteCount = favorites.Count();
       
  1736         TInt count = 0;
       
  1737         for ( TInt i = 0; i < favoriteCount; i++ ) 
       
  1738             {
       
  1739             const TDesC& nameSpace = favorites[ i ]->NodeNameSpace();
       
  1740             
       
  1741             count = doNotCleanNameSpaces->MdcaCount();
       
  1742             while( count-- ) 
       
  1743                 {
       
  1744                 if ( doNotCleanNameSpaces->MdcaPoint( count ) != nameSpace ) 
       
  1745                     {
       
  1746                     doNotCleanNameSpaces->AppendL( nameSpace );
       
  1747                     break;
       
  1748                     }
       
  1749                 }
       
  1750             }        
       
  1751         }
       
  1752     else // favorites need to be removed from the favorite manager too
       
  1753         {        
       
  1754         iFavoriteManager->RemoveFavoritesL( aClientUid );
       
  1755         }
       
  1756 
       
  1757     NodeDbManager().ClearClientL( aClientUid, *doNotCleanNameSpaces );
       
  1758     CleanupStack::PopAndDestroy( doNotCleanNameSpaces );    
       
  1759     }
       
  1760 
       
  1761 
       
  1762 void CNcdNodeManager::ClearNamespacesWithFavoritesL( const TUid& aClientUid ) 
       
  1763     {
       
  1764     DLTRACEIN((""));
       
  1765     const RPointerArray<CNcdNodeIdentifier>& favorites( 
       
  1766         iFavoriteManager->FavoriteNodesL( aClientUid ) );
       
  1767     
       
  1768     if ( !favorites.Count() ) 
       
  1769         {
       
  1770         DLTRACEOUT(("No favorites so nothing to do"));
       
  1771         return;
       
  1772         }
       
  1773         
       
  1774     // order by uid & namespace
       
  1775     TLinearOrder<CNcdNodeIdentifier> sort( 
       
  1776         CNcdNodeIdentifier::CompareOrderByUid );
       
  1777     RPointerArray<CNcdNodeIdentifier> sortedArray;
       
  1778     
       
  1779     // array won't own the identifiers so just close
       
  1780     CleanupClosePushL( sortedArray );
       
  1781     sortedArray.ReserveL( favorites.Count() );
       
  1782         
       
  1783     TInt count = favorites.Count();
       
  1784     DLTRACE(("Sorting %d favorites", count));
       
  1785     while ( count-- ) 
       
  1786         {
       
  1787         sortedArray.InsertInOrderL( favorites[ count ], sort );
       
  1788         }
       
  1789     
       
  1790     count = sortedArray.Count();
       
  1791     TInt index = 0;
       
  1792     // iterate through favorites one namespace at a time
       
  1793     while ( index < count )
       
  1794         {        
       
  1795         index = ClearNamespaceL( sortedArray, index );
       
  1796         }    
       
  1797     
       
  1798     CleanupStack::PopAndDestroy( &sortedArray );    
       
  1799     
       
  1800     DLTRACEOUT((""));
       
  1801     }
       
  1802     
       
  1803 
       
  1804 TInt CNcdNodeManager::ClearNamespaceL( 
       
  1805     const RPointerArray<CNcdNodeIdentifier>& aSortedArray, 
       
  1806     TInt aIndex )
       
  1807     {
       
  1808     DLTRACEIN((""));
       
  1809     TPtrC currentNamespace( aSortedArray[ aIndex ]->NodeNameSpace() );
       
  1810 
       
  1811     // Array for metadata id's that must not be removed
       
  1812     CDesCArrayFlat* doNotRemoveMetadataArray = 
       
  1813         new( ELeave ) CDesCArrayFlat( KListGranularity );
       
  1814         
       
  1815     // owns the array
       
  1816     RNcdDatabaseItems unremovableMetadata(         
       
  1817         KErrNotFound, // ignores type so all types that match the id are left
       
  1818         doNotRemoveMetadataArray );
       
  1819     CleanupClosePushL( unremovableMetadata );
       
  1820 
       
  1821     // Array for node id's that must not be removed
       
  1822     CPtrCArray* doNotRemoveArray = 
       
  1823         new( ELeave ) CPtrCArray( KListGranularity );
       
  1824 
       
  1825     // owns the array
       
  1826     RNcdDatabaseItems unremovableItem( 
       
  1827         NcdNodeClassIds::ENcdNode,
       
  1828         doNotRemoveArray );
       
  1829     
       
  1830     CleanupClosePushL( unremovableItem );
       
  1831 
       
  1832     // Array for icon id's that must not be removed
       
  1833     CDesCArrayFlat* doNotRemoveIconArray = 
       
  1834         new( ELeave ) CDesCArrayFlat( KListGranularity );
       
  1835 
       
  1836     // owns the array
       
  1837     RNcdDatabaseItems unremovableIcon( 
       
  1838         NcdNodeClassIds::ENcdIconData,
       
  1839         doNotRemoveIconArray );
       
  1840     
       
  1841     CleanupClosePushL( unremovableIcon );
       
  1842 
       
  1843     TInt pos = 0; // needed for CDesCArray::Find
       
  1844     TInt err = KErrNone;            
       
  1845     
       
  1846     TInt index = aIndex; 
       
  1847     TInt count = aSortedArray.Count();
       
  1848     // Generate array of id's that must not be removed from current namespace    
       
  1849     while( index < count && 
       
  1850            aSortedArray[ index ]->NodeNameSpace() == currentNamespace )          
       
  1851         {
       
  1852         doNotRemoveArray->AppendL( aSortedArray[ index ]->NodeId() );                              
       
  1853 
       
  1854         CNcdNodeIdentifier* metaId = 
       
  1855             NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( 
       
  1856                 *aSortedArray[ index ] );
       
  1857     
       
  1858         if ( doNotRemoveMetadataArray->Find( 
       
  1859                 metaId->NodeId(), pos, ECmpNormal ) )
       
  1860             {            
       
  1861             doNotRemoveMetadataArray->AppendL( metaId->NodeId() );
       
  1862             
       
  1863             const CNcdNodeMetaData* metadata( NULL );
       
  1864             TRAP( err, metadata = &NodeMetaDataL( *metaId ) );
       
  1865             LeaveIfNotErrorL( err, KErrNotFound );
       
  1866         
       
  1867             if ( metadata ) 
       
  1868                 {                                                                       
       
  1869                 // Icons are checked only when new metadata is added
       
  1870                 // IconL leaves only with KErrNotFound
       
  1871                 CNcdNodeIcon* icon( NULL );
       
  1872                 TRAP_IGNORE( icon = &metadata->IconL() );
       
  1873                 
       
  1874                 if ( icon && 
       
  1875                      doNotRemoveIconArray->Find( 
       
  1876                         icon->IconId(), pos, ECmpNormal ) ) 
       
  1877                     {
       
  1878                     DLTRACE(("Adding icon id to do not remove list"));
       
  1879                     doNotRemoveIconArray->AppendL( icon->IconId() );
       
  1880                     }
       
  1881 
       
  1882                 // close the opened metadata    
       
  1883                 CloseMetadatas();
       
  1884                 }
       
  1885             }
       
  1886         CleanupStack::PopAndDestroy( metaId );          
       
  1887         ++index;  
       
  1888         }
       
  1889 
       
  1890     RArray<RNcdDatabaseItems> items;
       
  1891     CleanupClosePushL( items );
       
  1892     
       
  1893     // note: ownership is not transferred
       
  1894     items.AppendL( unremovableItem );
       
  1895     items.AppendL( unremovableMetadata );
       
  1896     items.AppendL( unremovableIcon );
       
  1897     
       
  1898     DLTRACE(("Removing from database"));
       
  1899     // commits and compacts data     
       
  1900     NodeDbManager().RemoveDataFromDatabaseL( 
       
  1901         *aSortedArray[ index - 1 ], items );
       
  1902             
       
  1903     CleanupStack::PopAndDestroy( &items );
       
  1904     CleanupStack::PopAndDestroy( &unremovableIcon );
       
  1905     CleanupStack::PopAndDestroy( &unremovableItem );
       
  1906     CleanupStack::PopAndDestroy( &unremovableMetadata );    
       
  1907     
       
  1908     CheckNodesL( aSortedArray, aIndex, index );
       
  1909     return index;
       
  1910     }
       
  1911 
       
  1912 
       
  1913 void CNcdNodeManager::CheckNodesL( 
       
  1914     const RPointerArray<CNcdNodeIdentifier>& aNodeIds,
       
  1915     TInt aStart,
       
  1916     TInt aEnd )
       
  1917     {
       
  1918     DLTRACEIN(("aStart: %d, aEnd: %d", aStart, aEnd ));
       
  1919     for ( ; aStart < aEnd; ++aStart ) 
       
  1920         {        
       
  1921         CNcdNode& node = NodeL( *aNodeIds[ aStart ] );
       
  1922         node.NodeMetaDataL();
       
  1923         FullCacheCleanup();
       
  1924         }
       
  1925     }
       
  1926 
       
  1927 // ---------------------------------------------------------------------------
       
  1928 // Db functions that are needed from other class objects.
       
  1929 // The db functions are provided here instead of directly providing
       
  1930 // db manager because node manager may want to do some additional checking
       
  1931 // before db actions are allowed.
       
  1932 // ---------------------------------------------------------------------------
       
  1933 
       
  1934 
       
  1935 void CNcdNodeManager::DbRemoveNodeL( const CNcdNodeIdentifier& aIdentifier )
       
  1936     {
       
  1937     if ( iClientDatabaseLocks.Find( aIdentifier.ClientUid().iUid ) == KErrNotFound ) 
       
  1938         {        
       
  1939         NodeDbManager().RemoveDataFromDatabaseL( aIdentifier,
       
  1940                                                  NcdNodeClassIds::ENcdNode );
       
  1941         }
       
  1942     }
       
  1943 
       
  1944 
       
  1945 void CNcdNodeManager::DbSaveUserDataL( const CNcdNodeIdentifier& aUserDataIdentifier,
       
  1946                                        MNcdStorageDataItem& aDataItem )
       
  1947     {
       
  1948     NodeDbManager().SaveDataIntoDatabaseL( aUserDataIdentifier,
       
  1949                                            aDataItem,
       
  1950                                            NcdNodeClassIds::ENcdNodeUserData );    
       
  1951     }
       
  1952 
       
  1953     
       
  1954 void CNcdNodeManager::DbRemoveUserDataL( const CNcdNodeIdentifier& aUserDataIdentifier )
       
  1955     {
       
  1956     NodeDbManager().RemoveDataFromDatabaseL( aUserDataIdentifier,
       
  1957                                              NcdNodeClassIds::ENcdNodeUserData );     
       
  1958     }
       
  1959 
       
  1960     
       
  1961 void CNcdNodeManager::DbLoadUserDataL( const CNcdNodeIdentifier& aUserDataIdentifier,
       
  1962                                        MNcdStorageDataItem& aDataItem )
       
  1963     {
       
  1964     NodeDbManager().StartStorageLoadActionL( aUserDataIdentifier,
       
  1965                                              aDataItem,
       
  1966                                              NcdNodeClassIds::ENcdNodeUserData );
       
  1967     }
       
  1968 
       
  1969 
       
  1970 HBufC8* CNcdNodeManager::DbScreenshotDataLC( const CNcdNodeIdentifier& aScreenshotIdentifier )
       
  1971     {
       
  1972      return NodeDbManager().ReadDataFromDatabaseLC( aScreenshotIdentifier,
       
  1973                                                     NcdNodeClassIds::ENcdScreenshotData );     
       
  1974     }
       
  1975 
       
  1976 
       
  1977 HBufC8* CNcdNodeManager::DbIconDataLC( const CNcdNodeIdentifier& aIconIdentifier )
       
  1978     {
       
  1979     DLTRACEIN((""));
       
  1980      return NodeDbManager().ReadDataFromDatabaseLC( aIconIdentifier,
       
  1981                                                     NcdNodeClassIds::ENcdIconData );     
       
  1982     }
       
  1983 
       
  1984 
       
  1985 void CNcdNodeManager::DbSaveIconDataL( const CNcdNodeIdentifier& aIconIdentifier, 
       
  1986                                        const TDesC8& aIconData )
       
  1987     {
       
  1988     DLTRACEIN((""));
       
  1989     CNcdStorageDescriptorDataItem* iconDataItem = 
       
  1990         CNcdStorageDescriptorDataItem::NewLC( aIconData );
       
  1991     NodeDbManager().SaveDataIntoDatabaseL( aIconIdentifier, 
       
  1992                                            *iconDataItem,
       
  1993                                            NcdNodeClassIds::ENcdIconData );
       
  1994     CleanupStack::PopAndDestroy( iconDataItem );
       
  1995 
       
  1996     // Because node data was saved into the db. Check if the max size has
       
  1997     // been exceeded.
       
  1998     // This is propably good place to do checking because icons are one of
       
  1999     // the biggest datablobs that are saved into the db.
       
  2000     NodeCacheCleanerManager().
       
  2001         CacheCleanerL( aIconIdentifier.ClientUid() ).CheckDbSizeL();
       
  2002     DLTRACEOUT(("Data saved successfully"));
       
  2003     }
       
  2004 
       
  2005 
       
  2006 
       
  2007 // ---------------------------------------------------------------------------
       
  2008 // General tool functions
       
  2009 // ---------------------------------------------------------------------------
       
  2010 
       
  2011 void CNcdNodeManager::AddToParentL( const CNcdNodeIdentifier& aParentNodeIdentifier,
       
  2012                                     const CNcdNodeIdentifier& aChildNodeMetaDataIdentifier,
       
  2013                                     CNcdNodeFactory::TNcdNodeType aParentNodeType,
       
  2014                                     CNcdNodeFactory::TNcdNodePurpose aParentNodePurpose,
       
  2015                                     CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
  2016                                     TNcdRefHandleMode aMode,
       
  2017                                     TInt aIndex,
       
  2018                                     TBool aTransparent )
       
  2019     {
       
  2020     DLTRACEIN(( _L("Child: %S::%S Parent %S::%S"),
       
  2021               &aChildNodeMetaDataIdentifier.NodeNameSpace(), 
       
  2022               &aChildNodeMetaDataIdentifier.NodeId(), 
       
  2023               &aParentNodeIdentifier.NodeNameSpace(), 
       
  2024               &aParentNodeIdentifier.NodeId() ));
       
  2025     DLINFO(("Node purpose: %d", aNodePurpose));
       
  2026     DPROFILING_BEGIN( x );    
       
  2027     
       
  2028     if ( aParentNodeIdentifier.ContainsEmptyFields() )
       
  2029         {
       
  2030         // In some situations the parent may be empty. For example when temporary
       
  2031         // nodes are used. Because we do not create nodes with empty identifiers,
       
  2032         // we do not try to add the child to one either here. 
       
  2033         DLINFO(("Empty parent. Do not add child."));
       
  2034         return;
       
  2035         }
       
  2036 
       
  2037     if ( aParentNodeType != CNcdNodeFactory::ENcdNodeRoot
       
  2038          && aParentNodeType != CNcdNodeFactory::ENcdNodeFolder
       
  2039          && aParentNodeType != CNcdNodeFactory::ENcdNodeSearchBundle )
       
  2040         {
       
  2041         DLERROR(("Only root or folder can be a parent!"));
       
  2042         DASSERT( EFalse );
       
  2043         User::Leave( KErrArgument );
       
  2044         }
       
  2045         
       
  2046     DLINFO(("Parent node purpose: %d", aParentNodePurpose));
       
  2047     CNcdNodeFolder& folder( 
       
  2048         static_cast<CNcdNodeFolder&>( 
       
  2049             CheckAndCreateNodeL( aParentNodeType, 
       
  2050                                  aParentNodePurpose,
       
  2051                                  aParentNodeIdentifier ) ) );
       
  2052 
       
  2053     TBool childAdded = EFalse;
       
  2054     
       
  2055     CNcdNodeIdentifier* childIdentifier =
       
  2056         NcdNodeIdentifierEditor::CreateNodeIdentifierLC( aParentNodeIdentifier,
       
  2057                                                          aChildNodeMetaDataIdentifier );
       
  2058 
       
  2059     DASSERT( childIdentifier != NULL );    
       
  2060     
       
  2061     // Ensure that transparent nodes are set as transparent
       
  2062     aTransparent = aTransparent || 
       
  2063                  ( aNodePurpose == CNcdNodeFactory::ENcdTransparentNode ); 
       
  2064                  
       
  2065     CNcdNode* child = NodePtrL( *childIdentifier );          
       
  2066     DASSERT( child != NULL );
       
  2067     CNcdNodeFactory::TNcdNodeType nodeType = CNcdNodeFactory::NodeTypeL( *child );
       
  2068     
       
  2069     if( aMode == EInsert )
       
  2070         {
       
  2071         childAdded = folder.InsertChildL( *childIdentifier, aIndex,
       
  2072             aTransparent, nodeType );
       
  2073         }
       
  2074     else if ( aMode == EReplace )
       
  2075         {
       
  2076         childAdded = folder.ReplaceChildL( *childIdentifier, aIndex,
       
  2077             aTransparent, nodeType );
       
  2078         }
       
  2079     else if ( aMode == EAppend )
       
  2080         {
       
  2081         childAdded = folder.AppendChildL( *childIdentifier, aTransparent,
       
  2082             nodeType );
       
  2083         }
       
  2084     else 
       
  2085         {
       
  2086         DASSERT( aMode == EUpdate );
       
  2087         // Notice that here we do not set the childAdded value.
       
  2088         // So, the parent node will not be saved below.
       
  2089         // For example, when scheme nodes are loaded, they will be loaded by using the
       
  2090         // EUpdate value, which means that the root node will not be saved into the
       
  2091         // database and the scheme information is contained in root node only while
       
  2092         // the root node is in RAM. 
       
  2093         }
       
  2094 
       
  2095     if( childAdded )
       
  2096         {
       
  2097         DLINFO(( _L("Updating child: %S::%S to parent %S::%S in db"),
       
  2098                   &childIdentifier->NodeNameSpace(), 
       
  2099                   &childIdentifier->NodeId(), 
       
  2100                   &aParentNodeIdentifier.NodeNameSpace(), 
       
  2101                   &aParentNodeIdentifier.NodeId() ));       
       
  2102 
       
  2103         // Notice, that the RefHandler should Internalize the link after this operation
       
  2104         // because the transparent folder children should have the different parent set for
       
  2105         // requests than just the real parent.
       
  2106         child->CreateAndSetLinkL().SetParentIdentifierL( aParentNodeIdentifier );
       
  2107         
       
  2108         
       
  2109         // Check new status.
       
  2110         iSeenInfo->CheckChildNewStatusL( folder, aIndex );
       
  2111         
       
  2112         // The child was added to the list because it did not exist there before.
       
  2113         // This is reason enought to save the node the db. So, it is upto date.
       
  2114         DbSaveNodeL( folder );
       
  2115         DLINFO(("Parent updated"));
       
  2116         }
       
  2117 
       
  2118     CleanupStack::PopAndDestroy( childIdentifier );
       
  2119     DPROFILING_END( x );        
       
  2120     DLTRACEOUT((""));
       
  2121     }
       
  2122 
       
  2123 
       
  2124 
       
  2125 // ---------------------------------------------------------------------------
       
  2126 // CCatalogsCommunicable
       
  2127 // ---------------------------------------------------------------------------
       
  2128 
       
  2129 void CNcdNodeManager::ReceiveMessage( MCatalogsBaseMessage* aMessage,
       
  2130                                       TInt aFunctionNumber )
       
  2131     {
       
  2132     DLTRACEIN((""));
       
  2133 
       
  2134     DASSERT( aMessage );
       
  2135     
       
  2136     // Now, we can be sure that rest of the time iMessage exists.
       
  2137     // This member variable is set for the CounterPartLost function.
       
  2138     iMessage = aMessage;
       
  2139         
       
  2140     TInt trapError( KErrNone );
       
  2141         
       
  2142     switch( aFunctionNumber )
       
  2143         {           
       
  2144         case NcdNodeFunctionIds::ENcdRootNodeHandle:
       
  2145             DLINFO(("Getting root node"));
       
  2146             TRAP( trapError, RootNodeRequestL( *aMessage ) );
       
  2147             break;
       
  2148             
       
  2149         case NcdNodeFunctionIds::ENcdSearchRootNodeHandle:
       
  2150             DLINFO(("Getting search root node"));
       
  2151             TRAP( trapError, SearchRootNodeRequestL( *aMessage ) );
       
  2152             break;
       
  2153             
       
  2154         case NcdNodeFunctionIds::ENcdNodeHandle:
       
  2155             DLINFO(("Getting node"));
       
  2156             TRAP( trapError, NodeRequestL( *aMessage ) );
       
  2157             break;
       
  2158 
       
  2159         case NcdNodeFunctionIds::ENcdTemporaryNodeFolderHandle:
       
  2160             DLINFO(("Getting node"));
       
  2161             TRAP( trapError, TemporaryNodeRequestL( *aMessage, ENcdTemporaryNodeFolder, EFalse ) );
       
  2162             break;
       
  2163 
       
  2164         case NcdNodeFunctionIds::ENcdTemporaryNodeFolderWithMetaDataHandle:
       
  2165             DLINFO(("Getting node"));
       
  2166             TRAP( trapError, TemporaryNodeRequestL( *aMessage, ENcdTemporaryNodeFolder, ETrue ) );
       
  2167             break;
       
  2168 
       
  2169         case NcdNodeFunctionIds::ENcdTemporaryNodeItemHandle:
       
  2170             DLINFO(("Getting node"));
       
  2171             TRAP( trapError, TemporaryNodeRequestL( *aMessage, ENcdTemporaryNodeItem, EFalse ) );
       
  2172             break;
       
  2173             
       
  2174         case NcdNodeFunctionIds::ENcdTemporaryNodeItemWithMetaDataHandle:
       
  2175             DLINFO(("Getting node"));
       
  2176             TRAP( trapError, TemporaryNodeRequestL( *aMessage, ENcdTemporaryNodeItem, ETrue ) );
       
  2177             break;
       
  2178 
       
  2179         case NcdNodeFunctionIds::ENcdTemporaryBundleFolderHandle:
       
  2180             DLINFO(("Getting bundle folder"));
       
  2181             TRAP( trapError, TemporaryNodeRequestL( *aMessage, ENcdTemporaryBundleFolder, EFalse ) );
       
  2182             break;
       
  2183             
       
  2184         case NcdNodeFunctionIds::ENcdTemporaryBundleFolderWithMetaDataHandle:
       
  2185             DLINFO(("Getting bundle folder"));
       
  2186             TRAP( trapError, TemporaryNodeRequestL( *aMessage, ENcdTemporaryBundleFolder, ETrue ) );
       
  2187             break;
       
  2188 
       
  2189         case NcdNodeFunctionIds::ENcdCreateTemporaryOrSupplierNode:
       
  2190             DLINFO(("Getting temporary or supplier node"));
       
  2191             TRAP( trapError, TemporaryOrSupplierNodeRequestL( *aMessage ) );
       
  2192             break;
       
  2193             
       
  2194         case NcdNodeFunctionIds::ENcdCreateTemporaryNodeIfMetadataExists:
       
  2195             DLINFO(("Getting temporary node if metadata exists"));
       
  2196             TRAP( trapError, TemporaryNodeIfMetadataExistsRequestL( *aMessage ) );
       
  2197             break;
       
  2198 
       
  2199         case NcdNodeFunctionIds::ENcdRelease:
       
  2200             ReleaseRequest( *aMessage );
       
  2201             break;
       
  2202             
       
  2203         case NcdNodeFunctionIds::ENcdClearSearchResults:
       
  2204             TRAP( trapError, ClearSearchResultsRequestL( *aMessage ) );
       
  2205             break;
       
  2206             
       
  2207         case NcdNodeFunctionIds::ENcdIsCapabilitySupported:
       
  2208             TRAP( trapError, IsCapabilitySupportedRequestL( *aMessage ));
       
  2209             break;
       
  2210             
       
  2211         default:
       
  2212             break;
       
  2213         }
       
  2214 
       
  2215     if ( trapError != KErrNone )
       
  2216         {
       
  2217         // Because something went wrong the complete has not been
       
  2218         // yet called for the message.
       
  2219         // So, inform the client about the error.
       
  2220         DLINFO(("ERROR, Complete and release %d", trapError));
       
  2221         
       
  2222         aMessage->CompleteAndRelease( trapError );
       
  2223         }
       
  2224 
       
  2225     // Because the message should not be used after this, set it NULL.
       
  2226     // So, CounterPartLost function will know that no messages are
       
  2227     // waiting the response at the moment.
       
  2228     iMessage = NULL;        
       
  2229             
       
  2230     DLTRACEOUT((""));
       
  2231     }
       
  2232 
       
  2233 
       
  2234 void CNcdNodeManager::CounterPartLost( const MCatalogsSession& aSession )
       
  2235     {
       
  2236     DLTRACEIN((""));    
       
  2237     CommitSeenChanges( const_cast<MCatalogsSession&>( aSession ).Context() );
       
  2238     
       
  2239     // This function may be called whenever -- when the message is waiting
       
  2240     // response or when the message does not exist.
       
  2241     // iMessage may be NULL here, because in the end of the
       
  2242     // ReceiveMessage it is set to NULL. The life time of the message
       
  2243     // ends shortly after CompleteAndRelease is called.
       
  2244     if ( iMessage != NULL )
       
  2245         {
       
  2246         iMessage->CounterPartLost( aSession );
       
  2247         }    
       
  2248 
       
  2249     DLTRACEOUT((""));    
       
  2250     }
       
  2251 
       
  2252 
       
  2253 // ---------------------------------------------------------------------------
       
  2254 // Public:
       
  2255 // General getter and setter functions.
       
  2256 // ---------------------------------------------------------------------------
       
  2257 
       
  2258 CNcdNodeDbManager& CNcdNodeManager::NodeDbManager() const
       
  2259     {
       
  2260     return *iDbManager;
       
  2261     }
       
  2262     
       
  2263 CNcdNodeSeenInfo& CNcdNodeManager::SeenInfo() const
       
  2264     {
       
  2265     return *iSeenInfo;
       
  2266     }
       
  2267 
       
  2268 CNcdNodeFactory& CNcdNodeManager::NodeFactory() const
       
  2269     {
       
  2270     return *iNodeFactory;
       
  2271     }    
       
  2272 
       
  2273 CNcdNodeCacheCleanerManager& CNcdNodeManager::NodeCacheCleanerManager() const
       
  2274     {
       
  2275     return *iNodeCacheCleanerManager;
       
  2276     }    
       
  2277 
       
  2278 void CNcdNodeManager::SetFavoriteManager( CNcdFavoriteManager& aManager ) 
       
  2279     {
       
  2280     iFavoriteManager = &aManager;
       
  2281     }
       
  2282 
       
  2283 void CNcdNodeManager::SetNodeMetaDataL( CNcdNode& aNode )
       
  2284     {
       
  2285     DLTRACEIN(("Check metadata for node"));
       
  2286     CNcdNodeMetaData* metadata( NULL );
       
  2287     CNcdNodeLink* link = aNode.NodeLink();    
       
  2288     if ( link )
       
  2289         {
       
  2290         const CNcdNodeIdentifier& metaDataIdentifier( link->MetaDataIdentifier() );
       
  2291         if ( !metaDataIdentifier.ContainsEmptyFields() )
       
  2292             {
       
  2293             TRAP_IGNORE(
       
  2294                    metadata = &NodeMetaDataL( metaDataIdentifier ) );        
       
  2295             if ( metadata != NULL )
       
  2296                 {
       
  2297                 DLINFO(("Setting metadata for the created node"));
       
  2298                 aNode.SetNodeMetaDataL( *metadata );            
       
  2299                 }                    
       
  2300             }
       
  2301         }    
       
  2302     DLTRACEOUT((""));
       
  2303     }
       
  2304 
       
  2305 
       
  2306 // ---------------------------------------------------------------------------
       
  2307 // Protected:
       
  2308 // Db functions
       
  2309 // ---------------------------------------------------------------------------
       
  2310 
       
  2311 CNcdNode& CNcdNodeManager::DbNodeL( const CNcdNodeIdentifier& aIdentifier )
       
  2312     {
       
  2313     DLTRACEIN(( _L("Node id: %S, %S, %d"), 
       
  2314                 &aIdentifier.NodeNameSpace(),
       
  2315                 &aIdentifier.NodeId(),
       
  2316                 aIdentifier.ClientUid().iUid ));
       
  2317     DPROFILING_BEGIN( x );
       
  2318     // If the database is locked, leave immediately.
       
  2319     if ( iClientDatabaseLocks.Find( aIdentifier.ClientUid().iUid ) != KErrNotFound ) 
       
  2320         {
       
  2321         DLINFO(("Database locked -> leave."));
       
  2322         User::Leave( KErrNotFound );
       
  2323         }
       
  2324 
       
  2325     HBufC8* data( 
       
  2326         NodeDbManager().
       
  2327             ReadDataFromDatabaseLC( aIdentifier,
       
  2328                                     NcdNodeClassIds::ENcdNode ) );
       
  2329 
       
  2330     if ( data == NULL
       
  2331          || data->Length() == 0 )
       
  2332         {
       
  2333         // Node was not found from db. So, leave.
       
  2334         DLINFO(("Node was not found from db."));
       
  2335         User::Leave( KErrNotFound );
       
  2336         }
       
  2337 
       
  2338     // Create and internalize node according to the data gotten from the
       
  2339     // database.
       
  2340     CNcdNode* node( 
       
  2341         NodeFactory().
       
  2342             CreateNodeLC( aIdentifier,
       
  2343                           *data ) );   
       
  2344  
       
  2345      // Insert node to the cache.
       
  2346     AppendNodeToCacheL( node );        
       
  2347 
       
  2348     // Cache took ownership of the node.
       
  2349     CleanupStack::Pop( node );
       
  2350 
       
  2351     // Delete the node data because new node has been created. 
       
  2352     CleanupStack::PopAndDestroy( data );    
       
  2353 
       
  2354     // Now that the node has been created from the db, the metadata should
       
  2355     // be also set if it can be found. If it can, it should be set when the
       
  2356     // metadata is gotten from the internet and handled with DataHandlerL
       
  2357     SetNodeMetaDataL( *node );    
       
  2358     DPROFILING_END( x );
       
  2359     DLTRACEOUT((""));    
       
  2360     return *node;
       
  2361     }
       
  2362     
       
  2363     
       
  2364 CNcdNodeMetaData& CNcdNodeManager::DbMetaDataL( const CNcdNodeIdentifier& aIdentifier )
       
  2365     {
       
  2366     DLTRACEIN(( _L("Metadata id: %S, %S, %d"), 
       
  2367                 &aIdentifier.NodeNameSpace(),
       
  2368                 &aIdentifier.NodeId(),
       
  2369                 aIdentifier.ClientUid().iUid ));
       
  2370 
       
  2371     HBufC8* data( 
       
  2372         NodeDbManager().
       
  2373         ReadDataFromDatabaseLC( aIdentifier,
       
  2374                                 NcdNodeClassIds::ENcdMetaData ) );
       
  2375 
       
  2376     if ( data == NULL )
       
  2377         {
       
  2378         // Node was not found from db. So, leave.
       
  2379         DLINFO(("Node metadata was not found from db"));
       
  2380         User::Leave( KErrNotFound );
       
  2381         }
       
  2382     else if ( data->Length() == 0 )
       
  2383         {
       
  2384         // Node was not found from db. So, leave.
       
  2385         DLINFO(("Node metadata from db was empty"));
       
  2386         User::Leave( KErrNotFound );        
       
  2387         }
       
  2388 
       
  2389     // Use factory to create and to initialize the correct node from the data.
       
  2390     CNcdNodeMetaData* metaData( NodeFactory().CreateMetaDataLC( aIdentifier, *data ) );
       
  2391 
       
  2392     // Insert node to the cache.
       
  2393     iNodeMetaDataCache.AppendL( metaData );
       
  2394     
       
  2395     // Cache took ownership of the node.
       
  2396     CleanupStack::Pop( metaData );
       
  2397 
       
  2398     CleanupStack::PopAndDestroy( data );
       
  2399         
       
  2400     DLTRACEOUT((""));    
       
  2401     return *metaData;    
       
  2402     }
       
  2403 
       
  2404 
       
  2405 void CNcdNodeManager::DbSaveNodeL( CNcdNode& aNode )
       
  2406     {
       
  2407     DLTRACEIN((_L("Node id: %S, %S, %d"), 
       
  2408                &aNode.Identifier().NodeNameSpace(),
       
  2409                &aNode.Identifier().NodeId(),
       
  2410                aNode.Identifier().ClientUid().iUid));
       
  2411     DPROFILING_BEGIN( x );
       
  2412     // If the database is locked, do not do anything.
       
  2413     if ( iClientDatabaseLocks.Find( aNode.Identifier().ClientUid().iUid ) == 
       
  2414          KErrNotFound ) 
       
  2415         {
       
  2416         // Save the node information to the database
       
  2417         // The node implements MNcdStorageDataItem interface.
       
  2418         // So, the externalize function will insert the data to the stream
       
  2419         // and the database handler will save the stream to the database.
       
  2420         NodeDbManager().SaveDataIntoDatabaseL( aNode.Identifier(), 
       
  2421                                                aNode,
       
  2422                                                NcdNodeClassIds::ENcdNode );
       
  2423         }
       
  2424         
       
  2425 
       
  2426     // Inform cache cleaner about the node saving.
       
  2427     // Because the node has been updated into the db. Make sure
       
  2428     // that it will not be in the cleanup list anymore.
       
  2429     NodeCacheCleanerManager().
       
  2430         CacheCleanerL( aNode.Identifier().ClientUid() ).
       
  2431             RemoveCleanupIdentifier( aNode.Identifier() );
       
  2432     DPROFILING_END( x );
       
  2433     DLTRACEOUT((""));
       
  2434     }
       
  2435     
       
  2436     
       
  2437 void CNcdNodeManager::DbSaveNodesL( const CNcdNodeIdentifier& aRootNode ) 
       
  2438     {
       
  2439     DLTRACEIN((""));
       
  2440     
       
  2441     for ( TInt i = 0; i < iNodeCache.Count(); i++ ) 
       
  2442         {
       
  2443         CNcdNode* node = iNodeCache[i];
       
  2444         if ( NcdNodeIdentifierEditor::ParentOf( aRootNode, node->Identifier() ) ||
       
  2445              node->Identifier().Equals( aRootNode ) )
       
  2446             {
       
  2447             DLINFO((_L("Saving node ns: %S, id: %S"), &node->Identifier().NodeNameSpace(), &node->Identifier().NodeId() ));
       
  2448             DbSaveNodeL( *node );
       
  2449             }
       
  2450         }
       
  2451     }
       
  2452 
       
  2453 
       
  2454 void CNcdNodeManager::DbSaveNodeMetaDataL( CNcdNodeMetaData& aMetaData )
       
  2455     {
       
  2456     DLTRACEIN(( _L("Metadata id: %S, %S, %d"), 
       
  2457                 &aMetaData.Identifier().NodeNameSpace(),
       
  2458                 &aMetaData.Identifier().NodeId(),
       
  2459                 aMetaData.Identifier().ClientUid().iUid ));
       
  2460     DPROFILING_BEGIN( x );
       
  2461     // Save the node information to the database
       
  2462     // The node implements MNcdStorageDataItem interface.
       
  2463     // So, the externalize function will insert the data to the stream
       
  2464     // and the database handler will save the stream to the database.
       
  2465     NodeDbManager().SaveDataIntoDatabaseL( aMetaData.Identifier(), 
       
  2466                                            aMetaData,
       
  2467                                            NcdNodeClassIds::ENcdMetaData );
       
  2468 
       
  2469     // Because node data was saved into the db. Check if the max size has
       
  2470     // been exceeded.
       
  2471     // This is propably good enough place to do checking because most of the
       
  2472     // data is gotten from the metadata.
       
  2473     NodeCacheCleanerManager().
       
  2474         CacheCleanerL( aMetaData.Identifier().ClientUid() ).CheckDbSizeL();
       
  2475     
       
  2476     DPROFILING_END( x );    
       
  2477     DLTRACEOUT((""));
       
  2478     }
       
  2479 
       
  2480 
       
  2481 void CNcdNodeManager::DbSetMaxSizeL( const TUid& aClientUid, 
       
  2482                                     const TInt aMaxDbKiloByteSize )
       
  2483     {
       
  2484     DLTRACEIN(("Setting max db size: %d for client: %d", 
       
  2485                aMaxDbKiloByteSize, aClientUid));
       
  2486     
       
  2487     // The cache cleaner uses this information so forward the info for it.
       
  2488     NodeCacheCleanerManager().
       
  2489         CacheCleanerL(aClientUid).
       
  2490             SetDbMaxSize( aMaxDbKiloByteSize * KBytesToKilos );
       
  2491 
       
  2492     DLTRACEOUT((""));
       
  2493     }
       
  2494     
       
  2495 void CNcdNodeManager::LockNodeDbL( TUid aClientUid ) 
       
  2496     {
       
  2497     DLTRACEIN((""));
       
  2498     iClientDatabaseLocks.AppendL( aClientUid.iUid );
       
  2499     }
       
  2500     
       
  2501 void CNcdNodeManager::UnlockNodeDb( TUid aClientUid ) 
       
  2502     {
       
  2503     DLTRACEIN((""));
       
  2504     TInt index = iClientDatabaseLocks.Find( aClientUid.iUid );
       
  2505     if ( index != KErrNotFound ) 
       
  2506         {
       
  2507         iClientDatabaseLocks.Remove( index );
       
  2508         }
       
  2509     }
       
  2510 
       
  2511 // ---------------------------------------------------------------------------
       
  2512 // Protected:
       
  2513 // Functions that are called from the ReceiveMessageL, 
       
  2514 // which is meant to be used by the client side.
       
  2515 // ---------------------------------------------------------------------------
       
  2516 
       
  2517 void CNcdNodeManager::RootNodeRequestL( MCatalogsBaseMessage& aMessage )
       
  2518     {
       
  2519     DLTRACEIN((""));
       
  2520 
       
  2521     // Get the session that will contain the handle of the node
       
  2522     MCatalogsSession& requestSession( aMessage.Session() );
       
  2523 
       
  2524     // Creates the root if does not exist yet.
       
  2525     CNcdNodeFolder& root = CreateRootL( requestSession.Context() );
       
  2526 
       
  2527     // Add the node to the session and get the handle.
       
  2528     // If the node already existed in the session we will still
       
  2529     // get a new handle to the same object.
       
  2530     TInt32 rootHandle( requestSession.AddObjectL( &root ) );
       
  2531 
       
  2532     DLINFO(("Root handle: %d", rootHandle ));
       
  2533 
       
  2534     // Send the information to the client side
       
  2535     // If this leaves, ReceiveMessage will complete the message.
       
  2536     aMessage.CompleteAndReleaseL( rootHandle, KErrNone );
       
  2537 
       
  2538     DLTRACEOUT((""));
       
  2539     }
       
  2540 
       
  2541 void CNcdNodeManager::SearchRootNodeRequestL( MCatalogsBaseMessage& aMessage )
       
  2542     {
       
  2543     DLTRACEIN((""));
       
  2544 
       
  2545     // Get the session that will contain the handle of the node
       
  2546     MCatalogsSession& requestSession( aMessage.Session() );
       
  2547 
       
  2548     // Creates the search root if does not exist yet.
       
  2549     CNcdNodeFolder& searchRoot = CreateSearchRootL( requestSession.Context() );
       
  2550 
       
  2551     // Add the node to the session and get the handle.
       
  2552     // If the node already existed in the session we will still
       
  2553     // get a new handle to the same object.
       
  2554     TInt32 searchRootHandle( requestSession.AddObjectL( &searchRoot ) );
       
  2555 
       
  2556     DLINFO(("Search root handle: %d", searchRootHandle ));
       
  2557 
       
  2558     // Send the information to the client side
       
  2559     // If this leaves, ReceiveMessage will complete the message.
       
  2560     aMessage.CompleteAndReleaseL( searchRootHandle, KErrNone );
       
  2561 
       
  2562     DLTRACEOUT((""));
       
  2563     }
       
  2564 
       
  2565 
       
  2566 void CNcdNodeManager::NodeRequestL( MCatalogsBaseMessage& aMessage )
       
  2567     {
       
  2568     DLTRACEIN((""));
       
  2569 
       
  2570     CNcdNodeIdentifier* nodeIdentifier( RequestNodeIdentifierLC( aMessage ) );
       
  2571 
       
  2572     // Get the node from the cache or from the db.
       
  2573     // Notice that new node is not created if it is not found from the
       
  2574     // cache or from the db.
       
  2575     CNcdNode& node( NodeL( *nodeIdentifier ) );
       
  2576 
       
  2577     CleanupStack::PopAndDestroy( nodeIdentifier );
       
  2578     
       
  2579     DLINFO(("Node found"));
       
  2580 
       
  2581     // Add the node to the session and get the handle.
       
  2582     // If the node already existed in the session we will still
       
  2583     // get a new handle to the same object.
       
  2584     TInt32 nodeHandle( aMessage.Session().AddObjectL( &node ) );
       
  2585 
       
  2586     DLINFO(("Node handle: %d", nodeHandle ));
       
  2587 
       
  2588     // Send the information to the client side
       
  2589     // If this leaves, ReceiveMessage will complete the message.
       
  2590     aMessage.CompleteAndReleaseL( nodeHandle, KErrNone );
       
  2591 
       
  2592     DLTRACEOUT((""));
       
  2593     }
       
  2594     
       
  2595 
       
  2596 void CNcdNodeManager::TemporaryNodeRequestL(
       
  2597     MCatalogsBaseMessage& aMessage,
       
  2598     TNcdTemporaryNodeType aType,
       
  2599     TBool aCreateMetaData )
       
  2600     {
       
  2601     DLTRACEIN((""));
       
  2602     
       
  2603     CNcdNodeIdentifier* nodeIdentifier( RequestNodeIdentifierLC( aMessage ) );
       
  2604 
       
  2605     CNcdNode* node = &CreateTemporaryNodeL( 
       
  2606         *nodeIdentifier, 
       
  2607         aType, 
       
  2608         aCreateMetaData );
       
  2609     
       
  2610     CleanupStack::PopAndDestroy( nodeIdentifier );
       
  2611     
       
  2612     // Add the node to the session and get the handle.
       
  2613     // If the node already existed in the session we will still
       
  2614     // get a new handle to the same object.
       
  2615     TInt32 nodeHandle( aMessage.Session().AddObjectL( node ) );
       
  2616 
       
  2617     DLINFO(("Node handle: %d", nodeHandle ));
       
  2618 
       
  2619     // Send the information to the client side
       
  2620     // If this leaves, ReceiveMessage will complete the message.
       
  2621     aMessage.CompleteAndReleaseL( nodeHandle, KErrNone );
       
  2622 
       
  2623     DLTRACEOUT((""));
       
  2624     }
       
  2625 
       
  2626 
       
  2627 CNcdNode& CNcdNodeManager::CreateTemporaryNodeL(
       
  2628     CNcdNodeIdentifier& aTempNodeIdentifier,
       
  2629     TNcdTemporaryNodeType aType,
       
  2630     TBool aCreateMetaData )
       
  2631     {
       
  2632     DLTRACEIN((""));
       
  2633     // Check if the metadata exists already, and is of correct type.
       
  2634     CNcdNodeIdentifier* metaIdentifier =
       
  2635         NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( 
       
  2636                 aTempNodeIdentifier );
       
  2637     
       
  2638     CNcdNodeMetaData* meta( NULL );
       
  2639     TRAPD( err, meta = &NodeMetaDataL( *metaIdentifier ) );
       
  2640     if ( err == KErrNone ) 
       
  2641         {
       
  2642         // Metadata was found, check the type.
       
  2643         NcdNodeClassIds::TNcdNodeClassId acceptedMetaClassId = 
       
  2644             NcdNodeClassIds::ENcdNullObjectClassId;
       
  2645             
       
  2646         switch ( aType ) 
       
  2647             {
       
  2648             case ENcdTemporaryBundleFolder:
       
  2649             case ENcdTemporaryNodeFolder:
       
  2650                 acceptedMetaClassId = NcdNodeClassIds::ENcdFolderNodeMetaDataClassId;
       
  2651                 break;
       
  2652             
       
  2653             case ENcdTemporaryNodeItem:
       
  2654                 acceptedMetaClassId = NcdNodeClassIds::ENcdItemNodeMetaDataClassId;
       
  2655                 break;
       
  2656             
       
  2657             default:
       
  2658                 DASSERT( EFalse );
       
  2659                 break;
       
  2660             }
       
  2661                 
       
  2662         if ( meta->ClassId() != acceptedMetaClassId ) 
       
  2663             {
       
  2664             DLINFO(("Wrong metadata type, leave"));
       
  2665             User::Leave( KErrArgument );
       
  2666             }
       
  2667         }
       
  2668 
       
  2669             
       
  2670     // Get the node from the cache or from the db.
       
  2671     // Notice that new node is not created if it is not found from the
       
  2672     // cache or from the db.
       
  2673     CNcdNode* node( NULL );
       
  2674     switch( aType )
       
  2675         {
       
  2676         case ENcdTemporaryNodeFolder:        
       
  2677             node = &CreateNodeFolderL(
       
  2678                 CNcdNodeFactory::ENcdNormalNode, aTempNodeIdentifier );
       
  2679             break;
       
  2680             
       
  2681         case ENcdTemporaryNodeItem:
       
  2682             node = &CreateNodeItemL(
       
  2683                 CNcdNodeFactory::ENcdNormalNode, aTempNodeIdentifier );
       
  2684             break;
       
  2685         
       
  2686         case ENcdTemporaryBundleFolder:
       
  2687             node = &CreateNodeFolderL(
       
  2688                 CNcdNodeFactory::ENcdBundleNode, aTempNodeIdentifier );
       
  2689             break;
       
  2690         
       
  2691         default:
       
  2692             DASSERT( EFalse );
       
  2693             break;
       
  2694         }
       
  2695 
       
  2696     DASSERT( node );
       
  2697             
       
  2698     // Because this is temporary node, we will create or get the metadata for the node.
       
  2699     // This way the metadata will be at least initialized with the purchase history data.
       
  2700     if ( !meta && aCreateMetaData ) 
       
  2701         {
       
  2702         switch( aType )
       
  2703             {
       
  2704             case ENcdTemporaryBundleFolder:
       
  2705             case ENcdTemporaryNodeFolder:
       
  2706                 meta = &CreateNodeMetaDataL(
       
  2707                     *metaIdentifier, CNcdNodeFactory::ENcdNodeFolder );
       
  2708                 break;
       
  2709                 
       
  2710             case ENcdTemporaryNodeItem:
       
  2711                 meta = &CreateNodeMetaDataL(
       
  2712                     *metaIdentifier, CNcdNodeFactory::ENcdNodeItem );
       
  2713                 break;
       
  2714 
       
  2715             default:
       
  2716                 DASSERT( EFalse );
       
  2717                 break;
       
  2718             }
       
  2719         }
       
  2720 
       
  2721 
       
  2722     // Also to be sure that the node will be in initialized mode, we set the
       
  2723     // link for the node here.
       
  2724 
       
  2725     // Set the server and metadata information for the link.
       
  2726     // These are required, so the temp node may also be loaded from web.
       
  2727     node->CreateAndSetLinkL().SetServerUriL( node->Identifier().ServerUri() );
       
  2728     node->CreateAndSetLinkL().SetMetaDataIdentifierL( *metaIdentifier );
       
  2729 
       
  2730     CleanupStack::PopAndDestroy( metaIdentifier );    
       
  2731 
       
  2732     if ( meta )
       
  2733         {
       
  2734         // Set the metadata for the node.
       
  2735         node->SetNodeMetaDataL( *meta );
       
  2736         DLINFO(("Node and meta created"));
       
  2737         }
       
  2738 
       
  2739     // Also, save the node now that it has been updated
       
  2740     DbSaveNodeL( *node );
       
  2741     return *node;
       
  2742     }
       
  2743 
       
  2744     
       
  2745 void CNcdNodeManager::TemporaryOrSupplierNodeRequestL( MCatalogsBaseMessage& aMessage )
       
  2746     {
       
  2747     DLTRACEIN((""));
       
  2748     
       
  2749     // This will use the helper function to get the actual node identifier that is included
       
  2750     // into the message data.
       
  2751     CNcdNodeIdentifier* nodeIdentifier( RequestNodeIdentifierLC( aMessage ) );
       
  2752 
       
  2753     // The creator function requires metadata identifier in this case. 
       
  2754     // So, create correct identifier here.    
       
  2755     CNcdNodeIdentifier* metadataIdentifier( 
       
  2756         NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *nodeIdentifier ) );
       
  2757     CNcdNode& node = CreateTemporaryNodeOrSupplierL( *metadataIdentifier );
       
  2758     CleanupStack::PopAndDestroy( metadataIdentifier );
       
  2759 
       
  2760     CleanupStack::PopAndDestroy( nodeIdentifier );
       
  2761 
       
  2762     // NOTICE: We do not get the handle here, but the proxy side has to request it
       
  2763     // separately by using the normal node request. This just created the node.    
       
  2764 
       
  2765     // Send the information to the client side
       
  2766     // If this leaves, ReceiveMessage will complete the message.
       
  2767     // Notice that we just return zero here, because we do not have anything 
       
  2768     // special to give back.
       
  2769     aMessage.CompleteAndReleaseL( 0, KErrNone );
       
  2770 
       
  2771     DLTRACEOUT((""));
       
  2772     }
       
  2773     
       
  2774 
       
  2775 void CNcdNodeManager::TemporaryNodeIfMetadataExistsRequestL(
       
  2776     MCatalogsBaseMessage& aMessage )
       
  2777     {
       
  2778     DLTRACEIN((""));
       
  2779     
       
  2780     // This will use the helper function to get the actual node identifier that is included
       
  2781     // into the message data.
       
  2782     CNcdNodeIdentifier* nodeIdentifier( RequestNodeIdentifierLC( aMessage ) );
       
  2783 
       
  2784     // The creator function requires metadata identifier in this case. 
       
  2785     // So, create correct identifier here.    
       
  2786     CNcdNodeIdentifier* metadataIdentifier( 
       
  2787         NcdNodeIdentifierEditor::CreateMetaDataIdentifierLC( *nodeIdentifier ) );
       
  2788         
       
  2789     CNcdNode* node = CreateTemporaryNodeIfMetadataExistsL( *metadataIdentifier );
       
  2790     CleanupStack::PopAndDestroy( metadataIdentifier );
       
  2791     CleanupStack::PopAndDestroy( nodeIdentifier );
       
  2792     
       
  2793     // NOTICE: We do not get the handle here, but the proxy side has to request it
       
  2794     // separately by using the normal node request. This just created the node.    
       
  2795 
       
  2796     // Send the information to the client side
       
  2797     // If this leaves, ReceiveMessage will complete the message.
       
  2798     // Return the information whether the node was created or not.
       
  2799     TBool retValue = node != NULL;
       
  2800     aMessage.CompleteAndReleaseL( retValue, KErrNone );
       
  2801     }
       
  2802 
       
  2803 
       
  2804 void CNcdNodeManager::ReleaseRequest( MCatalogsBaseMessage& aMessage )
       
  2805     {
       
  2806     DLTRACEIN((""));
       
  2807 
       
  2808     // Commit the changes in seen info.
       
  2809     // Unable to handle the possible error.
       
  2810     CommitSeenChanges( aMessage.Session().Context() );
       
  2811 
       
  2812     // Decrease the reference count for this object.
       
  2813     // When the reference count reaches zero, this object will be destroyed
       
  2814     // and removed from the session.
       
  2815     MCatalogsSession& requestSession( aMessage.Session() );
       
  2816     TInt handle( aMessage.Handle() );
       
  2817     aMessage.CompleteAndRelease( KErrNone );
       
  2818     requestSession.RemoveObject( handle );
       
  2819             
       
  2820     DLTRACEOUT((""));
       
  2821     }
       
  2822 
       
  2823 
       
  2824 void CNcdNodeManager::ClearSearchResultsRequestL( MCatalogsBaseMessage& aMessage )
       
  2825     {
       
  2826     DLTRACEIN((""));
       
  2827     ClearSearchResultsL( aMessage.Session().Context() );
       
  2828     aMessage.CompleteAndReleaseL( KErrNone, KErrNone );
       
  2829     }
       
  2830 
       
  2831 void CNcdNodeManager::IsCapabilitySupportedRequestL(
       
  2832         MCatalogsBaseMessage& aMessage )
       
  2833     {
       
  2834     DLTRACEIN((""));        
       
  2835       
       
  2836     HBufC8* des = HBufC8::NewLC( aMessage.InputLength() );
       
  2837     TPtr8 ptr = des->Des();
       
  2838     aMessage.ReadInput( ptr );
       
  2839     RDesReadStream stream( *des );
       
  2840     CleanupReleasePushL( stream );
       
  2841     
       
  2842     CNcdNodeIdentifier* nodeId = CNcdNodeIdentifier::NewLC( stream );
       
  2843     CNcdNode& node = NodeL( *nodeId );
       
  2844     CleanupStack::PopAndDestroy( nodeId );
       
  2845     const TDesC* serverUri = NULL;
       
  2846     if( node.NodeLinkL().RemoteUri() != KNullDesC )
       
  2847         {
       
  2848         DLTRACE(("Using Remote URI as ServerURI"));
       
  2849         serverUri = &node.NodeLinkL().RemoteUri();
       
  2850         }
       
  2851     else
       
  2852         {
       
  2853         DLTRACE(("Using Server URI as ServerURI"));
       
  2854         serverUri = &node.NodeLinkL().ServerUri();
       
  2855         }
       
  2856     
       
  2857     HBufC* capability = NULL;
       
  2858     InternalizeDesL( capability, stream );
       
  2859     CleanupStack::PushL( capability );
       
  2860     
       
  2861     MNcdServerDetails& serverDetails =
       
  2862         iConfigurationManager.ServerDetailsL(
       
  2863             aMessage.Session().Context(),
       
  2864             *serverUri,
       
  2865             node.NodeLinkL().MetaDataIdentifier().NodeNameSpace() );
       
  2866             
       
  2867     TBool isCapabilitySupported = 
       
  2868         serverDetails.IsCapabilitySupported( *capability );
       
  2869         
       
  2870     DLINFO(( _L("server uri: %S, namespace: %S, capability: %S, is supported: %d"),
       
  2871         serverUri, &node.NodeLinkL().MetaDataIdentifier().NodeNameSpace(),
       
  2872         capability, isCapabilitySupported ));
       
  2873         
       
  2874     CleanupStack::PopAndDestroy( capability );
       
  2875     CleanupStack::PopAndDestroy( &stream );
       
  2876     CleanupStack::PopAndDestroy( des );
       
  2877     
       
  2878     aMessage.CompleteAndReleaseL( isCapabilitySupported, KErrNone );
       
  2879     }
       
  2880 
       
  2881 
       
  2882 TBool CNcdNodeManager::IsCapabilitySupportedL( const CNcdNodeIdentifier& aNodeIdentifier,
       
  2883     const TDesC& aCapability, MCatalogsContext& aContext )
       
  2884     {
       
  2885     DLTRACEIN((""));
       
  2886     
       
  2887     CNcdNode& node = NodeL( aNodeIdentifier );
       
  2888     const TDesC* serverUri = NULL;
       
  2889     if( node.NodeLinkL().RemoteUri() != KNullDesC )
       
  2890         {
       
  2891         DLTRACE(("Using Remote URI as ServerURI"));
       
  2892         serverUri = &node.NodeLinkL().RemoteUri();
       
  2893         }
       
  2894     else
       
  2895         {
       
  2896         DLTRACE(("Using Server URI as ServerURI"));
       
  2897         serverUri = &node.NodeLinkL().ServerUri();
       
  2898         }
       
  2899     
       
  2900     MNcdServerDetails& serverDetails =
       
  2901         iConfigurationManager.ServerDetailsL(
       
  2902             aContext,
       
  2903             *serverUri,
       
  2904             node.NodeLinkL().MetaDataIdentifier().NodeNameSpace() );
       
  2905             
       
  2906     TBool isCapabilitySupported = 
       
  2907         serverDetails.IsCapabilitySupported( aCapability );
       
  2908         
       
  2909     DLINFO(( _L("server uri: %S, namespace: %S, capability: %S, is supported: %d"),
       
  2910         serverUri, &node.NodeLinkL().MetaDataIdentifier().NodeNameSpace(),
       
  2911         &aCapability, isCapabilitySupported ));
       
  2912     return isCapabilitySupported;
       
  2913     }
       
  2914 
       
  2915 
       
  2916 CNcdNodeIdentifier* CNcdNodeManager::GetOriginIdentifierL( const CNcdNodeIdentifier& aNodeIdentifier )
       
  2917     {
       
  2918     DLTRACEIN((""));
       
  2919     CNcdNode& node = NodeL( aNodeIdentifier );
       
  2920     
       
  2921     CNcdNodeMetaData* nodeMeta( NULL );
       
  2922     DLTRACE(("Try to get metadata for node."));
       
  2923     TRAPD( err, nodeMeta = &node.NodeMetaDataL() );
       
  2924     if ( err == KErrNotFound ) 
       
  2925         {
       
  2926         DLTRACE(("Metadata not found, return NULL"));
       
  2927         return NULL;
       
  2928         }
       
  2929     User::LeaveIfError( err );
       
  2930     DASSERT( nodeMeta );
       
  2931     
       
  2932     CNcdPurchaseDetails* purchaseDetails = NULL;
       
  2933     DLTRACE(("Try to get purchase details for node."));
       
  2934     TRAP( err,
       
  2935         purchaseDetails = nodeMeta->PurchaseDetailsLC();
       
  2936         CleanupStack::Pop( purchaseDetails );
       
  2937         );
       
  2938     if ( err == KNcdErrorNoPurchaseInformation )
       
  2939         {
       
  2940         DLTRACE(("Purchase details not found for node, return NULL."))
       
  2941         return NULL;
       
  2942         }
       
  2943     else if ( err != KErrNone )
       
  2944         {
       
  2945         User::Leave( err );
       
  2946         }
       
  2947     // Create origin identifier
       
  2948     CleanupStack::PushL( purchaseDetails );
       
  2949     CNcdNodeIdentifier* originIdentifier = CNcdNodeIdentifier::NewL(
       
  2950         aNodeIdentifier.NodeNameSpace(), purchaseDetails->OriginNodeId(),
       
  2951         aNodeIdentifier.ClientUid() );
       
  2952     CleanupStack::PopAndDestroy( purchaseDetails );
       
  2953     DLTRACE(( _L("Purchase details found, origin node id: %S"), &originIdentifier->NodeId() ));
       
  2954     return originIdentifier;
       
  2955     }
       
  2956 
       
  2957 
       
  2958 void CNcdNodeManager::RemoveChildrenL( CNcdNodeFolder& aFolder )
       
  2959     {
       
  2960     DLTRACEIN((""));
       
  2961 
       
  2962     const RPointerArray<CNcdChildEntity>& childArray( aFolder.ChildArray() );
       
  2963     TInt count = childArray.Count();
       
  2964 
       
  2965     const RPointerArray<CNcdNodeIdentifier>& favorites( 
       
  2966         iFavoriteManager->FavoriteNodesL( aFolder.Identifier().ClientUid() ) );
       
  2967 
       
  2968     while ( count-- ) 
       
  2969         {        
       
  2970         RemoveNodeFromRamCache( childArray[ count ]->Identifier() );
       
  2971 
       
  2972         if ( !NcdNodeIdentifierUtils::ContainsIdentifier( 
       
  2973             childArray[ count ]->Identifier(),
       
  2974             favorites )  )
       
  2975             {
       
  2976             DbRemoveNodeL( childArray[ count ]->Identifier() );
       
  2977             }
       
  2978         }
       
  2979         
       
  2980     // Empties folder's child array
       
  2981     aFolder.RemoveChildren();
       
  2982         
       
  2983     DbSaveNodeL( aFolder );
       
  2984     }
       
  2985 
       
  2986 
       
  2987 void CNcdNodeManager::RemoveChildrenMetadataL( CNcdNodeFolder& aFolder )
       
  2988     {
       
  2989     DLTRACEIN((""));
       
  2990     const RPointerArray<CNcdChildEntity>& childArray( aFolder.ChildArray() );
       
  2991     TInt count = childArray.Count();
       
  2992     
       
  2993     if ( !count ) 
       
  2994         {
       
  2995         DLTRACEOUT(("No children"));
       
  2996         return;
       
  2997         }
       
  2998     
       
  2999     RPointerArray<CNcdNodeIdentifier> metaIdArray;
       
  3000     CleanupResetAndDestroyPushL( metaIdArray );
       
  3001     metaIdArray.ReserveL( count );    
       
  3002     
       
  3003     const RPointerArray<CNcdNodeIdentifier>& favorites( 
       
  3004         iFavoriteManager->FavoriteNodesL( aFolder.Identifier().ClientUid() ) );
       
  3005     
       
  3006     RPointerArray<CNcdNodeIdentifier> favoriteMetas;
       
  3007     CleanupResetAndDestroyPushL( favoriteMetas );
       
  3008             
       
  3009     // We need to convert node ids of favorite nodes to metadata ids so that
       
  3010     // we can be absolutely sure that we don't delete anything we are not
       
  3011     // supposed to delete
       
  3012     TInt favoriteCount = favorites.Count();
       
  3013     favoriteMetas.ReserveL( favoriteCount );
       
  3014     while( favoriteCount-- )
       
  3015         {        
       
  3016         CNcdNodeIdentifier* metaId = 
       
  3017             NcdNodeIdentifierEditor::CreateMetaDataIdentifierL(
       
  3018                 *favorites[ favoriteCount ] );
       
  3019         favoriteMetas.Append( metaId );
       
  3020         }
       
  3021     
       
  3022     while( count-- ) 
       
  3023         {
       
  3024         CNcdNodeIdentifier* metaId = 
       
  3025             NcdNodeIdentifierEditor::CreateMetaDataIdentifierL(
       
  3026                 childArray[ count ]->Identifier() );
       
  3027         
       
  3028         // Ensure that we don't remove favorite nodes
       
  3029         if ( !NcdNodeIdentifierUtils::ContainsIdentifier( 
       
  3030                 *metaId, 
       
  3031                 favoriteMetas ) )
       
  3032             {
       
  3033             DLTRACE(("Meta not favorite"));
       
  3034             CNcdNodeMetaData* metadata = FindNodeMetaDataFromCache( *metaId );
       
  3035             if ( metadata ) 
       
  3036                 {
       
  3037                 DLTRACE(("Setting metadata to be deleted as soon as possible from cache"));
       
  3038                 metadata->SetDeleteSoon( ETrue );
       
  3039                 }            
       
  3040             
       
  3041             // We don't have to worry about running out of memory because the
       
  3042             // array has already enough space reserved
       
  3043             metaIdArray.Append( metaId );
       
  3044             }
       
  3045         else 
       
  3046             {
       
  3047             delete metaId;
       
  3048             }
       
  3049         }
       
  3050     
       
  3051     CleanupStack::PopAndDestroy( &favoriteMetas );
       
  3052     
       
  3053     RArray<NcdNodeClassIds::TNcdNodeClassType> classTypes;
       
  3054     CleanupClosePushL( classTypes );   
       
  3055     classTypes.AppendL( NcdNodeClassIds::ENcdMetaData );        
       
  3056     
       
  3057     if ( iClientDatabaseLocks.Find( 
       
  3058             aFolder.Identifier().ClientUid().iUid ) == KErrNotFound ) 
       
  3059         {        
       
  3060         DLTRACE(("Removing %d metadatas from disk", metaIdArray.Count() ));
       
  3061         // Delete from database but don't compact since it's veeeery slow
       
  3062         NodeDbManager().RemoveDataFromDatabaseL( 
       
  3063             metaIdArray, classTypes, EFalse );
       
  3064         }
       
  3065         
       
  3066     CleanupStack::PopAndDestroy( 2, &metaIdArray ); // classTypes, metaIdArray
       
  3067     }
       
  3068 
       
  3069 
       
  3070 
       
  3071 // ---------------------------------------------------------------------------
       
  3072 // Protected:
       
  3073 // Functions that are called from functions that handle received messages.
       
  3074 // ---------------------------------------------------------------------------
       
  3075 
       
  3076 CNcdNodeIdentifier* CNcdNodeManager::RequestNodeIdentifierLC( MCatalogsBaseMessage& aMessage ) const
       
  3077     {
       
  3078     DLTRACEIN((""));
       
  3079     
       
  3080     // Get the session that will contain the handle of the node
       
  3081     MCatalogsSession& requestSession( aMessage.Session() );
       
  3082 
       
  3083     DLINFO(("Message, length: %X", aMessage.InputLength() ));
       
  3084 
       
  3085     // Get the node object
       
  3086     RBuf8 nodeIdentifierData;
       
  3087     nodeIdentifierData.CreateL( aMessage.InputLength() );
       
  3088     CleanupClosePushL( nodeIdentifierData );
       
  3089     User::LeaveIfError( aMessage.ReadInput( nodeIdentifierData ) );
       
  3090 
       
  3091     // Get the node information from the stream
       
  3092     CNcdNodeIdentifier* nodeIdentifier = 
       
  3093         CNcdNodeIdentifier::NewLC( nodeIdentifierData );
       
  3094         
       
  3095     // Check if we should update the nodeidentifier with the correct uid info
       
  3096     if ( nodeIdentifier->ClientUid() == TUid::Null() )
       
  3097         {        
       
  3098         // Nodeidentifier was created in the proxy side without knowing
       
  3099         // the uid value of the application.
       
  3100         // Create a new nodeidentifier here that will contain the actual UID
       
  3101         CNcdNodeIdentifier* uidNodeIdentifier =
       
  3102             CNcdNodeIdentifier::NewL( nodeIdentifier->NodeNameSpace(),
       
  3103                                       nodeIdentifier->NodeId(),
       
  3104                                       nodeIdentifier->ServerUri(),
       
  3105                                       requestSession.Context().FamilyId() );
       
  3106         CleanupStack::PopAndDestroy( nodeIdentifier );
       
  3107         nodeIdentifier = uidNodeIdentifier;
       
  3108         CleanupStack::PushL( nodeIdentifier );
       
  3109 
       
  3110         DLINFO(( ("Null uid. New uid: %d"), nodeIdentifier->ClientUid().iUid ));
       
  3111         }
       
  3112 
       
  3113     DLINFO((_L("Node namespace: %S, node id: %S, server uri: %S, node uid: %d"), 
       
  3114             &nodeIdentifier->NodeNameSpace(), 
       
  3115             &nodeIdentifier->NodeId(), 
       
  3116             &nodeIdentifier->ServerUri(),
       
  3117             nodeIdentifier->ClientUid()));
       
  3118 
       
  3119     CleanupStack::Pop( nodeIdentifier );
       
  3120     CleanupStack::PopAndDestroy( &nodeIdentifierData );
       
  3121     CleanupStack::PushL( nodeIdentifier );
       
  3122     
       
  3123     DLTRACEOUT((""));
       
  3124     
       
  3125     return nodeIdentifier;    
       
  3126     }
       
  3127         
       
  3128 
       
  3129 
       
  3130 // ---------------------------------------------------------------------------
       
  3131 // Private:
       
  3132 // Cache functions
       
  3133 // ---------------------------------------------------------------------------
       
  3134 
       
  3135 CNcdNode* CNcdNodeManager::FindNodeFromCacheL(
       
  3136     const CNcdNodeIdentifier& aIdentifier )
       
  3137     {
       
  3138     DLTRACEIN(( _L("Node id: %S, %S, %d"), 
       
  3139                 &aIdentifier.NodeNameSpace(),
       
  3140                 &aIdentifier.NodeId(),
       
  3141                 aIdentifier.ClientUid().iUid ));
       
  3142     
       
  3143     if ( aIdentifier.ContainsEmptyFields() ) 
       
  3144         {
       
  3145         DLERROR(("Identifier contains empty fields, leaving with KErrArgument (%d)", 
       
  3146             KErrArgument ));
       
  3147         User::Leave( KErrArgument );
       
  3148         }
       
  3149         
       
  3150     // Check from main cache at first.
       
  3151     CNcdNode* node = FindNodeFromMainCache( aIdentifier );
       
  3152     if ( node ) 
       
  3153         {
       
  3154         return node;
       
  3155         }
       
  3156  
       
  3157         
       
  3158     // Check from temp cache too. If node is found there, copy it to the main cache to
       
  3159     // keep the main cache up to date.
       
  3160     TInt index = FindNodeFromArray( aIdentifier, iTempNodeCache );
       
  3161     if ( index != KErrNotFound ) 
       
  3162         {
       
  3163         User::LeaveIfError( InsertNodeInOrder( 
       
  3164             iTempNodeCache[ index ], iNodeCache ) );
       
  3165         iTempNodeCache[ index ]->Open();
       
  3166         return iTempNodeCache[ index ];
       
  3167         }
       
  3168 
       
  3169     DLTRACEOUT((""));
       
  3170         
       
  3171     return NULL;    
       
  3172     }
       
  3173 
       
  3174 
       
  3175 // ---------------------------------------------------------------------------
       
  3176 // Private:
       
  3177 // Cache functions
       
  3178 // ---------------------------------------------------------------------------
       
  3179 
       
  3180 CNcdNode* CNcdNodeManager::FindNodeFromMainCache(
       
  3181     const CNcdNodeIdentifier& aIdentifier )
       
  3182     {
       
  3183     DLTRACEIN((""));
       
  3184     // Check if the node already exists in the cache.
       
  3185     // If it does, do not create it.
       
  3186     TInt index = FindNodeFromArray( aIdentifier, iNodeCache );
       
  3187     if ( index != KErrNotFound ) 
       
  3188         {
       
  3189         return iNodeCache[ index ];
       
  3190         }
       
  3191     return NULL;
       
  3192     
       
  3193     }
       
  3194 
       
  3195 
       
  3196 TInt CNcdNodeManager::FindNodeFromArray( 
       
  3197     const CNcdNodeIdentifier& aIdentifier,
       
  3198     const RPointerArray<CNcdNode>& aArray ) const
       
  3199     {            
       
  3200     
       
  3201     iSearchableNode->SetIdentifier( aIdentifier );
       
  3202     return aArray.FindInOrder( 
       
  3203         iSearchableNode, 
       
  3204         iNodeOrder );
       
  3205     
       
  3206     /*
       
  3207     for ( TInt i = 0; i < aArray.Count(); ++i )
       
  3208         {
       
  3209         if ( aArray[ i ]->Identifier().Equals( aIdentifier ) )
       
  3210             {
       
  3211             // The node has already been created.
       
  3212             // Return the old node.
       
  3213             return i;
       
  3214             }
       
  3215         }
       
  3216     return KErrNotFound; 
       
  3217      */
       
  3218     }
       
  3219 
       
  3220 
       
  3221 TInt CNcdNodeManager::InsertNodeInOrder( 
       
  3222     CNcdNode* aNode,
       
  3223     RPointerArray<CNcdNode>& aArray )
       
  3224     {    
       
  3225     return aArray.InsertInOrder( aNode, iNodeOrder );
       
  3226     //return aArray.Append( aNode );
       
  3227     }
       
  3228 
       
  3229 
       
  3230 CNcdNodeMetaData* CNcdNodeManager::FindNodeMetaDataFromCache( 
       
  3231     const CNcdNodeIdentifier& aIdentifier )
       
  3232     {
       
  3233     DLTRACEIN(( _L("Metadata id: %S, %S, %d"), 
       
  3234                 &aIdentifier.NodeNameSpace(),
       
  3235                 &aIdentifier.NodeId(),
       
  3236                 aIdentifier.ClientUid().iUid ));
       
  3237     
       
  3238     // Check if the metadata already exists in the cache.
       
  3239     // If it does, do not create it.
       
  3240     for ( TInt i = 0; i < iNodeMetaDataCache.Count(); ++i )
       
  3241         {
       
  3242         if ( iNodeMetaDataCache[ i ]->Identifier().Equals( aIdentifier ) )
       
  3243             {
       
  3244             // The node has already been created.
       
  3245             // Return the old node.
       
  3246             return iNodeMetaDataCache[ i ];
       
  3247             }
       
  3248         }
       
  3249 
       
  3250     DLTRACEOUT((""));
       
  3251         
       
  3252     return NULL;    
       
  3253     }
       
  3254 
       
  3255 
       
  3256 void CNcdNodeManager::NodeCacheCleanup()
       
  3257     {
       
  3258     DLTRACEIN((""));
       
  3259 
       
  3260     if ( iNodeCache.Count() < NcdProviderDefines::KNodeRamCacheMaxCount )
       
  3261         {
       
  3262         // Node cache has not reached the maximum size yet.
       
  3263         // So, no need to do cleanup yet.
       
  3264         return;
       
  3265         }
       
  3266 
       
  3267     CNcdNode* node( NULL );
       
  3268     TBool nodeRemoved( EFalse );    
       
  3269         
       
  3270     // Because the unreferenced item has the access count 1,
       
  3271     // we remove them from the cache and call Close, which will
       
  3272     // delete the item itself.
       
  3273     // The cache does not need to be totally cleaned. So, if the
       
  3274     // delimiter value is reached then the cleanup can be stopped.
       
  3275     for( TInt i = 0; 
       
  3276          i < iNodeCache.Count() 
       
  3277             && iNodeCache.Count() >= NcdProviderDefines::KNodeRamCacheDelimiterCount; 
       
  3278          ++i )
       
  3279         {
       
  3280         node = iNodeCache[ i ];
       
  3281         if( node->AccessCount() == 1 &&
       
  3282             iClientDatabaseLocks.Find(
       
  3283                 node->Identifier().ClientUid().iUid ) == KErrNotFound )
       
  3284             {
       
  3285             DLINFO(( _L("Remove node from cache: %S"), 
       
  3286                 &node->Identifier().NodeId() ));
       
  3287                 
       
  3288             // Because this node will not be in the cache anymore, we can remove
       
  3289             // it from the block list of the cleaner if it exists there. 
       
  3290             TRAP_IGNORE(
       
  3291                 NodeCacheCleanerManager().
       
  3292                     CacheCleanerL( node->Identifier().ClientUid() ).
       
  3293                         RemoveDoNotRemoveIdentifierL( node->Identifier() ) );        
       
  3294 
       
  3295             // Remove unreferenced node from the cache and destroy it.
       
  3296             iNodeCache.Remove( i );
       
  3297             i--;
       
  3298             node->Close();
       
  3299             node = NULL;
       
  3300 
       
  3301             nodeRemoved = ETrue;
       
  3302             
       
  3303             DLINFO(("node removed from the cache"));
       
  3304             }
       
  3305         }
       
  3306 
       
  3307     if ( nodeRemoved )
       
  3308         {
       
  3309         // Notice that we will come here only if the RAM cache max count has been
       
  3310         // reached. Otherwise the beginning of this function will return immediately.
       
  3311         // So, we will not come here every time some node is released. Therefore,
       
  3312         // this db check can be done here. It is run only once in a while.
       
  3313         DLINFO(("Nodes were removed from RAM cache. So, check also database."));
       
  3314         TRAP_IGNORE( NodeCacheCleanerManager().CheckAllL() );
       
  3315         }
       
  3316 
       
  3317     DLTRACEOUT((""));
       
  3318     }
       
  3319     
       
  3320     
       
  3321 void CNcdNodeManager::MetaDataCacheCleanup()
       
  3322     {
       
  3323     DLTRACEIN(("Metadata cache count: %d", iNodeMetaDataCache.Count() ));
       
  3324     
       
  3325     if ( iNodeMetaDataCache.Count() < NcdProviderDefines::KNodeRamCacheMaxCount )
       
  3326         {
       
  3327         // Node cache has not reached the maximum size yet.
       
  3328         // So, no need to do cleanup yet.
       
  3329         DLTRACEOUT(("No need for cleanup"));
       
  3330         return;
       
  3331         }            
       
  3332     
       
  3333     // Check if metadatas are used in some node
       
  3334     // Go through all the metadata info
       
  3335 
       
  3336     for ( TInt i = 0; 
       
  3337           i < iNodeMetaDataCache.Count()
       
  3338             && iNodeMetaDataCache.Count() >= NcdProviderDefines::KNodeRamCacheDelimiterCount; 
       
  3339           ++i )
       
  3340         {        
       
  3341         DLTRACEIN(("Going through %d nodes for metadata in index: %i", 
       
  3342             iNodeCache.Count(), i ));            
       
  3343                     
       
  3344         if( !IsMetadataUsed( iNodeMetaDataCache[ i ] ) )
       
  3345             {
       
  3346             DLTRACE(("Removing metadata"));
       
  3347             // Because none of the nodes needed this metadata,
       
  3348             // we may close the metadata and remove it from the cache.
       
  3349             CNcdNodeMetaData* metaData( iNodeMetaDataCache[ i ] );
       
  3350             iNodeMetaDataCache.Remove( i );
       
  3351             metaData->Close();
       
  3352             metaData = NULL;
       
  3353             // Because one item was removed also update the index
       
  3354             // for the next round.
       
  3355             --i;
       
  3356             DLINFO(("metadata removed from the cache"));
       
  3357             }
       
  3358         }        
       
  3359 
       
  3360     DLTRACEOUT((""));
       
  3361     }
       
  3362 
       
  3363 
       
  3364 TBool CNcdNodeManager::IsMetadataUsed( const CNcdNodeMetaData* aMetadata ) const
       
  3365     {        
       
  3366     DASSERT( aMetadata );
       
  3367     
       
  3368     // Compare the metadata against the metadata info that
       
  3369     // nodes contain.
       
  3370     for ( TInt j = 0; j < iNodeCache.Count(); ++j )
       
  3371         {
       
  3372         // Use non-leaving metadata getter            
       
  3373         if ( iNodeCache[ j ]->NodeMetaData() == aMetadata )
       
  3374             {                
       
  3375             DLTRACE(("Metadata in use, index: %d", j));
       
  3376             // Metadata was used in some node
       
  3377             return ETrue;            
       
  3378             }
       
  3379         }
       
  3380 
       
  3381     for ( TInt j = 0; j < iTempNodeCache.Count(); ++j )
       
  3382         {
       
  3383         // Use non-leaving metadata getter            
       
  3384         if ( iTempNodeCache[ j ]->NodeMetaData() == aMetadata )
       
  3385             {                
       
  3386             DLTRACE(("Metadata in use, index: %d", j));
       
  3387             // Metadata was used in some node            
       
  3388             return ETrue;
       
  3389             }
       
  3390         }
       
  3391     
       
  3392     return EFalse;
       
  3393     }
       
  3394     
       
  3395 
       
  3396 // Closes all nodes and metadata objects     
       
  3397 void CNcdNodeManager::FullCacheCleanup()
       
  3398     {
       
  3399     DLTRACEIN((""));
       
  3400     // Here we call the Close-function of the nodes which are CObjects.
       
  3401     // When the access count of CObject is decreased to zero, it will
       
  3402     // be destroyed. Because, the initial access number of the node is one,
       
  3403     // this manager has to call the Close method, so the node will be 
       
  3404     // deleted after nobody is using it.
       
  3405     DLINFO(("Closing node-objects"));
       
  3406     for ( TInt i = 0; i < iNodeCache.Count(); ++i )
       
  3407         {
       
  3408         // The element should always be deleted here because
       
  3409         // its access count should reach zero after this close.
       
  3410         // So, the access count should always print 1 to the debug log here.
       
  3411         DLINFO(("Close node %d access count: %d", 
       
  3412                 i, iNodeCache[ i ]->AccessCount()));
       
  3413 
       
  3414         // Because this node will not be in the cache anymore, we can remove
       
  3415         // it from the block list of the cleaner if it exists there.
       
  3416         TRAP_IGNORE(
       
  3417             NodeCacheCleanerManager().
       
  3418                 CacheCleanerL( iNodeCache[ i ]->Identifier().ClientUid() ).
       
  3419                     RemoveDoNotRemoveIdentifierL( 
       
  3420                         iNodeCache[ i ]->Identifier() ) );
       
  3421         
       
  3422         // Note that the element is most likely deleted after this close
       
  3423         // call. But, it does not matter here. Because the array is also
       
  3424         // reset after all the elements here have been closed. So, it does
       
  3425         // not matter that pointers to the deleted elements are left to the
       
  3426         // array.             
       
  3427         iNodeCache[ i ]->Close();
       
  3428         }
       
  3429     // Also, close the cache array.
       
  3430     iNodeCache.Reset();
       
  3431     
       
  3432     // Close the objects of temp cache too.
       
  3433     for ( TInt i = 0; i < iTempNodeCache.Count(); i++ ) 
       
  3434         {
       
  3435         // Because this node will not be in the cache anymore, we can remove
       
  3436         // it from the block list of the cleaner if it exists there.
       
  3437         TRAP_IGNORE(
       
  3438             NodeCacheCleanerManager().
       
  3439                 CacheCleanerL( iTempNodeCache[ i ]->Identifier().ClientUid() ).
       
  3440                     RemoveDoNotRemoveIdentifierL( 
       
  3441                         iTempNodeCache[ i ]->Identifier() ) );
       
  3442         iTempNodeCache[i]->Close();
       
  3443         }
       
  3444     iTempNodeCache.Reset();        
       
  3445     
       
  3446     DLINFO(("Closing nodemetadata-objects"));
       
  3447     CloseMetadatas();
       
  3448     }
       
  3449 
       
  3450 
       
  3451 void CNcdNodeManager::CloseMetadatas() 
       
  3452     {
       
  3453     DLTRACEIN((""));
       
  3454     for ( TInt i = 0; i < iNodeMetaDataCache.Count(); ++i )
       
  3455         {
       
  3456         DLINFO(("Close metadata %d access count: %d", 
       
  3457                 i, iNodeMetaDataCache[ i ]->AccessCount()));                
       
  3458         iNodeMetaDataCache[i]->Close();
       
  3459         }
       
  3460     iNodeMetaDataCache.Reset();
       
  3461 
       
  3462     DLTRACEOUT(("Nodemetadata-objects closed"));    
       
  3463     }
       
  3464     
       
  3465 
       
  3466 void CNcdNodeManager::AppendNodeToCacheL( CNcdNode* aNode )
       
  3467     {
       
  3468     DLTRACEIN((""));
       
  3469     
       
  3470     DASSERT( aNode );
       
  3471 
       
  3472     User::LeaveIfError( InsertNodeInOrder( aNode, iNodeCache ) );
       
  3473 
       
  3474     // Because this node was appended to the list, inform the cleaner that
       
  3475     // this node or its parents should not be removed from the database
       
  3476     NodeCacheCleanerManager().
       
  3477         CacheCleanerL( aNode->Identifier().ClientUid() ).
       
  3478             AddDoNotRemoveIdentifierL( aNode->Identifier() );
       
  3479         
       
  3480     DLTRACEOUT(("Nodes in cache: %d", iNodeCache.Count() ));
       
  3481     }
       
  3482 
       
  3483 
       
  3484 CNcdNode& CNcdNodeManager::CheckAndCreateNodeL( CNcdNodeFactory::TNcdNodeType aNodeType,
       
  3485                                                 CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
  3486                                                 const CNcdNodeIdentifier& aParentNodeIdentifier,
       
  3487                                                 const CNcdNodeIdentifier& aMetaIdentifier )
       
  3488     {
       
  3489     DLTRACEIN((""));
       
  3490     
       
  3491     CNcdNodeIdentifier* nodeIdentifier( 
       
  3492         NcdNodeIdentifierEditor::CreateNodeIdentifierLC( aParentNodeIdentifier,
       
  3493                                                          aMetaIdentifier ) );
       
  3494     CNcdNode& node( CheckAndCreateNodeL( aNodeType, aNodePurpose,
       
  3495                                          *nodeIdentifier ) );
       
  3496     CleanupStack::PopAndDestroy( nodeIdentifier );
       
  3497     
       
  3498     DLTRACEOUT((""));
       
  3499     
       
  3500     return node;
       
  3501     }
       
  3502 
       
  3503 
       
  3504 CNcdNode& CNcdNodeManager::CheckAndCreateNodeL( CNcdNodeFactory::TNcdNodeType aNodeType,
       
  3505                                                 CNcdNodeFactory::TNcdNodePurpose aNodePurpose,
       
  3506                                                 const CNcdNodeIdentifier& aNodeIdentifier )
       
  3507     {
       
  3508     DLTRACEIN((""));
       
  3509 
       
  3510     // Check if the node can be found from the RAM cache or from the db.
       
  3511     CNcdNode* node( NodePtrL( aNodeIdentifier) );
       
  3512 
       
  3513     // Get the class id of the node that has the given purpose.
       
  3514     // The data type parameter informs if an item or a folder should be created.
       
  3515     // Set the class id to be some item as a default.
       
  3516     NcdNodeClassIds::TNcdNodeClassId classId =
       
  3517             NodeFactory().NodeClassIdL( aNodeType, aNodePurpose );
       
  3518 
       
  3519     if ( node != NULL )
       
  3520         {
       
  3521         DLINFO(("Node was found"));
       
  3522         DLINFO(("Class comparison. Old: %d, new: %d",
       
  3523                 node->ClassId(), classId));
       
  3524 
       
  3525         // Check if we should replace the old node by new one because its type or purpose has changed.
       
  3526         if ( node->ClassId() != classId )
       
  3527             {
       
  3528             DLWARNING(("Be sure that the server has changed the type and there is no bug in the code!"));
       
  3529             // Because the original type is wrong type,
       
  3530             // remove the node from the RAM cache.
       
  3531             for ( TInt i = 0; i < iNodeCache.Count(); ++i )
       
  3532                 {
       
  3533                 if ( iNodeCache[ i ] == node )
       
  3534                     {
       
  3535                     DLINFO(("Remove node from db"));
       
  3536                     // Because node is removed from cache.
       
  3537                     // Call Close, so the access count will be correct
       
  3538                     // for the hanging node. Most likely it will be
       
  3539                     // deleted soon.                
       
  3540                     iNodeCache.Remove( i );
       
  3541                     // Because the node is removed from the cache
       
  3542                     // also inform cleaner that the node may be cleaned
       
  3543                     // from the database if wanted.
       
  3544                     NodeCacheCleanerManager().
       
  3545                         CacheCleanerL( node->Identifier().ClientUid() ).
       
  3546                                        RemoveDoNotRemoveIdentifierL( 
       
  3547                                         node->Identifier() );
       
  3548                     // Finally close the node. Because we do not own it
       
  3549                     // anymore.
       
  3550                     node->Close();
       
  3551                     node = NULL;
       
  3552                     break;
       
  3553                     }
       
  3554                 }
       
  3555                 
       
  3556             // Because the node was removed from the cache and we do not
       
  3557             // want to use the node that is saved into the db,
       
  3558             // we have to create the node directly here by using
       
  3559             // node factory. This way we get the new uninitialized node
       
  3560             // that is of the correct type.
       
  3561 
       
  3562             DLINFO(("Create node"));
       
  3563             // Create the node according to the class id
       
  3564             node = NodeFactory().CreateNodeLC( aNodeIdentifier,
       
  3565                                                classId );
       
  3566 
       
  3567             DASSERT( node );
       
  3568             
       
  3569             // Insert node to the cache.
       
  3570             // This will also insert the node back into do not remove list of
       
  3571             // the cleaner.
       
  3572             AppendNodeToCacheL( node );
       
  3573             
       
  3574             // Cache takes ownership of the node
       
  3575             CleanupStack::Pop( node );
       
  3576             }
       
  3577         }
       
  3578     else
       
  3579         {
       
  3580         DLINFO(("Node has to be created because it was not found"));
       
  3581         // Create the node according to the class id
       
  3582         node = NodeFactory().CreateNodeLC( aNodeIdentifier,
       
  3583                                            classId );
       
  3584 
       
  3585         
       
  3586         DASSERT( node );
       
  3587         
       
  3588         // Insert node to the cache.
       
  3589         // This will also insert the node back into do not remove list of
       
  3590         // the cleaner.
       
  3591         AppendNodeToCacheL( node );
       
  3592         
       
  3593         // Cache takes ownership of the node
       
  3594         CleanupStack::Pop( node );
       
  3595         }
       
  3596     
       
  3597     DLTRACEOUT((""));
       
  3598     
       
  3599     return *node;
       
  3600     }
       
  3601 
       
  3602 
       
  3603 CNcdNodeMetaData& CNcdNodeManager::CheckAndCreateMetaDataL( 
       
  3604     const CNcdNodeIdentifier& aMetaIdentifier,
       
  3605     CNcdNodeFactory::TNcdNodeType aMetaType )
       
  3606     {
       
  3607     DLTRACEIN((""));
       
  3608 
       
  3609     // Check if the metadata can be found from the RAM cache or from the db.
       
  3610     CNcdNodeMetaData* metaData( NULL );
       
  3611     TRAPD( metaDataError, metaData = &NodeMetaDataL( aMetaIdentifier ) );
       
  3612 
       
  3613     // Accept leave with KEreNotFound because next we can create it
       
  3614     if( metaDataError != KErrNone && metaDataError != KErrNotFound )
       
  3615         {
       
  3616         DLERROR(( "metaDataError: %d", metaDataError ));
       
  3617         User::Leave( metaDataError );
       
  3618         }
       
  3619     DLINFO((""));
       
  3620 
       
  3621     // Get the class id of the node that has the given purpose.
       
  3622     // The data type parameter informs if an item or a folder should be created.
       
  3623     // Set the class id to be some item as a default.
       
  3624     NcdNodeClassIds::TNcdNodeClassId classId =
       
  3625             NodeFactory().MetaDataClassId( aMetaType );
       
  3626 
       
  3627     if ( metaData != NULL )
       
  3628         {
       
  3629         DLINFO(("Metadata was found"));
       
  3630         DLINFO(("Class comparison. Old: %d, new: %d",
       
  3631                 metaData->ClassId(), classId));
       
  3632 
       
  3633         if ( metaData->ClassId() != classId )
       
  3634             {
       
  3635             DLWARNING(("Be sure that the server has changed the type and there is no bug in the code!"))
       
  3636             // Because the original type is wrong type,
       
  3637             // remove the node from the RAM cache.
       
  3638             for ( TInt i = 0; i < iNodeMetaDataCache.Count(); ++i )
       
  3639                 {
       
  3640                 if ( iNodeMetaDataCache[ i ] == metaData )
       
  3641                     {
       
  3642                     DLINFO(("Remove meta from db"));
       
  3643                     // Because metadata is removed from cache.
       
  3644                     // Call Close, so the access count will be correct
       
  3645                     // for the hanging metadata. Most likely it will be
       
  3646                     // deleted soon.                
       
  3647                     iNodeMetaDataCache.Remove( i );
       
  3648                     // Finally close the metadata. Because we do not own it
       
  3649                     // anymore.
       
  3650                     metaData->Close();
       
  3651                     metaData = NULL;
       
  3652                     break;
       
  3653                     }
       
  3654                 }
       
  3655                 
       
  3656             // Because the metadata was removed from the cache and we do not
       
  3657             // want to use the metadata that is saved into the db,
       
  3658             // we have to create the metadata directly here by using
       
  3659             // node factory. This way we get the new uninitialized node
       
  3660             // that is of the correct type.
       
  3661 
       
  3662             DLINFO(("Create metadata"));
       
  3663             // Create the node according to the class id
       
  3664             metaData = NodeFactory().CreateMetaDataLC( aMetaIdentifier,
       
  3665                                                        classId );
       
  3666 
       
  3667             if ( metaData == NULL )
       
  3668                 {
       
  3669                 // Node was not be created.
       
  3670                 DLERROR(("Metadata was not created."));
       
  3671                 DASSERT( EFalse );
       
  3672                 User::Leave( KErrNotFound );
       
  3673                 }
       
  3674             
       
  3675             // Insert node to the cache.
       
  3676             // This will also insert the node back into do not remove list of
       
  3677             // the cleaner.
       
  3678             iNodeMetaDataCache.AppendL( metaData );
       
  3679             
       
  3680             // Cache takes ownership of the node
       
  3681             CleanupStack::Pop( metaData );
       
  3682             }
       
  3683         }
       
  3684     else
       
  3685         {
       
  3686         DLINFO(("Metadata has to be created because it was not found"));
       
  3687         // Create the node according to the class id
       
  3688         metaData = NodeFactory().CreateMetaDataLC( aMetaIdentifier,
       
  3689                                                    classId );
       
  3690 
       
  3691         if ( metaData == NULL )
       
  3692             {
       
  3693             // Node was not be created.
       
  3694             DLERROR(("Node was not created."));
       
  3695             DASSERT( EFalse );
       
  3696             User::Leave( KErrNotFound );
       
  3697             }
       
  3698         
       
  3699         // Insert node to the cache.
       
  3700         // This will also insert the node back into do not remove list of
       
  3701         // the cleaner.
       
  3702         iNodeMetaDataCache.AppendL( metaData );
       
  3703         
       
  3704         // Cache takes ownership of the node
       
  3705         CleanupStack::Pop( metaData );
       
  3706         }
       
  3707     
       
  3708     DLTRACEOUT((""));
       
  3709     
       
  3710     return *metaData;
       
  3711     }
       
  3712     
       
  3713 
       
  3714 MNcdConfigurationManager& CNcdNodeManager::ConfigurationManager()  const
       
  3715     {
       
  3716     return iConfigurationManager;
       
  3717     }
       
  3718     
       
  3719 
       
  3720 void CNcdNodeManager::RemoveNodeFromRamCache( 
       
  3721     const CNcdNodeIdentifier& aIdentifier )
       
  3722     {
       
  3723     DLTRACEIN((""));
       
  3724     TInt index = FindNodeFromArray( aIdentifier, iNodeCache );
       
  3725     if ( index != KErrNotFound )
       
  3726         {
       
  3727         DLTRACE(("Removing node from RAM cache"));
       
  3728         iNodeCache[ index ]->Close();
       
  3729         iNodeCache.Remove( index );        
       
  3730         }
       
  3731     }
       
  3732 
       
  3733 
       
  3734 void CNcdNodeManager::CommitSeenChanges( const MCatalogsContext& aContext )
       
  3735     {
       
  3736     TRAP_IGNORE( iSeenInfo->CommitChangesL( aContext.FamilyId() ) );
       
  3737     }
       
  3738