Update ooo320-m1
[ooovba.git] / xmlsecurity / source / xmlsec / xmldocumentwrapper_xmlsecimpl.cxx
blobc2c07c4348b915990c51648a8a8ceb06e15225c5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmldocumentwrapper_xmlsecimpl.cxx,v $
10 * $Revision: 1.6 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmlsecurity.hxx"
34 #include "xmldocumentwrapper_xmlsecimpl.hxx"
35 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37 #include <xmloff/attrlist.hxx>
38 #include "xmlelementwrapper_xmlsecimpl.hxx"
40 //#include <malloc.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
46 * Deleted by AF
47 #include <memory.h>
50 #include <sys/types.h>
51 #include <sys/stat.h>
53 #ifndef INCLUDED_VECTOR
54 #include <vector>
55 #define INCLUDED_VECTOR
56 #endif
58 #ifdef UNX
59 #define stricmp strcasecmp
60 #endif
62 namespace cssu = com::sun::star::uno;
63 namespace cssl = com::sun::star::lang;
64 namespace cssxc = com::sun::star::xml::crypto;
65 namespace cssxcsax = com::sun::star::xml::csax;
66 namespace cssxs = com::sun::star::xml::sax;
67 namespace cssxw = com::sun::star::xml::wrapper;
69 #define SERVICE_NAME "com.sun.star.xml.wrapper.XMLDocumentWrapper"
70 #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl"
72 #define STRXMLNS "xmlns"
74 #define RTL_ASCII_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_ASCII_US
75 #define RTL_UTF8_USTRINGPARAM( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8
77 /* used by the recursiveDelete method */
78 #define NODE_REMOVED 0
79 #define NODE_NOTREMOVED 1
80 #define NODE_STOPED 2
82 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl( )
84 saxHelper.startDocument();
85 m_pDocument = saxHelper.getDocument();
88 * creates the virtual root element
90 saxHelper.startElement(rtl::OUString(RTL_UTF8_USTRINGPARAM( "root" )), cssu::Sequence<cssxcsax::XMLAttribute>());
92 m_pRootElement = saxHelper.getCurrentNode();
93 m_pCurrentElement = m_pRootElement;
96 XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
98 saxHelper.endDocument();
99 xmlFreeDoc(m_pDocument);
102 void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
103 /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
105 * NAME
106 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
108 * SYNOPSIS
109 * getNextSAXEvent();
111 * FUNCTION
112 * When converting the document into SAX events, this method is used to
113 * decide the next SAX event to be generated.
114 * Two member variables are checked to make the decision, the
115 * m_pCurrentElement and the m_nCurrentPosition.
116 * The m_pCurrentElement represents the node which have been covered, and
117 * the m_nCurrentPosition represents the event which have been sent.
118 * For example, suppose that the m_pCurrentElement
119 * points to element A, and the m_nCurrentPosition equals to
120 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
121 * endElement for element A if A has no child, or startElement for the
122 * first child element of element A otherwise.
123 * The m_nCurrentPosition can be one of following values:
124 * NODEPOSITION_STARTELEMENT for startElement;
125 * NODEPOSITION_ENDELEMENT for endElement;
126 * NODEPOSITION_NORMAL for other SAX events;
128 * INPUTS
129 * empty
131 * RESULT
132 * empty
134 * HISTORY
135 * 05.01.2004 - implemented
137 * AUTHOR
138 * Michael Mi
139 * Email: michael.mi@sun.com
140 ******************************************************************************/
142 OSL_ASSERT( m_pCurrentElement != NULL );
145 * Get the next event through tree order.
147 * if the current event is a startElement, then the next
148 * event depends on whether or not the current node has
149 * children.
151 if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT)
154 * If the current node has children, then its first child
155 * should be next current node, and the next event will be
156 * startElement or charaters(PI) based on that child's node
157 * type. Otherwise, the endElement of current node is the
158 * next event.
160 if (m_pCurrentElement->children != NULL)
162 m_pCurrentElement = m_pCurrentElement->children;
163 m_nCurrentPosition
164 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
165 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
167 else
169 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
173 * if the current event is a not startElement, then the next
174 * event depends on whether or not the current node has
175 * following sibling.
177 else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL)
179 xmlNodePtr pNextSibling = m_pCurrentElement->next;
182 * If the current node has following sibling, that sibling
183 * should be next current node, and the next event will be
184 * startElement or charaters(PI) based on that sibling's node
185 * type. Otherwise, the endElement of current node's parent
186 * becomes the next event.
188 if (pNextSibling != NULL)
190 m_pCurrentElement = pNextSibling;
191 m_nCurrentPosition
192 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
193 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
195 else
197 m_pCurrentElement = m_pCurrentElement->parent;
198 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
203 void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
204 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
205 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
206 const xmlNodePtr pNode) const
207 throw (cssxs::SAXException)
208 /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
210 * NAME
211 * sendStartElement -- Constructs a startElement SAX event
213 * SYNOPSIS
214 * sendStartElement(xHandler, xHandler2, pNode);
216 * FUNCTION
217 * Used when converting the document into SAX event stream.
218 * This method constructs a startElement SAX event for a particular
219 * element, then calls the startElement methods of the XDocumentHandlers.
221 * INPUTS
222 * xHandler - the first XDocumentHandler interface to receive the
223 * startElement SAX event. It can be NULL.
224 * xHandler2 - the second XDocumentHandler interface to receive the
225 * startElement SAX event. It can't be NULL.
226 * pNode - the node on which the startElement should be generated.
227 * This node must be a element type.
229 * RESULT
230 * empty
232 * HISTORY
233 * 05.01.2004 - implemented
235 * AUTHOR
236 * Michael Mi
237 * Email: michael.mi@sun.com
238 ******************************************************************************/
240 SvXMLAttributeList* pAttributeList = new SvXMLAttributeList();
241 cssu::Reference < cssxs::XAttributeList > xAttrList = cssu::Reference< cssxs::XAttributeList > (pAttributeList);
243 xmlNsPtr pNsDef = pNode->nsDef;
245 while (pNsDef != NULL)
247 const xmlChar* pNsPrefix = pNsDef->prefix;
248 const xmlChar* pNsHref = pNsDef->href;
250 if (pNsDef->prefix == NULL)
252 pAttributeList->AddAttribute(
253 rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS )),
254 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref )));
256 else
258 pAttributeList->AddAttribute(
259 rtl::OUString(RTL_UTF8_USTRINGPARAM( STRXMLNS ))
260 +rtl::OUString(RTL_UTF8_USTRINGPARAM( ":" ))
261 +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsPrefix )),
262 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pNsHref )));
265 pNsDef = pNsDef->next;
268 xmlAttrPtr pAttr = pNode->properties;
270 while (pAttr != NULL)
272 const xmlChar* pAttrName = pAttr->name;
273 xmlNsPtr pAttrNs = pAttr->ns;
275 rtl::OUString ouAttrName;
276 if (pAttrNs == NULL)
278 ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName ));
280 else
282 ouAttrName = rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrNs->prefix))
283 +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)":" ))
284 +rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)pAttrName ));
287 pAttributeList->AddAttribute(
288 ouAttrName,
289 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char*)(pAttr->children->content))));
290 pAttr = pAttr->next;
293 rtl::OString sNodeName = getNodeQName(pNode);
295 if (xHandler.is())
297 xHandler->startElement(
298 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )),
299 xAttrList);
302 xHandler2->startElement(
303 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )),
304 xAttrList);
307 void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
308 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
309 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
310 const xmlNodePtr pNode) const
311 throw (cssxs::SAXException)
312 /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
314 * NAME
315 * sendEndElement -- Constructs a endElement SAX event
317 * SYNOPSIS
318 * sendEndElement(xHandler, xHandler2, pNode);
320 * FUNCTION
321 * Used when converting the document into SAX event stream.
322 * This method constructs a endElement SAX event for a particular
323 * element, then calls the endElement methods of the XDocumentHandlers.
325 * INPUTS
326 * xHandler - the first XDocumentHandler interface to receive the
327 * endElement SAX event. It can be NULL.
328 * xHandler2 - the second XDocumentHandler interface to receive the
329 * endElement SAX event. It can't be NULL.
330 * pNode - the node on which the endElement should be generated.
331 * This node must be a element type.
333 * RESULT
334 * empty
336 * HISTORY
337 * 05.01.2004 - implemented
339 * AUTHOR
340 * Michael Mi
341 * Email: michael.mi@sun.com
342 ******************************************************************************/
344 rtl::OString sNodeName = getNodeQName(pNode);
346 if (xHandler.is())
348 xHandler->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )));
351 xHandler2->endElement(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(sNodeName.getStr())) )));
354 void XMLDocumentWrapper_XmlSecImpl::sendNode(
355 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
356 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
357 const xmlNodePtr pNode) const
358 throw (cssxs::SAXException)
359 /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
361 * NAME
362 * sendNode -- Constructs a characters SAX event or a
363 * processingInstruction SAX event
365 * SYNOPSIS
366 * sendNode(xHandler, xHandler2, pNode);
368 * FUNCTION
369 * Used when converting the document into SAX event stream.
370 * This method constructs a characters SAX event or a
371 * processingInstructionfor SAX event based on the type of a particular
372 * element, then calls the corresponding methods of the XDocumentHandlers.
374 * INPUTS
375 * xHandler - the first XDocumentHandler interface to receive the
376 * SAX event. It can be NULL.
377 * xHandler2 - the second XDocumentHandler interface to receive the
378 * SAX event. It can't be NULL.
379 * pNode - the node on which the endElement should be generated.
380 * If it is a text node, then a characters SAX event is
381 * generated; if it is a PI node, then a
382 * processingInstructionfor SAX event is generated.
384 * RESULT
385 * empty
387 * HISTORY
388 * 05.01.2004 - implemented
390 * AUTHOR
391 * Michael Mi
392 * Email: michael.mi@sun.com
393 ******************************************************************************/
395 xmlElementType type = pNode->type;
397 if (type == XML_TEXT_NODE)
399 if (xHandler.is())
401 xHandler->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
404 xHandler2->characters(rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
406 else if (type == XML_PI_NODE)
408 if (xHandler.is())
410 xHandler->processingInstruction(
411 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )),
412 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
415 xHandler2->processingInstruction(
416 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->name)) )),
417 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char*)(pNode->content)) )));
421 rtl::OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode) const
422 /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
424 * NAME
425 * getNodeQName -- Retrives the qualified name of a node
427 * SYNOPSIS
428 * name = getNodeQName(pNode);
430 * FUNCTION
431 * see NAME
433 * INPUTS
434 * pNode - the node whose name will be retrived
436 * RESULT
437 * name - the node's qualified name
439 * HISTORY
440 * 05.01.2004 - implemented
442 * AUTHOR
443 * Michael Mi
444 * Email: michael.mi@sun.com
445 ******************************************************************************/
447 rtl::OString sNodeName((const sal_Char*)pNode->name);
448 if (pNode->ns != NULL)
450 xmlNsPtr pNs = pNode->ns;
452 if (pNs->prefix != NULL)
454 rtl::OString sPrefix((const sal_Char*)pNs->prefix);
455 sNodeName = sPrefix+rtl::OString(":")+sNodeName;
459 return sNodeName;
462 xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement) const
463 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
465 * NAME
466 * checkElement -- Retrives the node wrapped by an XXMLElementWrapper
467 * interface
469 * SYNOPSIS
470 * node = checkElement(xXMLElement);
472 * FUNCTION
473 * see NAME
475 * INPUTS
476 * xXMLElement - the XXMLElementWrapper interface wraping a node
478 * RESULT
479 * node - the node wrapped in the XXMLElementWrapper interface
481 * HISTORY
482 * 05.01.2004 - implemented
484 * AUTHOR
485 * Michael Mi
486 * Email: michael.mi@sun.com
487 ******************************************************************************/
489 xmlNodePtr rc = NULL;
491 if (xXMLElement.is())
493 cssu::Reference< cssl::XUnoTunnel > xNodTunnel( xXMLElement, cssu::UNO_QUERY ) ;
494 if( !xNodTunnel.is() )
496 throw cssu::RuntimeException() ;
499 XMLElementWrapper_XmlSecImpl* pElement
500 = reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
501 sal::static_int_cast<sal_uIntPtr>(
502 xNodTunnel->getSomething(
503 XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ;
505 if( pElement == NULL ) {
506 throw cssu::RuntimeException() ;
509 rc = pElement->getNativeElement();
512 return rc;
515 sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
516 const xmlNodePtr pNode)
517 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
519 * NAME
520 * recursiveDelete -- Deletes a paticular node with its branch.
522 * SYNOPSIS
523 * result = recursiveDelete(pNode);
525 * FUNCTION
526 * Deletes a paticular node with its branch, while reserving the nodes
527 * (and their brance) listed in the m_aReservedNodes.
528 * The deletion process is preformed in the tree order, that is, a node
529 * is deleted after its previous sibling node is deleted, a parent node
530 * is deleted after its branch is deleted.
531 * During the deletion process when the m_pStopAtNode is reached, the
532 * progress is interrupted at once.
534 * INPUTS
535 * pNode - the node to be deleted
537 * RESULT
538 * result - the result of the deletion process, can be one of following
539 * values:
540 * NODE_STOPED - the process is interrupted by meeting the
541 * m_pStopAtNode
542 * NODE_NOTREMOVED - the pNode is not completely removed
543 * because there is its descendant in the
544 * m_aReservedNodes list
545 * NODE_REMOVED - the pNode and its branch are completely
546 * removed
548 * NOTES
549 * The node in the m_aReservedNodes list must be in the tree order, otherwise
550 * the result is unpredictable.
552 * HISTORY
553 * 05.01.2004 - implemented
555 * AUTHOR
556 * Michael Mi
557 * Email: michael.mi@sun.com
558 ******************************************************************************/
560 if (pNode == m_pStopAtNode)
562 return NODE_STOPED;
565 if (pNode != m_pCurrentReservedNode)
567 xmlNodePtr pChild = pNode->children;
569 xmlNodePtr pNextSibling;
570 bool bIsRemoved = true;
571 sal_Int32 nResult;
573 while( pChild != NULL )
575 pNextSibling = pChild->next;
576 nResult = recursiveDelete(pChild);
578 switch (nResult)
580 case NODE_STOPED:
581 return NODE_STOPED;
582 case NODE_NOTREMOVED:
583 bIsRemoved = false;
584 break;
585 case NODE_REMOVED:
586 removeNode(pChild);
587 break;
588 default:
589 throw cssu::RuntimeException();
592 pChild = pNextSibling;
595 if (pNode == m_pCurrentElement)
597 bIsRemoved = false;
600 return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
602 else
604 getNextReservedNode();
605 return NODE_NOTREMOVED;
609 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
610 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
612 * NAME
613 * getNextReservedNode -- Highlights the next reserved node in the
614 * reserved node list
616 * SYNOPSIS
617 * getNextReservedNode();
619 * FUNCTION
620 * The m_aReservedNodes array holds a node list, while the
621 * m_pCurrentReservedNode points to the one currently highlighted.
622 * This method is used to highlight the next node in the node list.
623 * This method is called at the time when the current highlighted node
624 * has been already processed, and the next node should be ready.
626 * INPUTS
627 * empty
629 * RESULT
630 * empty
632 * HISTORY
633 * 05.01.2004 - implemented
635 * AUTHOR
636 * Michael Mi
637 * Email: michael.mi@sun.com
638 ******************************************************************************/
640 if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
642 m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] );
643 m_nReservedNodeIndex ++;
645 else
647 m_pCurrentReservedNode = NULL;
651 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
652 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
654 * NAME
655 * removeNode -- Deletes a node with its branch unconditionaly
657 * SYNOPSIS
658 * removeNode( pNode );
660 * FUNCTION
661 * Delete the node along with its branch from the document.
663 * INPUTS
664 * pNode - the node to be deleted
666 * RESULT
667 * empty
669 * HISTORY
670 * 05.01.2004 - implemented
672 * AUTHOR
673 * Michael Mi
674 * Email: michael.mi@sun.com
675 ******************************************************************************/
677 /* you can't remove the current node */
678 OSL_ASSERT( m_pCurrentElement != pNode );
680 xmlAttrPtr pAttr = pNode->properties;
682 while (pAttr != NULL)
684 if (!stricmp((sal_Char*)pAttr->name,"id"))
686 xmlRemoveID(m_pDocument, pAttr);
689 pAttr = pAttr->next;
692 xmlUnlinkNode(pNode);
693 xmlFreeNode(pNode);
696 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
697 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
699 * NAME
700 * buildIDAttr -- build the ID attribute of a node
702 * SYNOPSIS
703 * buildIDAttr( pNode );
705 * FUNCTION
706 * see NAME
708 * INPUTS
709 * pNode - the node whose id attribute will be built
711 * RESULT
712 * empty
714 * HISTORY
715 * 14.06.2004 - implemented
717 * AUTHOR
718 * Michael Mi
719 * Email: michael.mi@sun.com
720 ******************************************************************************/
722 xmlAttrPtr idAttr = xmlHasProp( pNode, (const unsigned char *)"id" );
723 if (idAttr == NULL)
725 idAttr = xmlHasProp( pNode, (const unsigned char *)"Id" );
728 if (idAttr != NULL)
730 xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
731 xmlAddID( NULL, m_pDocument, idValue, idAttr );
735 void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const
736 /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
738 * NAME
739 * rebuildIDLink -- rebuild the ID link for the branch
741 * SYNOPSIS
742 * rebuildIDLink( pNode );
744 * FUNCTION
745 * see NAME
747 * INPUTS
748 * pNode - the node, from which the branch will be rebuilt
750 * RESULT
751 * empty
753 * HISTORY
754 * 14.06.2004 - implemented
756 * AUTHOR
757 * Michael Mi
758 * Email: michael.mi@sun.com
759 ******************************************************************************/
761 if (pNode != NULL && pNode->type == XML_ELEMENT_NODE)
763 buildIDAttr( pNode );
765 xmlNodePtr child = pNode->children;
766 while (child != NULL)
768 rebuildIDLink(child);
769 child = child->next;
774 /* XXMLDocumentWrapper */
775 cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
776 throw (cssu::RuntimeException)
778 XMLElementWrapper_XmlSecImpl* pElement = new XMLElementWrapper_XmlSecImpl(m_pCurrentElement);
779 return (cssu::Reference< cssxw::XXMLElementWrapper >)pElement;
782 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference< cssxw::XXMLElementWrapper >& element )
783 throw (cssu::RuntimeException)
785 m_pCurrentElement = checkElement( element );
786 saxHelper.setCurrentNode( m_pCurrentElement );
789 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
790 throw (cssu::RuntimeException)
792 OSL_ASSERT( m_pCurrentElement != NULL );
794 xmlNodePtr pOldCurrentElement = m_pCurrentElement;
797 * pop the top node in the parser context's
798 * nodeTab stack, then the parent of that node will
799 * automatically become the new stack top, and
800 * the current node as well.
802 saxHelper.endElement(
803 rtl::OUString(
804 RTL_UTF8_USTRINGPARAM (
805 (sal_Char*)(pOldCurrentElement->name)
806 )));
807 m_pCurrentElement = saxHelper.getCurrentNode();
810 * remove the node
812 removeNode(pOldCurrentElement);
815 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
816 throw (cssu::RuntimeException)
818 xmlNodePtr pNode = checkElement(node);
819 return (pNode == m_pCurrentElement);
822 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
823 throw (cssu::RuntimeException)
825 sal_Bool rc = sal_False;
827 if (m_pCurrentElement->children == NULL)
829 rc = sal_True;
832 return rc;
835 rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
836 throw (cssu::RuntimeException)
838 xmlNodePtr pNode = checkElement(node);
839 return rtl::OUString(RTL_UTF8_USTRINGPARAM ( (sal_Char*)pNode->name ));
842 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData(
843 const cssu::Reference< cssxw::XXMLElementWrapper >& node,
844 const cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >& reservedDescendants,
845 const cssu::Reference< cssxw::XXMLElementWrapper >& stopAtNode )
846 throw (cssu::RuntimeException)
848 xmlNodePtr pTargetNode = checkElement(node);
850 m_pStopAtNode = checkElement(stopAtNode);
851 m_aReservedNodes = reservedDescendants;
852 m_nReservedNodeIndex = 0;
854 getNextReservedNode();
856 recursiveDelete(pTargetNode);
859 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
860 throw (cssu::RuntimeException)
862 xmlNodePtr pTargetNode = checkElement(node);
863 xmlNodePtr pParent;
865 while (pTargetNode != NULL)
867 if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement)
869 break;
872 pParent = pTargetNode->parent;
873 removeNode(pTargetNode);
874 pTargetNode = pParent;
878 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference< cssxs::XDocumentHandler >& handler )
879 throw (cssxs::SAXException, cssu::RuntimeException)
881 if (m_pRootElement != NULL)
883 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
884 sal_Int32 nTempCurrentPosition = m_nCurrentPosition;
886 m_pCurrentElement = m_pRootElement;
888 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
889 cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
891 while(true)
893 switch (m_nCurrentPosition)
895 case NODEPOSITION_STARTELEMENT:
896 sendStartElement(NULL, xHandler, m_pCurrentElement);
897 break;
898 case NODEPOSITION_ENDELEMENT:
899 sendEndElement(NULL, xHandler, m_pCurrentElement);
900 break;
901 case NODEPOSITION_NORMAL:
902 sendNode(NULL, xHandler, m_pCurrentElement);
903 break;
906 if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
908 break;
911 getNextSAXEvent();
914 m_pCurrentElement = pTempCurrentElement;
915 m_nCurrentPosition = nTempCurrentPosition;
919 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
920 const cssu::Reference< cssxs::XDocumentHandler >& handler,
921 const cssu::Reference< cssxs::XDocumentHandler >& xEventKeeperHandler,
922 const cssu::Reference< cssxw::XXMLElementWrapper >& startNode,
923 const cssu::Reference< cssxw::XXMLElementWrapper >& endNode )
924 throw (cssxs::SAXException, cssu::RuntimeException)
927 * The first SAX event is the startElement of the startNode
928 * element.
930 bool bHasCurrentElementChild = (m_pCurrentElement->children != NULL);
932 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
934 m_pCurrentElement = checkElement(startNode);
936 if (m_pCurrentElement->type == XML_ELEMENT_NODE)
938 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
940 else
942 m_nCurrentPosition = NODEPOSITION_NORMAL;
945 xmlNodePtr pEndNode = checkElement(endNode);
947 cssu::Reference < cssxc::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, cssu::UNO_QUERY );
949 cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
951 while(true)
953 switch (m_nCurrentPosition)
955 case NODEPOSITION_STARTELEMENT:
956 sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
957 break;
958 case NODEPOSITION_ENDELEMENT:
959 sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
960 break;
961 case NODEPOSITION_NORMAL:
962 sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
963 break;
964 default:
965 throw cssu::RuntimeException();
968 if (xSAXEventKeeper->isBlocking())
970 xHandler = NULL;
973 if (pEndNode == NULL &&
974 ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
975 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
977 break;
980 getNextSAXEvent();
983 * If there is an end point specified, then check whether
984 * the current node equals to the end point. If so, stop
985 * generating.
987 if (pEndNode != NULL && m_pCurrentElement == pEndNode)
989 break;
993 m_pCurrentElement = pTempCurrentElement;
996 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
997 const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node )
998 throw (com::sun::star::uno::RuntimeException)
1000 xmlNodePtr pNode = checkElement( node );
1001 rebuildIDLink(pNode);
1005 /* cssxs::XDocumentHandler */
1006 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( )
1007 throw (cssxs::SAXException, cssu::RuntimeException)
1011 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( )
1012 throw (cssxs::SAXException, cssu::RuntimeException)
1016 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const rtl::OUString& aName, const cssu::Reference< cssxs::XAttributeList >& xAttribs )
1017 throw (cssxs::SAXException, cssu::RuntimeException)
1019 sal_Int32 nLength = xAttribs->getLength();
1020 cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
1022 for (int i = 0; i < nLength; ++i)
1024 aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
1025 aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
1028 _startElement(aName, aAttributes);
1031 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const rtl::OUString& aName )
1032 throw (cssxs::SAXException, cssu::RuntimeException)
1034 saxHelper.endElement(aName);
1035 m_pCurrentElement = saxHelper.getCurrentNode();
1038 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const rtl::OUString& aChars )
1039 throw (cssxs::SAXException, cssu::RuntimeException)
1041 saxHelper.characters(aChars);
1044 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
1045 throw (cssxs::SAXException, cssu::RuntimeException)
1047 saxHelper.ignorableWhitespace(aWhitespaces);
1050 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
1051 throw (cssxs::SAXException, cssu::RuntimeException)
1053 saxHelper.processingInstruction(aTarget, aData);
1056 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
1057 throw (cssxs::SAXException, cssu::RuntimeException)
1059 saxHelper.setDocumentLocator(xLocator);
1062 /* XCompressedDocumentHandler */
1063 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startDocument( )
1064 throw (cssxs::SAXException, cssu::RuntimeException)
1068 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endDocument( )
1069 throw (cssxs::SAXException, cssu::RuntimeException)
1073 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_startElement( const rtl::OUString& aName, const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
1074 throw (cssxs::SAXException, cssu::RuntimeException)
1076 saxHelper.startElement(aName, aAttributes);
1077 m_pCurrentElement = saxHelper.getCurrentNode();
1079 buildIDAttr( m_pCurrentElement );
1082 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endElement( const rtl::OUString& aName )
1083 throw (cssxs::SAXException, cssu::RuntimeException)
1085 endElement( aName );
1088 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_characters( const rtl::OUString& aChars )
1089 throw (cssxs::SAXException, cssu::RuntimeException)
1091 characters( aChars );
1094 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_ignorableWhitespace( const rtl::OUString& aWhitespaces )
1095 throw (cssxs::SAXException, cssu::RuntimeException)
1097 ignorableWhitespace( aWhitespaces );
1100 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_processingInstruction( const rtl::OUString& aTarget, const rtl::OUString& aData )
1101 throw (cssxs::SAXException, cssu::RuntimeException)
1103 processingInstruction( aTarget, aData );
1106 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_setDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const rtl::OUString& /*publicId*/, const rtl::OUString& /*systemId*/ )
1107 throw (cssxs::SAXException, cssu::RuntimeException)
1111 rtl::OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName ()
1112 throw (cssu::RuntimeException)
1114 return rtl::OUString ( RTL_ASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
1117 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl_supportsService( const rtl::OUString& ServiceName )
1118 throw (cssu::RuntimeException)
1120 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
1123 cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( )
1124 throw (cssu::RuntimeException)
1126 cssu::Sequence < rtl::OUString > aRet(1);
1127 rtl::OUString* pArray = aRet.getArray();
1128 pArray[0] = rtl::OUString ( RTL_ASCII_USTRINGPARAM ( SERVICE_NAME ) );
1129 return aRet;
1131 #undef SERVICE_NAME
1133 cssu::Reference< cssu::XInterface > SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance(
1134 const cssu::Reference< cssl::XMultiServiceFactory > &)
1135 throw( cssu::Exception )
1137 return (cppu::OWeakObject*) new XMLDocumentWrapper_XmlSecImpl( );
1140 /* XServiceInfo */
1141 rtl::OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
1142 throw (cssu::RuntimeException)
1144 return XMLDocumentWrapper_XmlSecImpl_getImplementationName();
1146 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const rtl::OUString& rServiceName )
1147 throw (cssu::RuntimeException)
1149 return XMLDocumentWrapper_XmlSecImpl_supportsService( rServiceName );
1151 cssu::Sequence< rtl::OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
1152 throw (cssu::RuntimeException)
1154 return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames();