messagingfw/wappushfw/SISLContentHandlers/src/CSLContentHandler.cpp
changeset 0 8e480a14352b
--- /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 );
+	}
+
+