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 .
21 #include "xmldocumentwrapper_xmlsecimpl.hxx"
23 #include <xmloff/attrlist.hxx>
24 #include "xmlelementwrapper_xmlsecimpl.hxx"
30 #include <sys/types.h>
36 #define stricmp strcasecmp
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
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 *************************
82 * getNextSAXEvent -- Prepares the next SAX event to be manipulate
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;
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
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
133 if (m_pCurrentElement
->children
!= NULL
)
135 m_pCurrentElement
= m_pCurrentElement
->children
;
137 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
138 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
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
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
;
165 = (m_pCurrentElement
->type
== XML_ELEMENT_NODE
)?
166 NODEPOSITION_STARTELEMENT
:NODEPOSITION_NORMAL
;
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 ************************
184 * sendStartElement -- Constructs a startElement SAX event
187 * sendStartElement(xHandler, xHandler2, pNode);
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.
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.
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
)));
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
;
248 ouAttrName
= OUString(C2U( (sal_Char
*)pAttrName
));
252 ouAttrName
= OUString(C2U( (sal_Char
*)pAttrNs
->prefix
))
253 +OUString(C2U( (sal_Char
*)":" ))
254 +OUString(C2U( (sal_Char
*)pAttrName
));
257 pAttributeList
->AddAttribute(
259 OUString(C2U( (sal_Char
*)(pAttr
->children
->content
))));
263 OString sNodeName
= getNodeQName(pNode
);
267 xHandler
->startElement(
268 OUString(C2U ( ((sal_Char
*)(sNodeName
.getStr())) )),
272 xHandler2
->startElement(
273 OUString(C2U ( ((sal_Char
*)(sNodeName
.getStr())) )),
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 **************************
285 * sendEndElement -- Constructs a endElement SAX event
288 * sendEndElement(xHandler, xHandler2, pNode);
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.
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.
308 * Email: michael.mi@sun.com
309 ******************************************************************************/
311 OString sNodeName
= getNodeQName(pNode
);
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 ********************************
329 * sendNode -- Constructs a characters SAX event or a
330 * processingInstruction SAX event
333 * sendNode(xHandler, xHandler2, pNode);
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.
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.
356 * Email: michael.mi@sun.com
357 ******************************************************************************/
359 xmlElementType type
= pNode
->type
;
361 if (type
== XML_TEXT_NODE
)
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
)
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 ****************************
389 * getNodeQName -- Retrives the qualified name of a node
392 * name = getNodeQName(pNode);
398 * pNode - the node whose name will be retrived
401 * name - the node's qualified name
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
;
423 xmlNodePtr
XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
) const
424 /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
427 * checkElement -- Retrives the node wrapped by an XXMLElementWrapper
431 * node = checkElement(xXMLElement);
437 * xXMLElement - the XXMLElementWrapper interface wraping a node
440 * node - the node wrapped in the XXMLElementWrapper interface
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();
473 sal_Int32
XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
474 const xmlNodePtr pNode
)
475 /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
478 * recursiveDelete -- Deletes a paticular node with its branch.
481 * result = recursiveDelete(pNode);
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.
493 * pNode - the node to be deleted
496 * result - the result of the deletion process, can be one of following
498 * NODE_STOPED - the process is interrupted by meeting the
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
507 * The node in the m_aReservedNodes list must be in the tree order, otherwise
508 * the result is unpredictable.
512 * Email: michael.mi@sun.com
513 ******************************************************************************/
515 if (pNode
== m_pStopAtNode
)
520 if (pNode
!= m_pCurrentReservedNode
)
522 xmlNodePtr pChild
= pNode
->children
;
524 xmlNodePtr pNextSibling
;
525 bool bIsRemoved
= true;
528 while( pChild
!= NULL
)
530 pNextSibling
= pChild
->next
;
531 nResult
= recursiveDelete(pChild
);
537 case NODE_NOTREMOVED
:
544 throw cssu::RuntimeException();
547 pChild
= pNextSibling
;
550 if (pNode
== m_pCurrentElement
)
555 return bIsRemoved
?NODE_REMOVED
:NODE_NOTREMOVED
;
559 getNextReservedNode();
560 return NODE_NOTREMOVED
;
564 void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
565 /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
568 * getNextReservedNode -- Highlights the next reserved node in the
572 * getNextReservedNode();
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.
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
++;
599 m_pCurrentReservedNode
= NULL
;
603 void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode
) const
604 /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
607 * removeNode -- Deletes a node with its branch unconditionaly
610 * removeNode( pNode );
613 * Delete the node along with its branch from the document.
616 * pNode - the node to be deleted
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
);
641 xmlUnlinkNode(pNode
);
645 void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode
) const
646 /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
649 * buildIDAttr -- build the ID attribute of a node
652 * buildIDAttr( pNode );
658 * pNode - the node whose id attribute will be built
665 * Email: michael.mi@sun.com
666 ******************************************************************************/
668 xmlAttrPtr idAttr
= xmlHasProp( pNode
, (const unsigned char *)"id" );
671 idAttr
= xmlHasProp( pNode
, (const unsigned char *)"Id" );
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 ***************************
685 * rebuildIDLink -- rebuild the ID link for the branch
688 * rebuildIDLink( pNode );
694 * pNode - the node, from which the branch will be rebuilt
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
);
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(
748 (sal_Char
*)(pOldCurrentElement
->name
)
750 m_pCurrentElement
= saxHelper
.getCurrentNode();
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
)
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
);
808 while (pTargetNode
!= NULL
)
810 if (pTargetNode
->children
!= NULL
|| pTargetNode
== m_pCurrentElement
)
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
;
836 switch (m_nCurrentPosition
)
838 case NODEPOSITION_STARTELEMENT
:
839 sendStartElement(NULL
, xHandler
, m_pCurrentElement
);
841 case NODEPOSITION_ENDELEMENT
:
842 sendEndElement(NULL
, xHandler
, m_pCurrentElement
);
844 case NODEPOSITION_NORMAL
:
845 sendNode(NULL
, xHandler
, m_pCurrentElement
);
849 if ( (m_pCurrentElement
== m_pRootElement
) && (m_nCurrentPosition
== NODEPOSITION_ENDELEMENT
))
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
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
;
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
;
896 switch (m_nCurrentPosition
)
898 case NODEPOSITION_STARTELEMENT
:
899 sendStartElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
901 case NODEPOSITION_ENDELEMENT
:
902 sendEndElement(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
904 case NODEPOSITION_NORMAL
:
905 sendNode(xHandler
, xEventKeeperHandler
, m_pCurrentElement
);
908 throw cssu::RuntimeException();
911 if (xSAXEventKeeper
->isBlocking())
916 if (pEndNode
== NULL
&&
917 ((bHasCurrentElementChild
&& m_pCurrentElement
== xmlGetLastChild(pTempCurrentElement
) && m_nCurrentPosition
!= NODEPOSITION_STARTELEMENT
) ||
918 (!bHasCurrentElementChild
&& m_pCurrentElement
== pTempCurrentElement
&& m_nCurrentPosition
== NODEPOSITION_STARTELEMENT
)))
926 * If there is an end point specified, then check whether
927 * the current node equals to the end point. If so, stop
930 if (pEndNode
!= NULL
&& m_pCurrentElement
== pEndNode
)
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
);
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( );
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: */