1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: xmldocumentwrapper_xmlsecimpl.cxx,v $
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"
50 #include <sys/types.h>
53 #ifndef INCLUDED_VECTOR
55 #define INCLUDED_VECTOR
59 #define stricmp strcasecmp
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
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 *************************
106 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
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;
135 * 05.01.2004 - implemented
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
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
160 if (m_pCurrentElement
->children
!= NULL
)
162 m_pCurrentElement
= m_pCurrentElement
->children
;
164 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
165 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
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
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
;
192 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
193 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
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 ************************
211 * sendStartElement -- Constructs a startElement SAX event
214 * sendStartElement(xHandler, xHandler2, pNode);
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.
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.
233 * 05.01.2004 - implemented
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
)));
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
;
278 ouAttrName
= rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char
*)pAttrName
));
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(
289 rtl::OUString(RTL_UTF8_USTRINGPARAM( (sal_Char
*)(pAttr
->children
->content
))));
293 rtl::OString sNodeName
= getNodeQName(pNode
);
297 xHandler
->startElement(
298 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char
*)(sNodeName
.getStr())) )),
302 xHandler2
->startElement(
303 rtl::OUString(RTL_UTF8_USTRINGPARAM ( ((sal_Char
*)(sNodeName
.getStr())) )),
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 **************************
315 * sendEndElement -- Constructs a endElement SAX event
318 * sendEndElement(xHandler, xHandler2, pNode);
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.
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.
337 * 05.01.2004 - implemented
341 * Email: michael.mi@sun.com
342 ******************************************************************************/
344 rtl::OString sNodeName
= getNodeQName(pNode
);
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 ********************************
362 * sendNode -- Constructs a characters SAX event or a
363 * processingInstruction SAX event
366 * sendNode(xHandler, xHandler2, pNode);
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.
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.
388 * 05.01.2004 - implemented
392 * Email: michael.mi@sun.com
393 ******************************************************************************/
395 xmlElementType type
= pNode
->type
;
397 if (type
== XML_TEXT_NODE
)
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
)
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 ****************************
425 * getNodeQName -- Retrives the qualified name of a node
428 * name = getNodeQName(pNode);
434 * pNode - the node whose name will be retrived
437 * name - the node's qualified name
440 * 05.01.2004 - implemented
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
;
462 xmlNodePtr
XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
) const
463 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
466 * checkElement -- Retrives the node wrapped by an XXMLElementWrapper
470 * node = checkElement(xXMLElement);
476 * xXMLElement - the XXMLElementWrapper interface wraping a node
479 * node - the node wrapped in the XXMLElementWrapper interface
482 * 05.01.2004 - implemented
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();
515 sal_Int32
XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
516 const xmlNodePtr pNode
)
517 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
520 * recursiveDelete -- Deletes a paticular node with its branch.
523 * result = recursiveDelete(pNode);
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.
535 * pNode - the node to be deleted
538 * result - the result of the deletion process, can be one of following
540 * NODE_STOPED - the process is interrupted by meeting the
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
549 * The node in the m_aReservedNodes list must be in the tree order, otherwise
550 * the result is unpredictable.
553 * 05.01.2004 - implemented
557 * Email: michael.mi@sun.com
558 ******************************************************************************/
560 if (pNode
== m_pStopAtNode
)
565 if (pNode
!= m_pCurrentReservedNode
)
567 xmlNodePtr pChild
= pNode
->children
;
569 xmlNodePtr pNextSibling
;
570 bool bIsRemoved
= true;
573 while( pChild
!= NULL
)
575 pNextSibling
= pChild
->next
;
576 nResult
= recursiveDelete(pChild
);
582 case NODE_NOTREMOVED
:
589 throw cssu::RuntimeException();
592 pChild
= pNextSibling
;
595 if (pNode
== m_pCurrentElement
)
600 return bIsRemoved
?NODE_REMOVED
:NODE_NOTREMOVED
;
604 getNextReservedNode();
605 return NODE_NOTREMOVED
;
609 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
610 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
613 * getNextReservedNode -- Highlights the next reserved node in the
617 * getNextReservedNode();
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.
633 * 05.01.2004 - implemented
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
++;
647 m_pCurrentReservedNode
= NULL
;
651 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode
) const
652 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
655 * removeNode -- Deletes a node with its branch unconditionaly
658 * removeNode( pNode );
661 * Delete the node along with its branch from the document.
664 * pNode - the node to be deleted
670 * 05.01.2004 - implemented
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
);
692 xmlUnlinkNode(pNode
);
696 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode
) const
697 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
700 * buildIDAttr -- build the ID attribute of a node
703 * buildIDAttr( pNode );
709 * pNode - the node whose id attribute will be built
715 * 14.06.2004 - implemented
719 * Email: michael.mi@sun.com
720 ******************************************************************************/
722 xmlAttrPtr idAttr
= xmlHasProp( pNode
, (const unsigned char *)"id" );
725 idAttr
= xmlHasProp( pNode
, (const unsigned char *)"Id" );
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 ***************************
739 * rebuildIDLink -- rebuild the ID link for the branch
742 * rebuildIDLink( pNode );
748 * pNode - the node, from which the branch will be rebuilt
754 * 14.06.2004 - implemented
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
);
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(
804 RTL_UTF8_USTRINGPARAM (
805 (sal_Char
*)(pOldCurrentElement
->name
)
807 m_pCurrentElement
= saxHelper
.getCurrentNode();
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
)
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
);
865 while (pTargetNode
!= NULL
)
867 if (pTargetNode
->children
!= NULL
|| pTargetNode
== m_pCurrentElement
)
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
;
893 switch (m_nCurrentPosition
)
895 case NODEPOSITION_STARTELEMENT
:
896 sendStartElement(NULL
, xHandler
, m_pCurrentElement
);
898 case NODEPOSITION_ENDELEMENT
:
899 sendEndElement(NULL
, xHandler
, m_pCurrentElement
);
901 case NODEPOSITION_NORMAL
:
902 sendNode(NULL
, xHandler
, m_pCurrentElement
);
906 if ( (m_pCurrentElement
== m_pRootElement
) && (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
))
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
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
;
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
;
953 switch (m_nCurrentPosition
)
955 case NODEPOSITION_STARTELEMENT
:
956 sendStartElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
958 case NODEPOSITION_ENDELEMENT
:
959 sendEndElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
961 case NODEPOSITION_NORMAL
:
962 sendNode(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
965 throw cssu::RuntimeException();
968 if (xSAXEventKeeper
->isBlocking())
973 if (pEndNode
== NULL
&&
974 ((bHasCurrentElementChild
&& m_pCurrentElement
== xmlGetLastChild(pTempCurrentElement
) && m_nCurrentPosition
!= NODEPOSITION_STARTELEMENT
) ||
975 (!bHasCurrentElementChild
&& m_pCurrentElement
== pTempCurrentElement
&& m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)))
983 * If there is an end point specified, then check whether
984 * the current node equals to the end point. If so, stop
987 if (pEndNode
!= NULL
&& m_pCurrentElement
== pEndNode
)
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
) );
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( );
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();