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