policymanagement/policyengine/policyengineserver/src/OperationParser.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:27:42 +0100
branchRCL_3
changeset 26 19bba8228ff0
parent 25 b183ec05bd8c
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201033 Kit: 201035

/*
* Copyright (c) 2002-2004 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: Implementation of policymanagement components
*
*/


// INCLUDE FILES

#include "OperationParser.h"
#include "PolicyParser.h"
#include "OperationParserConstants.h"
#include "PolicyManager.h"
#include "PolicyStorage.h"
#include "debug.h"
#include "ErrorCodes.h"


// CONSTANTS
_LIT8( KCDataElement, "KCData");
const TChar KXMLElementEndMark = '>';

// -----------------------------------------------------------------------------
// COperationParser::COperationParser()
// -----------------------------------------------------------------------------
//

COperationParser::COperationParser()
{
}

// -----------------------------------------------------------------------------
// COperationParser::~COperationParser()
// -----------------------------------------------------------------------------
//

COperationParser::~COperationParser()
{
	ResetOperations();
	delete iParser;
}

// -----------------------------------------------------------------------------
// COperationParser::NewL()
// -----------------------------------------------------------------------------
//

COperationParser * COperationParser::NewL( const TDesC8& aOperationDescription)
{
	//2nd phase constructor
	COperationParser * self = new (ELeave) COperationParser();
	
	CleanupStack::PushL( self);
	self->ConstructL( aOperationDescription);
	CleanupStack::Pop( self);
	
	return self;
}

// -----------------------------------------------------------------------------
// COperationParser::ConstructL()
// -----------------------------------------------------------------------------
//

void COperationParser::ConstructL( const TDesC8& aOperationDescription)
{
	//2nd phase constructor
	iParser = Xml::CParser::NewL( _L8( "text/xml"), *this );	
	iXMLContent.Set( aOperationDescription);
}	


// -----------------------------------------------------------------------------
// COperationParser::ResetOperations()
// -----------------------------------------------------------------------------
//
void COperationParser::ResetOperations()
{
	for ( TInt i(0); i < iOperations.Count(); i++)
	{
		delete iOperations[i];
		iOperations[i] = NULL;
	}

	iOperations.Close();
}

// -----------------------------------------------------------------------------
// COperationParser::ConstructL()
// -----------------------------------------------------------------------------
//

void COperationParser::HandleErrorL( const TDesC8& aErrorTxt, const TDesC8& aElementName)
{
	//parse error text
	iReturnText->Copy( _L8("(Line "));
	iReturnText->AppendNum( iActiveLine);
	iReturnText->Append( _L8(") "));
	iReturnText->Append( aErrorTxt);
	iReturnText->Append( _L8(": "));
	iReturnText->Append( aElementName);
		
	RDEBUG_2("Operation parser error: %S", &iReturnText);

	User::Leave( KErrOpParser);	
}




// -----------------------------------------------------------------------------
// COperationParser::ParseOperationsL()
// -----------------------------------------------------------------------------
//

void COperationParser::ParseOperationsL( TDes8& aReturnTxt)
{
	//reset line counter and initialize XML-parser
	iActiveLine = 0;
	iReturnText = &aReturnTxt;
	iXMLStackPointer = 0;
	ResetOperations();


	//initliaze symbian xml parser
	iParser->ParseBeginL();
	
	//Max size of chunk (max text length, which go once to parser)
	const TInt KMaxChunkLength = 1000;
	
	TPtrC8 xml = iXMLContent;
	TPtrC8 chunk;
	TInt length = KMaxChunkLength < xml.Length() ? KMaxChunkLength : xml.Length();

	do
	{
		//Find line feed mark (asciicode 10)
		TInt indexLineFeed = xml.Locate(10);
		TInt elementEndIndex = xml.Locate( KXMLElementEndMark );

		if ( elementEndIndex != KErrNotFound && (elementEndIndex < indexLineFeed || indexLineFeed == KErrNotFound))
		{
			length = elementEndIndex + 1;
		}
		else
		if ( indexLineFeed != KErrNotFound)
		{ 
			//max text, which go to parser is one line or KMaxChunkLength. Counter tracks line, where parsing is going
			iActiveLine++;
		
			length = indexLineFeed + 1;
		}

		//set chunk pointer
		chunk.Set( xml.Left(length));
		

		if ( ParserUtility::ContainsCDataField( chunk))
		{
			//cdata mark indicated in chunk, remove cdata area from chunk, 
			TPtrC8 cdata;
			ParserUtility::ReadCDataAreaL( cdata, chunk, xml);
			
			//pointer to cdata content
			ParserUtility::RemoveCDataMarksL( cdata);
	
			if ( !iActiveOperation)
			{
				HandleErrorL( ParserErrors::UnexpectedElement, KCDataElement); 
			}
			
			iActiveOperation->SetXACMLContentL( cdata);
			iActiveOperation->SetLineOffset( iActiveLine - 1);
			
			iActiveLine += ParserUtility::LineCounter( cdata);
		}
		else
		{
			//set remaining XACML description to xacmlDescription
			xml.Set( xml.Mid(length));			
		}

		//'|' and '~' are not allowed in policy system...
		if ( chunk.Locate('|') != KErrNotFound || chunk.Locate('~') != KErrNotFound)
		{
			HandleErrorL( ParserErrors::InvalidMark, ParserErrors::InvalidMarks); 
		}
		
		//drive description to parser	
		iParser->ParseL( chunk);
	
		length = KMaxChunkLength < xml.Length() ? KMaxChunkLength : xml.Length();
	} while ( length);

	//close parser
	iParser->ParseEndL();	
}


// -----------------------------------------------------------------------------
// COperationParser::OnProcessingInstructionL()
// -----------------------------------------------------------------------------
//
void COperationParser::ExecuteL( TInt aIndex, CPolicyManager *aManager)
{
	iOperations[ aIndex]->ExecuteL( aManager);
}

// -----------------------------------------------------------------------------
// COperationParser::OperationCount()
// -----------------------------------------------------------------------------
//
TInt COperationParser::OperationCount()
{
	return iOperations.Count();
}

// -----------------------------------------------------------------------------
// COperationParser::OnStartDocumentL()
// -----------------------------------------------------------------------------
//
	

void COperationParser::OnStartDocumentL(const Xml::RDocumentParameters& /*aDocParam*/, TInt /*aErrorCode*/)
{
}

// -----------------------------------------------------------------------------
// COperationParser::OnEndDocumentL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnEndDocumentL(TInt /*aErrorCode*/)
{
	
}

// -----------------------------------------------------------------------------
// COperationParser::OnStartElementL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnStartElementL(const Xml::RTagInfo& aElement, const Xml::RAttributeArray& aAttributes, TInt /*aErrorCode*/)
{
	using namespace OperationParserConstants;

  	TPtrC8 elementName = aElement.LocalName().DesC();
  	CPolicyStorage* policyStorage = CPolicyStorage::PolicyStorage();

	//package starts operation package
  	if ( elementName != XMLStack[ iXMLStackPointer] )
  	{
		HandleErrorL( ParserErrors::UnexpectedElement, elementName); 
  	}
  	
  	if ( elementName == Operation )
  	{
  		if ( !iActiveOperation )
  		{
  			iActiveOperation = COperationInfo::NewL();
  		}
  		else
  		{
  			HandleErrorL( ParserErrors::UnexpectedElement, elementName); 
  		}
  	} 
  	
   	//search element attributes
	for ( TInt i = 0; i < aAttributes.Count(); i++)
	{
		Xml::RAttribute attribute( aAttributes[i]);
		
		TPtrC8 attributeName = attribute.Attribute().LocalName().DesC();
		TPtrC8 attributeValue = attribute.Value().DesC();

	  	
		if ( iActiveOperation && elementName == Operation )
		{
			if ( attributeName == ActionId )
			{
				iActiveOperation->SetActionIdL( attributeValue );
			}
			else if ( attributeName == TargetId)
			{
				iActiveOperation->SetTargetElementIdL( attributeValue );
			}
			else if ( attributeName == UseBearerCert)
			{
				if ( attributeValue == True)
				{
					iActiveOperation->UseBearerCertificate( ETrue);
				}
				else
				{
					iActiveOperation->UseBearerCertificate( EFalse);
				}
			}
			else if ( attributeName == AddServerId)
			{
				if ( KErrNone != policyStorage->AddNewServerId( attributeValue))
				{
	  				HandleErrorL( ManagementErrors::ServerIdManagementError, attributeName); 
				}
			}
			else if ( attributeName == RemoveServerId)
			{
				if ( attributeValue == ResetAllTag)
				{
					if ( KErrNone != policyStorage->ResetServerIdList())
					{
	  					HandleErrorL( ManagementErrors::ServerIdManagementError, attributeName); 
					}
				}
				else
				{
					if ( KErrNone != policyStorage->RemoveServerId( attributeValue))
					{
		  				HandleErrorL( ManagementErrors::ServerIdManagementError, attributeName); 
					}
				}
			}
			else
			{
  				HandleErrorL( ParserErrors::UnexpectedAttribute, attributeName); 
			}
		}
		else
		{
  			HandleErrorL( ParserErrors::UnexpectedAttribute, attributeName); 
		}

	}
	
	iXMLStackPointer++;
}

// -----------------------------------------------------------------------------
// COperationParser::OnEndElementL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnEndElementL(const Xml::RTagInfo& aElement, TInt /*aErrorCode*/)
{
	using namespace OperationParserConstants;

  	TPtrC8 elementName = aElement.LocalName().DesC();

	//Add new operation operation list
	if ( elementName == Operation )
  	{
  		iOperations.AppendL( iActiveOperation);
  		iActiveOperation = NULL;
  	}
  	
  	iXMLStackPointer--;
}

// -----------------------------------------------------------------------------
// COperationParser::OnContentL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnContentL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
{
}

// -----------------------------------------------------------------------------
// COperationParser::OnStartPrefixMappingL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnStartPrefixMappingL(const RString& /*aPrefix*/, const RString& /*aUri*/, TInt /*aErrorCode*/)
{
	
}

// -----------------------------------------------------------------------------
// COperationParser::OnEndPrefixMappingL()
// -----------------------------------------------------------------------------
//

void COperationParser::OnEndPrefixMappingL(const RString& /*aPrefix*/, TInt /*aErrorCode*/)
{
	
}

// -----------------------------------------------------------------------------
// COperationParser::OnIgnorableWhiteSpaceL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnIgnorableWhiteSpaceL(const TDesC8& /*aBytes*/, TInt /*aErrorCode*/)
{
	
}

// -----------------------------------------------------------------------------
// COperationParser::OnSkippedEntityL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnSkippedEntityL(const RString& /*aName*/, TInt /*aErrorCode*/)
{
	
}

// -----------------------------------------------------------------------------
// COperationParser::OnProcessingInstructionL()
// -----------------------------------------------------------------------------
//
void COperationParser::OnProcessingInstructionL(const TDesC8& /*aTarget*/, const TDesC8& /*aData*/, TInt /*aErrorCode*/)
{
	
}

// -----------------------------------------------------------------------------
// COperationParser::OnError()
// -----------------------------------------------------------------------------
//
void COperationParser::OnError(TInt /*aErrorCode*/)
{
	//parse error text
	iReturnText->Copy( _L8("(Line "));
	iReturnText->AppendNum( iActiveLine);
	iReturnText->Append( _L8(") "));
	iReturnText->Append( ParserErrors::SyntaxError);

	RDEBUG_2("Operation parser error: %S", &iReturnText);

	// PolicyEngine expects this leave in error conditions -> prgram flow
	// goes to correct TRAP after this. Can not remove this Leave although
	// the function name does not have "L"
	User::Leave( KErrOpParser ); 	
}

// -----------------------------------------------------------------------------
// COperationParser::GetExtendedInterface()
// -----------------------------------------------------------------------------
//
TAny* COperationParser::GetExtendedInterface(const TInt32 /*aUid*/)
{
	return NULL;
}


// -----------------------------------------------------------------------------
// COperationParser::GetExtendedInterface()
// -----------------------------------------------------------------------------
//
COperationInfo::COperationInfo()
{
}


// -----------------------------------------------------------------------------
// COperationParser::~COperationInfo()
// -----------------------------------------------------------------------------
//
COperationInfo::~COperationInfo()
{
	delete iActionId;
	delete iTargetElement;
}

// -----------------------------------------------------------------------------
// COperationParser::NewL()
// -----------------------------------------------------------------------------
//

COperationInfo* COperationInfo::NewL()
{
	return new (ELeave) COperationInfo();
}

// -----------------------------------------------------------------------------
// COperationInfo::UseBearerCertificate()
// -----------------------------------------------------------------------------
//
void COperationInfo::UseBearerCertificate( const TBool aUseBearerCertificate)
{
	iUseBearerCertificate = aUseBearerCertificate;
}


// -----------------------------------------------------------------------------
// COperationParser::SetActionIdL()
// -----------------------------------------------------------------------------
//	
	
void COperationInfo::SetActionIdL( const TDesC8& aActionId)
{
	if ( iActionId )
	{
		User::Leave( KErrOpParser);
	}
	
	iActionId = aActionId.AllocL();
}

// -----------------------------------------------------------------------------
// COperationParser::SetTargetElementIdL()
// -----------------------------------------------------------------------------
//

void COperationInfo::SetTargetElementIdL( const TDesC8& aTargetElementId)
{
	if ( iTargetElement )
	{
		User::Leave( KErrOpParser);
	}
	
	iTargetElement = aTargetElementId.AllocL();
}

// -----------------------------------------------------------------------------
// COperationParser::SetXACMLContentL()
// -----------------------------------------------------------------------------
//

void COperationInfo::SetXACMLContentL( const TPtrC8& aXACMLContent)
{
	if ( iXACMLContent.Length())
	{
		User::Leave( KErrOpParser);
	}
	
	iXACMLContent.Set( aXACMLContent);
}


// -----------------------------------------------------------------------------
// COperationParser::ExecuteL()
// -----------------------------------------------------------------------------
//
		
void COperationInfo::ExecuteL( CPolicyManager *iManager)
{
	if ( *iActionId == OperationParserConstants::Add)
	{
		iManager->NewElementL( iLineOffset, *iTargetElement, iXACMLContent, iUseBearerCertificate);
	} 
	else if ( *iActionId == OperationParserConstants::Remove)
	{
		iManager->RemoveElementL( *iTargetElement);
	}
	else if ( *iActionId == OperationParserConstants::Replace)
	{
		iManager->ReplaceElementL( iLineOffset, *iTargetElement, iXACMLContent);
	}
	else
	{
		User::Panic( Panics::OperationParserPanic, KErrGeneral);
	}
}

// -----------------------------------------------------------------------------
// COperationParser::SetLineOffset()
// -----------------------------------------------------------------------------
//

void COperationInfo::SetLineOffset( const TInt& aLineOffset)
{
	iLineOffset = aLineOffset;
}