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