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