Bump version to 5.0-14
[LibreOffice.git] / xmlsecurity / source / xmlsec / xmldocumentwrapper_xmlsecimpl.cxx
blobae0b10770f090932b9be36da2995b6bf6a60d4a3
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 <cppuhelper/supportsservice.hxx>
25 #include "xmldocumentwrapper_xmlsecimpl.hxx"
27 #include <xmloff/attrlist.hxx>
28 #include "xmlelementwrapper_xmlsecimpl.hxx"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
37 #include <vector>
39 #ifdef UNX
40 #define stricmp strcasecmp
41 #endif
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
59 #define NODE_STOPED 2
61 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl()
62 : m_nCurrentPosition(0)
63 , m_pStopAtNode(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 *************************
88 * NAME
89 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
91 * SYNOPSIS
92 * getNextSAXEvent();
94 * FUNCTION
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;
111 * INPUTS
112 * empty
114 * RESULT
115 * empty
117 * AUTHOR
118 * Michael Mi
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
129 * children.
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
138 * next event.
140 if (m_pCurrentElement->children != NULL)
142 m_pCurrentElement = m_pCurrentElement->children;
143 m_nCurrentPosition
144 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
145 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
147 else
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
155 * following sibling.
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;
171 m_nCurrentPosition
172 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
173 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
175 else
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 ************************
190 * NAME
191 * sendStartElement -- Constructs a startElement SAX event
193 * SYNOPSIS
194 * sendStartElement(xHandler, xHandler2, pNode);
196 * FUNCTION
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.
201 * INPUTS
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.
209 * RESULT
210 * empty
212 * AUTHOR
213 * Michael Mi
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) )));
233 else
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;
252 OUString ouAttrName;
253 if (pAttrNs == NULL)
255 ouAttrName = OUString(C2U( reinterpret_cast<char const *>(pAttrName) ));
257 else
259 ouAttrName = OUString(C2U( reinterpret_cast<char const *>(pAttrNs->prefix)))
260 + ":" + OUString(C2U( reinterpret_cast<char const *>(pAttrName) ));
263 pAttributeList->AddAttribute(
264 ouAttrName,
265 OUString(C2U( reinterpret_cast<char*>(pAttr->children->content))));
266 pAttr = pAttr->next;
269 OString sNodeName = getNodeQName(pNode);
271 if (xHandler.is())
273 xHandler->startElement(
274 OUString(C2U ( sNodeName.getStr() )),
275 xAttrList);
278 xHandler2->startElement(
279 OUString(C2U ( sNodeName.getStr() )),
280 xAttrList);
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 **************************
290 * NAME
291 * sendEndElement -- Constructs a endElement SAX event
293 * SYNOPSIS
294 * sendEndElement(xHandler, xHandler2, pNode);
296 * FUNCTION
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.
301 * INPUTS
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.
309 * RESULT
310 * empty
312 * AUTHOR
313 * Michael Mi
314 * Email: michael.mi@sun.com
315 ******************************************************************************/
317 OString sNodeName = getNodeQName(pNode);
319 if (xHandler.is())
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 ********************************
334 * NAME
335 * sendNode -- Constructs a characters SAX event or a
336 * processingInstruction SAX event
338 * SYNOPSIS
339 * sendNode(xHandler, xHandler2, pNode);
341 * FUNCTION
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.
347 * INPUTS
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.
357 * RESULT
358 * empty
360 * AUTHOR
361 * Michael Mi
362 * Email: michael.mi@sun.com
363 ******************************************************************************/
365 xmlElementType type = pNode->type;
367 if (type == XML_TEXT_NODE)
369 if (xHandler.is())
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)
378 if (xHandler.is())
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 ****************************
394 * NAME
395 * getNodeQName -- Retrieves the qualified name of a node
397 * SYNOPSIS
398 * name = getNodeQName(pNode);
400 * FUNCTION
401 * see NAME
403 * INPUTS
404 * pNode - the node whose name will be retrieved
406 * RESULT
407 * name - the node's qualified name
409 * AUTHOR
410 * Michael Mi
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;
426 return sNodeName;
429 xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement)
430 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
432 * NAME
433 * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
434 * interface
436 * SYNOPSIS
437 * node = checkElement(xXMLElement);
439 * FUNCTION
440 * see NAME
442 * INPUTS
443 * xXMLElement - the XXMLElementWrapper interface wraping a node
445 * RESULT
446 * node - the node wrapped in the XXMLElementWrapper interface
448 * AUTHOR
449 * Michael Mi
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();
476 return rc;
479 sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
480 const xmlNodePtr pNode)
481 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
483 * NAME
484 * recursiveDelete -- Deletes a particular node with its branch.
486 * SYNOPSIS
487 * result = recursiveDelete(pNode);
489 * FUNCTION
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.
498 * INPUTS
499 * pNode - the node to be deleted
501 * RESULT
502 * result - the result of the deletion process, can be one of following
503 * values:
504 * NODE_STOPED - the process is interrupted by meeting the
505 * m_pStopAtNode
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
510 * removed
512 * NOTES
513 * The node in the m_aReservedNodes list must be in the tree order, otherwise
514 * the result is unpredictable.
516 * AUTHOR
517 * Michael Mi
518 * Email: michael.mi@sun.com
519 ******************************************************************************/
521 if (pNode == m_pStopAtNode)
523 return NODE_STOPED;
526 if (pNode != m_pCurrentReservedNode)
528 xmlNodePtr pChild = pNode->children;
530 xmlNodePtr pNextSibling;
531 bool bIsRemoved = true;
532 sal_Int32 nResult;
534 while( pChild != NULL )
536 pNextSibling = pChild->next;
537 nResult = recursiveDelete(pChild);
539 switch (nResult)
541 case NODE_STOPED:
542 return NODE_STOPED;
543 case NODE_NOTREMOVED:
544 bIsRemoved = false;
545 break;
546 case NODE_REMOVED:
547 removeNode(pChild);
548 break;
549 default:
550 throw cssu::RuntimeException();
553 pChild = pNextSibling;
556 if (pNode == m_pCurrentElement)
558 bIsRemoved = false;
561 return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
563 else
565 getNextReservedNode();
566 return NODE_NOTREMOVED;
570 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
571 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
573 * NAME
574 * getNextReservedNode -- Highlights the next reserved node in the
575 * reserved node list
577 * SYNOPSIS
578 * getNextReservedNode();
580 * FUNCTION
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.
587 * INPUTS
588 * empty
590 * RESULT
591 * empty
593 * AUTHOR
594 * Michael Mi
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 ++;
603 else
605 m_pCurrentReservedNode = NULL;
609 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
610 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
612 * NAME
613 * removeNode -- Deletes a node with its branch unconditionaly
615 * SYNOPSIS
616 * removeNode( pNode );
618 * FUNCTION
619 * Delete the node along with its branch from the document.
621 * INPUTS
622 * pNode - the node to be deleted
624 * RESULT
625 * empty
627 * AUTHOR
628 * Michael Mi
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);
644 pAttr = pAttr->next;
647 xmlUnlinkNode(pNode);
648 xmlFreeNode(pNode);
651 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
652 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
654 * NAME
655 * buildIDAttr -- build the ID attribute of a node
657 * SYNOPSIS
658 * buildIDAttr( pNode );
660 * FUNCTION
661 * see NAME
663 * INPUTS
664 * pNode - the node whose id attribute will be built
666 * RESULT
667 * empty
669 * AUTHOR
670 * Michael Mi
671 * Email: michael.mi@sun.com
672 ******************************************************************************/
674 xmlAttrPtr idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("id") );
675 if (idAttr == NULL)
677 idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("Id") );
680 if (idAttr != NULL)
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 ***************************
690 * NAME
691 * rebuildIDLink -- rebuild the ID link for the branch
693 * SYNOPSIS
694 * rebuildIDLink( pNode );
696 * FUNCTION
697 * see NAME
699 * INPUTS
700 * pNode - the node, from which the branch will be rebuilt
702 * RESULT
703 * empty
705 * AUTHOR
706 * Michael Mi
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);
718 child = child->next;
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(
752 OUString(
753 C2U (
754 reinterpret_cast<char const *>(pOldCurrentElement->name)
755 )));
756 m_pCurrentElement = saxHelper.getCurrentNode();
759 * remove the node
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)
774 bool rc = false;
776 if (m_pCurrentElement->children == NULL)
778 rc = true;
781 return rc;
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);
812 xmlNodePtr pParent;
814 while (pTargetNode != NULL)
816 if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement)
818 break;
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;
840 while(true)
842 switch (m_nCurrentPosition)
844 case NODEPOSITION_STARTELEMENT:
845 sendStartElement(NULL, xHandler, m_pCurrentElement);
846 break;
847 case NODEPOSITION_ENDELEMENT:
848 sendEndElement(NULL, xHandler, m_pCurrentElement);
849 break;
850 case NODEPOSITION_NORMAL:
851 sendNode(NULL, xHandler, m_pCurrentElement);
852 break;
855 if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
857 break;
860 getNextSAXEvent();
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
877 * element.
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;
889 else
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;
900 while(true)
902 switch (m_nCurrentPosition)
904 case NODEPOSITION_STARTELEMENT:
905 sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
906 break;
907 case NODEPOSITION_ENDELEMENT:
908 sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
909 break;
910 case NODEPOSITION_NORMAL:
911 sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
912 break;
913 default:
914 throw cssu::RuntimeException();
917 if (xSAXEventKeeper->isBlocking())
919 xHandler = NULL;
922 if (pEndNode == NULL &&
923 ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
924 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
926 break;
929 getNextSAXEvent();
932 * If there is an end point specified, then check whether
933 * the current node equals to the end point. If so, stop
934 * generating.
936 if (pEndNode != NULL && m_pCurrentElement == pEndNode)
938 break;
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";
1071 return aRet;
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( );
1081 /* XServiceInfo */
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: */