merged tag ooo/OOO330_m14
[LibreOffice.git] / xmlsecurity / source / xmlsec / xmldocumentwrapper_xmlsecimpl.cxx
blob341f66b9ef1fb2b3a62d79975176beca692ef7e7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #include "xmldocumentwrapper_xmlsecimpl.hxx"
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
34 #include <xmloff/attrlist.hxx>
35 #include "xmlelementwrapper_xmlsecimpl.hxx"
37 //#include <malloc.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
43 * Deleted by AF
44 #include <memory.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
50 #ifndef INCLUDED_VECTOR
51 #include <vector>
52 #define INCLUDED_VECTOR
53 #endif
55 #ifdef UNX
56 #define stricmp strcasecmp
57 #endif
59 namespace cssu = com::sun::star::uno;
60 namespace cssl = com::sun::star::lang;
61 namespace cssxc = com::sun::star::xml::crypto;
62 namespace cssxcsax = com::sun::star::xml::csax;
63 namespace cssxs = com::sun::star::xml::sax;
64 namespace cssxw = com::sun::star::xml::wrapper;
66 #define SERVICE_NAME "com.sun.star.xml.wrapper.XMLDocumentWrapper"
67 #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl"
69 #define STRXMLNS "xmlns"
71 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
72 #define RTL_UTF8_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8
74 /* used by the recursiveDelete method */
75 #define NODE_REMOVED 0
76 #define NODE_NOTREMOVED 1
77 #define NODE_STOPED 2
79 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl( )
81 saxHelper.startDocument();
82 m_pDocument = saxHelper.getDocument();
85 * creates the virtual root element
87 saxHelper.startElement(rtl::OUString(RTL_UTF8_USTRINGPARAM( "root" )), cssu::Sequence<cssxcsax::XMLAttribute>());
89 m_pRootElement = saxHelper.getCurrentNode();
90 m_pCurrentElement = m_pRootElement;
93 XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
95 saxHelper.endDocument();
96 xmlFreeDoc(m_pDocument);
99 void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
100 /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
102 * NAME
103 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
105 * SYNOPSIS
106 * getNextSAXEvent();
108 * FUNCTION
109 * When converting the document into SAX events, this method is used to
110 * decide the next SAX event to be generated.
111 * Two member variables are checked to make the decision, the
112 * m_pCurrentElement and the m_nCurrentPosition.
113 * The m_pCurrentElement represents the node which have been covered, and
114 * the m_nCurrentPosition represents the event which have been sent.
115 * For example, suppose that the m_pCurrentElement
116 * points to element A, and the m_nCurrentPosition equals to
117 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
118 * endElement for element A if A has no child, or startElement for the
119 * first child element of element A otherwise.
120 * The m_nCurrentPosition can be one of following values:
121 * NODEPOSITION_STARTELEMENT for startElement;
122 * NODEPOSITION_ENDELEMENT for endElement;
123 * NODEPOSITION_NORMAL for other SAX events;
125 * INPUTS
126 * empty
128 * RESULT
129 * empty
131 * HISTORY
132 * 05.01.2004 - implemented
134 * AUTHOR
135 * Michael Mi
136 * Email: michael.mi@sun.com
137 ******************************************************************************/
139 OSL_ASSERT( m_pCurrentElement != NULL );
142 * Get the next event through tree order.
144 * if the current event is a startElement, then the next
145 * event depends on whether or not the current node has
146 * children.
148 if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT)
151 * If the current node has children, then its first child
152 * should be next current node, and the next event will be
153 * startElement or charaters(PI) based on that child's node
154 * type. Otherwise, the endElement of current node is the
155 * next event.
157 if (m_pCurrentElement->children != NULL)
159 m_pCurrentElement = m_pCurrentElement->children;
160 m_nCurrentPosition
161 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
162 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
164 else
166 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
170 * if the current event is a not startElement, then the next
171 * event depends on whether or not the current node has
172 * following sibling.
174 else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL)
176 xmlNodePtr pNextSibling = m_pCurrentElement->next;
179 * If the current node has following sibling, that sibling
180 * should be next current node, and the next event will be
181 * startElement or charaters(PI) based on that sibling's node
182 * type. Otherwise, the endElement of current node's parent
183 * becomes the next event.
185 if (pNextSibling != NULL)
187 m_pCurrentElement = pNextSibling;
188 m_nCurrentPosition
189 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
190 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
192 else
194 m_pCurrentElement = m_pCurrentElement->parent;
195 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
200 void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
201 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
202 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
203 const xmlNodePtr pNode) const
204 throw (cssxs::SAXException)
205 /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
207 * NAME
208 * sendStartElement -- Constructs a startElement SAX event
210 * SYNOPSIS
211 * sendStartElement(xHandler, xHandler2, pNode);
213 * FUNCTION
214 * Used when converting the document into SAX event stream.
215 * This method constructs a startElement SAX event for a particular
216 * element, then calls the startElement methods of the XDocumentHandlers.
218 * INPUTS
219 * xHandler - the first XDocumentHandler interface to receive the
220 * startElement SAX event. It can be NULL.
221 * xHandler2 - the second XDocumentHandler interface to receive the
222 * startElement SAX event. It can't be NULL.
223 * pNode - the node on which the startElement should be generated.
224 * This node must be a element type.
226 * RESULT
227 * empty
229 * HISTORY
230 * 05.01.2004 - implemented
232 * AUTHOR
233 * Michael Mi
234 * Email: michael.mi@sun.com
235 ******************************************************************************/
237 SvXMLAttributeList* pAttributeList = new SvXMLAttributeList();
238 cssu::Reference < cssxs::XAttributeList > xAttrList = cssu::Reference< cssxs::XAttributeList > (pAttributeList);
240 xmlNsPtr pNsDef = pNode->nsDef;
242 while (pNsDef != NULL)
244 const xmlChar* pNsPrefix = pNsDef->prefix;
245 const xmlChar* pNsHref = pNsDef->href;
247 if (pNsDef->prefix == NULL)
249 pAttributeList->AddAttribute(
250 rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS )),
251 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref )));
253 else
255 pAttributeList->AddAttribute(
256 rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS ))
257 +rtl::OUString(RTL_UTF8_USTRINGPARAM( ":" ))
258 +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsPrefix )),
259 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref )));
262 pNsDef = pNsDef->next;
265 xmlAttrPtr pAttr = pNode->properties;
267 while (pAttr != NULL)
269 const xmlChar* pAttrName = pAttr->name;
270 xmlNsPtr pAttrNs = pAttr->ns;
272 rtl::OUString ouAttrName;
273 if (pAttrNs == NULL)
275 ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName ));
277 else
279 ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrNs->prefix))
280 +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)":" ))
281 +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName ));
284 pAttributeList->AddAttribute(
285 ouAttrName,
286 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)(pAttr->children->content))));
287 pAttr = pAttr->next;
290 rtl::OString sNodeName = getNodeQName(pNode);
292 if (xHandler.is())
294 xHandler->startElement(
295 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )),
296 xAttrList);
299 xHandler2->startElement(
300 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )),
301 xAttrList);
304 void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
305 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
306 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
307 const xmlNodePtr pNode) const
308 throw (cssxs::SAXException)
309 /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
311 * NAME
312 * sendEndElement -- Constructs a endElement SAX event
314 * SYNOPSIS
315 * sendEndElement(xHandler, xHandler2, pNode);
317 * FUNCTION
318 * Used when converting the document into SAX event stream.
319 * This method constructs a endElement SAX event for a particular
320 * element, then calls the endElement methods of the XDocumentHandlers.
322 * INPUTS
323 * xHandler - the first XDocumentHandler interface to receive the
324 * endElement SAX event. It can be NULL.
325 * xHandler2 - the second XDocumentHandler interface to receive the
326 * endElement SAX event. It can't be NULL.
327 * pNode - the node on which the endElement should be generated.
328 * This node must be a element type.
330 * RESULT
331 * empty
333 * HISTORY
334 * 05.01.2004 - implemented
336 * AUTHOR
337 * Michael Mi
338 * Email: michael.mi@sun.com
339 ******************************************************************************/
341 rtl::OString sNodeName = getNodeQName(pNode);
343 if (xHandler.is())
345 xHandler->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )));
348 xHandler2->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )));
351 void XMLDocumentWrapper_XmlSecImpl::sendNode(
352 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
353 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
354 const xmlNodePtr pNode) const
355 throw (cssxs::SAXException)
356 /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
358 * NAME
359 * sendNode -- Constructs a characters SAX event or a
360 * processingInstruction SAX event
362 * SYNOPSIS
363 * sendNode(xHandler, xHandler2, pNode);
365 * FUNCTION
366 * Used when converting the document into SAX event stream.
367 * This method constructs a characters SAX event or a
368 * processingInstructionfor SAX event based on the type of a particular
369 * element, then calls the corresponding methods of the XDocumentHandlers.
371 * INPUTS
372 * xHandler - the first XDocumentHandler interface to receive the
373 * SAX event. It can be NULL.
374 * xHandler2 - the second XDocumentHandler interface to receive the
375 * SAX event. It can't be NULL.
376 * pNode - the node on which the endElement should be generated.
377 * If it is a text node, then a characters SAX event is
378 * generated; if it is a PI node, then a
379 * processingInstructionfor SAX event is generated.
381 * RESULT
382 * empty
384 * HISTORY
385 * 05.01.2004 - implemented
387 * AUTHOR
388 * Michael Mi
389 * Email: michael.mi@sun.com
390 ******************************************************************************/
392 xmlElementType type = pNode->type;
394 if (type == XML_TEXT_NODE)
396 if (xHandler.is())
398 xHandler->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
401 xHandler2->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
403 else if (type == XML_PI_NODE)
405 if (xHandler.is())
407 xHandler->processingInstruction(
408 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )),
409 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
412 xHandler2->processingInstruction(
413 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )),
414 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
418 rtl::OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode) const
419 /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
421 * NAME
422 * getNodeQName -- Retrives the qualified name of a node
424 * SYNOPSIS
425 * name = getNodeQName(pNode);
427 * FUNCTION
428 * see NAME
430 * INPUTS
431 * pNode - the node whose name will be retrived
433 * RESULT
434 * name - the node's qualified name
436 * HISTORY
437 * 05.01.2004 - implemented
439 * AUTHOR
440 * Michael Mi
441 * Email: michael.mi@sun.com
442 ******************************************************************************/
444 rtl::OString sNodeName((const sal_Char*)pNode->name);
445 if (pNode->ns != NULL)
447 xmlNsPtr pNs = pNode->ns;
449 if (pNs->prefix != NULL)
451 rtl::OString sPrefix((const sal_Char*)pNs->prefix);
452 sNodeName = sPrefix+rtl::OString(":")+sNodeName;
456 return sNodeName;
459 xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement) const
460 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
462 * NAME
463 * checkElement -- Retrives the node wrapped by an XXMLElementWrapper
464 * interface
466 * SYNOPSIS
467 * node = checkElement(xXMLElement);
469 * FUNCTION
470 * see NAME
472 * INPUTS
473 * xXMLElement - the XXMLElementWrapper interface wraping a node
475 * RESULT
476 * node - the node wrapped in the XXMLElementWrapper interface
478 * HISTORY
479 * 05.01.2004 - implemented
481 * AUTHOR
482 * Michael Mi
483 * Email: michael.mi@sun.com
484 ******************************************************************************/
486 xmlNodePtr rc = NULL;
488 if (xXMLElement.is())
490 cssu::Reference< cssl::XUnoTunnel > xNodTunnel( xXMLElement, cssu::UNO_QUERY ) ;
491 if( !xNodTunnel.is() )
493 throw cssu::RuntimeException() ;
496 XMLElementWrapper_XmlSecImpl* pElement
497 = reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
498 sal::static_int_cast<sal_uIntPtr>(
499 xNodTunnel->getSomething(
500 XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ;
502 if( pElement == NULL ) {
503 throw cssu::RuntimeException() ;
506 rc = pElement->getNativeElement();
509 return rc;
512 sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
513 const xmlNodePtr pNode)
514 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
516 * NAME
517 * recursiveDelete -- Deletes a paticular node with its branch.
519 * SYNOPSIS
520 * result = recursiveDelete(pNode);
522 * FUNCTION
523 * Deletes a paticular node with its branch, while reserving the nodes
524 * (and their brance) listed in the m_aReservedNodes.
525 * The deletion process is preformed in the tree order, that is, a node
526 * is deleted after its previous sibling node is deleted, a parent node
527 * is deleted after its branch is deleted.
528 * During the deletion process when the m_pStopAtNode is reached, the
529 * progress is interrupted at once.
531 * INPUTS
532 * pNode - the node to be deleted
534 * RESULT
535 * result - the result of the deletion process, can be one of following
536 * values:
537 * NODE_STOPED - the process is interrupted by meeting the
538 * m_pStopAtNode
539 * NODE_NOTREMOVED - the pNode is not completely removed
540 * because there is its descendant in the
541 * m_aReservedNodes list
542 * NODE_REMOVED - the pNode and its branch are completely
543 * removed
545 * NOTES
546 * The node in the m_aReservedNodes list must be in the tree order, otherwise
547 * the result is unpredictable.
549 * HISTORY
550 * 05.01.2004 - implemented
552 * AUTHOR
553 * Michael Mi
554 * Email: michael.mi@sun.com
555 ******************************************************************************/
557 if (pNode == m_pStopAtNode)
559 return NODE_STOPED;
562 if (pNode != m_pCurrentReservedNode)
564 xmlNodePtr pChild = pNode->children;
566 xmlNodePtr pNextSibling;
567 bool bIsRemoved = true;
568 sal_Int32 nResult;
570 while( pChild != NULL )
572 pNextSibling = pChild->next;
573 nResult = recursiveDelete(pChild);
575 switch (nResult)
577 case NODE_STOPED:
578 return NODE_STOPED;
579 case NODE_NOTREMOVED:
580 bIsRemoved = false;
581 break;
582 case NODE_REMOVED:
583 removeNode(pChild);
584 break;
585 default:
586 throw cssu::RuntimeException();
589 pChild = pNextSibling;
592 if (pNode == m_pCurrentElement)
594 bIsRemoved = false;
597 return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
599 else
601 getNextReservedNode();
602 return NODE_NOTREMOVED;
606 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
607 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
609 * NAME
610 * getNextReservedNode -- Highlights the next reserved node in the
611 * reserved node list
613 * SYNOPSIS
614 * getNextReservedNode();
616 * FUNCTION
617 * The m_aReservedNodes array holds a node list, while the
618 * m_pCurrentReservedNode points to the one currently highlighted.
619 * This method is used to highlight the next node in the node list.
620 * This method is called at the time when the current highlighted node
621 * has been already processed, and the next node should be ready.
623 * INPUTS
624 * empty
626 * RESULT
627 * empty
629 * HISTORY
630 * 05.01.2004 - implemented
632 * AUTHOR
633 * Michael Mi
634 * Email: michael.mi@sun.com
635 ******************************************************************************/
637 if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
639 m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] );
640 m_nReservedNodeIndex ++;
642 else
644 m_pCurrentReservedNode = NULL;
648 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
649 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
651 * NAME
652 * removeNode -- Deletes a node with its branch unconditionaly
654 * SYNOPSIS
655 * removeNode( pNode );
657 * FUNCTION
658 * Delete the node along with its branch from the document.
660 * INPUTS
661 * pNode - the node to be deleted
663 * RESULT
664 * empty
666 * HISTORY
667 * 05.01.2004 - implemented
669 * AUTHOR
670 * Michael Mi
671 * Email: michael.mi@sun.com
672 ******************************************************************************/
674 /* you can't remove the current node */
675 OSL_ASSERT( m_pCurrentElement != pNode );
677 xmlAttrPtr pAttr = pNode->properties;
679 while (pAttr != NULL)
681 if (!stricmp((sal_Char*)pAttr->name,"id"))
683 xmlRemoveID(m_pDocument, pAttr);
686 pAttr = pAttr->next;
689 xmlUnlinkNode(pNode);
690 xmlFreeNode(pNode);
693 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
694 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
696 * NAME
697 * buildIDAttr -- build the ID attribute of a node
699 * SYNOPSIS
700 * buildIDAttr( pNode );
702 * FUNCTION
703 * see NAME
705 * INPUTS
706 * pNode - the node whose id attribute will be built
708 * RESULT
709 * empty
711 * HISTORY
712 * 14.06.2004 - implemented
714 * AUTHOR
715 * Michael Mi
716 * Email: michael.mi@sun.com
717 ******************************************************************************/
719 xmlAttrPtr idAttr = xmlHasProp( pNode, (const unsigned char *)"id" );
720 if (idAttr == NULL)
722 idAttr = xmlHasProp( pNode, (const unsigned char *)"Id" );
725 if (idAttr != NULL)
727 xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
728 xmlAddID( NULL, m_pDocument, idValue, idAttr );
732 void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const
733 /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
735 * NAME
736 * rebuildIDLink -- rebuild the ID link for the branch
738 * SYNOPSIS
739 * rebuildIDLink( pNode );
741 * FUNCTION
742 * see NAME
744 * INPUTS
745 * pNode - the node, from which the branch will be rebuilt
747 * RESULT
748 * empty
750 * HISTORY
751 * 14.06.2004 - implemented
753 * AUTHOR
754 * Michael Mi
755 * Email: michael.mi@sun.com
756 ******************************************************************************/
758 if (pNode != NULL && pNode->type == XML_ELEMENT_NODE)
760 buildIDAttr( pNode );
762 xmlNodePtr child = pNode->children;
763 while (child != NULL)
765 rebuildIDLink(child);
766 child = child->next;
771 /* XXMLDocumentWrapper */
772 cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
773 throw (cssu::RuntimeException)
775 XMLElementWrapper_XmlSecImpl* pElement = new XMLElementWrapper_XmlSecImpl(m_pCurrentElement);
776 return (cssu::Reference< cssxw::XXMLElementWrapper >)pElement;
779 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference< cssxw::XXMLElementWrapper >& element )
780 throw (cssu::RuntimeException)
782 m_pCurrentElement = checkElement( element );
783 saxHelper.setCurrentNode( m_pCurrentElement );
786 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
787 throw (cssu::RuntimeException)
789 OSL_ASSERT( m_pCurrentElement != NULL );
791 xmlNodePtr pOldCurrentElement = m_pCurrentElement;
794 * pop the top node in the parser context's
795 * nodeTab stack, then the parent of that node will
796 * automatically become the new stack top, and
797 * the current node as well.
799 saxHelper.endElement(
800 rtl::OUString(
801 RTL_UTF8_USTRINGPARAM (
802 (sal_Char*)(pOldCurrentElement->name)
803 )));
804 m_pCurrentElement = saxHelper.getCurrentNode();
807 * remove the node
809 removeNode(pOldCurrentElement);
812 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
813 throw (cssu::RuntimeException)
815 xmlNodePtr pNode = checkElement(node);
816 return (pNode == m_pCurrentElement);
819 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
820 throw (cssu::RuntimeException)
822 sal_Bool rc = sal_False;
824 if (m_pCurrentElement->children == NULL)
826 rc = sal_True;
829 return rc;
832 rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
833 throw (cssu::RuntimeException)
835 xmlNodePtr pNode = checkElement(node);
836 return rtl::OUString(RTL_UTF8_USTRINGPARAM ( (sal_Char*)pNode->name ));
839 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData(
840 const cssu::Reference< cssxw::XXMLElementWrapper >& node,
841 const cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >& reservedDescendants,
842 const cssu::Reference< cssxw::XXMLElementWrapper >& stopAtNode )
843 throw (cssu::RuntimeException)
845 xmlNodePtr pTargetNode = checkElement(node);
847 m_pStopAtNode = checkElement(stopAtNode);
848 m_aReservedNodes = reservedDescendants;
849 m_nReservedNodeIndex = 0;
851 getNextReservedNode();
853 recursiveDelete(pTargetNode);
856 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
857 throw (cssu::RuntimeException)
859 xmlNodePtr pTargetNode = checkElement(node);
860 xmlNodePtr pParent;
862 while (pTargetNode != NULL)
864 if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement)
866 break;
869 pParent = pTargetNode->parent;
870 removeNode(pTargetNode);
871 pTargetNode = pParent;
875 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference< cssxs::XDocumentHandler >& handler )
876 throw (cssxs::SAXException, cssu::RuntimeException)
878 if (m_pRootElement != NULL)
880 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
881 sal_Int32 nTempCurrentPosition = m_nCurrentPosition;
883 m_pCurrentElement = m_pRootElement;
885 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
886 cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
888 while(true)
890 switch (m_nCurrentPosition)
892 case NODEPOSITION_STARTELEMENT:
893 sendStartElement(NULL, xHandler, m_pCurrentElement);
894 break;
895 case NODEPOSITION_ENDELEMENT:
896 sendEndElement(NULL, xHandler, m_pCurrentElement);
897 break;
898 case NODEPOSITION_NORMAL:
899 sendNode(NULL, xHandler, m_pCurrentElement);
900 break;
903 if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
905 break;
908 getNextSAXEvent();
911 m_pCurrentElement = pTempCurrentElement;
912 m_nCurrentPosition = nTempCurrentPosition;
916 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
917 const cssu::Reference< cssxs::XDocumentHandler >& handler,
918 const cssu::Reference< cssxs::XDocumentHandler >& xEventKeeperHandler,
919 const cssu::Reference< cssxw::XXMLElementWrapper >& startNode,
920 const cssu::Reference< cssxw::XXMLElementWrapper >& endNode )
921 throw (cssxs::SAXException, cssu::RuntimeException)
924 * The first SAX event is the startElement of the startNode
925 * element.
927 bool bHasCurrentElementChild = (m_pCurrentElement->children != NULL);
929 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
931 m_pCurrentElement = checkElement(startNode);
933 if (m_pCurrentElement->type == XML_ELEMENT_NODE)
935 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
937 else
939 m_nCurrentPosition = NODEPOSITION_NORMAL;
942 xmlNodePtr pEndNode = checkElement(endNode);
944 cssu::Reference < cssxc::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, cssu::UNO_QUERY );
946 cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
948 while(true)
950 switch (m_nCurrentPosition)
952 case NODEPOSITION_STARTELEMENT:
953 sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
954 break;
955 case NODEPOSITION_ENDELEMENT:
956 sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
957 break;
958 case NODEPOSITION_NORMAL:
959 sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
960 break;
961 default:
962 throw cssu::RuntimeException();
965 if (xSAXEventKeeper->isBlocking())
967 xHandler = NULL;
970 if (pEndNode == NULL &&
971 ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
972 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
974 break;
977 getNextSAXEvent();
980 * If there is an end point specified, then check whether
981 * the current node equals to the end point. If so, stop
982 * generating.
984 if (pEndNode != NULL && m_pCurrentElement == pEndNode)
986 break;
990 m_pCurrentElement = pTempCurrentElement;
993 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
994 const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node )
995 throw (com::sun::star::uno::RuntimeException)
997 xmlNodePtr pNode = checkElement( node );
998 rebuildIDLink(pNode);
1002 /* cssxs::XDocumentHandler */
1003 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( )
1004 throw (cssxs::SAXException, cssu::RuntimeException)
1008 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( )
1009 throw (cssxs::SAXException, cssu::RuntimeException)
1013 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const rtl::OUString& aName, const cssu::Reference< cssxs::XAttributeList >& xAttribs )
1014 throw (cssxs::SAXException, cssu::RuntimeException)
1016 sal_Int32 nLength = xAttribs->getLength();
1017 cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
1019 for (int i = 0; i < nLength; ++i)
1021 aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
1022 aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
1025 _startElement(aName, aAttributes);
1028 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const rtl::OUString& aName )
1029 throw (cssxs::SAXException, cssu::RuntimeException)
1031 saxHelper.endElement(aName);
1032 m_pCurrentElement = saxHelper.getCurrentNode();
1035 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const rtl::OUString& aChars )
1036 throw (cssxs::SAXException, cssu::RuntimeException)
1038 saxHelper.characters(aChars);
1041 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
1042 throw (cssxs::SAXException, cssu::RuntimeException)
1044 saxHelper.ignorableWhitespace(aWhitespaces);
1047 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
1048 throw (cssxs::SAXException, cssu::RuntimeException)
1050 saxHelper.processingInstruction(aTarget, aData);
1053 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
1054 throw (cssxs::SAXException, cssu::RuntimeException)
1056 saxHelper.setDocumentLocator(xLocator);
1059 /* XCompressedDocumentHandler */
1060 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startDocument( )
1061 throw (cssxs::SAXException, cssu::RuntimeException)
1065 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endDocument( )
1066 throw (cssxs::SAXException, cssu::RuntimeException)
1070 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startElement( const rtl::OUString& aName, const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
1071 throw (cssxs::SAXException, cssu::RuntimeException)
1073 saxHelper.startElement(aName, aAttributes);
1074 m_pCurrentElement = saxHelper.getCurrentNode();
1076 buildIDAttr( m_pCurrentElement );
1079 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endElement( const rtl::OUString& aName )
1080 throw (cssxs::SAXException, cssu::RuntimeException)
1082 endElement( aName );
1085 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_characters( const rtl::OUString& aChars )
1086 throw (cssxs::SAXException, cssu::RuntimeException)
1088 characters( aChars );
1091 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_ignorableWhitespace( const rtl::OUString& aWhitespaces )
1092 throw (cssxs::SAXException, cssu::RuntimeException)
1094 ignorableWhitespace( aWhitespaces );
1097 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
1098 throw (cssxs::SAXException, cssu::RuntimeException)
1100 processingInstruction( aTarget, aData );
1103 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_setDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const rtl::OUString& /*publicId*/, const rtl::OUString& /*systemId*/ )
1104 throw (cssxs::SAXException, cssu::RuntimeException)
1108 rtl::OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName ()
1109 throw (cssu::RuntimeException)
1111 return rtl::OUString ( RTL_ASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
1114 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName )
1115 throw (cssu::RuntimeException)
1117 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
1120 cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( )
1121 throw (cssu::RuntimeException)
1123 cssu::Sequence < rtl::OUString > aRet(1);
1124 rtl::OUString* pArray = aRet.getArray();
1125 pArray[0] = rtl::OUString ( RTL_ASCII_USTRINGPARAM ( SERVICE_NAME ) );
1126 return aRet;
1128 #undef SERVICE_NAME
1130 cssu::Reference< cssu::XInterface > SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance(
1131 const cssu::Reference< cssl::XMultiServiceFactory > &)
1132 throw( cssu::Exception )
1134 return (cppu::OWeakObject*) new XMLDocumentWrapper_XmlSecImpl( );
1137 /* XServiceInfo */
1138 rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
1139 throw (cssu::RuntimeException)
1141 return XMLDocumentWrapper_XmlSecImpl_getImplementationName();
1143 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const rtl::OUString& rServiceName )
1144 throw (cssu::RuntimeException)
1146 return XMLDocumentWrapper_XmlSecImpl_supportsService( rServiceName );
1148 cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
1149 throw (cssu::RuntimeException)
1151 return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames();