/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmlsecurity.hxx"

#include "xmldocumentwrapper_xmlsecimpl.hxx"
#include <com/sun/star/lang/XMultiServiceFactory.hpp>

#include <xmloff/attrlist.hxx>
#include "xmlelementwrapper_xmlsecimpl.hxx"

//#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*
 * Deleted by AF
#include <memory.h>
 */

#include <sys/types.h>
#include <sys/stat.h>

#ifndef INCLUDED_VECTOR
#include <vector>
#define INCLUDED_VECTOR
#endif

#ifdef UNX
#define stricmp strcasecmp
#endif

namespace cssu = com::sun::star::uno;
namespace cssl = com::sun::star::lang;
namespace cssxc = com::sun::star::xml::crypto;
namespace cssxcsax = com::sun::star::xml::csax;
namespace cssxs = com::sun::star::xml::sax;
namespace cssxw = com::sun::star::xml::wrapper;

#define SERVICE_NAME "com.sun.star.xml.wrapper.XMLDocumentWrapper"
#define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl"

#define STRXMLNS "xmlns"

#define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
#define RTL_UTF8_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8

/* used by the recursiveDelete method */
#define NODE_REMOVED    0
#define NODE_NOTREMOVED 1
#define NODE_STOPED     2

XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl( )
{
	saxHelper.startDocument();
	m_pDocument = saxHelper.getDocument();

	/*
	 * creates the virtual root element
	 */
	saxHelper.startElement(rtl::OUString(RTL_UTF8_USTRINGPARAM( "root" )), cssu::Sequence<cssxcsax::XMLAttribute>());

	m_pRootElement = saxHelper.getCurrentNode();
	m_pCurrentElement = m_pRootElement;
}

XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
{
	saxHelper.endDocument();
	xmlFreeDoc(m_pDocument);
}

void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
/****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
 *
 *   NAME
 *	getNextSAXEvent -- Prepares the next SAX event to be manipulate
 *
 *   SYNOPSIS
 *	getNextSAXEvent();
 *
 *   FUNCTION
 *	When converting the document into SAX events, this method is used to
 *	decide the next SAX event to be generated.
 *	Two member variables are checked to make the decision, the
 *	m_pCurrentElement and the m_nCurrentPosition.
 *	The m_pCurrentElement represents the node which have been covered, and
 *	the m_nCurrentPosition represents the event which have been sent.
 *	For example, suppose that the m_pCurrentElement
 *	points to element A, and the m_nCurrentPosition equals to
 *	NODEPOSITION_STARTELEMENT, then the next SAX event should be the
 *	endElement for element A if A has no child, or startElement for the
 *	first child element of element A otherwise.
 *	The m_nCurrentPosition can be one of following values:
 *	NODEPOSITION_STARTELEMENT for startElement;
 *	NODEPOSITION_ENDELEMENT for endElement;
 *	NODEPOSITION_NORMAL for other SAX events;
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	OSL_ASSERT( m_pCurrentElement != NULL );

        /*
         * Get the next event through tree order.
         *
         * if the current event is a startElement, then the next
         * event depends on whether or not the current node has
         * children.
         */
	if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT)
	{
	        /*
	         * If the current node has children, then its first child
	         * should be next current node, and the next event will be
	         * startElement or charaters(PI) based on that child's node
	         * type. Otherwise, the endElement of current node is the
	         * next event.
	         */
		if (m_pCurrentElement->children != NULL)
		{
			m_pCurrentElement = m_pCurrentElement->children;
			m_nCurrentPosition
				= (m_pCurrentElement->type == XML_ELEMENT_NODE)?
					NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
		}
		else
		{
			m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
		}
	}
        /*
         * if the current event is a not startElement, then the next
         * event depends on whether or not the current node has
         * following sibling.
         */
	else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL)
	{
		xmlNodePtr pNextSibling = m_pCurrentElement->next;

	        /*
	         * If the current node has following sibling, that sibling
	         * should be next current node, and the next event will be
	         * startElement or charaters(PI) based on that sibling's node
	         * type. Otherwise, the endElement of current node's parent
	         * becomes the next event.
	         */
		if (pNextSibling != NULL)
		{
			m_pCurrentElement = pNextSibling;
			m_nCurrentPosition
				= (m_pCurrentElement->type == XML_ELEMENT_NODE)?
					NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
		}
		else
		{
			m_pCurrentElement = m_pCurrentElement->parent;
			m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
		}
	}
}

void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
	const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
	const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
	const xmlNodePtr pNode) const
	throw (cssxs::SAXException)
/****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
 *
 *   NAME
 *	sendStartElement -- Constructs a startElement SAX event
 *
 *   SYNOPSIS
 *	sendStartElement(xHandler, xHandler2, pNode);
 *
 *   FUNCTION
 *	Used when converting the document into SAX event stream.
 *	This method constructs a startElement SAX event for a particular
 *	element, then calls the startElement methods of the XDocumentHandlers.
 *
 *   INPUTS
 *	xHandler -	the first XDocumentHandler interface to receive the
 *			startElement SAX event. It can be NULL.
 *	xHandler2 -	the second XDocumentHandler interface to receive the
 *			startElement SAX event. It can't be NULL.
 *	pNode -		the node on which the startElement should be generated.
 *			This node must be a element type.
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	SvXMLAttributeList* pAttributeList = new SvXMLAttributeList();
	cssu::Reference < cssxs::XAttributeList > xAttrList = cssu::Reference< cssxs::XAttributeList > (pAttributeList);

	xmlNsPtr pNsDef = pNode->nsDef;

	while (pNsDef != NULL)
	{
		const xmlChar* pNsPrefix = pNsDef->prefix;
		const xmlChar* pNsHref = pNsDef->href;

		if (pNsDef->prefix == NULL)
		{
			pAttributeList->AddAttribute(
				rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS )),
				rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref )));
		}
		else
		{
			pAttributeList->AddAttribute(
				rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS ))
				+rtl::OUString(RTL_UTF8_USTRINGPARAM( ":" ))
				+rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsPrefix )),
				rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref )));
		}

		pNsDef = pNsDef->next;
	}

	xmlAttrPtr pAttr = pNode->properties;

	while (pAttr != NULL)
	{
		const xmlChar* pAttrName = pAttr->name;
		xmlNsPtr pAttrNs = pAttr->ns;

		rtl::OUString ouAttrName;
		if (pAttrNs == NULL)
		{
			ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName ));
		}
		else
		{
			ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrNs->prefix))
				+rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)":" ))
				+rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName ));
		}

		pAttributeList->AddAttribute(
			ouAttrName,
			rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)(pAttr->children->content))));
		pAttr = pAttr->next;
	}

	rtl::OString sNodeName = getNodeQName(pNode);

	if (xHandler.is())
	{
		xHandler->startElement(
			rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )),
			xAttrList);
	}

	xHandler2->startElement(
		rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )),
		xAttrList);
}

void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
	const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
	const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
	const xmlNodePtr pNode) const
	throw (cssxs::SAXException)
/****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
 *
 *   NAME
 *	sendEndElement -- Constructs a endElement SAX event
 *
 *   SYNOPSIS
 *	sendEndElement(xHandler, xHandler2, pNode);
 *
 *   FUNCTION
 *	Used when converting the document into SAX event stream.
 *	This method constructs a endElement SAX event for a particular
 *	element, then calls the endElement methods of the XDocumentHandlers.
 *
 *   INPUTS
 *	xHandler -	the first XDocumentHandler interface to receive the
 *			endElement SAX event. It can be NULL.
 *	xHandler2 -	the second XDocumentHandler interface to receive the
 *			endElement SAX event. It can't be NULL.
 *	pNode -		the node on which the endElement should be generated.
 *			This node must be a element type.
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	rtl::OString sNodeName = getNodeQName(pNode);

	if (xHandler.is())
	{
		xHandler->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )));
	}

	xHandler2->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )));
}

void XMLDocumentWrapper_XmlSecImpl::sendNode(
	const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
	const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
	const xmlNodePtr pNode) const
	throw (cssxs::SAXException)
/****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
 *
 *   NAME
 *	sendNode -- Constructs a characters SAX event or a
 *	processingInstruction SAX event
 *
 *   SYNOPSIS
 *	sendNode(xHandler, xHandler2, pNode);
 *
 *   FUNCTION
 *	Used when converting the document into SAX event stream.
 *	This method constructs a characters SAX event or a
 *	processingInstructionfor SAX event based on the type of a particular
 *	element, then calls the corresponding methods of the XDocumentHandlers.
 *
 *   INPUTS
 *	xHandler -	the first XDocumentHandler interface to receive the
 *			SAX event. It can be NULL.
 *	xHandler2 -	the second XDocumentHandler interface to receive the
 *			SAX event. It can't be NULL.
 *	pNode -		the node on which the endElement should be generated.
 *			If it is a text node, then a characters SAX event is
 *			generated; if it is a PI node, then a
 *			processingInstructionfor SAX event is generated.
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	xmlElementType type = pNode->type;

	if (type == XML_TEXT_NODE)
	{
		if (xHandler.is())
		{
			xHandler->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
		}

		xHandler2->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
	}
	else if (type == XML_PI_NODE)
	{
		if (xHandler.is())
		{
			xHandler->processingInstruction(
				rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )),
				rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
		}

		xHandler2->processingInstruction(
			rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )),
			rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
	}
}

rtl::OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode) const
/****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
 *
 *   NAME
 *	getNodeQName -- Retrieves the qualified name of a node
 *
 *   SYNOPSIS
 *	name = getNodeQName(pNode);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pNode -	the node whose name will be retrieved
 *
 *   RESULT
 *	name - the node's qualified name
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	rtl::OString sNodeName((const sal_Char*)pNode->name);
	if (pNode->ns != NULL)
	{
		xmlNsPtr pNs = pNode->ns;

		if (pNs->prefix != NULL)
		{
			rtl::OString sPrefix((const sal_Char*)pNs->prefix);
			sNodeName = sPrefix+rtl::OString(":")+sNodeName;
		}
	}

	return sNodeName;
}

xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement) const
/****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
 *
 *   NAME
 *	checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
 *	interface
 *
 *   SYNOPSIS
 *	node = checkElement(xXMLElement);
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	xXMLElement -	the XXMLElementWrapper interface wrapping a node
 *
 *   RESULT
 *	node - the node wrapped in the XXMLElementWrapper interface
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	xmlNodePtr rc = NULL;

	if (xXMLElement.is())
	{
		cssu::Reference< cssl::XUnoTunnel > xNodTunnel( xXMLElement, cssu::UNO_QUERY ) ;
		if( !xNodTunnel.is() )
		{
			throw cssu::RuntimeException() ;
		}

		XMLElementWrapper_XmlSecImpl* pElement
			= reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
                sal::static_int_cast<sal_uIntPtr>(
                    xNodTunnel->getSomething(
                        XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ;

		if( pElement == NULL ) {
			throw cssu::RuntimeException() ;
		}

		rc = pElement->getNativeElement();
	}

	return rc;
}

sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
	const xmlNodePtr pNode)
/****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
 *
 *   NAME
 *	recursiveDelete -- Deletes a particular node with its branch.
 *
 *   SYNOPSIS
 *	result = recursiveDelete(pNode);
 *
 *   FUNCTION
 *	Deletes a particular node with its branch, while reserving the nodes
 *	(and their brance) listed in the m_aReservedNodes.
 *	The deletion process is preformed in the tree order, that is, a node
 *	is deleted after its previous sibling node is deleted, a parent node
 *	is deleted after its branch is deleted.
 *	During the deletion process when the m_pStopAtNode is reached, the
 *	progress is interrupted at once.
 *
 *   INPUTS
 *	pNode -	the node to be deleted
 *
 *   RESULT
 *	result -	the result of the deletion process, can be one of following
 *			values:
 *			NODE_STOPED - the process is interrupted by meeting the
 *				m_pStopAtNode
 *			NODE_NOTREMOVED - the pNode is not completely removed
 *				because there is its descendant in the
 *				m_aReservedNodes list
 *			NODE_REMOVED - the pNode and its branch are completely
 *				removed
 *
 *   NOTES
 *	The node in the m_aReservedNodes list must be in the tree order, otherwise
 *	the result is unpredictable.
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (pNode == m_pStopAtNode)
	{
		return NODE_STOPED;
	}

	if (pNode != m_pCurrentReservedNode)
	{
		xmlNodePtr pChild = pNode->children;

		xmlNodePtr pNextSibling;
		bool bIsRemoved = true;
		sal_Int32 nResult;

		while( pChild != NULL )
		{
			pNextSibling = pChild->next;
			nResult = recursiveDelete(pChild);

			switch (nResult)
			{
			case NODE_STOPED:
				return NODE_STOPED;
			case NODE_NOTREMOVED:
				bIsRemoved = false;
				break;
			case NODE_REMOVED:
				removeNode(pChild);
				break;
			default:
				throw cssu::RuntimeException();
			}

			pChild = pNextSibling;
		}

		if (pNode == m_pCurrentElement)
		{
			bIsRemoved = false;
		}

		return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
	}
	else
	{
		getNextReservedNode();
		return NODE_NOTREMOVED;
	}
}

void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
/****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
 *
 *   NAME
 *	getNextReservedNode -- Highlights the next reserved node in the
 *	reserved node list
 *
 *   SYNOPSIS
 *	getNextReservedNode();
 *
 *   FUNCTION
 *	The m_aReservedNodes array holds a node list, while the
 *	m_pCurrentReservedNode points to the one currently highlighted.
 *	This method is used to highlight the next node in the node list.
 *	This method is called at the time when the current highlighted node
 *	has been already processed, and the next node should be ready.
 *
 *   INPUTS
 *	empty
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
	{
		m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] );
		m_nReservedNodeIndex ++;
	}
	else
	{
		m_pCurrentReservedNode = NULL;
	}
}

void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
/****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
 *
 *   NAME
 *	removeNode -- Deletes a node with its branch unconditionaly
 *
 *   SYNOPSIS
 *	removeNode( pNode );
 *
 *   FUNCTION
 *	Delete the node along with its branch from the document.
 *
 *   INPUTS
 *	pNode -	the node to be deleted
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	05.01.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	/* you can't remove the current node */
	OSL_ASSERT( m_pCurrentElement != pNode );

	xmlAttrPtr pAttr = pNode->properties;

	while (pAttr != NULL)
	{
		if (!stricmp((sal_Char*)pAttr->name,"id"))
		{
			xmlRemoveID(m_pDocument, pAttr);
		}

		pAttr = pAttr->next;
	}

	xmlUnlinkNode(pNode);
	xmlFreeNode(pNode);
}

void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
/****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
 *
 *   NAME
 *	buildIDAttr -- build the ID attribute of a node
 *
 *   SYNOPSIS
 *	buildIDAttr( pNode );
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pNode -	the node whose id attribute will be built
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	14.06.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	xmlAttrPtr idAttr = xmlHasProp( pNode, (const unsigned char *)"id" );
	if (idAttr == NULL)
	{
		idAttr = xmlHasProp( pNode, (const unsigned char *)"Id" );
	}

	if (idAttr != NULL)
	{
		xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
		xmlAddID( NULL, m_pDocument, idValue, idAttr );
	}
}

void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const
/****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
 *
 *   NAME
 *	rebuildIDLink -- rebuild the ID link for the branch
 *
 *   SYNOPSIS
 *	rebuildIDLink( pNode );
 *
 *   FUNCTION
 *	see NAME
 *
 *   INPUTS
 *	pNode -	the node, from which the branch will be rebuilt
 *
 *   RESULT
 *	empty
 *
 *   HISTORY
 *	14.06.2004 -	implemented
 *
 *   AUTHOR
 *	Michael Mi
 *	Email: michael.mi@sun.com
 ******************************************************************************/
{
	if (pNode != NULL && pNode->type == XML_ELEMENT_NODE)
	{
		buildIDAttr( pNode );

		xmlNodePtr child = pNode->children;
		while (child != NULL)
		{
			rebuildIDLink(child);
			child = child->next;
		}
	}
}

/* XXMLDocumentWrapper */
cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement(  )
	throw (cssu::RuntimeException)
{
	XMLElementWrapper_XmlSecImpl* pElement = new XMLElementWrapper_XmlSecImpl(m_pCurrentElement);
	return (cssu::Reference< cssxw::XXMLElementWrapper >)pElement;
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference< cssxw::XXMLElementWrapper >& element )
	throw (cssu::RuntimeException)
{
	m_pCurrentElement = checkElement( element );
	saxHelper.setCurrentNode( m_pCurrentElement );
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement(  )
	throw (cssu::RuntimeException)
{
	OSL_ASSERT( m_pCurrentElement != NULL );

	xmlNodePtr pOldCurrentElement = m_pCurrentElement;

	/*
	 * pop the top node in the parser context's
	 * nodeTab stack, then the parent of that node will
	 * automatically become the new stack top, and
	 * the current node as well.
	 */
	saxHelper.endElement(
		rtl::OUString(
			RTL_UTF8_USTRINGPARAM (
				(sal_Char*)(pOldCurrentElement->name)
			)));
	m_pCurrentElement = saxHelper.getCurrentNode();

	/*
	 * remove the node
	 */
	removeNode(pOldCurrentElement);
}

sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
	throw (cssu::RuntimeException)
{
	xmlNodePtr pNode = checkElement(node);
	return (pNode == m_pCurrentElement);
}

sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty(  )
	throw (cssu::RuntimeException)
{
	sal_Bool rc = sal_False;

	if (m_pCurrentElement->children == NULL)
	{
		rc = sal_True;
	}

	return rc;
}

rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
	throw (cssu::RuntimeException)
{
	xmlNodePtr pNode = checkElement(node);
	return rtl::OUString(RTL_UTF8_USTRINGPARAM ( (sal_Char*)pNode->name ));
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData(
	const cssu::Reference< cssxw::XXMLElementWrapper >& node,
	const cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >& reservedDescendants,
	const cssu::Reference< cssxw::XXMLElementWrapper >& stopAtNode )
	throw (cssu::RuntimeException)
{
	xmlNodePtr pTargetNode = checkElement(node);

	m_pStopAtNode = checkElement(stopAtNode);
	m_aReservedNodes = reservedDescendants;
	m_nReservedNodeIndex = 0;

	getNextReservedNode();

	recursiveDelete(pTargetNode);
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
	throw (cssu::RuntimeException)
{
	xmlNodePtr pTargetNode = checkElement(node);
	xmlNodePtr pParent;

	while (pTargetNode != NULL)
	{
		if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement)
		{
			break;
		}

		pParent = pTargetNode->parent;
		removeNode(pTargetNode);
		pTargetNode = pParent;
	}
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference< cssxs::XDocumentHandler >& handler )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	if (m_pRootElement != NULL)
	{
		xmlNodePtr pTempCurrentElement = m_pCurrentElement;
		sal_Int32 nTempCurrentPosition = m_nCurrentPosition;

		m_pCurrentElement = m_pRootElement;

		m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
		cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;

		while(true)
		{
			switch (m_nCurrentPosition)
			{
			case NODEPOSITION_STARTELEMENT:
				sendStartElement(NULL, xHandler, m_pCurrentElement);
				break;
			case NODEPOSITION_ENDELEMENT:
				sendEndElement(NULL, xHandler, m_pCurrentElement);
				break;
			case NODEPOSITION_NORMAL:
				sendNode(NULL, xHandler, m_pCurrentElement);
				break;
			}

			if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
			{
				break;
			}

			getNextSAXEvent();
		}

		m_pCurrentElement = pTempCurrentElement;
		m_nCurrentPosition = nTempCurrentPosition;
	}
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
	const cssu::Reference< cssxs::XDocumentHandler >& handler,
	const cssu::Reference< cssxs::XDocumentHandler >& xEventKeeperHandler,
	const cssu::Reference< cssxw::XXMLElementWrapper >& startNode,
	const cssu::Reference< cssxw::XXMLElementWrapper >& endNode )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
        /*
         * The first SAX event is the startElement of the startNode
         * element.
         */
	bool bHasCurrentElementChild = (m_pCurrentElement->children != NULL);

	xmlNodePtr pTempCurrentElement = m_pCurrentElement;

	m_pCurrentElement = checkElement(startNode);

	if (m_pCurrentElement->type == XML_ELEMENT_NODE)
	{
		m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
	}
	else
	{
		m_nCurrentPosition = NODEPOSITION_NORMAL;
	}

	xmlNodePtr pEndNode = checkElement(endNode);

	cssu::Reference < cssxc::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, cssu::UNO_QUERY );

	cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;

	while(true)
	{
		switch (m_nCurrentPosition)
		{
		case NODEPOSITION_STARTELEMENT:
			sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
			break;
		case NODEPOSITION_ENDELEMENT:
			sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
			break;
		case NODEPOSITION_NORMAL:
			sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
			break;
		default:
			throw cssu::RuntimeException();
		}

		if (xSAXEventKeeper->isBlocking())
		{
			xHandler = NULL;
		}

		if (pEndNode == NULL &&
			((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
			 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
		{
			break;
		}

		getNextSAXEvent();

	        /*
	         * If there is an end point specified, then check whether
	         * the current node equals to the end point. If so, stop
	         * generating.
	         */
		if (pEndNode != NULL && m_pCurrentElement == pEndNode)
		{
			break;
		}
	}

	m_pCurrentElement = pTempCurrentElement;
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
	const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node )
	throw (com::sun::star::uno::RuntimeException)
{
	xmlNodePtr pNode = checkElement( node );
	rebuildIDLink(pNode);
}


/* cssxs::XDocumentHandler */
void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument(  )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument(  )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const rtl::OUString& aName, const cssu::Reference< cssxs::XAttributeList >& xAttribs )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	sal_Int32 nLength = xAttribs->getLength();
	cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);

	for (int i = 0; i < nLength; ++i)
	{
		aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
		aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
	}

	_startElement(aName, aAttributes);
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const rtl::OUString& aName )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	saxHelper.endElement(aName);
	m_pCurrentElement = saxHelper.getCurrentNode();
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const rtl::OUString& aChars )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	saxHelper.characters(aChars);
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	saxHelper.ignorableWhitespace(aWhitespaces);
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	saxHelper.processingInstruction(aTarget, aData);
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	saxHelper.setDocumentLocator(xLocator);
}

/* XCompressedDocumentHandler */
void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startDocument(  )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endDocument(  )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startElement( const rtl::OUString& aName, const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	saxHelper.startElement(aName, aAttributes);
	m_pCurrentElement = saxHelper.getCurrentNode();

	buildIDAttr( m_pCurrentElement );
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endElement( const rtl::OUString& aName )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	endElement( aName );
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_characters( const rtl::OUString& aChars )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	characters( aChars );
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_ignorableWhitespace( const rtl::OUString& aWhitespaces )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	ignorableWhitespace( aWhitespaces );
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
	processingInstruction( aTarget, aData );
}

void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_setDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const rtl::OUString& /*publicId*/, const rtl::OUString& /*systemId*/ )
	throw (cssxs::SAXException, cssu::RuntimeException)
{
}

rtl::OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName ()
	throw (cssu::RuntimeException)
{
	return rtl::OUString ( RTL_ASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
}

sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName )
	throw (cssu::RuntimeException)
{
	return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
}

cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames(  )
	throw (cssu::RuntimeException)
{
	cssu::Sequence < rtl::OUString > aRet(1);
	rtl::OUString* pArray = aRet.getArray();
	pArray[0] =  rtl::OUString ( RTL_ASCII_USTRINGPARAM ( SERVICE_NAME ) );
	return aRet;
}
#undef SERVICE_NAME

cssu::Reference< cssu::XInterface > SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance(
	const cssu::Reference< cssl::XMultiServiceFactory > &)
	throw( cssu::Exception )
{
	return (cppu::OWeakObject*) new XMLDocumentWrapper_XmlSecImpl( );
}

/* XServiceInfo */
rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName(  )
	throw (cssu::RuntimeException)
{
	return XMLDocumentWrapper_XmlSecImpl_getImplementationName();
}
sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const rtl::OUString& rServiceName )
	throw (cssu::RuntimeException)
{
	return XMLDocumentWrapper_XmlSecImpl_supportsService( rServiceName );
}
cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames(  )
	throw (cssu::RuntimeException)
{
	return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames();
}
