|
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 |