diff options
Diffstat (limited to 'xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx')
-rw-r--r-- | xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx | 1187 |
1 files changed, 1187 insertions, 0 deletions
diff --git a/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx b/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx new file mode 100644 index 000000000000..795ac4a8d225 --- /dev/null +++ b/xmlsecurity/source/xmlsec/xmldocumentwrapper_xmlsecimpl.cxx @@ -0,0 +1,1187 @@ +/************************************************************************* + * + * $RCSfile: xmldocumentwrapper_xmlsecimpl.cxx,v $ + * + * $Revision: 1.1.1.1 $ + * + * last change: $Author: mt $ $Date: 2004-07-12 13:15:21 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (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.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#include "xmldocumentwrapper_xmlsecimpl.hxx" + +#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#endif + +#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" )), NULL); + + 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 -- Retrives the qualified name of a node + * + * SYNOPSIS + * name = getNodeQName(pNode); + * + * FUNCTION + * see NAME + * + * INPUTS + * pNode - the node whose name will be retrived + * + * 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 -- Retrives the node wrapped by an XXMLElementWrapper + * interface + * + * SYNOPSIS + * node = checkElement(xXMLElement); + * + * FUNCTION + * see NAME + * + * INPUTS + * xXMLElement - the XXMLElementWrapper interface wraping 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 + = ( XMLElementWrapper_XmlSecImpl* )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 paticular node with its branch. + * + * SYNOPSIS + * result = recursiveDelete(pNode); + * + * FUNCTION + * Deletes a paticular 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(); + break; + } + + 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(); + break; + } + + 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 > & rSMgr) + 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(); +} + |