/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: xmldocumentwrapper_xmlsecimpl.cxx,v $ * $Revision: 1.6 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org 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 version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_xmlsecurity.hxx" #include "xmldocumentwrapper_xmlsecimpl.hxx" #include #include #include "xmlelementwrapper_xmlsecimpl.hxx" //#include #include #include #include /* * Deleted by AF #include */ #include #include #ifndef INCLUDED_VECTOR #include #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()); 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 = reinterpret_cast( sal::static_int_cast( 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(); } 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(); }