diff -r 000000000000 -r 8e480a14352b messagingfw/wappushfw/SISLContentHandlers/src/CSLContentHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/wappushfw/SISLContentHandlers/src/CSLContentHandler.cpp Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,407 @@ +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// + +// Local includes +// +#include "CSLContentHandler.h" + +// System includes +// +#include +#include +#include +#include + +#include "sltagstable.h" +#include "slattributetable.h" +#include "slattributevaluetable.h" + +//text SL MIME type +//_LIT(KSLTextContentType, "text/vnd.wap.sl"); + +#if defined(_DEBUG) +_LIT(KErrPushMsgNull, "NULL CPushMessage"); +#endif + +// Constants +_LIT(KReserved, "Reserved"); + +void CSLContentHandler::CPushHandlerBase_Reserved1() + { + User::Panic(KReserved, KErrNotSupported); + } + +void CSLContentHandler::CPushHandlerBase_Reserved2() + { + User::Panic(KReserved, KErrNotSupported); + } + +/** + * The SL Content handler private constructor. + * Index number : ESLContentHandlerIndex + */ +CSLContentHandler::CSLContentHandler() +: CContentHandlerBase(), iPushMsgAction(KErrNotFound), iSlMsgEntryId(KMsvNullIndexEntryId) + { + } + +/** + * This will complete initialization of the object + */ +void CSLContentHandler::ConstructL() + { + iWapPushUtils= CSISLPushMsgUtils::NewL(); + CActiveScheduler::Add(this); + } + +/** + * Static Factory Construction + * + * Version of NewL which leaves nothing + * on the cleanup stack + */ +CSLContentHandler* CSLContentHandler::NewL() + { + CSLContentHandler* self = new(ELeave) CSLContentHandler; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/** + * Default d'tor + */ +CSLContentHandler::~CSLContentHandler() + { + __LOG_PTR_DEBUG("CSLContentHandler:: Destructor Called"); + delete iHrefBuf; + delete iWapPushUtils; + } + +/** + * HandleMessage Async. Version + * Takes ownership of Push Message and sets self active to continue + * processing message. + * @param aPushMsg + * CPushMessage to process + * @param aStatus + * request status variable for use in asynchronous operations + */ +void CSLContentHandler::HandleMessageL(CPushMessage* aPushMsg, TRequestStatus& aStatus) + { + __LOG_PTR_DEBUG("CSLContentHandler:: HandleMessage Async Func. Called"); + __ASSERT_DEBUG( aPushMsg != NULL, User::Panic(KErrPushMsgNull, KErrNone)); + + iMessage = aPushMsg; + iAcknowledge = ETrue; + SetConfirmationStatus(aStatus); + + iState= EParsing; + IdleComplete(); + } + +/** + * HandleMessage Sync. Version + * Takes ownership of Push Message and sets self active to continue + * processing message. + * + * Initial State: Set data members then go to the next state + * @param aPushMsg + * CPushMessage to process + */ +void CSLContentHandler::HandleMessageL(CPushMessage* aPushMsg) + { + __LOG_PTR_DEBUG("CSLContentHandler:: HandleMessage Sync Func. Called"); + __ASSERT_DEBUG( aPushMsg != NULL, User::Panic(KErrPushMsgNull, KErrNone)); + + iAcknowledge = EFalse; + iMessage = aPushMsg; + + iState= EParsing; + IdleComplete(); + } + +/** + * Parse the Push SL message using XML parser. + * If Push Message is an SLC then convert it first to text using + * CWbxmlConverterUtil class. + */ +void CSLContentHandler::ParsePushMsgL() + { + __LOG_PTR_DEBUG("CSLContentHandler::ParsePushMsgL called") + + CMessageParser* myParser = CMessageParser::NewL ( *iMessage, + *this, + &sltagstable::Table, + &slattributetable::Table, + &slattributevaluetable::Table ); + CleanupStack::PushL ( myParser ); + myParser->ParseMessageL (); + + + + + + + + + + + User::LeaveIfError ( myParser->LastError() ); + + CleanupStack::PopAndDestroy ( myParser ); + + // if 'action' attribute not specified, the value 'execute-low' is used. + if( iPushMsgAction == KErrNotFound ) + { + iPushMsgAction= CSLPushMsgEntry::ESLPushMsgExecuteLow; + } + + + + // 'href' attribute is mandatory, if not specified then leave with an error. + if( !iHrefBuf ) + { + User::Leave(KErrCorrupt); + } + + iState= ESearching; + IdleComplete(); + } + +/** + * Searching for an existing SL Msg entry in the message store + */ +void CSLContentHandler::SearchingForDuplicatesMsgEntryL() + { + __LOG_PTR_DEBUG("CWapPushMsgUtils: FindUrlL called") + iSlMsgEntryId= iWapPushUtils->FindUrlL(*iHrefBuf, KUidWapPushMsgSL); + + iState= EProcessing; + IdleComplete(); + } + +/** + * Creating/Saving or Updating SL Msg Entry in the message store + * - If there is NO duplicate Msg then Create/Save a PushMsgEntry from + * the received PushMsg. + * - If there is a duplicate Msg then Update the existing PushMsgEntry. + * + * The recieved PushMsg is deleted in any case in the destructor. + */ +void CSLContentHandler::ProcessingPushMsgEntryL() + { + TBool isInt; + TPtrC8 appURI; + TInt appID=0; + iMessage->GetAppIdL(appURI, appID, isInt); + + CSLPushMsgEntry* slPushMsgEntry=NULL; + if (isInt) + { + slPushMsgEntry = CSLPushMsgEntry::NewL(appID); + } + else + { + slPushMsgEntry = CSLPushMsgEntry::NewL(appURI); + } + CleanupStack::PushL(slPushMsgEntry); + + if(iSlMsgEntryId == KMsvNullIndexEntryId) + { + //SL Msg with same href not existing in Msg Store ==> Create/Save the SL Msg + SetSlPushMsgEntryFieldsL(*slPushMsgEntry); + TMsvId localFolderId; + iWapPushUtils->GetPushMsgFolderIdL(localFolderId); + __LOG_PTR_DEBUG("CSLPushMsgEntry: SaveL called"); + iSlMsgEntryId = slPushMsgEntry->SaveL(iWapPushUtils->Session(), localFolderId); + } + else + { + //Find Msg of the same href THEN need to Update IF it has a low priorty action attribute + __LOG_PTR_DEBUG("CWapPushMsgUtils: GetAction called"); + if(iPushMsgAction > iWapPushUtils->GetActionL(iSlMsgEntryId)) + { + // The received SL Push Msg has higher action than existing SL Entry THEN + // Update existing SL Msg Entry + // Change header Fields and action Attribute on the existing entry and UPDATE + __LOG_PTR_DEBUG("CSLPushMsgEntry: RetrieveL called"); + slPushMsgEntry->RetrieveL(iWapPushUtils->Session(),iSlMsgEntryId); + SetSlPushMsgEntryFieldsL(*slPushMsgEntry); + __LOG_PTR_DEBUG("CSLPushMsgEntry: UpdateL called"); + slPushMsgEntry->UpdateL(iWapPushUtils->Session()); + } + } + CleanupStack::PopAndDestroy(); //slPushMsgEntry + + iState= EDone; + IdleComplete(); + } + +/** + * Set SL entry fields prior to storing message. + * @param aSlPushMsgEntry + * entry represents message format to use when storing it + */ +void CSLContentHandler::SetSlPushMsgEntryFieldsL(CSLPushMsgEntry& aSlPushMsgEntry) + { + + //set URL and Action fields + aSlPushMsgEntry.SetUrlL(*iHrefBuf); + aSlPushMsgEntry.SetAction(iPushMsgAction); + + // Set all the relevant header fields + TPtrC8 msgHeaderPtr; + iMessage->GetHeader(msgHeaderPtr); + aSlPushMsgEntry.SetHeaderL(msgHeaderPtr); + + TPtrC8 from; + if (!iMessage->GetBinaryHeaderField(EHttpFrom,from) && + !iMessage->GetBinaryHeaderField(EHttpXWapInitiatorURI,from) && + !iMessage->GetBinaryHeaderField(EHttpContentLocation,from) ) + { + from.Set(KNullDesC8); + } + aSlPushMsgEntry.SetFromL(from); + + if(iMessage->MessageAllowed()) + { + aSlPushMsgEntry.SetTrusted(ETrue); + } + else + { + aSlPushMsgEntry.SetTrusted(EFalse); + } + + TPtrC8 serverAddress8; + iMessage->GetServerAddress(serverAddress8); + aSlPushMsgEntry.SetMsgOriginUriL(serverAddress8); + + TTime puchMsgDate; + if(iMessage->GetHeaderField(EHttpDate, puchMsgDate)) + aSlPushMsgEntry.SetTimeSent(puchMsgDate ); + } + +/** + * Same functionality as DoCancel() + */ +void CSLContentHandler::CancelHandleMessage() + { + __LOG_PTR_DEBUG("CSLContentHandler:: CancelHandleMessage Called"); + Complete(KErrCancel); + } + +/** + * Terminates any activity + */ +void CSLContentHandler::DoCancel() + { + __LOG_PTR_DEBUG("CSLContentHandler:: DoCancel Called"); + Complete(KErrCancel); + } + +/** + * Step through the various representative states for handling a message + * Four States: + * EParsing - Parses SL push message (retrieving the href and action attributes) + * ESearching - Searching in the msg Store for any duplicate Sl Msg Entry + * EProcessing - Save or update SL msg in the Msg store + * EDone - Clean up + */ +void CSLContentHandler::RunL() + { + __LOG_PTR_DEBUG("CSLContentHandler:: RunL Called"); + switch(iState) + { + case EParsing: + ParsePushMsgL(); + break; + case ESearching: + SearchingForDuplicatesMsgEntryL(); + break; + case EProcessing: + ProcessingPushMsgEntryL(); + break; + case EDone: + Complete(KErrNone); + break; + default: + break; + } + } + +/** + * This is invoked when RunL Leaves with an error so clean up and return + */ +TInt CSLContentHandler::RunError(TInt aError) + { + __LOG_PTR_DEBUG("CSLContentHandler::RunError Called"); + iState=EDone; + Complete(aError); + return KErrNone; + } + +void CSLContentHandler::HandleElementL ( const RString& /* aTag */, const RString& aAttributeName, const RString& aAttributeValue ) + { + __LOG_PTR_DEBUG("CSIContentHandler:: HandleElementL Called"); + + switch ( aAttributeName.Index ( slattributetable::Table ) ) + { + case slattributetable::EHref: + delete iHrefBuf; + iHrefBuf = NULL; + iHrefBuf = EscapeUtils::ConvertToUnicodeFromUtf8L ( aAttributeValue.DesC() ); + break; + + case slattributetable::EAction1: + case slattributetable::EAction2: + case slattributetable::EAction3: + { + switch ( aAttributeValue.Index ( slattributevaluetable::Table ) ) + { + // execute-low + case slattributevaluetable::EAction1: + iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteLow; + break; + + case slattributevaluetable::EAction2: + iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteHigh; + break; + + case slattributevaluetable::EAction3: + iPushMsgAction = CSLPushMsgEntry::ESLPushMsgExecuteCache; + break; + + default: + // shouldn't come here. + User::Invariant (); + } + } + break; + + default: + // shouldn't come here. + User::Invariant (); + } + } + +void CSLContentHandler::HandleContentL ( const TDesC8& /* aBytes */ ) + { + // SL message doesn't contain text. so can be ignored. + User::LeaveIfError ( KErrNone ); + } + +