tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / xmlsecurity / source / xmlsec / xmldocumentwrapper_xmlsecimpl.cxx
blob87c84471549c583a8959ae593be8a99f9a682279
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/xml/crypto/sax/XSAXEventKeeper.hpp>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <xmlsec/xmldocumentwrapper_xmlsecimpl.hxx>
27 #include "xmlelementwrapper_xmlsecimpl.hxx"
28 #include <comphelper/attributelist.hxx>
29 #include <rtl/ref.hxx>
31 #ifdef UNX
32 #define stricmp strcasecmp
33 #endif
35 using namespace com::sun::star;
37 #define STRXMLNS "xmlns"
39 /* used by the recursiveDelete method */
40 #define NODE_REMOVED 0
41 #define NODE_NOTREMOVED 1
42 #define NODE_STOPPED 2
44 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl()
45 : m_nCurrentPosition(0)
46 , m_pStopAtNode(nullptr)
47 , m_pCurrentReservedNode(nullptr)
48 , m_nReservedNodeIndex(0)
50 saxHelper.startDocument();
51 m_pDocument = saxHelper.getDocument();
54 * creates the virtual root element
56 saxHelper.startElement(u"root", uno::Sequence<css::xml::csax::XMLAttribute>());
58 m_pRootElement = saxHelper.getCurrentNode();
59 m_pCurrentElement = m_pRootElement;
62 XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
64 saxHelper.endDocument();
65 xmlFreeDoc(m_pDocument);
68 void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
69 /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
71 * NAME
72 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
74 * FUNCTION
75 * When converting the document into SAX events, this method is used to
76 * decide the next SAX event to be generated.
77 * Two member variables are checked to make the decision, the
78 * m_pCurrentElement and the m_nCurrentPosition.
79 * The m_pCurrentElement represents the node which have been covered, and
80 * the m_nCurrentPosition represents the event which have been sent.
81 * For example, suppose that the m_pCurrentElement
82 * points to element A, and the m_nCurrentPosition equals to
83 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
84 * endElement for element A if A has no child, or startElement for the
85 * first child element of element A otherwise.
86 * The m_nCurrentPosition can be one of following values:
87 * NODEPOSITION_STARTELEMENT for startElement;
88 * NODEPOSITION_ENDELEMENT for endElement;
89 * NODEPOSITION_NORMAL for other SAX events;
90 ******************************************************************************/
92 assert(m_pCurrentElement != nullptr);
95 * Get the next event through tree order.
97 * if the current event is a startElement, then the next
98 * event depends on whether or not the current node has
99 * children.
101 if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT)
104 * If the current node has children, then its first child
105 * should be next current node, and the next event will be
106 * startElement or characters(PI) based on that child's node
107 * type. Otherwise, the endElement of current node is the
108 * next event.
110 if (m_pCurrentElement->children != nullptr)
112 m_pCurrentElement = m_pCurrentElement->children;
113 m_nCurrentPosition
114 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
115 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
117 else
119 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
123 * if the current event is a not startElement, then the next
124 * event depends on whether or not the current node has
125 * following sibling.
127 else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL)
129 xmlNodePtr pNextSibling = m_pCurrentElement->next;
132 * If the current node has following sibling, that sibling
133 * should be next current node, and the next event will be
134 * startElement or characters(PI) based on that sibling's node
135 * type. Otherwise, the endElement of current node's parent
136 * becomes the next event.
138 if (pNextSibling != nullptr)
140 m_pCurrentElement = pNextSibling;
141 m_nCurrentPosition
142 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
143 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
145 else
147 m_pCurrentElement = m_pCurrentElement->parent;
148 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
153 void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
154 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler,
155 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2,
156 const xmlNodePtr pNode)
157 /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
159 * NAME
160 * sendStartElement -- Constructs a startElement SAX event
162 * FUNCTION
163 * Used when converting the document into SAX event stream.
164 * This method constructs a startElement SAX event for a particular
165 * element, then calls the startElement methods of the XDocumentHandlers.
167 * INPUTS
168 * xHandler - the first XDocumentHandler interface to receive the
169 * startElement SAX event. It can be NULL.
170 * xHandler2 - the second XDocumentHandler interface to receive the
171 * startElement SAX event. It can't be NULL.
172 * pNode - the node on which the startElement should be generated.
173 * This node must be an element type.
174 ******************************************************************************/
176 rtl::Reference<comphelper::AttributeList> pAttributeList = new comphelper::AttributeList();
178 xmlNsPtr pNsDef = pNode->nsDef;
180 while (pNsDef != nullptr)
182 const xmlChar* pNsPrefix = pNsDef->prefix;
183 const xmlChar* pNsHref = pNsDef->href;
185 if (pNsDef->prefix == nullptr)
187 pAttributeList->AddAttribute(
188 u"" STRXMLNS ""_ustr,
189 OUString::fromUtf8(reinterpret_cast<char const *>(pNsHref)));
191 else
193 pAttributeList->AddAttribute(
194 STRXMLNS ":"
195 +OUString::fromUtf8(reinterpret_cast<char const *>(pNsPrefix)),
196 OUString::fromUtf8(reinterpret_cast<char const *>(pNsHref)));
199 pNsDef = pNsDef->next;
202 xmlAttrPtr pAttr = pNode->properties;
204 while (pAttr != nullptr)
206 const xmlChar* pAttrName = pAttr->name;
207 xmlNsPtr pAttrNs = pAttr->ns;
209 OUString ouAttrName;
210 if (pAttrNs == nullptr)
212 ouAttrName = OUString::fromUtf8(reinterpret_cast<char const *>(pAttrName));
214 else
216 ouAttrName = OUString::fromUtf8(reinterpret_cast<char const *>(pAttrNs->prefix))
217 + ":" + OUString::fromUtf8(reinterpret_cast<char const *>(pAttrName));
220 pAttributeList->AddAttribute(
221 ouAttrName,
222 OUString::fromUtf8(reinterpret_cast<char*>(pAttr->children->content)));
223 pAttr = pAttr->next;
226 OString sNodeName = getNodeQName(pNode);
228 if (xHandler.is())
230 xHandler->startElement(
231 OUString::fromUtf8(sNodeName),
232 pAttributeList);
235 xHandler2->startElement(
236 OUString::fromUtf8(sNodeName),
237 pAttributeList);
240 void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
241 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler,
242 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2,
243 const xmlNodePtr pNode)
244 /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
246 * NAME
247 * sendEndElement -- Constructs an endElement SAX event
249 * FUNCTION
250 * Used when converting the document into SAX event stream.
251 * This method constructs an endElement SAX event for a particular
252 * element, then calls the endElement methods of the XDocumentHandlers.
254 * INPUTS
255 * xHandler - the first XDocumentHandler interface to receive the
256 * endElement SAX event. It can be NULL.
257 * xHandler2 - the second XDocumentHandler interface to receive the
258 * endElement SAX event. It can't be NULL.
259 * pNode - the node on which the endElement should be generated.
260 * This node must be an element type.
261 ******************************************************************************/
263 OString sNodeName = getNodeQName(pNode);
265 if (xHandler.is())
267 xHandler->endElement(OUString::fromUtf8(sNodeName));
270 xHandler2->endElement(OUString::fromUtf8(sNodeName));
273 void XMLDocumentWrapper_XmlSecImpl::sendNode(
274 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler,
275 const uno::Reference< css::xml::sax::XDocumentHandler >& xHandler2,
276 const xmlNodePtr pNode)
277 /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
279 * NAME
280 * sendNode -- Constructs a characters SAX event or a
281 * processingInstruction SAX event
283 * FUNCTION
284 * Used when converting the document into SAX event stream.
285 * This method constructs a characters SAX event or a
286 * processingInstructionfor SAX event based on the type of a particular
287 * element, then calls the corresponding methods of the XDocumentHandlers.
289 * INPUTS
290 * xHandler - the first XDocumentHandler interface to receive the
291 * SAX event. It can be NULL.
292 * xHandler2 - the second XDocumentHandler interface to receive the
293 * SAX event. It can't be NULL.
294 * pNode - the node on which the endElement should be generated.
295 * If it is a text node, then a characters SAX event is
296 * generated; if it is a PI node, then a
297 * processingInstructionfor SAX event is generated.
298 ******************************************************************************/
300 xmlElementType type = pNode->type;
302 if (type == XML_TEXT_NODE)
304 if (xHandler.is())
306 xHandler->characters(OUString::fromUtf8(reinterpret_cast<char*>(pNode->content)));
309 xHandler2->characters(OUString::fromUtf8(reinterpret_cast<char*>(pNode->content)));
311 else if (type == XML_PI_NODE)
313 if (xHandler.is())
315 xHandler->processingInstruction(
316 OUString::fromUtf8(reinterpret_cast<char const *>(pNode->name)),
317 OUString::fromUtf8(reinterpret_cast<char const *>(pNode->content)));
320 xHandler2->processingInstruction(
321 OUString::fromUtf8(reinterpret_cast<char const *>(pNode->name)),
322 OUString::fromUtf8(reinterpret_cast<char*>(pNode->content)));
326 OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode)
327 /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
329 * NAME
330 * getNodeQName -- Retrieves the qualified name of a node
332 * INPUTS
333 * pNode - the node whose name will be retrieved
335 * RESULT
336 * name - the node's qualified name
337 ******************************************************************************/
339 OString sNodeName(reinterpret_cast<const char*>(pNode->name));
340 if (pNode->ns != nullptr)
342 xmlNsPtr pNs = pNode->ns;
344 if (pNs->prefix != nullptr)
346 OString sPrefix(reinterpret_cast<const char*>(pNs->prefix));
347 sNodeName = sPrefix + ":" + sNodeName;
351 return sNodeName;
354 xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& xXMLElement)
355 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
357 * NAME
358 * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
359 * interface
361 * INPUTS
362 * xXMLElement - the XXMLElementWrapper interface wrapping a node
364 * RESULT
365 * node - the node wrapped in the XXMLElementWrapper interface
366 ******************************************************************************/
368 xmlNodePtr rc = nullptr;
370 if (xXMLElement.is())
372 XMLElementWrapper_XmlSecImpl* pElement
373 = dynamic_cast<XMLElementWrapper_XmlSecImpl*>(xXMLElement.get());
375 if( pElement == nullptr ) {
376 throw uno::RuntimeException() ;
379 rc = pElement->getNativeElement();
382 return rc;
385 sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
386 const xmlNodePtr pNode)
387 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
389 * NAME
390 * recursiveDelete -- Deletes a particular node with its branch.
392 * FUNCTION
393 * Deletes a particular node with its branch, while reserving the nodes
394 * (and their branches) listed in the m_aReservedNodes.
395 * The deletion process is performed in the tree order, that is, a node
396 * is deleted after its previous sibling node is deleted, a parent node
397 * is deleted after its branch is deleted.
398 * During the deletion process when the m_pStopAtNode is reached, the
399 * progress is interrupted at once.
401 * INPUTS
402 * pNode - the node to be deleted
404 * RESULT
405 * result - the result of the deletion process, can be one of following
406 * values:
407 * NODE_STOPPED - the process is interrupted by meeting the
408 * m_pStopAtNode
409 * NODE_NOTREMOVED - the pNode is not completely removed
410 * because there is its descendant in the
411 * m_aReservedNodes list
412 * NODE_REMOVED - the pNode and its branch are completely
413 * removed
415 * NOTES
416 * The node in the m_aReservedNodes list must be in the tree order, otherwise
417 * the result is unpredictable.
418 ******************************************************************************/
420 if (pNode == m_pStopAtNode)
422 return NODE_STOPPED;
425 if (pNode != m_pCurrentReservedNode)
427 xmlNodePtr pChild = pNode->children;
429 xmlNodePtr pNextSibling;
430 bool bIsRemoved = true;
431 sal_Int32 nResult;
433 while( pChild != nullptr )
435 pNextSibling = pChild->next;
436 nResult = recursiveDelete(pChild);
438 switch (nResult)
440 case NODE_STOPPED:
441 return NODE_STOPPED;
442 case NODE_NOTREMOVED:
443 bIsRemoved = false;
444 break;
445 case NODE_REMOVED:
446 removeNode(pChild);
447 break;
448 default:
449 throw uno::RuntimeException();
452 pChild = pNextSibling;
455 if (pNode == m_pCurrentElement)
457 bIsRemoved = false;
460 return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
462 else
464 getNextReservedNode();
465 return NODE_NOTREMOVED;
469 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
470 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
472 * NAME
473 * getNextReservedNode -- Highlights the next reserved node in the
474 * reserved node list
476 * FUNCTION
477 * The m_aReservedNodes array holds a node list, while the
478 * m_pCurrentReservedNode points to the one currently highlighted.
479 * This method is used to highlight the next node in the node list.
480 * This method is called at the time when the current highlighted node
481 * has been already processed, and the next node should be ready.
482 ******************************************************************************/
484 if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
486 m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] );
487 m_nReservedNodeIndex ++;
489 else
491 m_pCurrentReservedNode = nullptr;
495 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
496 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
498 * NAME
499 * removeNode -- Deletes a node with its branch unconditionally
501 * FUNCTION
502 * Delete the node along with its branch from the document.
504 * INPUTS
505 * pNode - the node to be deleted
506 ******************************************************************************/
508 /* you can't remove the current node */
509 OSL_ASSERT( m_pCurrentElement != pNode );
511 xmlAttrPtr pAttr = pNode->properties;
513 while (pAttr != nullptr)
515 if (!stricmp(reinterpret_cast<char const *>(pAttr->name), "id"))
517 xmlRemoveID(m_pDocument, pAttr);
520 pAttr = pAttr->next;
523 xmlUnlinkNode(pNode);
524 xmlFreeNode(pNode);
527 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
528 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
530 * NAME
531 * buildIDAttr -- build the ID attribute of a node
533 * INPUTS
534 * pNode - the node whose id attribute will be built
535 ******************************************************************************/
537 xmlAttrPtr idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("id") );
538 if (idAttr == nullptr)
540 idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("Id") );
543 if (idAttr != nullptr)
545 xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
546 xmlAddID( nullptr, m_pDocument, idValue, idAttr );
550 void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const
551 /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
553 * NAME
554 * rebuildIDLink -- rebuild the ID link for the branch
556 * INPUTS
557 * pNode - the node, from which the branch will be rebuilt
558 ******************************************************************************/
560 if (pNode != nullptr && pNode->type == XML_ELEMENT_NODE)
562 buildIDAttr( pNode );
564 xmlNodePtr child = pNode->children;
565 while (child != nullptr)
567 rebuildIDLink(child);
568 child = child->next;
573 /* XXMLDocumentWrapper */
574 uno::Reference< css::xml::wrapper::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
576 return new XMLElementWrapper_XmlSecImpl(m_pCurrentElement);
579 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& element )
581 m_pCurrentElement = checkElement( element );
582 saxHelper.setCurrentNode( m_pCurrentElement );
585 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
587 OSL_ASSERT( m_pCurrentElement != nullptr );
589 xmlNodePtr pOldCurrentElement = m_pCurrentElement;
592 * pop the top node in the parser context's
593 * nodeTab stack, then the parent of that node will
594 * automatically become the new stack top, and
595 * the current node as well.
597 saxHelper.endElement(OUString::fromUtf8(reinterpret_cast<char const *>(pOldCurrentElement->name)));
598 m_pCurrentElement = saxHelper.getCurrentNode();
601 * remove the node
603 removeNode(pOldCurrentElement);
606 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
608 xmlNodePtr pNode = checkElement(node);
609 return (pNode == m_pCurrentElement);
612 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
614 bool rc = false;
616 if (m_pCurrentElement->children == nullptr)
618 rc = true;
621 return rc;
624 OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
626 xmlNodePtr pNode = checkElement(node);
627 return OUString::fromUtf8(reinterpret_cast<char const *>(pNode->name));
630 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData(
631 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node,
632 const uno::Sequence< uno::Reference< css::xml::wrapper::XXMLElementWrapper > >& reservedDescendants,
633 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& stopAtNode )
635 xmlNodePtr pTargetNode = checkElement(node);
637 m_pStopAtNode = checkElement(stopAtNode);
638 m_aReservedNodes = reservedDescendants;
639 m_nReservedNodeIndex = 0;
641 getNextReservedNode();
643 recursiveDelete(pTargetNode);
646 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
648 xmlNodePtr pTargetNode = checkElement(node);
649 xmlNodePtr pParent;
651 while (pTargetNode != nullptr)
653 if (pTargetNode->children != nullptr || pTargetNode == m_pCurrentElement)
655 break;
658 pParent = pTargetNode->parent;
659 removeNode(pTargetNode);
660 pTargetNode = pParent;
664 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const uno::Reference< css::xml::sax::XDocumentHandler >& handler )
666 if (m_pRootElement == nullptr)
667 return;
669 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
670 sal_Int32 nTempCurrentPosition = m_nCurrentPosition;
672 m_pCurrentElement = m_pRootElement;
674 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
676 while(true)
678 switch (m_nCurrentPosition)
680 case NODEPOSITION_STARTELEMENT:
681 sendStartElement(nullptr, handler, m_pCurrentElement);
682 break;
683 case NODEPOSITION_ENDELEMENT:
684 sendEndElement(nullptr, handler, m_pCurrentElement);
685 break;
686 case NODEPOSITION_NORMAL:
687 sendNode(nullptr, handler, m_pCurrentElement);
688 break;
691 if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
693 break;
696 getNextSAXEvent();
699 m_pCurrentElement = pTempCurrentElement;
700 m_nCurrentPosition = nTempCurrentPosition;
703 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
704 const uno::Reference< css::xml::sax::XDocumentHandler >& handler,
705 const uno::Reference< css::xml::sax::XDocumentHandler >& xEventKeeperHandler,
706 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& startNode,
707 const uno::Reference< css::xml::wrapper::XXMLElementWrapper >& endNode )
710 * The first SAX event is the startElement of the startNode
711 * element.
713 bool bHasCurrentElementChild = (m_pCurrentElement->children != nullptr);
715 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
717 m_pCurrentElement = checkElement(startNode);
719 if (m_pCurrentElement->type == XML_ELEMENT_NODE)
721 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
723 else
725 m_nCurrentPosition = NODEPOSITION_NORMAL;
728 xmlNodePtr pEndNode = checkElement(endNode);
730 uno::Reference < css::xml::crypto::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, uno::UNO_QUERY );
732 uno::Reference< css::xml::sax::XDocumentHandler > xHandler = handler;
734 while(true)
736 switch (m_nCurrentPosition)
738 case NODEPOSITION_STARTELEMENT:
739 sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
740 break;
741 case NODEPOSITION_ENDELEMENT:
742 sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
743 break;
744 case NODEPOSITION_NORMAL:
745 sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
746 break;
747 default:
748 throw uno::RuntimeException();
751 if (xSAXEventKeeper->isBlocking())
753 xHandler = nullptr;
756 if (pEndNode == nullptr &&
757 ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
758 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
760 break;
763 getNextSAXEvent();
766 * If there is an end point specified, then check whether
767 * the current node equals to the end point. If so, stop
768 * generating.
770 if (pEndNode != nullptr && m_pCurrentElement == pEndNode)
772 break;
776 m_pCurrentElement = pTempCurrentElement;
779 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
780 const css::uno::Reference< css::xml::wrapper::XXMLElementWrapper >& node )
782 xmlNodePtr pNode = checkElement( node );
783 rebuildIDLink(pNode);
787 /* css::xml::sax::XDocumentHandler */
788 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( )
792 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( )
796 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const OUString& aName, const uno::Reference< css::xml::sax::XAttributeList >& xAttribs )
798 sal_Int32 nLength = xAttribs->getLength();
799 uno::Sequence< css::xml::csax::XMLAttribute > aAttributes (nLength);
800 auto aAttributesRange = asNonConstRange(aAttributes);
802 for (int i = 0; i < nLength; ++i)
804 aAttributesRange[i].sName = xAttribs->getNameByIndex(static_cast<short>(i));
805 aAttributesRange[i].sValue =xAttribs->getValueByIndex(static_cast<short>(i));
808 compressedStartElement(aName, aAttributes);
811 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const OUString& aName )
813 saxHelper.endElement(aName);
814 m_pCurrentElement = saxHelper.getCurrentNode();
817 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const OUString& aChars )
819 saxHelper.characters(aChars);
822 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString& aWhitespaces )
824 saxHelper.ignorableWhitespace(aWhitespaces);
827 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString& aTarget, const OUString& aData )
829 saxHelper.processingInstruction(aTarget, aData);
832 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const uno::Reference< css::xml::sax::XLocator >& )
836 /* XCompressedDocumentHandler */
837 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartDocument( )
841 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndDocument( )
845 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartElement( const OUString& aName, const uno::Sequence< css::xml::csax::XMLAttribute >& aAttributes )
847 saxHelper.startElement(aName, aAttributes);
848 m_pCurrentElement = saxHelper.getCurrentNode();
850 buildIDAttr( m_pCurrentElement );
853 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndElement( const OUString& aName )
855 endElement( aName );
858 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedCharacters( const OUString& aChars )
860 characters( aChars );
863 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedIgnorableWhitespace( const OUString& aWhitespaces )
865 ignorableWhitespace( aWhitespaces );
868 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedProcessingInstruction( const OUString& aTarget, const OUString& aData )
870 processingInstruction( aTarget, aData );
873 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedSetDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const OUString& /*publicId*/, const OUString& /*systemId*/ )
877 /* XServiceInfo */
878 OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
880 return u"com.sun.star.xml.wrapper.XMLDocumentWrapper"_ustr;
883 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString& rServiceName )
885 return cppu::supportsService( this, rServiceName );
888 uno::Sequence< OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
890 return { u"com.sun.star.xml.wrapper.XMLDocumentWrapper"_ustr };
893 extern "C" SAL_DLLPUBLIC_EXPORT uno::XInterface*
894 com_sun_star_xml_wrapper_XMLDocumentWrapper_get_implementation(
895 uno::XComponentContext* /*pCtx*/, uno::Sequence<uno::Any> const& /*rSeq*/)
897 return cppu::acquire(new XMLDocumentWrapper_XmlSecImpl());
900 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */