|
1 /* |
|
2 * Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Implements CNcdParentOfTransparentNode class |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32err.h> |
|
20 #include <e32base.h> |
|
21 |
|
22 #include "ncdparentoftransparentnode.h" |
|
23 #include "ncdchildentity.h" |
|
24 #include "ncdnodeidentifier.h" |
|
25 #include "catalogsutils.h" |
|
26 #include "catalogsbasemessage.h" |
|
27 #include "ncdnodefunctionids.h" |
|
28 #include "ncdnodeclassids.h" |
|
29 #include "catalogsconstants.h" |
|
30 #include "ncdsearchnodefolder.h" |
|
31 #include "ncdnodetransparentfolder.h" |
|
32 |
|
33 |
|
34 |
|
35 CNcdParentOfTransparentNode::CNcdParentOfTransparentNode( CNcdNodeManager& aNodeManager, |
|
36 NcdNodeClassIds::TNcdNodeClassId aNodeClassId ) |
|
37 : CNcdNodeFolder( aNodeManager, aNodeClassId ) |
|
38 { |
|
39 } |
|
40 |
|
41 void CNcdParentOfTransparentNode::ConstructL( const CNcdNodeIdentifier& aIdentifier ) |
|
42 { |
|
43 CNcdNodeFolder::ConstructL( aIdentifier ); |
|
44 } |
|
45 |
|
46 CNcdParentOfTransparentNode::~CNcdParentOfTransparentNode() |
|
47 { |
|
48 } |
|
49 |
|
50 |
|
51 void CNcdParentOfTransparentNode::ExternalizeL( RWriteStream& aStream ) |
|
52 { |
|
53 DLTRACEIN(("")); |
|
54 CNcdNodeFolder::ExternalizeL( aStream ); |
|
55 DLTRACEOUT(("")); |
|
56 } |
|
57 |
|
58 void CNcdParentOfTransparentNode::InternalizeL( RReadStream& aStream ) |
|
59 { |
|
60 DLTRACEIN(("")); |
|
61 CNcdNodeFolder::InternalizeL( aStream ); |
|
62 DLTRACEOUT(("")); |
|
63 } |
|
64 |
|
65 |
|
66 |
|
67 void CNcdParentOfTransparentNode::ExternalizeDataForRequestL( RWriteStream& aStream ) const |
|
68 { |
|
69 DLTRACEIN(("this: %X", this)); |
|
70 |
|
71 // Just delegate the command forward |
|
72 CNcdNodeFolder::ExternalizeDataForRequestL( aStream ); |
|
73 |
|
74 // This will give the correct child count that may be needed in proxy side. |
|
75 // Because the child count may differ there if transparent child folders are |
|
76 // replaced by their children. |
|
77 aStream.WriteInt32L( ChildArray().Count() ); |
|
78 |
|
79 DLTRACEOUT(("")); |
|
80 } |
|
81 |
|
82 |
|
83 void CNcdParentOfTransparentNode::ExternalizeChildArrayForRequestL( RWriteStream& aStream ) const |
|
84 { |
|
85 DLTRACEIN(("this: %X", this)); |
|
86 DPROFILING_BEGIN( x ); |
|
87 |
|
88 // Fixes PRECLI-1539 |
|
89 // This method doesn't support paging and the parent implementation doesn't support |
|
90 // transparents but since search folders need paging but not transparents we call the |
|
91 // base class |
|
92 // |
|
93 // Note: No sense overriding this method in CNcdSearchNodeFolder because its |
|
94 // children need this implementation so we would have to implement overrides also |
|
95 // to them |
|
96 if ( ClassId() == NcdNodeClassIds::ENcdSearchFolderNodeClassId ) |
|
97 { |
|
98 DLTRACE(("No need for transparent support, call CNcdNodeFolder-method")); |
|
99 CNcdNodeFolder::ExternalizeChildArrayForRequestL( aStream ); |
|
100 return; |
|
101 } |
|
102 |
|
103 CNcdNode* childNode( NULL ); |
|
104 CNcdNodeFolder* transparentFolder( NULL ); |
|
105 const CNcdNodeIdentifier* childIdentifier( NULL ); |
|
106 const CNcdNodeIdentifier* transparentChildIdentifier( NULL ); |
|
107 |
|
108 // This array will contain the identifiers of the children that are set for |
|
109 // the proxy side |
|
110 RPointerArray<CNcdChildEntity> childEntitys; |
|
111 CleanupResetAndDestroyPushL( childEntitys ); |
|
112 |
|
113 // Remember to check if this folder contains any transparent folders. |
|
114 // Add all the children into the temporary array that will contain |
|
115 // the identifiers of the children for the proxy folder. |
|
116 // child entitys need an index as well as identifier |
|
117 |
|
118 |
|
119 const RPointerArray<CNcdChildEntity>& childArray( ChildArray() ); |
|
120 TInt childCount = childArray.Count(); |
|
121 childEntitys.ReserveL( childCount ); |
|
122 DLTRACE(( "Externalizing at least %d children", childCount )); |
|
123 TInt childIndex = 0; |
|
124 for ( TInt i = 0; i < childCount; ++i ) |
|
125 { |
|
126 childNode = NULL; |
|
127 childIdentifier = &childArray[i]->Identifier(); |
|
128 DASSERT( childIdentifier ); |
|
129 if ( childArray[i]->IsTransparent() ) |
|
130 { |
|
131 DLTRACE(("child is likely transparent")); |
|
132 childNode = NodeManager().NodePtrL( *childIdentifier ); |
|
133 |
|
134 // This is as a backup |
|
135 if ( childNode != NULL |
|
136 && (childNode->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId || |
|
137 (childNode->ClassId() == NcdNodeClassIds::ENcdSearchFolderNodeClassId && |
|
138 NodeManager().SearchFolderL( *childIdentifier ).IsTransparent() ) ) ) |
|
139 { |
|
140 DLINFO(("Transparent folder found for child array")); |
|
141 // Because the transparent folder is replaced, |
|
142 // add the the children of the transparent folder here. |
|
143 transparentFolder = static_cast<CNcdNodeFolder*>(childNode); |
|
144 const RPointerArray<CNcdChildEntity>& children = transparentFolder->ChildArray(); |
|
145 DLINFO((("Transparent folder has %d children"), children.Count() )); |
|
146 for( TInt j = 0; j < children.Count(); ++j ) |
|
147 { |
|
148 transparentChildIdentifier = &children[j]->Identifier(); |
|
149 |
|
150 DLINFO(("Child of transparent to array.")); |
|
151 CNcdChildEntity* childEntity = |
|
152 CNcdChildEntity::NewLC( |
|
153 childIndex++, |
|
154 *transparentChildIdentifier, |
|
155 children[j]->IsTransparent(), |
|
156 children[j]->NodeType() ); |
|
157 childEntitys.AppendL( childEntity ); |
|
158 CleanupStack::Pop( childEntity ); |
|
159 } |
|
160 } |
|
161 else |
|
162 { |
|
163 // In case childNode was found but it wasn't really transparent |
|
164 childNode = NULL; |
|
165 } |
|
166 |
|
167 } |
|
168 |
|
169 // Handle non-transparents and nodes that were not found from node manager |
|
170 if ( !childNode ) |
|
171 { |
|
172 DLINFO(("Normal child. Add to the array.")); |
|
173 DLNODEID(( *childIdentifier )); |
|
174 |
|
175 // Child was normal child. |
|
176 CNcdChildEntity* childEntity = CNcdChildEntity::NewLC( |
|
177 childIndex++, |
|
178 *childIdentifier, |
|
179 childArray[i]->IsTransparent(), |
|
180 childArray[i]->NodeType() ); |
|
181 childEntitys.AppendL( childEntity ); |
|
182 CleanupStack::Pop( childEntity ); |
|
183 } |
|
184 } |
|
185 |
|
186 // First insert the size of the child array |
|
187 aStream.WriteInt32L( childEntitys.Count() ); |
|
188 |
|
189 // Insert all the child identifier info for the proxy into the stream |
|
190 for( TInt i = 0; i < childEntitys.Count(); ++i ) |
|
191 { |
|
192 // Inform that the next class is child entity |
|
193 aStream.WriteInt32L( NcdNodeClassIds::ENcdChildEntityClassId ); |
|
194 childEntitys[ i ]->ExternalizeL( aStream ); |
|
195 } |
|
196 |
|
197 // Close the array, but do not delete its elements that are owned else where. |
|
198 CleanupStack::PopAndDestroy( &childEntitys ); |
|
199 DPROFILING_END( x ); |
|
200 DLTRACEOUT(("")); |
|
201 } |
|
202 |
|
203 |
|
204 void CNcdParentOfTransparentNode::ReceiveMessage( MCatalogsBaseMessage* aMessage, |
|
205 TInt aFunctionNumber ) |
|
206 { |
|
207 DLTRACEIN(("handle: %d, function: %d", aMessage->Handle(), |
|
208 aFunctionNumber)); |
|
209 |
|
210 DASSERT( aMessage ); |
|
211 |
|
212 // Now, we can be sure that rest of the time iMessage exists. |
|
213 // This member variable is set for the CounterPartLost function. |
|
214 iMessage = aMessage; |
|
215 |
|
216 TInt trapError( KErrNone ); |
|
217 |
|
218 switch( aFunctionNumber ) |
|
219 { |
|
220 case NcdNodeFunctionIds::ENcdIsTransparentChildExpired: |
|
221 TRAP( trapError, IsTransparentChildExpiredL( *aMessage ) ); |
|
222 break; |
|
223 |
|
224 default: |
|
225 // Let base class handle this message |
|
226 iMessage = NULL; |
|
227 CNcdNodeFolder::ReceiveMessage( aMessage, aFunctionNumber ); |
|
228 return; |
|
229 } |
|
230 |
|
231 if ( trapError != KErrNone ) |
|
232 { |
|
233 // Because something went wrong the complete has not been |
|
234 // yet called for the message. |
|
235 // So, inform the client about the error. |
|
236 DLTRACEIN(("Complete with error message")); |
|
237 aMessage->CompleteAndRelease( trapError ); |
|
238 } |
|
239 |
|
240 // Because the message should not be used after this, set it NULL. |
|
241 // So, CounterPartLost function will know that no messages are |
|
242 // waiting the response at the moment. |
|
243 iMessage = NULL; |
|
244 |
|
245 DLTRACEOUT(("")); |
|
246 } |
|
247 |
|
248 void CNcdParentOfTransparentNode::IsTransparentChildExpiredL( MCatalogsBaseMessage& aMessage ) const |
|
249 { |
|
250 DLTRACEIN(("")); |
|
251 |
|
252 CBufBase* buf = CBufFlat::NewL( KBufExpandSize ); |
|
253 CleanupStack::PushL( buf ); |
|
254 |
|
255 RBufWriteStream stream( *buf ); |
|
256 CleanupClosePushL( stream ); |
|
257 |
|
258 // Write the value to the stream |
|
259 stream.WriteInt32L( IsTransparentChildExpiredL() ); |
|
260 |
|
261 // Commits data to the stream when closing. |
|
262 CleanupStack::PopAndDestroy( &stream ); |
|
263 |
|
264 if ( buf->Size() > 0 ) |
|
265 { |
|
266 DLINFO(( "Completing the message, buf len: %d", buf->Ptr(0).Length() )); |
|
267 } |
|
268 |
|
269 // If this leaves ReceiveMessage function will complete the message. |
|
270 aMessage.CompleteAndReleaseL( buf->Ptr( 0 ), KErrNone ); |
|
271 |
|
272 |
|
273 DLINFO(("Deleting the buf")); |
|
274 CleanupStack::PopAndDestroy( buf ); |
|
275 |
|
276 DLTRACEOUT(("")); |
|
277 } |
|
278 |
|
279 TBool CNcdParentOfTransparentNode::IsTransparentChildExpiredL() const |
|
280 { |
|
281 DLTRACEIN(("")); |
|
282 TBool isTransparentChildExpired = EFalse; |
|
283 for( TInt i = 0 ; i < ServerChildCountL() ; i++ ) |
|
284 { |
|
285 CNcdNode* child = NULL; |
|
286 TRAPD( err, child = &NodeManager().NodeL( ChildByServerIndexL(i) ) ); |
|
287 if( err == KErrNotFound || |
|
288 ( err == KErrNone && |
|
289 child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId && |
|
290 child->State() != MNcdNode::EStateInitialized ) ) |
|
291 { |
|
292 DLTRACE(("At least one child was expired/uninitialized/not found.")); |
|
293 isTransparentChildExpired = ETrue; |
|
294 break; |
|
295 } |
|
296 else if ( err == KErrNone && |
|
297 child->ClassId() == NcdNodeClassIds::ENcdTransparentFolderNodeClassId && |
|
298 child->State() == MNcdNode::EStateInitialized ) |
|
299 { |
|
300 DLTRACE(("Transparent child folder, check it's children")); |
|
301 CNcdNodeTransparentFolder* transpFolder = |
|
302 static_cast<CNcdNodeTransparentFolder*>(child); |
|
303 if ( transpFolder->HasExpiredOrMissingChildrenL() ) |
|
304 { |
|
305 DLTRACE(("Transparent child folder's child expired or missing.")); |
|
306 isTransparentChildExpired = ETrue; |
|
307 break; |
|
308 } |
|
309 } |
|
310 else if ( err != KErrNone && err != KErrNotFound ) |
|
311 { |
|
312 DLTRACE(("Error: %d", err)); |
|
313 User::Leave( err ); |
|
314 } |
|
315 } |
|
316 return isTransparentChildExpired; |
|
317 } |