1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <osl/diagnose.h>
23 #include <com/sun/star/uno/XComponentContext.hpp>
24 #include <cppuhelper/supportsservice.hxx>
25 #include "xmldocumentwrapper_xmlsecimpl.hxx"
27 #include <xmloff/attrlist.hxx>
28 #include "xmlelementwrapper_xmlsecimpl.hxx"
34 #include <sys/types.h>
40 #define stricmp strcasecmp
43 namespace cssu
= com::sun::star::uno
;
44 namespace cssl
= com::sun::star::lang
;
45 namespace cssxc
= com::sun::star::xml::crypto
;
46 namespace cssxcsax
= com::sun::star::xml::csax
;
47 namespace cssxs
= com::sun::star::xml::sax
;
48 namespace cssxw
= com::sun::star::xml::wrapper
;
50 #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl"
52 #define STRXMLNS "xmlns"
54 #define C2U( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8
56 /* used by the recursiveDelete method */
57 #define NODE_REMOVED 0
58 #define NODE_NOTREMOVED 1
61 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl()
62 : m_nCurrentPosition(0)
64 , m_pCurrentReservedNode(0)
65 , m_nReservedNodeIndex(0)
67 saxHelper
.startDocument();
68 m_pDocument
= saxHelper
.getDocument();
71 * creates the virtual root element
73 saxHelper
.startElement(OUString(C2U( "root" )), cssu::Sequence
<cssxcsax::XMLAttribute
>());
75 m_pRootElement
= saxHelper
.getCurrentNode();
76 m_pCurrentElement
= m_pRootElement
;
79 XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
81 saxHelper
.endDocument();
82 xmlFreeDoc(m_pDocument
);
85 void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
86 /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
89 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
95 * When converting the document into SAX events, this method is used to
96 * decide the next SAX event to be generated.
97 * Two member variables are checked to make the decision, the
98 * m_pCurrentElement and the m_nCurrentPosition.
99 * The m_pCurrentElement represents the node which have been covered, and
100 * the m_nCurrentPosition represents the event which have been sent.
101 * For example, suppose that the m_pCurrentElement
102 * points to element A, and the m_nCurrentPosition equals to
103 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
104 * endElement for element A if A has no child, or startElement for the
105 * first child element of element A otherwise.
106 * The m_nCurrentPosition can be one of following values:
107 * NODEPOSITION_STARTELEMENT for startElement;
108 * NODEPOSITION_ENDELEMENT for endElement;
109 * NODEPOSITION_NORMAL for other SAX events;
119 * Email: michael.mi@sun.com
120 ******************************************************************************/
122 OSL_ASSERT( m_pCurrentElement
!= NULL
);
125 * Get the next event through tree order.
127 * if the current event is a startElement, then the next
128 * event depends on whether or not the current node has
131 if (m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)
134 * If the current node has children, then its first child
135 * should be next current node, and the next event will be
136 * startElement or charaters(PI) based on that child's node
137 * type. Otherwise, the endElement of current node is the
140 if (m_pCurrentElement
->children
!= NULL
)
142 m_pCurrentElement
= m_pCurrentElement
->children
;
144 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
145 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
149 m_nCurrentPosition
= NODEPOSITION_ENDELEMENT
;
153 * if the current event is a not startElement, then the next
154 * event depends on whether or not the current node has
157 else if (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
|| m_nCurrentPosition
== NODEPOSITION_NORMAL
)
159 xmlNodePtr pNextSibling
= m_pCurrentElement
->next
;
162 * If the current node has following sibling, that sibling
163 * should be next current node, and the next event will be
164 * startElement or charaters(PI) based on that sibling's node
165 * type. Otherwise, the endElement of current node's parent
166 * becomes the next event.
168 if (pNextSibling
!= NULL
)
170 m_pCurrentElement
= pNextSibling
;
172 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
173 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
177 m_pCurrentElement
= m_pCurrentElement
->parent
;
178 m_nCurrentPosition
= NODEPOSITION_ENDELEMENT
;
183 void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
184 const cssu::Reference
< cssxs::XDocumentHandler
>& xHandler
,
185 const cssu::Reference
< cssxs::XDocumentHandler
>& xHandler2
,
186 const xmlNodePtr pNode
)
187 throw (cssxs::SAXException
)
188 /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
191 * sendStartElement -- Constructs a startElement SAX event
194 * sendStartElement(xHandler, xHandler2, pNode);
197 * Used when converting the document into SAX event stream.
198 * This method constructs a startElement SAX event for a particular
199 * element, then calls the startElement methods of the XDocumentHandlers.
202 * xHandler - the first XDocumentHandler interface to receive the
203 * startElement SAX event. It can be NULL.
204 * xHandler2 - the second XDocumentHandler interface to receive the
205 * startElement SAX event. It can't be NULL.
206 * pNode - the node on which the startElement should be generated.
207 * This node must be a element type.
214 * Email: michael.mi@sun.com
215 ******************************************************************************/
217 SvXMLAttributeList
* pAttributeList
= new SvXMLAttributeList();
218 cssu::Reference
< cssxs::XAttributeList
> xAttrList
= cssu::Reference
< cssxs::XAttributeList
> (pAttributeList
);
220 xmlNsPtr pNsDef
= pNode
->nsDef
;
222 while (pNsDef
!= NULL
)
224 const xmlChar
* pNsPrefix
= pNsDef
->prefix
;
225 const xmlChar
* pNsHref
= pNsDef
->href
;
227 if (pNsDef
->prefix
== NULL
)
229 pAttributeList
->AddAttribute(
230 OUString(C2U( STRXMLNS
)),
231 OUString(C2U( reinterpret_cast<char const *>(pNsHref
) )));
235 pAttributeList
->AddAttribute(
236 OUString(C2U( STRXMLNS
))
237 +OUString(C2U( ":" ))
238 +OUString(C2U( reinterpret_cast<char const *>(pNsPrefix
) )),
239 OUString(C2U( reinterpret_cast<char const *>(pNsHref
) )));
242 pNsDef
= pNsDef
->next
;
245 xmlAttrPtr pAttr
= pNode
->properties
;
247 while (pAttr
!= NULL
)
249 const xmlChar
* pAttrName
= pAttr
->name
;
250 xmlNsPtr pAttrNs
= pAttr
->ns
;
255 ouAttrName
= OUString(C2U( reinterpret_cast<char const *>(pAttrName
) ));
259 ouAttrName
= OUString(C2U( reinterpret_cast<char const *>(pAttrNs
->prefix
)))
260 + ":" + OUString(C2U( reinterpret_cast<char const *>(pAttrName
) ));
263 pAttributeList
->AddAttribute(
265 OUString(C2U( reinterpret_cast<char*>(pAttr
->children
->content
))));
269 OString sNodeName
= getNodeQName(pNode
);
273 xHandler
->startElement(
274 OUString(C2U ( sNodeName
.getStr() )),
278 xHandler2
->startElement(
279 OUString(C2U ( sNodeName
.getStr() )),
283 void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
284 const cssu::Reference
< cssxs::XDocumentHandler
>& xHandler
,
285 const cssu::Reference
< cssxs::XDocumentHandler
>& xHandler2
,
286 const xmlNodePtr pNode
)
287 throw (cssxs::SAXException
)
288 /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
291 * sendEndElement -- Constructs a endElement SAX event
294 * sendEndElement(xHandler, xHandler2, pNode);
297 * Used when converting the document into SAX event stream.
298 * This method constructs a endElement SAX event for a particular
299 * element, then calls the endElement methods of the XDocumentHandlers.
302 * xHandler - the first XDocumentHandler interface to receive the
303 * endElement SAX event. It can be NULL.
304 * xHandler2 - the second XDocumentHandler interface to receive the
305 * endElement SAX event. It can't be NULL.
306 * pNode - the node on which the endElement should be generated.
307 * This node must be a element type.
314 * Email: michael.mi@sun.com
315 ******************************************************************************/
317 OString sNodeName
= getNodeQName(pNode
);
321 xHandler
->endElement(OUString(C2U ( sNodeName
.getStr() )));
324 xHandler2
->endElement(OUString(C2U ( sNodeName
.getStr() )));
327 void XMLDocumentWrapper_XmlSecImpl::sendNode(
328 const cssu::Reference
< cssxs::XDocumentHandler
>& xHandler
,
329 const cssu::Reference
< cssxs::XDocumentHandler
>& xHandler2
,
330 const xmlNodePtr pNode
)
331 throw (cssxs::SAXException
)
332 /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
335 * sendNode -- Constructs a characters SAX event or a
336 * processingInstruction SAX event
339 * sendNode(xHandler, xHandler2, pNode);
342 * Used when converting the document into SAX event stream.
343 * This method constructs a characters SAX event or a
344 * processingInstructionfor SAX event based on the type of a particular
345 * element, then calls the corresponding methods of the XDocumentHandlers.
348 * xHandler - the first XDocumentHandler interface to receive the
349 * SAX event. It can be NULL.
350 * xHandler2 - the second XDocumentHandler interface to receive the
351 * SAX event. It can't be NULL.
352 * pNode - the node on which the endElement should be generated.
353 * If it is a text node, then a characters SAX event is
354 * generated; if it is a PI node, then a
355 * processingInstructionfor SAX event is generated.
362 * Email: michael.mi@sun.com
363 ******************************************************************************/
365 xmlElementType type
= pNode
->type
;
367 if (type
== XML_TEXT_NODE
)
371 xHandler
->characters(OUString(C2U ( reinterpret_cast<char*>(pNode
->content
) )));
374 xHandler2
->characters(OUString(C2U ( reinterpret_cast<char*>(pNode
->content
) )));
376 else if (type
== XML_PI_NODE
)
380 xHandler
->processingInstruction(
381 OUString(C2U ( reinterpret_cast<char const *>(pNode
->name
) )),
382 OUString(C2U ( reinterpret_cast<char const *>(pNode
->content
) )));
385 xHandler2
->processingInstruction(
386 OUString(C2U ( reinterpret_cast<char const *>(pNode
->name
) )),
387 OUString(C2U ( reinterpret_cast<char*>(pNode
->content
) )));
391 OString
XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode
)
392 /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
395 * getNodeQName -- Retrieves the qualified name of a node
398 * name = getNodeQName(pNode);
404 * pNode - the node whose name will be retrieved
407 * name - the node's qualified name
411 * Email: michael.mi@sun.com
412 ******************************************************************************/
414 OString
sNodeName(reinterpret_cast<const char*>(pNode
->name
));
415 if (pNode
->ns
!= NULL
)
417 xmlNsPtr pNs
= pNode
->ns
;
419 if (pNs
->prefix
!= NULL
)
421 OString
sPrefix(reinterpret_cast<const char*>(pNs
->prefix
));
422 sNodeName
= sPrefix
+OString(":")+sNodeName
;
429 xmlNodePtr
XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
)
430 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
433 * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
437 * node = checkElement(xXMLElement);
443 * xXMLElement - the XXMLElementWrapper interface wraping a node
446 * node - the node wrapped in the XXMLElementWrapper interface
450 * Email: michael.mi@sun.com
451 ******************************************************************************/
453 xmlNodePtr rc
= NULL
;
455 if (xXMLElement
.is())
457 cssu::Reference
< cssl::XUnoTunnel
> xNodTunnel( xXMLElement
, cssu::UNO_QUERY
) ;
458 if( !xNodTunnel
.is() )
460 throw cssu::RuntimeException() ;
463 XMLElementWrapper_XmlSecImpl
* pElement
464 = reinterpret_cast<XMLElementWrapper_XmlSecImpl
*>(
465 sal::static_int_cast
<sal_uIntPtr
>(
466 xNodTunnel
->getSomething(
467 XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ;
469 if( pElement
== NULL
) {
470 throw cssu::RuntimeException() ;
473 rc
= pElement
->getNativeElement();
479 sal_Int32
XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
480 const xmlNodePtr pNode
)
481 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
484 * recursiveDelete -- Deletes a particular node with its branch.
487 * result = recursiveDelete(pNode);
490 * Deletes a particular node with its branch, while reserving the nodes
491 * (and their brance) listed in the m_aReservedNodes.
492 * The deletion process is preformed in the tree order, that is, a node
493 * is deleted after its previous sibling node is deleted, a parent node
494 * is deleted after its branch is deleted.
495 * During the deletion process when the m_pStopAtNode is reached, the
496 * progress is interrupted at once.
499 * pNode - the node to be deleted
502 * result - the result of the deletion process, can be one of following
504 * NODE_STOPED - the process is interrupted by meeting the
506 * NODE_NOTREMOVED - the pNode is not completely removed
507 * because there is its descendant in the
508 * m_aReservedNodes list
509 * NODE_REMOVED - the pNode and its branch are completely
513 * The node in the m_aReservedNodes list must be in the tree order, otherwise
514 * the result is unpredictable.
518 * Email: michael.mi@sun.com
519 ******************************************************************************/
521 if (pNode
== m_pStopAtNode
)
526 if (pNode
!= m_pCurrentReservedNode
)
528 xmlNodePtr pChild
= pNode
->children
;
530 xmlNodePtr pNextSibling
;
531 bool bIsRemoved
= true;
534 while( pChild
!= NULL
)
536 pNextSibling
= pChild
->next
;
537 nResult
= recursiveDelete(pChild
);
543 case NODE_NOTREMOVED
:
550 throw cssu::RuntimeException();
553 pChild
= pNextSibling
;
556 if (pNode
== m_pCurrentElement
)
561 return bIsRemoved
?NODE_REMOVED
:NODE_NOTREMOVED
;
565 getNextReservedNode();
566 return NODE_NOTREMOVED
;
570 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
571 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
574 * getNextReservedNode -- Highlights the next reserved node in the
578 * getNextReservedNode();
581 * The m_aReservedNodes array holds a node list, while the
582 * m_pCurrentReservedNode points to the one currently highlighted.
583 * This method is used to highlight the next node in the node list.
584 * This method is called at the time when the current highlighted node
585 * has been already processed, and the next node should be ready.
595 * Email: michael.mi@sun.com
596 ******************************************************************************/
598 if (m_nReservedNodeIndex
< m_aReservedNodes
.getLength())
600 m_pCurrentReservedNode
= checkElement( m_aReservedNodes
[m_nReservedNodeIndex
] );
601 m_nReservedNodeIndex
++;
605 m_pCurrentReservedNode
= NULL
;
609 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode
) const
610 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
613 * removeNode -- Deletes a node with its branch unconditionaly
616 * removeNode( pNode );
619 * Delete the node along with its branch from the document.
622 * pNode - the node to be deleted
629 * Email: michael.mi@sun.com
630 ******************************************************************************/
632 /* you can't remove the current node */
633 OSL_ASSERT( m_pCurrentElement
!= pNode
);
635 xmlAttrPtr pAttr
= pNode
->properties
;
637 while (pAttr
!= NULL
)
639 if (!stricmp(reinterpret_cast<char const *>(pAttr
->name
), "id"))
641 xmlRemoveID(m_pDocument
, pAttr
);
647 xmlUnlinkNode(pNode
);
651 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode
) const
652 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
655 * buildIDAttr -- build the ID attribute of a node
658 * buildIDAttr( pNode );
664 * pNode - the node whose id attribute will be built
671 * Email: michael.mi@sun.com
672 ******************************************************************************/
674 xmlAttrPtr idAttr
= xmlHasProp( pNode
, reinterpret_cast<const unsigned char *>("id") );
677 idAttr
= xmlHasProp( pNode
, reinterpret_cast<const unsigned char *>("Id") );
682 xmlChar
* idValue
= xmlNodeListGetString( m_pDocument
, idAttr
->children
, 1 ) ;
683 xmlAddID( NULL
, m_pDocument
, idValue
, idAttr
);
687 void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode
) const
688 /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
691 * rebuildIDLink -- rebuild the ID link for the branch
694 * rebuildIDLink( pNode );
700 * pNode - the node, from which the branch will be rebuilt
707 * Email: michael.mi@sun.com
708 ******************************************************************************/
710 if (pNode
!= NULL
&& pNode
->type
== XML_ELEMENT_NODE
)
712 buildIDAttr( pNode
);
714 xmlNodePtr child
= pNode
->children
;
715 while (child
!= NULL
)
717 rebuildIDLink(child
);
723 /* XXMLDocumentWrapper */
724 cssu::Reference
< cssxw::XXMLElementWrapper
> SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
725 throw (cssu::RuntimeException
, std::exception
)
727 XMLElementWrapper_XmlSecImpl
* pElement
= new XMLElementWrapper_XmlSecImpl(m_pCurrentElement
);
728 return cssu::Reference
< cssxw::XXMLElementWrapper
>(pElement
);
731 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& element
)
732 throw (cssu::RuntimeException
, std::exception
)
734 m_pCurrentElement
= checkElement( element
);
735 saxHelper
.setCurrentNode( m_pCurrentElement
);
738 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
739 throw (cssu::RuntimeException
, std::exception
)
741 OSL_ASSERT( m_pCurrentElement
!= NULL
);
743 xmlNodePtr pOldCurrentElement
= m_pCurrentElement
;
746 * pop the top node in the parser context's
747 * nodeTab stack, then the parent of that node will
748 * automatically become the new stack top, and
749 * the current node as well.
751 saxHelper
.endElement(
754 reinterpret_cast<char const *>(pOldCurrentElement
->name
)
756 m_pCurrentElement
= saxHelper
.getCurrentNode();
761 removeNode(pOldCurrentElement
);
764 sal_Bool SAL_CALL
XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference
< cssxw::XXMLElementWrapper
>& node
)
765 throw (cssu::RuntimeException
, std::exception
)
767 xmlNodePtr pNode
= checkElement(node
);
768 return (pNode
== m_pCurrentElement
);
771 sal_Bool SAL_CALL
XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
772 throw (cssu::RuntimeException
, std::exception
)
776 if (m_pCurrentElement
->children
== NULL
)
784 OUString SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference
< cssxw::XXMLElementWrapper
>& node
)
785 throw (cssu::RuntimeException
, std::exception
)
787 xmlNodePtr pNode
= checkElement(node
);
788 return OUString(C2U ( reinterpret_cast<char const *>(pNode
->name
) ));
791 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::clearUselessData(
792 const cssu::Reference
< cssxw::XXMLElementWrapper
>& node
,
793 const cssu::Sequence
< cssu::Reference
< cssxw::XXMLElementWrapper
> >& reservedDescendants
,
794 const cssu::Reference
< cssxw::XXMLElementWrapper
>& stopAtNode
)
795 throw (cssu::RuntimeException
, std::exception
)
797 xmlNodePtr pTargetNode
= checkElement(node
);
799 m_pStopAtNode
= checkElement(stopAtNode
);
800 m_aReservedNodes
= reservedDescendants
;
801 m_nReservedNodeIndex
= 0;
803 getNextReservedNode();
805 recursiveDelete(pTargetNode
);
808 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference
< cssxw::XXMLElementWrapper
>& node
)
809 throw (cssu::RuntimeException
, std::exception
)
811 xmlNodePtr pTargetNode
= checkElement(node
);
814 while (pTargetNode
!= NULL
)
816 if (pTargetNode
->children
!= NULL
|| pTargetNode
== m_pCurrentElement
)
821 pParent
= pTargetNode
->parent
;
822 removeNode(pTargetNode
);
823 pTargetNode
= pParent
;
827 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference
< cssxs::XDocumentHandler
>& handler
)
828 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
830 if (m_pRootElement
!= NULL
)
832 xmlNodePtr pTempCurrentElement
= m_pCurrentElement
;
833 sal_Int32 nTempCurrentPosition
= m_nCurrentPosition
;
835 m_pCurrentElement
= m_pRootElement
;
837 m_nCurrentPosition
= NODEPOSITION_STARTELEMENT
;
838 cssu::Reference
< cssxs::XDocumentHandler
> xHandler
= handler
;
842 switch (m_nCurrentPosition
)
844 case NODEPOSITION_STARTELEMENT
:
845 sendStartElement(NULL
, xHandler
, m_pCurrentElement
);
847 case NODEPOSITION_ENDELEMENT
:
848 sendEndElement(NULL
, xHandler
, m_pCurrentElement
);
850 case NODEPOSITION_NORMAL
:
851 sendNode(NULL
, xHandler
, m_pCurrentElement
);
855 if ( (m_pCurrentElement
== m_pRootElement
) && (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
))
863 m_pCurrentElement
= pTempCurrentElement
;
864 m_nCurrentPosition
= nTempCurrentPosition
;
868 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
869 const cssu::Reference
< cssxs::XDocumentHandler
>& handler
,
870 const cssu::Reference
< cssxs::XDocumentHandler
>& xEventKeeperHandler
,
871 const cssu::Reference
< cssxw::XXMLElementWrapper
>& startNode
,
872 const cssu::Reference
< cssxw::XXMLElementWrapper
>& endNode
)
873 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
876 * The first SAX event is the startElement of the startNode
879 bool bHasCurrentElementChild
= (m_pCurrentElement
->children
!= NULL
);
881 xmlNodePtr pTempCurrentElement
= m_pCurrentElement
;
883 m_pCurrentElement
= checkElement(startNode
);
885 if (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)
887 m_nCurrentPosition
= NODEPOSITION_STARTELEMENT
;
891 m_nCurrentPosition
= NODEPOSITION_NORMAL
;
894 xmlNodePtr pEndNode
= checkElement(endNode
);
896 cssu::Reference
< cssxc::sax::XSAXEventKeeper
> xSAXEventKeeper( xEventKeeperHandler
, cssu::UNO_QUERY
);
898 cssu::Reference
< cssxs::XDocumentHandler
> xHandler
= handler
;
902 switch (m_nCurrentPosition
)
904 case NODEPOSITION_STARTELEMENT
:
905 sendStartElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
907 case NODEPOSITION_ENDELEMENT
:
908 sendEndElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
910 case NODEPOSITION_NORMAL
:
911 sendNode(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
914 throw cssu::RuntimeException();
917 if (xSAXEventKeeper
->isBlocking())
922 if (pEndNode
== NULL
&&
923 ((bHasCurrentElementChild
&& m_pCurrentElement
== xmlGetLastChild(pTempCurrentElement
) && m_nCurrentPosition
!= NODEPOSITION_STARTELEMENT
) ||
924 (!bHasCurrentElementChild
&& m_pCurrentElement
== pTempCurrentElement
&& m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)))
932 * If there is an end point specified, then check whether
933 * the current node equals to the end point. If so, stop
936 if (pEndNode
!= NULL
&& m_pCurrentElement
== pEndNode
)
942 m_pCurrentElement
= pTempCurrentElement
;
945 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
946 const com::sun::star::uno::Reference
< com::sun::star::xml::wrapper::XXMLElementWrapper
>& node
)
947 throw (com::sun::star::uno::RuntimeException
, std::exception
)
949 xmlNodePtr pNode
= checkElement( node
);
950 rebuildIDLink(pNode
);
954 /* cssxs::XDocumentHandler */
955 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::startDocument( )
956 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
960 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::endDocument( )
961 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
965 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::startElement( const OUString
& aName
, const cssu::Reference
< cssxs::XAttributeList
>& xAttribs
)
966 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
968 sal_Int32 nLength
= xAttribs
->getLength();
969 cssu::Sequence
< cssxcsax::XMLAttribute
> aAttributes (nLength
);
971 for (int i
= 0; i
< nLength
; ++i
)
973 aAttributes
[i
].sName
= xAttribs
->getNameByIndex((short)i
);
974 aAttributes
[i
].sValue
=xAttribs
->getValueByIndex((short)i
);
977 compressedStartElement(aName
, aAttributes
);
980 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::endElement( const OUString
& aName
)
981 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
983 saxHelper
.endElement(aName
);
984 m_pCurrentElement
= saxHelper
.getCurrentNode();
987 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::characters( const OUString
& aChars
)
988 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
990 saxHelper
.characters(aChars
);
993 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString
& aWhitespaces
)
994 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
996 saxHelper
.ignorableWhitespace(aWhitespaces
);
999 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString
& aTarget
, const OUString
& aData
)
1000 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1002 saxHelper
.processingInstruction(aTarget
, aData
);
1005 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference
< cssxs::XLocator
>& )
1006 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1010 /* XCompressedDocumentHandler */
1011 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedStartDocument( )
1012 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1016 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedEndDocument( )
1017 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1021 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedStartElement( const OUString
& aName
, const cssu::Sequence
< cssxcsax::XMLAttribute
>& aAttributes
)
1022 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1024 saxHelper
.startElement(aName
, aAttributes
);
1025 m_pCurrentElement
= saxHelper
.getCurrentNode();
1027 buildIDAttr( m_pCurrentElement
);
1030 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedEndElement( const OUString
& aName
)
1031 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1033 endElement( aName
);
1036 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedCharacters( const OUString
& aChars
)
1037 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1039 characters( aChars
);
1042 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedIgnorableWhitespace( const OUString
& aWhitespaces
)
1043 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1045 ignorableWhitespace( aWhitespaces
);
1048 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedProcessingInstruction( const OUString
& aTarget
, const OUString
& aData
)
1049 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1051 processingInstruction( aTarget
, aData
);
1054 void SAL_CALL
XMLDocumentWrapper_XmlSecImpl::compressedSetDocumentLocator( sal_Int32
/*columnNumber*/, sal_Int32
/*lineNumber*/, const OUString
& /*publicId*/, const OUString
& /*systemId*/ )
1055 throw (cssxs::SAXException
, cssu::RuntimeException
, std::exception
)
1059 OUString
XMLDocumentWrapper_XmlSecImpl_getImplementationName ()
1060 throw (cssu::RuntimeException
)
1062 return OUString ( IMPLEMENTATION_NAME
);
1065 cssu::Sequence
< OUString
> SAL_CALL
XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( )
1066 throw (cssu::RuntimeException
)
1068 cssu::Sequence
< OUString
> aRet(1);
1069 OUString
* pArray
= aRet
.getArray();
1070 pArray
[0] = "com.sun.star.xml.wrapper.XMLDocumentWrapper";
1074 cssu::Reference
< cssu::XInterface
> SAL_CALL
XMLDocumentWrapper_XmlSecImpl_createInstance(
1075 const cssu::Reference
< cssu::XComponentContext
> &)
1076 throw( cssu::Exception
)
1078 return (cppu::OWeakObject
*) new XMLDocumentWrapper_XmlSecImpl( );
1082 OUString SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
1083 throw (cssu::RuntimeException
, std::exception
)
1085 return XMLDocumentWrapper_XmlSecImpl_getImplementationName();
1087 sal_Bool SAL_CALL
XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString
& rServiceName
)
1088 throw (cssu::RuntimeException
, std::exception
)
1090 return cppu::supportsService( this, rServiceName
);
1092 cssu::Sequence
< OUString
> SAL_CALL
XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
1093 throw (cssu::RuntimeException
, std::exception
)
1095 return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames();
1098 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */