Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <osl/diagnose.h>
23 : #include <com/sun/star/uno/XComponentContext.hpp>
24 : #include <cppuhelper/supportsservice.hxx>
25 : #include "xmldocumentwrapper_xmlsecimpl.hxx"
26 :
27 : #include <xmloff/attrlist.hxx>
28 : #include "xmlelementwrapper_xmlsecimpl.hxx"
29 :
30 : #include <stdlib.h>
31 : #include <string.h>
32 :
33 : #include <sys/types.h>
34 : #include <sys/stat.h>
35 :
36 : #include <vector>
37 :
38 : #ifdef UNX
39 : #define stricmp strcasecmp
40 : #endif
41 :
42 : namespace cssu = com::sun::star::uno;
43 : namespace cssl = com::sun::star::lang;
44 : namespace cssxc = com::sun::star::xml::crypto;
45 : namespace cssxcsax = com::sun::star::xml::csax;
46 : namespace cssxs = com::sun::star::xml::sax;
47 : namespace cssxw = com::sun::star::xml::wrapper;
48 :
49 : #define IMPLEMENTATION_NAME "com.sun.star.xml.security.bridge.xmlsec.XMLDocumentWrapper_XmlSecImpl"
50 :
51 : #define STRXMLNS "xmlns"
52 :
53 : #define C2U( asciiStr ) asciiStr, strlen( asciiStr ), RTL_TEXTENCODING_UTF8
54 :
55 : /* used by the recursiveDelete method */
56 : #define NODE_REMOVED 0
57 : #define NODE_NOTREMOVED 1
58 : #define NODE_STOPED 2
59 :
60 1 : XMLDocumentWrapper_XmlSecImpl::XMLDocumentWrapper_XmlSecImpl()
61 : : m_nCurrentPosition(0)
62 : , m_pStopAtNode(0)
63 : , m_pCurrentReservedNode(0)
64 1 : , m_nReservedNodeIndex(0)
65 : {
66 1 : saxHelper.startDocument();
67 1 : m_pDocument = saxHelper.getDocument();
68 :
69 : /*
70 : * creates the virtual root element
71 : */
72 1 : saxHelper.startElement(OUString(C2U( "root" )), cssu::Sequence<cssxcsax::XMLAttribute>());
73 :
74 1 : m_pRootElement = saxHelper.getCurrentNode();
75 1 : m_pCurrentElement = m_pRootElement;
76 1 : }
77 :
78 3 : XMLDocumentWrapper_XmlSecImpl::~XMLDocumentWrapper_XmlSecImpl()
79 : {
80 1 : saxHelper.endDocument();
81 1 : xmlFreeDoc(m_pDocument);
82 2 : }
83 :
84 0 : void XMLDocumentWrapper_XmlSecImpl::getNextSAXEvent()
85 : /****** XMLDocumentWrapper_XmlSecImpl/getNextSAXEvent *************************
86 : *
87 : * NAME
88 : * getNextSAXEvent -- Prepares the next SAX event to be manipulate
89 : *
90 : * SYNOPSIS
91 : * getNextSAXEvent();
92 : *
93 : * FUNCTION
94 : * When converting the document into SAX events, this method is used to
95 : * decide the next SAX event to be generated.
96 : * Two member variables are checked to make the decision, the
97 : * m_pCurrentElement and the m_nCurrentPosition.
98 : * The m_pCurrentElement represents the node which have been covered, and
99 : * the m_nCurrentPosition represents the event which have been sent.
100 : * For example, suppose that the m_pCurrentElement
101 : * points to element A, and the m_nCurrentPosition equals to
102 : * NODEPOSITION_STARTELEMENT, then the next SAX event should be the
103 : * endElement for element A if A has no child, or startElement for the
104 : * first child element of element A otherwise.
105 : * The m_nCurrentPosition can be one of following values:
106 : * NODEPOSITION_STARTELEMENT for startElement;
107 : * NODEPOSITION_ENDELEMENT for endElement;
108 : * NODEPOSITION_NORMAL for other SAX events;
109 : *
110 : * INPUTS
111 : * empty
112 : *
113 : * RESULT
114 : * empty
115 : *
116 : * AUTHOR
117 : * Michael Mi
118 : * Email: michael.mi@sun.com
119 : ******************************************************************************/
120 : {
121 : OSL_ASSERT( m_pCurrentElement != NULL );
122 :
123 : /*
124 : * Get the next event through tree order.
125 : *
126 : * if the current event is a startElement, then the next
127 : * event depends on whether or not the current node has
128 : * children.
129 : */
130 0 : if (m_nCurrentPosition == NODEPOSITION_STARTELEMENT)
131 : {
132 : /*
133 : * If the current node has children, then its first child
134 : * should be next current node, and the next event will be
135 : * startElement or charaters(PI) based on that child's node
136 : * type. Otherwise, the endElement of current node is the
137 : * next event.
138 : */
139 0 : if (m_pCurrentElement->children != NULL)
140 : {
141 0 : m_pCurrentElement = m_pCurrentElement->children;
142 : m_nCurrentPosition
143 0 : = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
144 0 : NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
145 : }
146 : else
147 : {
148 0 : m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
149 : }
150 : }
151 : /*
152 : * if the current event is a not startElement, then the next
153 : * event depends on whether or not the current node has
154 : * following sibling.
155 : */
156 0 : else if (m_nCurrentPosition == NODEPOSITION_ENDELEMENT || m_nCurrentPosition == NODEPOSITION_NORMAL)
157 : {
158 0 : xmlNodePtr pNextSibling = m_pCurrentElement->next;
159 :
160 : /*
161 : * If the current node has following sibling, that sibling
162 : * should be next current node, and the next event will be
163 : * startElement or charaters(PI) based on that sibling's node
164 : * type. Otherwise, the endElement of current node's parent
165 : * becomes the next event.
166 : */
167 0 : if (pNextSibling != NULL)
168 : {
169 0 : m_pCurrentElement = pNextSibling;
170 : m_nCurrentPosition
171 0 : = (m_pCurrentElement->type == XML_ELEMENT_NODE)?
172 0 : NODEPOSITION_STARTELEMENT:NODEPOSITION_NORMAL;
173 : }
174 : else
175 : {
176 0 : m_pCurrentElement = m_pCurrentElement->parent;
177 0 : m_nCurrentPosition = NODEPOSITION_ENDELEMENT;
178 : }
179 : }
180 0 : }
181 :
182 0 : void XMLDocumentWrapper_XmlSecImpl::sendStartElement(
183 : const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
184 : const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
185 : const xmlNodePtr pNode)
186 : throw (cssxs::SAXException)
187 : /****** XMLDocumentWrapper_XmlSecImpl/sendStartElement ************************
188 : *
189 : * NAME
190 : * sendStartElement -- Constructs a startElement SAX event
191 : *
192 : * SYNOPSIS
193 : * sendStartElement(xHandler, xHandler2, pNode);
194 : *
195 : * FUNCTION
196 : * Used when converting the document into SAX event stream.
197 : * This method constructs a startElement SAX event for a particular
198 : * element, then calls the startElement methods of the XDocumentHandlers.
199 : *
200 : * INPUTS
201 : * xHandler - the first XDocumentHandler interface to receive the
202 : * startElement SAX event. It can be NULL.
203 : * xHandler2 - the second XDocumentHandler interface to receive the
204 : * startElement SAX event. It can't be NULL.
205 : * pNode - the node on which the startElement should be generated.
206 : * This node must be a element type.
207 : *
208 : * RESULT
209 : * empty
210 : *
211 : * AUTHOR
212 : * Michael Mi
213 : * Email: michael.mi@sun.com
214 : ******************************************************************************/
215 : {
216 0 : SvXMLAttributeList* pAttributeList = new SvXMLAttributeList();
217 0 : cssu::Reference < cssxs::XAttributeList > xAttrList = cssu::Reference< cssxs::XAttributeList > (pAttributeList);
218 :
219 0 : xmlNsPtr pNsDef = pNode->nsDef;
220 :
221 0 : while (pNsDef != NULL)
222 : {
223 0 : const xmlChar* pNsPrefix = pNsDef->prefix;
224 0 : const xmlChar* pNsHref = pNsDef->href;
225 :
226 0 : if (pNsDef->prefix == NULL)
227 : {
228 : pAttributeList->AddAttribute(
229 : OUString(C2U( STRXMLNS )),
230 0 : OUString(C2U( reinterpret_cast<char const *>(pNsHref) )));
231 : }
232 : else
233 : {
234 : pAttributeList->AddAttribute(
235 : OUString(C2U( STRXMLNS ))
236 0 : +OUString(C2U( ":" ))
237 0 : +OUString(C2U( reinterpret_cast<char const *>(pNsPrefix) )),
238 0 : OUString(C2U( reinterpret_cast<char const *>(pNsHref) )));
239 : }
240 :
241 0 : pNsDef = pNsDef->next;
242 : }
243 :
244 0 : xmlAttrPtr pAttr = pNode->properties;
245 :
246 0 : while (pAttr != NULL)
247 : {
248 0 : const xmlChar* pAttrName = pAttr->name;
249 0 : xmlNsPtr pAttrNs = pAttr->ns;
250 :
251 0 : OUString ouAttrName;
252 0 : if (pAttrNs == NULL)
253 : {
254 0 : ouAttrName = OUString(C2U( reinterpret_cast<char const *>(pAttrName) ));
255 : }
256 : else
257 : {
258 0 : ouAttrName = OUString(C2U( reinterpret_cast<char const *>(pAttrNs->prefix)))
259 0 : + ":" + OUString(C2U( reinterpret_cast<char const *>(pAttrName) ));
260 : }
261 :
262 : pAttributeList->AddAttribute(
263 : ouAttrName,
264 0 : OUString(C2U( reinterpret_cast<char*>(pAttr->children->content))));
265 0 : pAttr = pAttr->next;
266 0 : }
267 :
268 0 : OString sNodeName = getNodeQName(pNode);
269 :
270 0 : if (xHandler.is())
271 : {
272 0 : xHandler->startElement(
273 0 : OUString(C2U ( sNodeName.getStr() )),
274 0 : xAttrList);
275 : }
276 :
277 0 : xHandler2->startElement(
278 0 : OUString(C2U ( sNodeName.getStr() )),
279 0 : xAttrList);
280 0 : }
281 :
282 0 : void XMLDocumentWrapper_XmlSecImpl::sendEndElement(
283 : const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
284 : const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
285 : const xmlNodePtr pNode)
286 : throw (cssxs::SAXException)
287 : /****** XMLDocumentWrapper_XmlSecImpl/sendEndElement **************************
288 : *
289 : * NAME
290 : * sendEndElement -- Constructs a endElement SAX event
291 : *
292 : * SYNOPSIS
293 : * sendEndElement(xHandler, xHandler2, pNode);
294 : *
295 : * FUNCTION
296 : * Used when converting the document into SAX event stream.
297 : * This method constructs a endElement SAX event for a particular
298 : * element, then calls the endElement methods of the XDocumentHandlers.
299 : *
300 : * INPUTS
301 : * xHandler - the first XDocumentHandler interface to receive the
302 : * endElement SAX event. It can be NULL.
303 : * xHandler2 - the second XDocumentHandler interface to receive the
304 : * endElement SAX event. It can't be NULL.
305 : * pNode - the node on which the endElement should be generated.
306 : * This node must be a element type.
307 : *
308 : * RESULT
309 : * empty
310 : *
311 : * AUTHOR
312 : * Michael Mi
313 : * Email: michael.mi@sun.com
314 : ******************************************************************************/
315 : {
316 0 : OString sNodeName = getNodeQName(pNode);
317 :
318 0 : if (xHandler.is())
319 : {
320 0 : xHandler->endElement(OUString(C2U ( sNodeName.getStr() )));
321 : }
322 :
323 0 : xHandler2->endElement(OUString(C2U ( sNodeName.getStr() )));
324 0 : }
325 :
326 0 : void XMLDocumentWrapper_XmlSecImpl::sendNode(
327 : const cssu::Reference< cssxs::XDocumentHandler >& xHandler,
328 : const cssu::Reference< cssxs::XDocumentHandler >& xHandler2,
329 : const xmlNodePtr pNode)
330 : throw (cssxs::SAXException)
331 : /****** XMLDocumentWrapper_XmlSecImpl/sendNode ********************************
332 : *
333 : * NAME
334 : * sendNode -- Constructs a characters SAX event or a
335 : * processingInstruction SAX event
336 : *
337 : * SYNOPSIS
338 : * sendNode(xHandler, xHandler2, pNode);
339 : *
340 : * FUNCTION
341 : * Used when converting the document into SAX event stream.
342 : * This method constructs a characters SAX event or a
343 : * processingInstructionfor SAX event based on the type of a particular
344 : * element, then calls the corresponding methods of the XDocumentHandlers.
345 : *
346 : * INPUTS
347 : * xHandler - the first XDocumentHandler interface to receive the
348 : * SAX event. It can be NULL.
349 : * xHandler2 - the second XDocumentHandler interface to receive the
350 : * SAX event. It can't be NULL.
351 : * pNode - the node on which the endElement should be generated.
352 : * If it is a text node, then a characters SAX event is
353 : * generated; if it is a PI node, then a
354 : * processingInstructionfor SAX event is generated.
355 : *
356 : * RESULT
357 : * empty
358 : *
359 : * AUTHOR
360 : * Michael Mi
361 : * Email: michael.mi@sun.com
362 : ******************************************************************************/
363 : {
364 0 : xmlElementType type = pNode->type;
365 :
366 0 : if (type == XML_TEXT_NODE)
367 : {
368 0 : if (xHandler.is())
369 : {
370 0 : xHandler->characters(OUString(C2U ( reinterpret_cast<char*>(pNode->content) )));
371 : }
372 :
373 0 : xHandler2->characters(OUString(C2U ( reinterpret_cast<char*>(pNode->content) )));
374 : }
375 0 : else if (type == XML_PI_NODE)
376 : {
377 0 : if (xHandler.is())
378 : {
379 0 : xHandler->processingInstruction(
380 0 : OUString(C2U ( reinterpret_cast<char const *>(pNode->name) )),
381 0 : OUString(C2U ( reinterpret_cast<char const *>(pNode->content) )));
382 : }
383 :
384 0 : xHandler2->processingInstruction(
385 0 : OUString(C2U ( reinterpret_cast<char const *>(pNode->name) )),
386 0 : OUString(C2U ( reinterpret_cast<char*>(pNode->content) )));
387 : }
388 0 : }
389 :
390 0 : OString XMLDocumentWrapper_XmlSecImpl::getNodeQName(const xmlNodePtr pNode)
391 : /****** XMLDocumentWrapper_XmlSecImpl/getNodeQName ****************************
392 : *
393 : * NAME
394 : * getNodeQName -- Retrieves the qualified name of a node
395 : *
396 : * SYNOPSIS
397 : * name = getNodeQName(pNode);
398 : *
399 : * FUNCTION
400 : * see NAME
401 : *
402 : * INPUTS
403 : * pNode - the node whose name will be retrieved
404 : *
405 : * RESULT
406 : * name - the node's qualified name
407 : *
408 : * AUTHOR
409 : * Michael Mi
410 : * Email: michael.mi@sun.com
411 : ******************************************************************************/
412 : {
413 0 : OString sNodeName(reinterpret_cast<const char*>(pNode->name));
414 0 : if (pNode->ns != NULL)
415 : {
416 0 : xmlNsPtr pNs = pNode->ns;
417 :
418 0 : if (pNs->prefix != NULL)
419 : {
420 0 : OString sPrefix(reinterpret_cast<const char*>(pNs->prefix));
421 0 : sNodeName = sPrefix+OString(":")+sNodeName;
422 : }
423 : }
424 :
425 0 : return sNodeName;
426 : }
427 :
428 0 : xmlNodePtr XMLDocumentWrapper_XmlSecImpl::checkElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement)
429 : /****** XMLDocumentWrapper_XmlSecImpl/checkElement ****************************
430 : *
431 : * NAME
432 : * checkElement -- Retrieves the node wrapped by an XXMLElementWrapper
433 : * interface
434 : *
435 : * SYNOPSIS
436 : * node = checkElement(xXMLElement);
437 : *
438 : * FUNCTION
439 : * see NAME
440 : *
441 : * INPUTS
442 : * xXMLElement - the XXMLElementWrapper interface wraping a node
443 : *
444 : * RESULT
445 : * node - the node wrapped in the XXMLElementWrapper interface
446 : *
447 : * AUTHOR
448 : * Michael Mi
449 : * Email: michael.mi@sun.com
450 : ******************************************************************************/
451 : {
452 0 : xmlNodePtr rc = NULL;
453 :
454 0 : if (xXMLElement.is())
455 : {
456 0 : cssu::Reference< cssl::XUnoTunnel > xNodTunnel( xXMLElement, cssu::UNO_QUERY ) ;
457 0 : if( !xNodTunnel.is() )
458 : {
459 0 : throw cssu::RuntimeException() ;
460 : }
461 :
462 : XMLElementWrapper_XmlSecImpl* pElement
463 : = reinterpret_cast<XMLElementWrapper_XmlSecImpl*>(
464 : sal::static_int_cast<sal_uIntPtr>(
465 0 : xNodTunnel->getSomething(
466 0 : XMLElementWrapper_XmlSecImpl::getUnoTunnelImplementationId() ))) ;
467 :
468 0 : if( pElement == NULL ) {
469 0 : throw cssu::RuntimeException() ;
470 : }
471 :
472 0 : rc = pElement->getNativeElement();
473 : }
474 :
475 0 : return rc;
476 : }
477 :
478 0 : sal_Int32 XMLDocumentWrapper_XmlSecImpl::recursiveDelete(
479 : const xmlNodePtr pNode)
480 : /****** XMLDocumentWrapper_XmlSecImpl/recursiveDelete *************************
481 : *
482 : * NAME
483 : * recursiveDelete -- Deletes a particular node with its branch.
484 : *
485 : * SYNOPSIS
486 : * result = recursiveDelete(pNode);
487 : *
488 : * FUNCTION
489 : * Deletes a particular node with its branch, while reserving the nodes
490 : * (and their brance) listed in the m_aReservedNodes.
491 : * The deletion process is preformed in the tree order, that is, a node
492 : * is deleted after its previous sibling node is deleted, a parent node
493 : * is deleted after its branch is deleted.
494 : * During the deletion process when the m_pStopAtNode is reached, the
495 : * progress is interrupted at once.
496 : *
497 : * INPUTS
498 : * pNode - the node to be deleted
499 : *
500 : * RESULT
501 : * result - the result of the deletion process, can be one of following
502 : * values:
503 : * NODE_STOPED - the process is interrupted by meeting the
504 : * m_pStopAtNode
505 : * NODE_NOTREMOVED - the pNode is not completely removed
506 : * because there is its descendant in the
507 : * m_aReservedNodes list
508 : * NODE_REMOVED - the pNode and its branch are completely
509 : * removed
510 : *
511 : * NOTES
512 : * The node in the m_aReservedNodes list must be in the tree order, otherwise
513 : * the result is unpredictable.
514 : *
515 : * AUTHOR
516 : * Michael Mi
517 : * Email: michael.mi@sun.com
518 : ******************************************************************************/
519 : {
520 0 : if (pNode == m_pStopAtNode)
521 : {
522 0 : return NODE_STOPED;
523 : }
524 :
525 0 : if (pNode != m_pCurrentReservedNode)
526 : {
527 0 : xmlNodePtr pChild = pNode->children;
528 :
529 : xmlNodePtr pNextSibling;
530 0 : bool bIsRemoved = true;
531 : sal_Int32 nResult;
532 :
533 0 : while( pChild != NULL )
534 : {
535 0 : pNextSibling = pChild->next;
536 0 : nResult = recursiveDelete(pChild);
537 :
538 0 : switch (nResult)
539 : {
540 : case NODE_STOPED:
541 0 : return NODE_STOPED;
542 : case NODE_NOTREMOVED:
543 0 : bIsRemoved = false;
544 0 : break;
545 : case NODE_REMOVED:
546 0 : removeNode(pChild);
547 0 : break;
548 : default:
549 0 : throw cssu::RuntimeException();
550 : }
551 :
552 0 : pChild = pNextSibling;
553 : }
554 :
555 0 : if (pNode == m_pCurrentElement)
556 : {
557 0 : bIsRemoved = false;
558 : }
559 :
560 0 : return bIsRemoved?NODE_REMOVED:NODE_NOTREMOVED;
561 : }
562 : else
563 : {
564 0 : getNextReservedNode();
565 0 : return NODE_NOTREMOVED;
566 : }
567 : }
568 :
569 0 : void XMLDocumentWrapper_XmlSecImpl::getNextReservedNode()
570 : /****** XMLDocumentWrapper_XmlSecImpl/getNextReservedNode *********************
571 : *
572 : * NAME
573 : * getNextReservedNode -- Highlights the next reserved node in the
574 : * reserved node list
575 : *
576 : * SYNOPSIS
577 : * getNextReservedNode();
578 : *
579 : * FUNCTION
580 : * The m_aReservedNodes array holds a node list, while the
581 : * m_pCurrentReservedNode points to the one currently highlighted.
582 : * This method is used to highlight the next node in the node list.
583 : * This method is called at the time when the current highlighted node
584 : * has been already processed, and the next node should be ready.
585 : *
586 : * INPUTS
587 : * empty
588 : *
589 : * RESULT
590 : * empty
591 : *
592 : * AUTHOR
593 : * Michael Mi
594 : * Email: michael.mi@sun.com
595 : ******************************************************************************/
596 : {
597 0 : if (m_nReservedNodeIndex < m_aReservedNodes.getLength())
598 : {
599 0 : m_pCurrentReservedNode = checkElement( m_aReservedNodes[m_nReservedNodeIndex] );
600 0 : m_nReservedNodeIndex ++;
601 : }
602 : else
603 : {
604 0 : m_pCurrentReservedNode = NULL;
605 : }
606 0 : }
607 :
608 0 : void XMLDocumentWrapper_XmlSecImpl::removeNode(const xmlNodePtr pNode) const
609 : /****** XMLDocumentWrapper_XmlSecImpl/removeNode ******************************
610 : *
611 : * NAME
612 : * removeNode -- Deletes a node with its branch unconditionaly
613 : *
614 : * SYNOPSIS
615 : * removeNode( pNode );
616 : *
617 : * FUNCTION
618 : * Delete the node along with its branch from the document.
619 : *
620 : * INPUTS
621 : * pNode - the node to be deleted
622 : *
623 : * RESULT
624 : * empty
625 : *
626 : * AUTHOR
627 : * Michael Mi
628 : * Email: michael.mi@sun.com
629 : ******************************************************************************/
630 : {
631 : /* you can't remove the current node */
632 : OSL_ASSERT( m_pCurrentElement != pNode );
633 :
634 0 : xmlAttrPtr pAttr = pNode->properties;
635 :
636 0 : while (pAttr != NULL)
637 : {
638 0 : if (!stricmp(reinterpret_cast<char const *>(pAttr->name), "id"))
639 : {
640 0 : xmlRemoveID(m_pDocument, pAttr);
641 : }
642 :
643 0 : pAttr = pAttr->next;
644 : }
645 :
646 0 : xmlUnlinkNode(pNode);
647 0 : xmlFreeNode(pNode);
648 0 : }
649 :
650 0 : void XMLDocumentWrapper_XmlSecImpl::buildIDAttr(xmlNodePtr pNode) const
651 : /****** XMLDocumentWrapper_XmlSecImpl/buildIDAttr *****************************
652 : *
653 : * NAME
654 : * buildIDAttr -- build the ID attribute of a node
655 : *
656 : * SYNOPSIS
657 : * buildIDAttr( pNode );
658 : *
659 : * FUNCTION
660 : * see NAME
661 : *
662 : * INPUTS
663 : * pNode - the node whose id attribute will be built
664 : *
665 : * RESULT
666 : * empty
667 : *
668 : * AUTHOR
669 : * Michael Mi
670 : * Email: michael.mi@sun.com
671 : ******************************************************************************/
672 : {
673 0 : xmlAttrPtr idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("id") );
674 0 : if (idAttr == NULL)
675 : {
676 0 : idAttr = xmlHasProp( pNode, reinterpret_cast<const unsigned char *>("Id") );
677 : }
678 :
679 0 : if (idAttr != NULL)
680 : {
681 0 : xmlChar* idValue = xmlNodeListGetString( m_pDocument, idAttr->children, 1 ) ;
682 0 : xmlAddID( NULL, m_pDocument, idValue, idAttr );
683 : }
684 0 : }
685 :
686 0 : void XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(xmlNodePtr pNode) const
687 : /****** XMLDocumentWrapper_XmlSecImpl/rebuildIDLink ***************************
688 : *
689 : * NAME
690 : * rebuildIDLink -- rebuild the ID link for the branch
691 : *
692 : * SYNOPSIS
693 : * rebuildIDLink( pNode );
694 : *
695 : * FUNCTION
696 : * see NAME
697 : *
698 : * INPUTS
699 : * pNode - the node, from which the branch will be rebuilt
700 : *
701 : * RESULT
702 : * empty
703 : *
704 : * AUTHOR
705 : * Michael Mi
706 : * Email: michael.mi@sun.com
707 : ******************************************************************************/
708 : {
709 0 : if (pNode != NULL && pNode->type == XML_ELEMENT_NODE)
710 : {
711 0 : buildIDAttr( pNode );
712 :
713 0 : xmlNodePtr child = pNode->children;
714 0 : while (child != NULL)
715 : {
716 0 : rebuildIDLink(child);
717 0 : child = child->next;
718 : }
719 : }
720 0 : }
721 :
722 : /* XXMLDocumentWrapper */
723 0 : cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getCurrentElement( )
724 : throw (cssu::RuntimeException, std::exception)
725 : {
726 0 : XMLElementWrapper_XmlSecImpl* pElement = new XMLElementWrapper_XmlSecImpl(m_pCurrentElement);
727 0 : return cssu::Reference< cssxw::XXMLElementWrapper >(pElement);
728 : }
729 :
730 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setCurrentElement( const cssu::Reference< cssxw::XXMLElementWrapper >& element )
731 : throw (cssu::RuntimeException, std::exception)
732 : {
733 0 : m_pCurrentElement = checkElement( element );
734 0 : saxHelper.setCurrentNode( m_pCurrentElement );
735 0 : }
736 :
737 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::removeCurrentElement( )
738 : throw (cssu::RuntimeException, std::exception)
739 : {
740 : OSL_ASSERT( m_pCurrentElement != NULL );
741 :
742 0 : xmlNodePtr pOldCurrentElement = m_pCurrentElement;
743 :
744 : /*
745 : * pop the top node in the parser context's
746 : * nodeTab stack, then the parent of that node will
747 : * automatically become the new stack top, and
748 : * the current node as well.
749 : */
750 : saxHelper.endElement(
751 : OUString(
752 0 : C2U (
753 : reinterpret_cast<char const *>(pOldCurrentElement->name)
754 0 : )));
755 0 : m_pCurrentElement = saxHelper.getCurrentNode();
756 :
757 : /*
758 : * remove the node
759 : */
760 0 : removeNode(pOldCurrentElement);
761 0 : }
762 :
763 0 : sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrent( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
764 : throw (cssu::RuntimeException, std::exception)
765 : {
766 0 : xmlNodePtr pNode = checkElement(node);
767 0 : return (pNode == m_pCurrentElement);
768 : }
769 :
770 0 : sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::isCurrentElementEmpty( )
771 : throw (cssu::RuntimeException, std::exception)
772 : {
773 0 : bool rc = false;
774 :
775 0 : if (m_pCurrentElement->children == NULL)
776 : {
777 0 : rc = true;
778 : }
779 :
780 0 : return rc;
781 : }
782 :
783 0 : OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getNodeName( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
784 : throw (cssu::RuntimeException, std::exception)
785 : {
786 0 : xmlNodePtr pNode = checkElement(node);
787 0 : return OUString(C2U ( reinterpret_cast<char const *>(pNode->name) ));
788 : }
789 :
790 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::clearUselessData(
791 : const cssu::Reference< cssxw::XXMLElementWrapper >& node,
792 : const cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >& reservedDescendants,
793 : const cssu::Reference< cssxw::XXMLElementWrapper >& stopAtNode )
794 : throw (cssu::RuntimeException, std::exception)
795 : {
796 0 : xmlNodePtr pTargetNode = checkElement(node);
797 :
798 0 : m_pStopAtNode = checkElement(stopAtNode);
799 0 : m_aReservedNodes = reservedDescendants;
800 0 : m_nReservedNodeIndex = 0;
801 :
802 0 : getNextReservedNode();
803 :
804 0 : recursiveDelete(pTargetNode);
805 0 : }
806 :
807 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::collapse( const cssu::Reference< cssxw::XXMLElementWrapper >& node )
808 : throw (cssu::RuntimeException, std::exception)
809 : {
810 0 : xmlNodePtr pTargetNode = checkElement(node);
811 : xmlNodePtr pParent;
812 :
813 0 : while (pTargetNode != NULL)
814 : {
815 0 : if (pTargetNode->children != NULL || pTargetNode == m_pCurrentElement)
816 : {
817 : break;
818 : }
819 :
820 0 : pParent = pTargetNode->parent;
821 0 : removeNode(pTargetNode);
822 0 : pTargetNode = pParent;
823 : }
824 0 : }
825 :
826 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::getTree( const cssu::Reference< cssxs::XDocumentHandler >& handler )
827 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
828 : {
829 0 : if (m_pRootElement != NULL)
830 : {
831 0 : xmlNodePtr pTempCurrentElement = m_pCurrentElement;
832 0 : sal_Int32 nTempCurrentPosition = m_nCurrentPosition;
833 :
834 0 : m_pCurrentElement = m_pRootElement;
835 :
836 0 : m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
837 0 : cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
838 :
839 : while(true)
840 : {
841 0 : switch (m_nCurrentPosition)
842 : {
843 : case NODEPOSITION_STARTELEMENT:
844 0 : sendStartElement(NULL, xHandler, m_pCurrentElement);
845 0 : break;
846 : case NODEPOSITION_ENDELEMENT:
847 0 : sendEndElement(NULL, xHandler, m_pCurrentElement);
848 0 : break;
849 : case NODEPOSITION_NORMAL:
850 0 : sendNode(NULL, xHandler, m_pCurrentElement);
851 0 : break;
852 : }
853 :
854 0 : if ( (m_pCurrentElement == m_pRootElement) && (m_nCurrentPosition == NODEPOSITION_ENDELEMENT ))
855 : {
856 0 : break;
857 : }
858 :
859 0 : getNextSAXEvent();
860 : }
861 :
862 0 : m_pCurrentElement = pTempCurrentElement;
863 0 : m_nCurrentPosition = nTempCurrentPosition;
864 : }
865 0 : }
866 :
867 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::generateSAXEvents(
868 : const cssu::Reference< cssxs::XDocumentHandler >& handler,
869 : const cssu::Reference< cssxs::XDocumentHandler >& xEventKeeperHandler,
870 : const cssu::Reference< cssxw::XXMLElementWrapper >& startNode,
871 : const cssu::Reference< cssxw::XXMLElementWrapper >& endNode )
872 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
873 : {
874 : /*
875 : * The first SAX event is the startElement of the startNode
876 : * element.
877 : */
878 0 : bool bHasCurrentElementChild = (m_pCurrentElement->children != NULL);
879 :
880 0 : xmlNodePtr pTempCurrentElement = m_pCurrentElement;
881 :
882 0 : m_pCurrentElement = checkElement(startNode);
883 :
884 0 : if (m_pCurrentElement->type == XML_ELEMENT_NODE)
885 : {
886 0 : m_nCurrentPosition = NODEPOSITION_STARTELEMENT;
887 : }
888 : else
889 : {
890 0 : m_nCurrentPosition = NODEPOSITION_NORMAL;
891 : }
892 :
893 0 : xmlNodePtr pEndNode = checkElement(endNode);
894 :
895 0 : cssu::Reference < cssxc::sax::XSAXEventKeeper > xSAXEventKeeper( xEventKeeperHandler, cssu::UNO_QUERY );
896 :
897 0 : cssu::Reference< cssxs::XDocumentHandler > xHandler = handler;
898 :
899 : while(true)
900 : {
901 0 : switch (m_nCurrentPosition)
902 : {
903 : case NODEPOSITION_STARTELEMENT:
904 0 : sendStartElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
905 0 : break;
906 : case NODEPOSITION_ENDELEMENT:
907 0 : sendEndElement(xHandler, xEventKeeperHandler, m_pCurrentElement);
908 0 : break;
909 : case NODEPOSITION_NORMAL:
910 0 : sendNode(xHandler, xEventKeeperHandler, m_pCurrentElement);
911 0 : break;
912 : default:
913 0 : throw cssu::RuntimeException();
914 : }
915 :
916 0 : if (xSAXEventKeeper->isBlocking())
917 : {
918 0 : xHandler = NULL;
919 : }
920 :
921 0 : if (pEndNode == NULL &&
922 0 : ((bHasCurrentElementChild && m_pCurrentElement == xmlGetLastChild(pTempCurrentElement) && m_nCurrentPosition != NODEPOSITION_STARTELEMENT) ||
923 0 : (!bHasCurrentElementChild && m_pCurrentElement == pTempCurrentElement && m_nCurrentPosition == NODEPOSITION_STARTELEMENT)))
924 : {
925 0 : break;
926 : }
927 :
928 0 : getNextSAXEvent();
929 :
930 : /*
931 : * If there is an end point specified, then check whether
932 : * the current node equals to the end point. If so, stop
933 : * generating.
934 : */
935 0 : if (pEndNode != NULL && m_pCurrentElement == pEndNode)
936 : {
937 0 : break;
938 : }
939 : }
940 :
941 0 : m_pCurrentElement = pTempCurrentElement;
942 0 : }
943 :
944 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::rebuildIDLink(
945 : const com::sun::star::uno::Reference< com::sun::star::xml::wrapper::XXMLElementWrapper >& node )
946 : throw (com::sun::star::uno::RuntimeException, std::exception)
947 : {
948 0 : xmlNodePtr pNode = checkElement( node );
949 0 : rebuildIDLink(pNode);
950 0 : }
951 :
952 :
953 : /* cssxs::XDocumentHandler */
954 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startDocument( )
955 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
956 : {
957 0 : }
958 :
959 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endDocument( )
960 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
961 : {
962 0 : }
963 :
964 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::startElement( const OUString& aName, const cssu::Reference< cssxs::XAttributeList >& xAttribs )
965 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
966 : {
967 0 : sal_Int32 nLength = xAttribs->getLength();
968 0 : cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
969 :
970 0 : for (int i = 0; i < nLength; ++i)
971 : {
972 0 : aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
973 0 : aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
974 : }
975 :
976 0 : compressedStartElement(aName, aAttributes);
977 0 : }
978 :
979 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::endElement( const OUString& aName )
980 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
981 : {
982 0 : saxHelper.endElement(aName);
983 0 : m_pCurrentElement = saxHelper.getCurrentNode();
984 0 : }
985 :
986 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::characters( const OUString& aChars )
987 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
988 : {
989 0 : saxHelper.characters(aChars);
990 0 : }
991 :
992 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::ignorableWhitespace( const OUString& aWhitespaces )
993 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
994 : {
995 0 : saxHelper.ignorableWhitespace(aWhitespaces);
996 0 : }
997 :
998 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::processingInstruction( const OUString& aTarget, const OUString& aData )
999 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1000 : {
1001 0 : saxHelper.processingInstruction(aTarget, aData);
1002 0 : }
1003 :
1004 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >& )
1005 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1006 : {
1007 0 : }
1008 :
1009 : /* XCompressedDocumentHandler */
1010 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartDocument( )
1011 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1012 : {
1013 0 : }
1014 :
1015 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndDocument( )
1016 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1017 : {
1018 0 : }
1019 :
1020 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedStartElement( const OUString& aName, const cssu::Sequence< cssxcsax::XMLAttribute >& aAttributes )
1021 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1022 : {
1023 0 : saxHelper.startElement(aName, aAttributes);
1024 0 : m_pCurrentElement = saxHelper.getCurrentNode();
1025 :
1026 0 : buildIDAttr( m_pCurrentElement );
1027 0 : }
1028 :
1029 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedEndElement( const OUString& aName )
1030 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1031 : {
1032 0 : endElement( aName );
1033 0 : }
1034 :
1035 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedCharacters( const OUString& aChars )
1036 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1037 : {
1038 0 : characters( aChars );
1039 0 : }
1040 :
1041 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedIgnorableWhitespace( const OUString& aWhitespaces )
1042 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1043 : {
1044 0 : ignorableWhitespace( aWhitespaces );
1045 0 : }
1046 :
1047 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedProcessingInstruction( const OUString& aTarget, const OUString& aData )
1048 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1049 : {
1050 0 : processingInstruction( aTarget, aData );
1051 0 : }
1052 :
1053 0 : void SAL_CALL XMLDocumentWrapper_XmlSecImpl::compressedSetDocumentLocator( sal_Int32 /*columnNumber*/, sal_Int32 /*lineNumber*/, const OUString& /*publicId*/, const OUString& /*systemId*/ )
1054 : throw (cssxs::SAXException, cssu::RuntimeException, std::exception)
1055 : {
1056 0 : }
1057 :
1058 11 : OUString XMLDocumentWrapper_XmlSecImpl_getImplementationName ()
1059 : throw (cssu::RuntimeException)
1060 : {
1061 11 : return OUString ( IMPLEMENTATION_NAME );
1062 : }
1063 :
1064 2 : cssu::Sequence< OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames( )
1065 : throw (cssu::RuntimeException)
1066 : {
1067 2 : cssu::Sequence < OUString > aRet(1);
1068 2 : OUString* pArray = aRet.getArray();
1069 2 : pArray[0] = "com.sun.star.xml.wrapper.XMLDocumentWrapper";
1070 2 : return aRet;
1071 : }
1072 :
1073 1 : cssu::Reference< cssu::XInterface > SAL_CALL XMLDocumentWrapper_XmlSecImpl_createInstance(
1074 : const cssu::Reference< cssu::XComponentContext > &)
1075 : throw( cssu::Exception )
1076 : {
1077 1 : return static_cast<cppu::OWeakObject*>(new XMLDocumentWrapper_XmlSecImpl( ));
1078 : }
1079 :
1080 : /* XServiceInfo */
1081 1 : OUString SAL_CALL XMLDocumentWrapper_XmlSecImpl::getImplementationName( )
1082 : throw (cssu::RuntimeException, std::exception)
1083 : {
1084 1 : return XMLDocumentWrapper_XmlSecImpl_getImplementationName();
1085 : }
1086 0 : sal_Bool SAL_CALL XMLDocumentWrapper_XmlSecImpl::supportsService( const OUString& rServiceName )
1087 : throw (cssu::RuntimeException, std::exception)
1088 : {
1089 0 : return cppu::supportsService( this, rServiceName );
1090 : }
1091 1 : cssu::Sequence< OUString > SAL_CALL XMLDocumentWrapper_XmlSecImpl::getSupportedServiceNames( )
1092 : throw (cssu::RuntimeException, std::exception)
1093 : {
1094 1 : return XMLDocumentWrapper_XmlSecImpl_getSupportedServiceNames();
1095 : }
1096 :
1097 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|