applayerprotocols/wappushsupport/XmlLib/XmlLib.cpp
changeset 0 b16258d2340f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/applayerprotocols/wappushsupport/XmlLib/XmlLib.cpp	Tue Feb 02 01:09:52 2010 +0200
@@ -0,0 +1,291 @@
+// Copyright (c) 1999-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:
+// XmlLib.h
+// 
+//
+
+// Local includes
+//
+#include "XmlPars.h"
+#include "XmlValid.h"
+
+//	System includes
+//
+#include <attrlut.h>
+#include <xmlelemt.h>
+#include <wapattrdf.h>
+#include <estatus.h>
+#include <mwappluginsp.h>
+#include <mframeworksp.h>
+#include <xmllib.h>
+
+//	METHOD IMPLEMENTATIONS
+//
+
+EXPORT_C CXmlLibrary::CXmlLibrary(MWapPluginSP& aPluginSP, CXmlElement* aRootNode)
+: iPluginSP(aPluginSP), iRootNode(aRootNode)
+	{
+	}
+
+EXPORT_C CXmlLibrary::~CXmlLibrary()
+	{
+	delete iParser;
+	}
+
+EXPORT_C CXmlLibrary* CXmlLibrary::NewL(MWapPluginSP& aPluginSP, CXmlElement* aRootNode)
+	{
+	CXmlLibrary* self = CXmlLibrary::NewLC(aPluginSP, aRootNode);
+	CleanupStack::Pop(self);
+	return(self);
+	}
+
+EXPORT_C CXmlLibrary* CXmlLibrary::NewLC(MWapPluginSP& aPluginSP, CXmlElement* aRootNode)
+	{
+	CXmlLibrary* self = new(ELeave) CXmlLibrary(aPluginSP, aRootNode);
+	CleanupStack::PushL(self);
+	self->ConstructL();
+	return(self);
+	}
+
+EXPORT_C void CXmlLibrary::ConstructL()
+	{
+	}
+
+EXPORT_C void CXmlLibrary::PrepareParserL()
+// A utlity method to set up the parser for parsing
+// Notice, that the iRootNode has to be set before this one is called!
+	{
+	iParser = CXmlParser::NewL(iPluginSP.AttributeLUT());
+	iParser->ResetL(iRootNode);
+	}
+
+EXPORT_C void CXmlLibrary::ResetL(CXmlElement* aRootNode)
+// Reset the library and parser for processing of new document
+	{
+	iRootNode = aRootNode;
+	iDTD = NULL;
+	if( iParser != NULL)
+		{
+		iParser->ResetL(iRootNode);
+		}
+	}
+
+// WAP 1.2 Addition!
+EXPORT_C TInt CXmlLibrary::ProcessDataL(TDesC8& aData)
+	{
+	HBufC8* newData = aData.AllocLC();
+	TInt ret = ProcessDataL(*newData);
+	CleanupStack::PopAndDestroy();	// newData
+	return (ret);
+	}
+
+EXPORT_C TInt CXmlLibrary::ProcessDataL(HBufC8& aData)
+// Method for processing the streaming data
+	{
+	if( iParser == NULL )
+		{
+		PrepareParserL();
+		}
+	iParser->ProcessDataL(aData);
+
+	return( ExecuteDataProcessingL() );
+	}
+
+EXPORT_C TInt CXmlLibrary::CommitL()
+// Method to inform the library that all the data has been passed in
+// Performs finishing tasks for the parsing, checks if all the data was parsed
+// correctly and if the DTD tree was available the validation is also performed!
+	{
+	TInt returnCode = CommitParserL();
+	if( returnCode != KErrNone )
+		{
+		return( returnCode );
+		}
+
+	if( iDTD != NULL )
+		{
+		// iDTD contains the correct dtdRoot, call the protected method
+		return( ExecuteValidateL(iDTD) );
+		}
+
+	return(KErrNone);
+	}
+
+EXPORT_C TInt CXmlLibrary::ValidateL(CBNFNode& aDTDRootNode)
+// Service method for validation
+	{
+	CBNFNode* dtdTree = ExtractDTDTree(&aDTDRootNode);
+	if( dtdTree == NULL )
+		{
+		// Check to see if we have buffered the data.
+		const HBufC* id = iPluginSP.AttributeLUT().Des2IDL(KXmlLibBufferedDocumentAttribute);
+		if (iRootNode->AttributeExists(id))
+			{
+			// Attribute exists - delete the data adn attribute
+			CDataNoDelete* attribute = (CDataNoDelete*)iRootNode->CNode::Attribute((TAny*)id);
+			HBufC* bufferedDocument = (HBufC*)attribute->Data();
+			delete bufferedDocument;
+			iRootNode->DeleteAttribute(id);
+			}
+		return( EWapErrXmlLibInvalidDTD );
+		}
+	return( ExecuteValidateL(dtdTree) );
+	}
+
+EXPORT_C TInt CXmlLibrary::ExecuteValidateL(CBNFNode* aDTDRootNode)
+// Actual execution of validation. This method can be overridden by
+// inheriting classes.
+// The aDTDRootNode MUST contain the actual DTD tree, not the engine Root.
+	{
+	TInt returnValue = KErrNone;
+
+	// Check if the document has already been validated
+	const HBufC* validAttrId = iPluginSP.AttributeLUT().Des2IDL(KWAPDocumentValidStatusAttributeName);
+	if( iRootNode->AttributeExists(validAttrId) )
+		{
+		return( EWapErrXmlLibDocumentAlreadyValid );
+		}
+
+	// If there was no DTD during the parsing the incoming data was buffered and
+	// attached as an attribute to the document root node. Now we have received all
+	// the data and have a DTD, so parse the document again!
+	const HBufC* id = iPluginSP.AttributeLUT().Des2IDL(KXmlLibBufferedDocumentAttribute);
+	if( iRootNode->AttributeExists(id) )
+		{
+		if( iDTD == NULL )
+			{
+			iDTD = aDTDRootNode;
+			}
+		if( iParser != NULL )
+			{
+			iParser->ResetL(iRootNode);
+			}
+		CDataNoDelete* attribute = (CDataNoDelete*)iRootNode->CNode::Attribute((TAny*)id);
+		HBufC* bufferedDocument = (HBufC*)attribute->Data();
+		iRootNode->DeleteAttribute(id);
+		returnValue = ProcessDataL(bufferedDocument);
+		if( returnValue == KErrNone )
+			{
+			returnValue = CommitParserL();
+			}
+		if(returnValue != KErrNone )
+			{
+			return(returnValue);
+			}
+		}
+	// Validation of the parsed document
+	CXmlValidator* validator = CXmlValidator::NewL(*aDTDRootNode, iPluginSP.AttributeLUT());
+	CleanupStack::PushL(validator);
+	returnValue = validator->ValidateTreeL(iRootNode);
+	CleanupStack::PopAndDestroy(validator);
+
+	// Should the validation finish without errors, mark the document validated 
+	// by attaching an attribute to the root node
+	if( returnValue == KErrNone )
+		{
+		iRootNode->SetAttributeL(KWAPDocumentValidStatusAttributeName, KNullDesC, iPluginSP.AttributeLUT());
+		}	
+	return( returnValue );
+	}
+
+TInt CXmlLibrary::ProcessDataL(HBufC16* aData)
+// Internal utility function. Used when reparsing the buffered document.
+// The attributes in the document nodes are 16-bit character data, hence we need a different interface.
+	{
+	if( iParser == NULL )
+		{
+		PrepareParserL();
+		}
+	iParser->ProcessDataL(aData);
+
+	return( ExecuteDataProcessingL() );
+	}
+
+TInt CXmlLibrary::CommitParserL()
+// Internal utility function for finishing off the parser and checking the errors, if any
+	{
+	// Finish off the parser
+	iParser->SetStatus(EPluginComplete);
+	iParser->CommitL();
+	if( iParser->ErrorCode() != KErrNone )
+		{
+		return( iParser->ErrorCode() );
+		}
+	if( !iParser->Valid() )
+		{
+		return( EWapErrXmlLibInvalidDocument );
+		}
+	return( KErrNone );
+	}
+
+TInt CXmlLibrary::ExecuteDataProcessingL()
+// A method to examine return codes from parser after a single
+// parsing pass. Here we also initiate DTD fetched if the parser
+// returns appropriate signals or we might activate the data gathering
+// in the parser, if no DTD is available.
+	{
+
+	if( iParser->ErrorCode() == CXmlParser::EDTDDefinitionFound ||
+		iParser->ErrorCode() == CXmlParser::ENoDTDDefined )
+		{
+		if( iDTD == NULL)
+			{
+			if( iParser->ErrorCode() == CXmlParser::EDTDDefinitionFound )
+				{
+				iDTD = (CBNFNode*)iPluginSP.PrepareDTDL(*iParser->DocType(), *iParser->DTDUrl(), (CDocumentNode*)iRootNode);  // DocType might be NULL!
+				}
+			else
+				{
+				iDTD = (CBNFNode*)iPluginSP.PrepareDTDL(*iDefaultDoctype, *iDefaultDTDUrl, (CDocumentNode*)iRootNode);
+				}
+
+			if( iDTD != NULL )
+				{
+				iDTD = ExtractDTDTree(iDTD);
+				if( iDTD == NULL )
+					{
+					// The engine returned us its root to DTD tree, but this node didn't
+					// contain the actual DTD tree, hence report an error
+					return( EWapErrXmlLibInvalidDTD );
+					}
+				}
+			}
+		if( iDTD == NULL )
+			{
+			iParser->SetDataGathering(ETrue);
+			}
+		else
+			{
+			iParser->SetDTD(iDTD);
+			}
+		iParser->ContinueL();
+		}
+	return( iParser->ErrorCode() );
+	}
+
+CBNFNode* CXmlLibrary::ExtractDTDTree(CBNFNode* aDTDRoot)
+// Internal utility function for extracting the actual DTD tree
+// from the document root node provided by the engine.
+	{
+	if( aDTDRoot != NULL )
+		return( (CBNFNode*)aDTDRoot->NextChild() );
+	else
+		return( NULL );
+	}
+
+// RESERVED FOR FUTURE USE
+EXPORT_C void CXmlLibrary::CXmlLibrary_Reserved1()
+	{
+	}
+