bump product version to 4.1.6.2
[LibreOffice.git] / xmlsecurity / source / xmlsec / xmldocumentwrapper_xmlsecimpl.cxx
blob853bbc63ccad77963ba97f68ac94ebccfa20e0e3
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 .
21 #include "xmldocumentwrapper_xmlsecimpl.hxx"
23 #include <xmloff/attrlist.hxx>
24 #include "xmlelementwrapper_xmlsecimpl.hxx"
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
33 #include <vector>
35 #ifdef UNX
36 #define stricmp strcasecmp
37 #endif
39 namespace cssu = com::sun::star::uno;
40 namespace cssl = com::sun::star::lang;
41 namespace cssxc = com::sun::star::xml::crypto;
42 namespace cssxcsax = com::sun::star::xml::csax;
43 namespace cssxs = com::sun::star::xml::sax;
44 namespace cssxw = com::sun::star::xml::wrapper;
46 #define SERVICE_NAME "com.sun.star.xml.wrapper.XMLDocumentWrapper"
47 #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl"
49 #define STRXMLNS "xmlns"
51 #define C2U( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8
53 /* used by the recursiveDelete method */
54 #define NODE_REMOVED 0
55 #define NODE_NOTREMOVED 1
56 #define NODE_STOPED 2
58 XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl( )
60 saxHelper.startDocument();
61 m_pDocument = saxHelper.getDocument();
64 * creates the virtual root element
66 saxHelper.startElement(OUString(C2U( "root" )), cssu::Sequence<cssxcsax::XMLAttribute>());
68 m_pRootElement = saxHelper.getCurrentNode();
69 m_pCurrentElement = m_pRootElement;
72 XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
74 saxHelper.endDocument();
75 xmlFreeDoc(m_pDocument);
78 void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
79 /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
81 * NAME
82 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
84 * SYNOPSIS
85 * getNextSAXEvent();
87 * FUNCTION
88 * When converting the document into SAX events, this method is used to
89 * decide the next SAX event to be generated.
90 * Two member variables are checked to make the decision, the
91 * m_pCurrentElement and the m_nCurrentPosition.
92 * The m_pCurrentElement represents the node which have been covered, and
93 * the m_nCurrentPosition represents the event which have been sent.
94 * For example, suppose that the m_pCurrentElement
95 * points to element A, and the m_nCurrentPosition equals to
96 * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
97 * endElement for element A if A has no child, or startElement for the
98 * first child element of element A otherwise.
99 * The m_nCurrentPosition can be one of following values:
100 * NODEPOSITION_STARTELEMENT for startElement;
101 * NODEPOSITION_ENDELEMENT for endElement;
102 * NODEPOSITION_NORMAL for other SAX events;
104 * INPUTS
105 * empty
107 * RESULT
108 * empty
110 * AUTHOR
111 * Michael Mi
112 * Email: michael.mi@sun.com
113 ******************************************************************************/
115 OSL_ASSERT( m_pCurrentElement != NULL );
118 * Get the next event through tree order.
120 * if the current event is a startElement, then the next
121 * event depends on whether or not the current node has
122 * children.
124 if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT)
127 * If the current node has children, then its first child
128 * should be next current node, and the next event will be
129 * startElement or charaters(PI) based on that child's node
130 * type. Otherwise, the endElement of current node is the
131 * next event.
133 if (m_pCurrentElement->children != NULL)
135 m_pCurrentElement = m_pCurrentElement->children;
136 m_nCurrentPosition
137 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
138 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
140 else
142 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
146 * if the current event is a not startElement, then the next
147 * event depends on whether or not the current node has
148 * following sibling.
150 else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL)
152 xmlNodePtr pNextSibling = m_pCurrentElement->next;
155 * If the current node has following sibling, that sibling
156 * should be next current node, and the next event will be
157 * startElement or charaters(PI) based on that sibling's node
158 * type. Otherwise, the endElement of current node's parent
159 * becomes the next event.
161 if (pNextSibling != NULL)
163 m_pCurrentElement = pNextSibling;
164 m_nCurrentPosition
165 = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
166 NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
168 else
170 m_pCurrentElement = m_pCurrentElement->parent;
171 m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
176 void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
177 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
178 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
179 const xmlNodePtr pNode) const
180 throw (cssxs::SAXException)
181 /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
183 * NAME
184 * sendStartElement -- Constructs a startElement SAX event
186 * SYNOPSIS
187 * sendStartElement(xHandler, xHandler2, pNode);
189 * FUNCTION
190 * Used when converting the document into SAX event stream.
191 * This method constructs a startElement SAX event for a particular
192 * element, then calls the startElement methods of the XDocumentHandlers.
194 * INPUTS
195 * xHandler - the first XDocumentHandler interface to receive the
196 * startElement SAX event. It can be NULL.
197 * xHandler2 - the second XDocumentHandler interface to receive the
198 * startElement SAX event. It can't be NULL.
199 * pNode - the node on which the startElement should be generated.
200 * This node must be a element type.
202 * RESULT
203 * empty
205 * AUTHOR
206 * Michael Mi
207 * Email: michael.mi@sun.com
208 ******************************************************************************/
210 SvXMLAttributeList* pAttributeList = new SvXMLAttributeList();
211 cssu::Reference < cssxs::XAttributeList > xAttrList = cssu::Reference< cssxs::XAttributeList > (pAttributeList);
213 xmlNsPtr pNsDef = pNode->nsDef;
215 while (pNsDef != NULL)
217 const xmlChar* pNsPrefix = pNsDef->prefix;
218 const xmlChar* pNsHref = pNsDef->href;
220 if (pNsDef->prefix == NULL)
222 pAttributeList->AddAttribute(
223 OUString(C2U( STRXMLNS )),
224 OUString(C2U( (sal_Char*)pNsHref )));
226 else
228 pAttributeList->AddAttribute(
229 OUString(C2U( STRXMLNS ))
230 +OUString(C2U( ":" ))
231 +OUString(C2U( (sal_Char*)pNsPrefix )),
232 OUString(C2U( (sal_Char*)pNsHref )));
235 pNsDef = pNsDef->next;
238 xmlAttrPtr pAttr = pNode->properties;
240 while (pAttr != NULL)
242 const xmlChar* pAttrName = pAttr->name;
243 xmlNsPtr pAttrNs = pAttr->ns;
245 OUString ouAttrName;
246 if (pAttrNs == NULL)
248 ouAttrName = OUString(C2U( (sal_Char*)pAttrName ));
250 else
252 ouAttrName = OUString(C2U( (sal_Char*)pAttrNs->prefix))
253 +OUString(C2U( (sal_Char*)":" ))
254 +OUString(C2U( (sal_Char*)pAttrName ));
257 pAttributeList->AddAttribute(
258 ouAttrName,
259 OUString(C2U( (sal_Char*)(pAttr->children->content))));
260 pAttr = pAttr->next;
263 OString sNodeName = getNodeQName(pNode);
265 if (xHandler.is())
267 xHandler->startElement(
268 OUString(C2U ( ((sal_Char*)(sNodeName.getStr())) )),
269 xAttrList);
272 xHandler2->startElement(
273 OUString(C2U ( ((sal_Char*)(sNodeName.getStr())) )),
274 xAttrList);
277 void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
278 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
279 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
280 const xmlNodePtr pNode) const
281 throw (cssxs::SAXException)
282 /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
284 * NAME
285 * sendEndElement -- Constructs a endElement SAX event
287 * SYNOPSIS
288 * sendEndElement(xHandler, xHandler2, pNode);
290 * FUNCTION
291 * Used when converting the document into SAX event stream.
292 * This method constructs a endElement SAX event for a particular
293 * element, then calls the endElement methods of the XDocumentHandlers.
295 * INPUTS
296 * xHandler - the first XDocumentHandler interface to receive the
297 * endElement SAX event. It can be NULL.
298 * xHandler2 - the second XDocumentHandler interface to receive the
299 * endElement SAX event. It can't be NULL.
300 * pNode - the node on which the endElement should be generated.
301 * This node must be a element type.
303 * RESULT
304 * empty
306 * AUTHOR
307 * Michael Mi
308 * Email: michael.mi@sun.com
309 ******************************************************************************/
311 OString sNodeName = getNodeQName(pNode);
313 if (xHandler.is())
315 xHandler->endElement(OUString(C2U ( ((sal_Char*)(sNodeName.getStr())) )));
318 xHandler2->endElement(OUString(C2U ( ((sal_Char*)(sNodeName.getStr())) )));
321 void XMLDocumentWrapper_XmlSecImpl::sendNode(
322 const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
323 const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
324 const xmlNodePtr pNode) const
325 throw (cssxs::SAXException)
326 /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
328 * NAME
329 * sendNode -- Constructs a characters SAX event or a
330 * processingInstruction SAX event
332 * SYNOPSIS
333 * sendNode(xHandler, xHandler2, pNode);
335 * FUNCTION
336 * Used when converting the document into SAX event stream.
337 * This method constructs a characters SAX event or a
338 * processingInstructionfor SAX event based on the type of a particular
339 * element, then calls the corresponding methods of the XDocumentHandlers.
341 * INPUTS
342 * xHandler - the first XDocumentHandler interface to receive the
343 * SAX event. It can be NULL.
344 * xHandler2 - the second XDocumentHandler interface to receive the
345 * SAX event. It can't be NULL.
346 * pNode - the node on which the endElement should be generated.
347 * If it is a text node, then a characters SAX event is
348 * generated; if it is a PI node, then a
349 * processingInstructionfor SAX event is generated.
351 * RESULT
352 * empty
354 * AUTHOR
355 * Michael Mi
356 * Email: michael.mi@sun.com
357 ******************************************************************************/
359 xmlElementType type = pNode->type;
361 if (type == XML_TEXT_NODE)
363 if (xHandler.is())
365 xHandler->characters(OUString(C2U ( ((sal_Char*)(pNode->content)) )));
368 xHandler2->characters(OUString(C2U ( ((sal_Char*)(pNode->content)) )));
370 else if (type == XML_PI_NODE)
372 if (xHandler.is())
374 xHandler->processingInstruction(
375 OUString(C2U ( ((sal_Char*)(pNode->name)) )),
376 OUString(C2U ( ((sal_Char*)(pNode->content)) )));
379 xHandler2->processingInstruction(
380 OUString(C2U ( ((sal_Char*)(pNode->name)) )),
381 OUString(C2U ( ((sal_Char*)(pNode->content)) )));
385 OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode) const
386 /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
388 * NAME
389 * getNodeQName -- Retrives the qualified name of a node
391 * SYNOPSIS
392 * name = getNodeQName(pNode);
394 * FUNCTION
395 * see NAME
397 * INPUTS
398 * pNode - the node whose name will be retrived
400 * RESULT
401 * name - the node's qualified name
403 * AUTHOR
404 * Michael Mi
405 * Email: michael.mi@sun.com
406 ******************************************************************************/
408 OString sNodeName((const sal_Char*)pNode->name);
409 if (pNode->ns != NULL)
411 xmlNsPtr pNs = pNode->ns;
413 if (pNs->prefix != NULL)
415 OString sPrefix((const sal_Char*)pNs->prefix);
416 sNodeName = sPrefix+OString(":")+sNodeName;
420 return sNodeName;
423 xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement) const
424 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
426 * NAME
427 * checkElement -- Retrives the node wrapped by an XXMLElementWrapper
428 * interface
430 * SYNOPSIS
431 * node = checkElement(xXMLElement);
433 * FUNCTION
434 * see NAME
436 * INPUTS
437 * xXMLElement - the XXMLElementWrapper interface wraping a node
439 * RESULT
440 * node - the node wrapped in the XXMLElementWrapper interface
442 * AUTHOR
443 * Michael Mi
444 * Email: michael.mi@sun.com
445 ******************************************************************************/
447 xmlNodePtr rc = NULL;
449 if (xXMLElement.is())
451 cssu::Reference< cssl::XUnoTunnel > xNodTunnel( xXMLElement, cssu::UNO_QUERY ) ;
452 if( !xNodTunnel.is() )
454 throw cssu::RuntimeException() ;
457 XMLElementWrapper_XmlSecImpl* pElement
458 = reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
459 sal::static_int_cast<sal_uIntPtr>(
460 xNodTunnel->getSomething(
461 XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ;
463 if( pElement == NULL ) {
464 throw cssu::RuntimeException() ;
467 rc = pElement->getNativeElement();
470 return rc;
473 sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
474 const xmlNodePtr pNode)
475 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
477 * NAME
478 * recursiveDelete -- Deletes a paticular node with its branch.
480 * SYNOPSIS
481 * result = recursiveDelete(pNode);
483 * FUNCTION
484 * Deletes a paticular node with its branch, while reserving the nodes
485 * (and their brance) listed in the m_aReservedNodes.
486 * The deletion process is preformed in the tree order, that is, a node
487 * is deleted after its previous sibling node is deleted, a parent node
488 * is deleted after its branch is deleted.
489 * During the deletion process when the m_pStopAtNode is reached, the
490 * progress is interrupted at once.
492 * INPUTS
493 * pNode - the node to be deleted
495 * RESULT
496 * result - the result of the deletion process, can be one of following
497 * values:
498 * NODE_STOPED - the process is interrupted by meeting the
499 * m_pStopAtNode
500 * NODE_NOTREMOVED - the pNode is not completely removed
501 * because there is its descendant in the
502 * m_aReservedNodes list
503 * NODE_REMOVED - the pNode and its branch are completely
504 * removed
506 * NOTES
507 * The node in the m_aReservedNodes list must be in the tree order, otherwise
508 * the result is unpredictable.
510 * AUTHOR
511 * Michael Mi
512 * Email: michael.mi@sun.com
513 ******************************************************************************/
515 if (pNode == m_pStopAtNode)
517 return NODE_STOPED;
520 if (pNode != m_pCurrentReservedNode)
522 xmlNodePtr pChild = pNode->children;
524 xmlNodePtr pNextSibling;
525 bool bIsRemoved = true;
526 sal_Int32 nResult;
528 while( pChild != NULL )
530 pNextSibling = pChild->next;
531 nResult = recursiveDelete(pChild);
533 switch (nResult)
535 case NODE_STOPED:
536 return NODE_STOPED;
537 case NODE_NOTREMOVED:
538 bIsRemoved = false;
539 break;
540 case NODE_REMOVED:
541 removeNode(pChild);
542 break;
543 default:
544 throw cssu::RuntimeException();
547 pChild = pNextSibling;
550 if (pNode == m_pCurrentElement)
552 bIsRemoved = false;
555 return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
557 else
559 getNextReservedNode();
560 return NODE_NOTREMOVED;
564 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
565 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
567 * NAME
568 * getNextReservedNode -- Highlights the next reserved node in the
569 * reserved node list
571 * SYNOPSIS
572 * getNextReservedNode();
574 * FUNCTION
575 * The m_aReservedNodes array holds a node list, while the
576 * m_pCurrentReservedNode points to the one currently highlighted.
577 * This method is used to highlight the next node in the node list.
578 * This method is called at the time when the current highlighted node
579 * has been already processed, and the next node should be ready.
581 * INPUTS
582 * empty
584 * RESULT
585 * empty
587 * AUTHOR
588 * Michael Mi
589 * Email: michael.mi@sun.com
590 ******************************************************************************/
592 if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
594 m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] );
595 m_nReservedNodeIndex ++;
597 else
599 m_pCurrentReservedNode = NULL;
603 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
604 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
606 * NAME
607 * removeNode -- Deletes a node with its branch unconditionaly
609 * SYNOPSIS
610 * removeNode( pNode );
612 * FUNCTION
613 * Delete the node along with its branch from the document.
615 * INPUTS
616 * pNode - the node to be deleted
618 * RESULT
619 * empty
621 * AUTHOR
622 * Michael Mi
623 * Email: michael.mi@sun.com
624 ******************************************************************************/
626 /* you can't remove the current node */
627 OSL_ASSERT( m_pCurrentElement != pNode );
629 xmlAttrPtr pAttr = pNode->properties;
631 while (pAttr != NULL)
633 if (!stricmp((sal_Char*)pAttr->name,"id"))
635 xmlRemoveID(m_pDocument, pAttr);
638 pAttr = pAttr->next;
641 xmlUnlinkNode(pNode);
642 xmlFreeNode(pNode);
645 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
646 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
648 * NAME
649 * buildIDAttr -- build the ID attribute of a node
651 * SYNOPSIS
652 * buildIDAttr( pNode );
654 * FUNCTION
655 * see NAME
657 * INPUTS
658 * pNode - the node whose id attribute will be built
660 * RESULT
661 * empty
663 * AUTHOR
664 * Michael Mi
665 * Email: michael.mi@sun.com
666 ******************************************************************************/
668 xmlAttrPtr idAttr = xmlHasProp( pNode, (const unsigned char *)"id" );
669 if (idAttr == NULL)
671 idAttr = xmlHasProp( pNode, (const unsigned char *)"Id" );
674 if (idAttr != NULL)
676 xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
677 xmlAddID( NULL, m_pDocument, idValue, idAttr );
681 void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const
682 /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
684 * NAME
685 * rebuildIDLink -- rebuild the ID link for the branch
687 * SYNOPSIS
688 * rebuildIDLink( pNode );
690 * FUNCTION
691 * see NAME
693 * INPUTS
694 * pNode - the node, from which the branch will be rebuilt
696 * RESULT
697 * empty
699 * AUTHOR
700 * Michael Mi
701 * Email: michael.mi@sun.com
702 ******************************************************************************/
704 if (pNode != NULL && pNode->type == XML_ELEMENT_NODE)
706 buildIDAttr( pNode );
708 xmlNodePtr child = pNode->children;
709 while (child != NULL)
711 rebuildIDLink(child);
712 child = child->next;
717 /* XXMLDocumentWrapper */
718 cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
719 throw (cssu::RuntimeException)
721 XMLElementWrapper_XmlSecImpl* pElement = new XMLElementWrapper_XmlSecImpl(m_pCurrentElement);
722 return (cssu::Reference< cssxw::XXMLElementWrapper >)pElement;
725 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference< cssxw::XXMLElementWrapper >& element )
726 throw (cssu::RuntimeException)
728 m_pCurrentElement = checkElement( element );
729 saxHelper.setCurrentNode( m_pCurrentElement );
732 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
733 throw (cssu::RuntimeException)
735 OSL_ASSERT( m_pCurrentElement != NULL );
737 xmlNodePtr pOldCurrentElement = m_pCurrentElement;
740 * pop the top node in the parser context's
741 * nodeTab stack, then the parent of that node will
742 * automatically become the new stack top, and
743 * the current node as well.
745 saxHelper.endElement(
746 OUString(
747 C2U (
748 (sal_Char*)(pOldCurrentElement->name)
749 )));
750 m_pCurrentElement = saxHelper.getCurrentNode();
753 * remove the node
755 removeNode(pOldCurrentElement);
758 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
759 throw (cssu::RuntimeException)
761 xmlNodePtr pNode = checkElement(node);
762 return (pNode == m_pCurrentElement);
765 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
766 throw (cssu::RuntimeException)
768 sal_Bool rc = sal_False;
770 if (m_pCurrentElement->children == NULL)
772 rc = sal_True;
775 return rc;
778 OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
779 throw (cssu::RuntimeException)
781 xmlNodePtr pNode = checkElement(node);
782 return OUString(C2U ( (sal_Char*)pNode->name ));
785 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData(
786 const cssu::Reference< cssxw::XXMLElementWrapper >& node,
787 const cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >& reservedDescendants,
788 const cssu::Reference< cssxw::XXMLElementWrapper >& stopAtNode )
789 throw (cssu::RuntimeException)
791 xmlNodePtr pTargetNode = checkElement(node);
793 m_pStopAtNode = checkElement(stopAtNode);
794 m_aReservedNodes = reservedDescendants;
795 m_nReservedNodeIndex = 0;
797 getNextReservedNode();
799 recursiveDelete(pTargetNode);
802 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
803 throw (cssu::RuntimeException)
805 xmlNodePtr pTargetNode = checkElement(node);
806 xmlNodePtr pParent;
808 while (pTargetNode != NULL)
810 if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement)
812 break;
815 pParent = pTargetNode->parent;
816 removeNode(pTargetNode);
817 pTargetNode = pParent;
821 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference< cssxs::XDocumentHandler >& handler )
822 throw (cssxs::SAXException, cssu::RuntimeException)
824 if (m_pRootElement != NULL)
826 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
827 sal_Int32 nTempCurrentPosition = m_nCurrentPosition;
829 m_pCurrentElement = m_pRootElement;
831 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
832 cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
834 while(true)
836 switch (m_nCurrentPosition)
838 case NODEPOSITION_STARTELEMENT:
839 sendStartElement(NULL, xHandler, m_pCurrentElement);
840 break;
841 case NODEPOSITION_ENDELEMENT:
842 sendEndElement(NULL, xHandler, m_pCurrentElement);
843 break;
844 case NODEPOSITION_NORMAL:
845 sendNode(NULL, xHandler, m_pCurrentElement);
846 break;
849 if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
851 break;
854 getNextSAXEvent();
857 m_pCurrentElement = pTempCurrentElement;
858 m_nCurrentPosition = nTempCurrentPosition;
862 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
863 const cssu::Reference< cssxs::XDocumentHandler >& handler,
864 const cssu::Reference< cssxs::XDocumentHandler >& xEventKeeperHandler,
865 const cssu::Reference< cssxw::XXMLElementWrapper >& startNode,
866 const cssu::Reference< cssxw::XXMLElementWrapper >& endNode )
867 throw (cssxs::SAXException, cssu::RuntimeException)
870 * The first SAX event is the startElement of the startNode
871 * element.
873 bool bHasCurrentElementChild = (m_pCurrentElement->children != NULL);
875 xmlNodePtr pTempCurrentElement = m_pCurrentElement;
877 m_pCurrentElement = checkElement(startNode);
879 if (m_pCurrentElement->type == XML_ELEMENT_NODE)
881 m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
883 else
885 m_nCurrentPosition = NODEPOSITION_NORMAL;
888 xmlNodePtr pEndNode = checkElement(endNode);
890 cssu::Reference < cssxc::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, cssu::UNO_QUERY );
892 cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
894 while(true)
896 switch (m_nCurrentPosition)
898 case NODEPOSITION_STARTELEMENT:
899 sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
900 break;
901 case NODEPOSITION_ENDELEMENT:
902 sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
903 break;
904 case NODEPOSITION_NORMAL:
905 sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
906 break;
907 default:
908 throw cssu::RuntimeException();
911 if (xSAXEventKeeper->isBlocking())
913 xHandler = NULL;
916 if (pEndNode == NULL &&
917 ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
918 (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
920 break;
923 getNextSAXEvent();
926 * If there is an end point specified, then check whether
927 * the current node equals to the end point. If so, stop
928 * generating.
930 if (pEndNode != NULL && m_pCurrentElement == pEndNode)
932 break;
936 m_pCurrentElement = pTempCurrentElement;
939 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
940 const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node )
941 throw (com::sun::star::uno::RuntimeException)
943 xmlNodePtr pNode = checkElement( node );
944 rebuildIDLink(pNode);
948 /* cssxs::XDocumentHandler */
949 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( )
950 throw (cssxs::SAXException, cssu::RuntimeException)
954 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( )
955 throw (cssxs::SAXException, cssu::RuntimeException)
959 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const OUString& aName, const cssu::Reference< cssxs::XAttributeList >& xAttribs )
960 throw (cssxs::SAXException, cssu::RuntimeException)
962 sal_Int32 nLength = xAttribs->getLength();
963 cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
965 for (int i = 0; i < nLength; ++i)
967 aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
968 aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
971 _startElement(aName, aAttributes);
974 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const OUString& aName )
975 throw (cssxs::SAXException, cssu::RuntimeException)
977 saxHelper.endElement(aName);
978 m_pCurrentElement = saxHelper.getCurrentNode();
981 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const OUString& aChars )
982 throw (cssxs::SAXException, cssu::RuntimeException)
984 saxHelper.characters(aChars);
987 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString& aWhitespaces )
988 throw (cssxs::SAXException, cssu::RuntimeException)
990 saxHelper.ignorableWhitespace(aWhitespaces);
993 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString& aTarget, const OUString& aData )
994 throw (cssxs::SAXException, cssu::RuntimeException)
996 saxHelper.processingInstruction(aTarget, aData);
999 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& xLocator )
1000 throw (cssxs::SAXException, cssu::RuntimeException)
1002 saxHelper.setDocumentLocator(xLocator);
1005 /* XCompressedDocumentHandler */
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 OUString& aName, const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
1017 throw (cssxs::SAXException, cssu::RuntimeException)
1019 saxHelper.startElement(aName, aAttributes);
1020 m_pCurrentElement = saxHelper.getCurrentNode();
1022 buildIDAttr( m_pCurrentElement );
1025 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_endElement( const OUString& aName )
1026 throw (cssxs::SAXException, cssu::RuntimeException)
1028 endElement( aName );
1031 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_characters( const OUString& aChars )
1032 throw (cssxs::SAXException, cssu::RuntimeException)
1034 characters( aChars );
1037 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_ignorableWhitespace( const OUString& aWhitespaces )
1038 throw (cssxs::SAXException, cssu::RuntimeException)
1040 ignorableWhitespace( aWhitespaces );
1043 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_processingInstruction( const OUString& aTarget, const OUString& aData )
1044 throw (cssxs::SAXException, cssu::RuntimeException)
1046 processingInstruction( aTarget, aData );
1049 void SAL_CALL XMLDocumentWrapper_XmlSecImpl::_setDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const OUString& /*publicId*/, const OUString& /*systemId*/ )
1050 throw (cssxs::SAXException, cssu::RuntimeException)
1054 OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName ()
1055 throw (cssu::RuntimeException)
1057 return OUString ( IMPLEMENTATION_NAME );
1060 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl_supportsService( const OUString& ServiceName )
1061 throw (cssu::RuntimeException)
1063 return ServiceName == SERVICE_NAME;
1066 cssu::Sequence< OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( )
1067 throw (cssu::RuntimeException)
1069 cssu::Sequence < OUString > aRet(1);
1070 OUString* pArray = aRet.getArray();
1071 pArray[0] = OUString ( SERVICE_NAME );
1072 return aRet;
1074 #undef SERVICE_NAME
1076 cssu::Reference< cssu::XInterface > SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance(
1077 const cssu::Reference< cssu::XComponentContext > &)
1078 throw( cssu::Exception )
1080 return (cppu::OWeakObject*) new XMLDocumentWrapper_XmlSecImpl( );
1083 /* XServiceInfo */
1084 OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
1085 throw (cssu::RuntimeException)
1087 return XMLDocumentWrapper_XmlSecImpl_getImplementationName();
1089 sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString& rServiceName )
1090 throw (cssu::RuntimeException)
1092 return XMLDocumentWrapper_XmlSecImpl_supportsService( rServiceName );
1094 cssu::Sequence< OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
1095 throw (cssu::RuntimeException)
1097 return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames();
1100 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */