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"
47 #include <sys/types.h>
50 #ifndef INCLUDED_VECTOR
52 #define INCLUDED_VECTOR
56 #define stricmp strcasecmp
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
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 *************************
103 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
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;
132 * 05.01.2004 - implemented
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
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
157 if (m_pCurrentElement
->children
!= NULL
)
159 m_pCurrentElement
= m_pCurrentElement
->children
;
161 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
162 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
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
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
;
189 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
190 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
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 ************************
208 * sendStartElement -- Constructs a startElement SAX event
211 * sendStartElement(xHandler, xHandler2, pNode);
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.
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.
230 * 05.01.2004 - implemented
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
)));
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
;
275 ouAttrName
= rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char
*)pAttrName
));
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(
286 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char
*)(pAttr
->children
->content
))));
290 rtl::OString sNodeName
= getNodeQName(pNode
);
294 xHandler
->startElement(
295 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char
*)(sNodeName
.getStr())) )),
299 xHandler2
->startElement(
300 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char
*)(sNodeName
.getStr())) )),
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 **************************
312 * sendEndElement -- Constructs a endElement SAX event
315 * sendEndElement(xHandler, xHandler2, pNode);
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.
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.
334 * 05.01.2004 - implemented
338 * Email: michael.mi@sun.com
339 ******************************************************************************/
341 rtl::OString sNodeName
= getNodeQName(pNode
);
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 ********************************
359 * sendNode -- Constructs a characters SAX event or a
360 * processingInstruction SAX event
363 * sendNode(xHandler, xHandler2, pNode);
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.
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.
385 * 05.01.2004 - implemented
389 * Email: michael.mi@sun.com
390 ******************************************************************************/
392 xmlElementType type
= pNode
->type
;
394 if (type
== XML_TEXT_NODE
)
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
)
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 ****************************
422 * getNodeQName -- Retrives the qualified name of a node
425 * name = getNodeQName(pNode);
431 * pNode - the node whose name will be retrived
434 * name - the node's qualified name
437 * 05.01.2004 - implemented
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
;
459 xmlNodePtr
XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
) const
460 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
463 * checkElement -- Retrives the node wrapped by an XXMLElementWrapper
467 * node = checkElement(xXMLElement);
473 * xXMLElement - the XXMLElementWrapper interface wraping a node
476 * node - the node wrapped in the XXMLElementWrapper interface
479 * 05.01.2004 - implemented
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();
512 sal_Int32
XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
513 const xmlNodePtr pNode
)
514 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
517 * recursiveDelete -- Deletes a paticular node with its branch.
520 * result = recursiveDelete(pNode);
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.
532 * pNode - the node to be deleted
535 * result - the result of the deletion process, can be one of following
537 * NODE_STOPED - the process is interrupted by meeting the
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
546 * The node in the m_aReservedNodes list must be in the tree order, otherwise
547 * the result is unpredictable.
550 * 05.01.2004 - implemented
554 * Email: michael.mi@sun.com
555 ******************************************************************************/
557 if (pNode
== m_pStopAtNode
)
562 if (pNode
!= m_pCurrentReservedNode
)
564 xmlNodePtr pChild
= pNode
->children
;
566 xmlNodePtr pNextSibling
;
567 bool bIsRemoved
= true;
570 while( pChild
!= NULL
)
572 pNextSibling
= pChild
->next
;
573 nResult
= recursiveDelete(pChild
);
579 case NODE_NOTREMOVED
:
586 throw cssu::RuntimeException();
589 pChild
= pNextSibling
;
592 if (pNode
== m_pCurrentElement
)
597 return bIsRemoved
?NODE_REMOVED
:NODE_NOTREMOVED
;
601 getNextReservedNode();
602 return NODE_NOTREMOVED
;
606 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
607 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
610 * getNextReservedNode -- Highlights the next reserved node in the
614 * getNextReservedNode();
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.
630 * 05.01.2004 - implemented
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
++;
644 m_pCurrentReservedNode
= NULL
;
648 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode
) const
649 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
652 * removeNode -- Deletes a node with its branch unconditionaly
655 * removeNode( pNode );
658 * Delete the node along with its branch from the document.
661 * pNode - the node to be deleted
667 * 05.01.2004 - implemented
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
);
689 xmlUnlinkNode(pNode
);
693 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode
) const
694 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
697 * buildIDAttr -- build the ID attribute of a node
700 * buildIDAttr( pNode );
706 * pNode - the node whose id attribute will be built
712 * 14.06.2004 - implemented
716 * Email: michael.mi@sun.com
717 ******************************************************************************/
719 xmlAttrPtr idAttr
= xmlHasProp( pNode
, (const unsigned char *)"id" );
722 idAttr
= xmlHasProp( pNode
, (const unsigned char *)"Id" );
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 ***************************
736 * rebuildIDLink -- rebuild the ID link for the branch
739 * rebuildIDLink( pNode );
745 * pNode - the node, from which the branch will be rebuilt
751 * 14.06.2004 - implemented
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
);
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(
801 RTL_UTF8_USTRINGPARAM (
802 (sal_Char
*)(pOldCurrentElement
->name
)
804 m_pCurrentElement
= saxHelper
.getCurrentNode();
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
)
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
);
862 while (pTargetNode
!= NULL
)
864 if (pTargetNode
->children
!= NULL
|| pTargetNode
== m_pCurrentElement
)
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
;
890 switch (m_nCurrentPosition
)
892 case NODEPOSITION_STARTELEMENT
:
893 sendStartElement(NULL
, xHandler
, m_pCurrentElement
);
895 case NODEPOSITION_ENDELEMENT
:
896 sendEndElement(NULL
, xHandler
, m_pCurrentElement
);
898 case NODEPOSITION_NORMAL
:
899 sendNode(NULL
, xHandler
, m_pCurrentElement
);
903 if ( (m_pCurrentElement
== m_pRootElement
) && (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
))
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
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
;
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
;
950 switch (m_nCurrentPosition
)
952 case NODEPOSITION_STARTELEMENT
:
953 sendStartElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
955 case NODEPOSITION_ENDELEMENT
:
956 sendEndElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
958 case NODEPOSITION_NORMAL
:
959 sendNode(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
962 throw cssu::RuntimeException();
965 if (xSAXEventKeeper
->isBlocking())
970 if (pEndNode
== NULL
&&
971 ((bHasCurrentElementChild
&& m_pCurrentElement
== xmlGetLastChild(pTempCurrentElement
) && m_nCurrentPosition
!= NODEPOSITION_STARTELEMENT
) ||
972 (!bHasCurrentElementChild
&& m_pCurrentElement
== pTempCurrentElement
&& m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)))
980 * If there is an end point specified, then check whether
981 * the current node equals to the end point. If so, stop
984 if (pEndNode
!= NULL
&& m_pCurrentElement
== pEndNode
)
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
) );
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( );
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();