--- /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 <push/sislpushmsgutils.h>
+#include <push/cslpushmsgentry.h>
+#include <escapeutils.h>
+#include <msvids.h>
+
+#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 );
+ }
+
+