|
1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 // Local includes |
|
17 // |
|
18 #include "CSLContentHandler.h" |
|
19 |
|
20 // System includes |
|
21 // |
|
22 #include <push/sislpushmsgutils.h> |
|
23 #include <push/cslpushmsgentry.h> |
|
24 #include <escapeutils.h> |
|
25 #include <msvids.h> |
|
26 |
|
27 #include "sltagstable.h" |
|
28 #include "slattributetable.h" |
|
29 #include "slattributevaluetable.h" |
|
30 |
|
31 //text SL MIME type |
|
32 //_LIT(KSLTextContentType, "text/vnd.wap.sl"); |
|
33 |
|
34 #if defined(_DEBUG) |
|
35 _LIT(KErrPushMsgNull, "NULL CPushMessage"); |
|
36 #endif |
|
37 |
|
38 // Constants |
|
39 _LIT(KReserved, "Reserved"); |
|
40 |
|
41 void CSLContentHandler::CPushHandlerBase_Reserved1() |
|
42 { |
|
43 User::Panic(KReserved, KErrNotSupported); |
|
44 } |
|
45 |
|
46 void CSLContentHandler::CPushHandlerBase_Reserved2() |
|
47 { |
|
48 User::Panic(KReserved, KErrNotSupported); |
|
49 } |
|
50 |
|
51 /** |
|
52 * The SL Content handler private constructor. |
|
53 * Index number : ESLContentHandlerIndex |
|
54 */ |
|
55 CSLContentHandler::CSLContentHandler() |
|
56 : CContentHandlerBase(), iPushMsgAction(KErrNotFound), iSlMsgEntryId(KMsvNullIndexEntryId) |
|
57 { |
|
58 } |
|
59 |
|
60 /** |
|
61 * This will complete initialization of the object |
|
62 */ |
|
63 void CSLContentHandler::ConstructL() |
|
64 { |
|
65 iWapPushUtils= CSISLPushMsgUtils::NewL(); |
|
66 CActiveScheduler::Add(this); |
|
67 } |
|
68 |
|
69 /** |
|
70 * Static Factory Construction |
|
71 * |
|
72 * Version of NewL which leaves nothing |
|
73 * on the cleanup stack |
|
74 */ |
|
75 CSLContentHandler* CSLContentHandler::NewL() |
|
76 { |
|
77 CSLContentHandler* self = new(ELeave) CSLContentHandler; |
|
78 CleanupStack::PushL(self); |
|
79 self->ConstructL(); |
|
80 CleanupStack::Pop(self); |
|
81 return self; |
|
82 } |
|
83 |
|
84 /** |
|
85 * Default d'tor |
|
86 */ |
|
87 CSLContentHandler::~CSLContentHandler() |
|
88 { |
|
89 __LOG_PTR_DEBUG("CSLContentHandler:: Destructor Called"); |
|
90 delete iHrefBuf; |
|
91 delete iWapPushUtils; |
|
92 } |
|
93 |
|
94 /** |
|
95 * HandleMessage Async. Version |
|
96 * Takes ownership of Push Message and sets self active to continue |
|
97 * processing message. |
|
98 * @param aPushMsg |
|
99 * CPushMessage to process |
|
100 * @param aStatus |
|
101 * request status variable for use in asynchronous operations |
|
102 */ |
|
103 void CSLContentHandler::HandleMessageL(CPushMessage* aPushMsg, TRequestStatus& aStatus) |
|
104 { |
|
105 __LOG_PTR_DEBUG("CSLContentHandler:: HandleMessage Async Func. Called"); |
|
106 __ASSERT_DEBUG( aPushMsg != NULL, User::Panic(KErrPushMsgNull, KErrNone)); |
|
107 |
|
108 iMessage = aPushMsg; |
|
109 iAcknowledge = ETrue; |
|
110 SetConfirmationStatus(aStatus); |
|
111 |
|
112 iState= EParsing; |
|
113 IdleComplete(); |
|
114 } |
|
115 |
|
116 /** |
|
117 * HandleMessage Sync. Version |
|
118 * Takes ownership of Push Message and sets self active to continue |
|
119 * processing message. |
|
120 * |
|
121 * Initial State: Set data members then go to the next state |
|
122 * @param aPushMsg |
|
123 * CPushMessage to process |
|
124 */ |
|
125 void CSLContentHandler::HandleMessageL(CPushMessage* aPushMsg) |
|
126 { |
|
127 __LOG_PTR_DEBUG("CSLContentHandler:: HandleMessage Sync Func. Called"); |
|
128 __ASSERT_DEBUG( aPushMsg != NULL, User::Panic(KErrPushMsgNull, KErrNone)); |
|
129 |
|
130 iAcknowledge = EFalse; |
|
131 iMessage = aPushMsg; |
|
132 |
|
133 iState= EParsing; |
|
134 IdleComplete(); |
|
135 } |
|
136 |
|
137 /** |
|
138 * Parse the Push SL message using XML parser. |
|
139 * If Push Message is an SLC then convert it first to text using |
|
140 * CWbxmlConverterUtil class. |
|
141 */ |
|
142 void CSLContentHandler::ParsePushMsgL() |
|
143 { |
|
144 __LOG_PTR_DEBUG("CSLContentHandler::ParsePushMsgL called") |
|
145 |
|
146 CMessageParser* myParser = CMessageParser::NewL ( *iMessage, |
|
147 *this, |
|
148 &sltagstable::Table, |
|
149 &slattributetable::Table, |
|
150 &slattributevaluetable::Table ); |
|
151 CleanupStack::PushL ( myParser ); |
|
152 myParser->ParseMessageL (); |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 |
|
161 |
|
162 |
|
163 User::LeaveIfError ( myParser->LastError() ); |
|
164 |
|
165 CleanupStack::PopAndDestroy ( myParser ); |
|
166 |
|
167 // if 'action' attribute not specified, the value 'execute-low' is used. |
|
168 if( iPushMsgAction == KErrNotFound ) |
|
169 { |
|
170 iPushMsgAction= CSLPushMsgEntry::ESLPushMsgExecuteLow; |
|
171 } |
|
172 |
|
173 |
|
174 |
|
175 // 'href' attribute is mandatory, if not specified then leave with an error. |
|
176 if( !iHrefBuf ) |
|
177 { |
|
178 User::Leave(KErrCorrupt); |
|
179 } |
|
180 |
|
181 iState= ESearching; |
|
182 IdleComplete(); |
|
183 } |
|
184 |
|
185 /** |
|
186 * Searching for an existing SL Msg entry in the message store |
|
187 */ |
|
188 void CSLContentHandler::SearchingForDuplicatesMsgEntryL() |
|
189 { |
|
190 __LOG_PTR_DEBUG("CWapPushMsgUtils: FindUrlL called") |
|
191 iSlMsgEntryId= iWapPushUtils->FindUrlL(*iHrefBuf, KUidWapPushMsgSL); |
|
192 |
|
193 iState= EProcessing; |
|
194 IdleComplete(); |
|
195 } |
|
196 |
|
197 /** |
|
198 * Creating/Saving or Updating SL Msg Entry in the message store |
|
199 * - If there is NO duplicate Msg then Create/Save a PushMsgEntry from |
|
200 * the received PushMsg. |
|
201 * - If there is a duplicate Msg then Update the existing PushMsgEntry. |
|
202 * |
|
203 * The recieved PushMsg is deleted in any case in the destructor. |
|
204 */ |
|
205 void CSLContentHandler::ProcessingPushMsgEntryL() |
|
206 { |
|
207 TBool isInt; |
|
208 TPtrC8 appURI; |
|
209 TInt appID=0; |
|
210 iMessage->GetAppIdL(appURI, appID, isInt); |
|
211 |
|
212 CSLPushMsgEntry* slPushMsgEntry=NULL; |
|
213 if (isInt) |
|
214 { |
|
215 slPushMsgEntry = CSLPushMsgEntry::NewL(appID); |
|
216 } |
|
217 else |
|
218 { |
|
219 slPushMsgEntry = CSLPushMsgEntry::NewL(appURI); |
|
220 } |
|
221 CleanupStack::PushL(slPushMsgEntry); |
|
222 |
|
223 if(iSlMsgEntryId == KMsvNullIndexEntryId) |
|
224 { |
|
225 //SL Msg with same href not existing in Msg Store ==> Create/Save the SL Msg |
|
226 SetSlPushMsgEntryFieldsL(*slPushMsgEntry); |
|
227 TMsvId localFolderId; |
|
228 iWapPushUtils->GetPushMsgFolderIdL(localFolderId); |
|
229 __LOG_PTR_DEBUG("CSLPushMsgEntry: SaveL called"); |
|
230 iSlMsgEntryId = slPushMsgEntry->SaveL(iWapPushUtils->Session(), localFolderId); |
|
231 } |
|
232 else |
|
233 { |
|
234 //Find Msg of the same href THEN need to Update IF it has a low priorty action attribute |
|
235 __LOG_PTR_DEBUG("CWapPushMsgUtils: GetAction called"); |
|
236 if(iPushMsgAction > iWapPushUtils->GetActionL(iSlMsgEntryId)) |
|
237 { |
|
238 // The received SL Push Msg has higher action than existing SL Entry THEN |
|
239 // Update existing SL Msg Entry |
|
240 // Change header Fields and action Attribute on the existing entry and UPDATE |
|
241 __LOG_PTR_DEBUG("CSLPushMsgEntry: RetrieveL called"); |
|
242 slPushMsgEntry->RetrieveL(iWapPushUtils->Session(),iSlMsgEntryId); |
|
243 SetSlPushMsgEntryFieldsL(*slPushMsgEntry); |
|
244 __LOG_PTR_DEBUG("CSLPushMsgEntry: UpdateL called"); |
|
245 slPushMsgEntry->UpdateL(iWapPushUtils->Session()); |
|
246 } |
|
247 } |
|
248 CleanupStack::PopAndDestroy(); //slPushMsgEntry |
|
249 |
|
250 iState= EDone; |
|
251 IdleComplete(); |
|
252 } |
|
253 |
|
254 /** |
|
255 * Set SL entry fields prior to storing message. |
|
256 * @param aSlPushMsgEntry |
|
257 * entry represents message format to use when storing it |
|
258 */ |
|
259 void CSLContentHandler::SetSlPushMsgEntryFieldsL(CSLPushMsgEntry& aSlPushMsgEntry) |
|
260 { |
|
261 |
|
262 //set URL and Action fields |
|
263 aSlPushMsgEntry.SetUrlL(*iHrefBuf); |
|
264 aSlPushMsgEntry.SetAction(iPushMsgAction); |
|
265 |
|
266 // Set all the relevant header fields |
|
267 TPtrC8 msgHeaderPtr; |
|
268 iMessage->GetHeader(msgHeaderPtr); |
|
269 aSlPushMsgEntry.SetHeaderL(msgHeaderPtr); |
|
270 |
|
271 TPtrC8 from; |
|
272 if (!iMessage->GetBinaryHeaderField(EHttpFrom,from) && |
|
273 !iMessage->GetBinaryHeaderField(EHttpXWapInitiatorURI,from) && |
|
274 !iMessage->GetBinaryHeaderField(EHttpContentLocation,from) ) |
|
275 { |
|
276 from.Set(KNullDesC8); |
|
277 } |
|
278 aSlPushMsgEntry.SetFromL(from); |
|
279 |
|
280 if(iMessage->MessageAllowed()) |
|
281 { |
|
282 aSlPushMsgEntry.SetTrusted(ETrue); |
|
283 } |
|
284 else |
|
285 { |
|
286 aSlPushMsgEntry.SetTrusted(EFalse); |
|
287 } |
|
288 |
|
289 TPtrC8 serverAddress8; |
|
290 iMessage->GetServerAddress(serverAddress8); |
|
291 aSlPushMsgEntry.SetMsgOriginUriL(serverAddress8); |
|
292 |
|
293 TTime puchMsgDate; |
|
294 if(iMessage->GetHeaderField(EHttpDate, puchMsgDate)) |
|
295 aSlPushMsgEntry.SetTimeSent(puchMsgDate ); |
|
296 } |
|
297 |
|
298 /** |
|
299 * Same functionality as DoCancel() |
|
300 */ |
|
301 void CSLContentHandler::CancelHandleMessage() |
|
302 { |
|
303 __LOG_PTR_DEBUG("CSLContentHandler:: CancelHandleMessage Called"); |
|
304 Complete(KErrCancel); |
|
305 } |
|
306 |
|
307 /** |
|
308 * Terminates any activity |
|
309 */ |
|
310 void CSLContentHandler::DoCancel() |
|
311 { |
|
312 __LOG_PTR_DEBUG("CSLContentHandler:: DoCancel Called"); |
|
313 Complete(KErrCancel); |
|
314 } |
|
315 |
|
316 /** |
|
317 * Step through the various representative states for handling a message |
|
318 * Four States: |
|
319 * EParsing - Parses SL push message (retrieving the href and action attributes) |
|
320 * ESearching - Searching in the msg Store for any duplicate Sl Msg Entry |
|
321 * EProcessing - Save or update SL msg in the Msg store |
|
322 * EDone - Clean up |
|
323 */ |
|
324 void CSLContentHandler::RunL() |
|
325 { |
|
326 __LOG_PTR_DEBUG("CSLContentHandler:: RunL Called"); |
|
327 switch(iState) |
|
328 { |
|
329 case EParsing: |
|
330 ParsePushMsgL(); |
|
331 break; |
|
332 case ESearching: |
|
333 SearchingForDuplicatesMsgEntryL(); |
|
334 break; |
|
335 case EProcessing: |
|
336 ProcessingPushMsgEntryL(); |
|
337 break; |
|
338 case EDone: |
|
339 Complete(KErrNone); |
|
340 break; |
|
341 default: |
|
342 break; |
|
343 } |
|
344 } |
|
345 |
|
346 /** |
|
347 * This is invoked when RunL Leaves with an error so clean up and return |
|
348 */ |
|
349 TInt CSLContentHandler::RunError(TInt aError) |
|
350 { |
|
351 __LOG_PTR_DEBUG("CSLContentHandler::RunError Called"); |
|
352 iState=EDone; |
|
353 Complete(aError); |
|
354 return KErrNone; |
|
355 } |
|
356 |
|
357 void CSLContentHandler::HandleElementL ( const RString& /* aTag */, const RString& aAttributeName, const RString& aAttributeValue ) |
|
358 { |
|
359 __LOG_PTR_DEBUG("CSIContentHandler:: HandleElementL Called"); |
|
360 |
|
361 switch ( aAttributeName.Index ( slattributetable::Table ) ) |
|
362 { |
|
363 case slattributetable::EHref: |
|
364 delete iHrefBuf; |
|
365 iHrefBuf = NULL; |
|
366 iHrefBuf = EscapeUtils::ConvertToUnicodeFromUtf8L ( aAttributeValue.DesC() ); |
|
367 break; |
|
368 |
|
369 case slattributetable::EAction1: |
|
370 case slattributetable::EAction2: |
|
371 case slattributetable::EAction3: |
|
372 { |
|
373 switch ( aAttributeValue.Index ( slattributevaluetable::Table ) ) |
|
374 { |
|
375 // execute-low |
|
376 case slattributevaluetable::EAction1: |
|
377 iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteLow; |
|
378 break; |
|
379 |
|
380 case slattributevaluetable::EAction2: |
|
381 iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteHigh; |
|
382 break; |
|
383 |
|
384 case slattributevaluetable::EAction3: |
|
385 iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteCache; |
|
386 break; |
|
387 |
|
388 default: |
|
389 // shouldn't come here. |
|
390 User::Invariant (); |
|
391 } |
|
392 } |
|
393 break; |
|
394 |
|
395 default: |
|
396 // shouldn't come here. |
|
397 User::Invariant (); |
|
398 } |
|
399 } |
|
400 |
|
401 void CSLContentHandler::HandleContentL ( const TDesC8& /* aBytes */ ) |
|
402 { |
|
403 // SL message doesn't contain text. so can be ignored. |
|
404 User::LeaveIfError ( KErrNone ); |
|
405 } |
|
406 |
|
407 |