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 "saxeventkeeperimpl.hxx"
22 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
23 : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
24 : #include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp>
25 :
26 : namespace cssu = com::sun::star::uno;
27 : namespace cssl = com::sun::star::lang;
28 : namespace cssxc = com::sun::star::xml::crypto;
29 : namespace cssxcsax = com::sun::star::xml::csax;
30 : namespace cssxw = com::sun::star::xml::wrapper;
31 : namespace cssxs = com::sun::star::xml::sax;
32 :
33 : #define SERVICE_NAME "com.sun.star.xml.crypto.sax.SAXEventKeeper"
34 : #define IMPLEMENTATION_NAME "com.sun.star.xml.security.framework.SAXEventKeeperImpl"
35 :
36 : #define _USECOMPRESSEDDOCUMENTHANDLER
37 :
38 0 : SAXEventKeeperImpl::SAXEventKeeperImpl( )
39 : :m_pRootBufferNode(NULL),
40 : m_pCurrentBufferNode(NULL),
41 : m_nNextElementMarkId(1),
42 : m_pNewBlocker(NULL),
43 : m_pCurrentBlockingBufferNode(NULL),
44 : m_bIsReleasing(false),
45 0 : m_bIsForwarding(false)
46 : {
47 0 : m_vElementMarkBuffers.reserve(2);
48 0 : m_vNewElementCollectors.reserve(2);
49 0 : m_vReleasedElementMarkBuffers.reserve(2);
50 0 : }
51 :
52 0 : SAXEventKeeperImpl::~SAXEventKeeperImpl()
53 : {
54 : /*
55 : * delete the BufferNode tree
56 : */
57 0 : if (m_pRootBufferNode != NULL)
58 : {
59 0 : m_pRootBufferNode->freeAllChildren();
60 0 : delete m_pRootBufferNode;
61 : }
62 :
63 0 : m_pRootBufferNode = m_pCurrentBufferNode = m_pCurrentBlockingBufferNode = NULL;
64 :
65 : /*
66 : * delete all unfreed ElementMarks
67 : */
68 0 : m_vNewElementCollectors.clear();
69 0 : m_pNewBlocker = NULL;
70 :
71 0 : std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin();
72 0 : for( ; ii != m_vElementMarkBuffers.end(); ++ii )
73 : {
74 0 : delete (*ii);
75 : }
76 0 : m_vElementMarkBuffers.clear();
77 0 : }
78 :
79 0 : void SAXEventKeeperImpl::setCurrentBufferNode(BufferNode* pBufferNode)
80 : /****** SAXEventKeeperImpl/setCurrentBufferNode ******************************
81 : *
82 : * NAME
83 : * setCurrentBufferNode -- set a new active BufferNode.
84 : *
85 : * SYNOPSIS
86 : * setCurrentBufferNode( pBufferNode );
87 : *
88 : * FUNCTION
89 : * connects this BufferNode into the BufferNode tree as a child of the
90 : * current active BufferNode. Then makes this BufferNode as the current
91 : * active BufferNode.
92 : * If the previous active BufferNode points to the root
93 : * BufferNode, which means that no buffering operation was proceeding,
94 : * then notifies the status change listener that buffering operation
95 : * will begin at once.
96 : *
97 : * INPUTS
98 : * pBufferNode - a BufferNode which will be the new active BufferNode
99 : *
100 : * RESULT
101 : * empty
102 : *
103 : * AUTHOR
104 : * Michael Mi
105 : * Email: michael.mi@sun.com
106 : ******************************************************************************/
107 : {
108 0 : if (pBufferNode != m_pCurrentBufferNode)
109 : {
110 0 : if ( m_pCurrentBufferNode == m_pRootBufferNode &&
111 0 : m_xSAXEventKeeperStatusChangeListener.is())
112 : {
113 0 : m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_True);
114 : }
115 :
116 0 : if (pBufferNode->getParent() == NULL)
117 : {
118 0 : m_pCurrentBufferNode->addChild(pBufferNode);
119 0 : pBufferNode->setParent(m_pCurrentBufferNode);
120 : }
121 :
122 0 : m_pCurrentBufferNode = pBufferNode;
123 : }
124 0 : }
125 :
126 0 : BufferNode* SAXEventKeeperImpl::addNewElementMarkBuffers()
127 : /****** SAXEventKeeperImpl/addNewElementMarkBuffers **************************
128 : *
129 : * NAME
130 : * addNewElementMarkBuffers -- add new ElementCollectors and new Blocker.
131 : *
132 : * SYNOPSIS
133 : * pBufferNode = addNewElementMarkBuffers( );
134 : *
135 : * FUNCTION
136 : * if there are new ElementCollector or new Blocker to be added, then
137 : * connect all of them with the current BufferNode. In case of the
138 : * current BufferNode doesn't exist, creates one.
139 : * Clears up the new ElementCollector list and the new Blocker pointer.
140 : *
141 : * INPUTS
142 : * empty
143 : *
144 : * RESULT
145 : * pBufferNode - the BufferNode that has been connected with both new
146 : * ElementCollectors and new Blocker.
147 : *
148 : * AUTHOR
149 : * Michael Mi
150 : * Email: michael.mi@sun.com
151 : ******************************************************************************/
152 : {
153 0 : BufferNode* pBufferNode = NULL;
154 :
155 0 : if (m_pNewBlocker || !m_vNewElementCollectors.empty() )
156 : {
157 : /*
158 : * When the current BufferNode is right pointing to the current
159 : * working element in the XMLDocumentWrapper component, then
160 : * no new BufferNode is needed to create.
161 : * This situation can only happen in the "Forwarding" mode.
162 : */
163 0 : if ( (m_pCurrentBufferNode != NULL) &&
164 0 : (m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement())))
165 : {
166 0 : pBufferNode = m_pCurrentBufferNode;
167 : }
168 : else
169 : {
170 0 : pBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
171 : }
172 :
173 0 : if (m_pNewBlocker != NULL)
174 : {
175 0 : pBufferNode->setBlocker(m_pNewBlocker);
176 :
177 : /*
178 : * If no blocking before, then notify the status change listener that
179 : * the SAXEventKeeper has entered "blocking" status, during which, no
180 : * SAX events will be forwarded to the next document handler.
181 : */
182 0 : if (m_pCurrentBlockingBufferNode == NULL)
183 : {
184 0 : m_pCurrentBlockingBufferNode = pBufferNode;
185 :
186 0 : if (m_xSAXEventKeeperStatusChangeListener.is())
187 : {
188 0 : m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_True);
189 : }
190 : }
191 :
192 0 : m_pNewBlocker = NULL;
193 : }
194 :
195 0 : if (!m_vNewElementCollectors.empty())
196 : {
197 0 : std::vector< const ElementCollector* >::const_iterator ii = m_vNewElementCollectors.begin();
198 :
199 0 : for( ; ii != m_vNewElementCollectors.end(); ++ii )
200 : {
201 0 : pBufferNode->addElementCollector(*ii);
202 : }
203 :
204 0 : m_vNewElementCollectors.clear();
205 : }
206 : }
207 :
208 0 : return pBufferNode;
209 : }
210 :
211 0 : ElementMark* SAXEventKeeperImpl::findElementMarkBuffer(sal_Int32 nId) const
212 : /****** SAXEventKeeperImpl/findElementMarkBuffer *****************************
213 : *
214 : * NAME
215 : * findElementMarkBuffer -- finds an ElementMark.
216 : *
217 : * SYNOPSIS
218 : * pElementMark = findElementMarkBuffer( nId );
219 : *
220 : * FUNCTION
221 : * searches an ElementMark with the particular Id in the ElementMark
222 : * list.
223 : *
224 : * INPUTS
225 : * nId - the Id of the ElementMark to be searched.
226 : *
227 : * RESULT
228 : * pElementMark - the ElementMark with the particular Id, or NULL when
229 : * no such Id exists.
230 : *
231 : * AUTHOR
232 : * Michael Mi
233 : * Email: michael.mi@sun.com
234 : ******************************************************************************/
235 : {
236 0 : ElementMark* pElementMark = NULL;
237 :
238 0 : std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin();
239 :
240 0 : for( ; ii != m_vElementMarkBuffers.end(); ++ii )
241 : {
242 0 : if ( nId == (*ii)->getBufferId())
243 : {
244 0 : pElementMark = (ElementMark*)*ii;
245 0 : break;
246 : }
247 : }
248 :
249 0 : return pElementMark;
250 : }
251 :
252 0 : void SAXEventKeeperImpl::removeElementMarkBuffer(sal_Int32 nId)
253 : /****** SAXEventKeeperImpl/removeElementMarkBuffer ***************************
254 : *
255 : * NAME
256 : * removeElementMarkBuffer -- removes an ElementMark
257 : *
258 : * SYNOPSIS
259 : * removeElementMarkBuffer( nId );
260 : *
261 : * FUNCTION
262 : * removes an ElementMark with the particular Id in the ElementMark list.
263 : *
264 : * INPUTS
265 : * nId - the Id of the ElementMark to be removed.
266 : *
267 : * RESULT
268 : * empty
269 : *
270 : * AUTHOR
271 : * Michael Mi
272 : * Email: michael.mi@sun.com
273 : ******************************************************************************/
274 : {
275 0 : std::vector< const ElementMark* >::iterator ii = m_vElementMarkBuffers.begin();
276 :
277 0 : for( ; ii != m_vElementMarkBuffers.end(); ++ii )
278 : {
279 0 : if ( nId == (*ii)->getBufferId())
280 : {
281 : /*
282 : * checks whether this ElementMark still in the new ElementCollect array
283 : */
284 0 : std::vector< const ElementCollector* >::iterator jj = m_vNewElementCollectors.begin();
285 0 : for( ; jj != m_vNewElementCollectors.end(); ++jj )
286 : {
287 0 : if ((*ii) == (*jj))
288 : {
289 0 : m_vNewElementCollectors.erase(jj);
290 0 : break;
291 : }
292 : }
293 :
294 : /*
295 : * checks whether this ElementMark is the new Blocker
296 : */
297 0 : if ((*ii) == m_pNewBlocker)
298 : {
299 0 : m_pNewBlocker = NULL;
300 : }
301 :
302 : /*
303 : * destory the ElementMark
304 : */
305 0 : delete (*ii);
306 :
307 0 : m_vElementMarkBuffers.erase( ii );
308 : break;
309 : }
310 : }
311 0 : }
312 :
313 0 : rtl::OUString SAXEventKeeperImpl::printBufferNode(
314 : BufferNode* pBufferNode, sal_Int32 nIndent) const
315 : /****** SAXEventKeeperImpl/printBufferNode ***********************************
316 : *
317 : * NAME
318 : * printBufferNode -- retrieves the information of a BufferNode and its
319 : * branch.
320 : *
321 : * SYNOPSIS
322 : * info = printBufferNode( pBufferNode, nIndent );
323 : *
324 : * FUNCTION
325 : * all retrieved information includes:
326 : * 1. whether it is the current BufferNode;
327 : * 2. whether it is the current blocking BufferNode;
328 : * 3. the name of the parent element;
329 : * 4. the name of this element;
330 : * 5. all ElementCollectors working on this BufferNode;
331 : * 6. the Blocker working on this BufferNode;
332 : * 7. all child BufferNodes' information.
333 : *
334 : * INPUTS
335 : * pBufferNode - the BufferNode from where information will be retrieved.
336 : * nIndent - how many space characters prefixed before the output
337 : * message.
338 : *
339 : * RESULT
340 : * info - the information string
341 : *
342 : * AUTHOR
343 : * Michael Mi
344 : * Email: michael.mi@sun.com
345 : ******************************************************************************/
346 : {
347 0 : rtl::OUString rc;
348 :
349 0 : for ( int i=0; i<nIndent; ++i )
350 : {
351 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
352 : }
353 :
354 0 : if (pBufferNode == m_pCurrentBufferNode)
355 : {
356 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[%]" ));
357 : }
358 :
359 0 : if (pBufferNode == m_pCurrentBlockingBufferNode)
360 : {
361 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[B]" ));
362 : }
363 :
364 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
365 0 : rc += m_xXMLDocument->getNodeName(pBufferNode->getXMLElement());
366 :
367 0 : BufferNode* pParent = (BufferNode*)pBufferNode->getParent();
368 0 : if (pParent != NULL)
369 : {
370 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[" ));
371 0 : rc += m_xXMLDocument->getNodeName(pParent->getXMLElement());
372 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "]" ));
373 : }
374 :
375 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":EC=" ));
376 0 : rc += pBufferNode->printChildren();
377 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " BR=" ));
378 :
379 0 : ElementMark * pBlocker = pBufferNode->getBlocker();
380 0 : if (pBlocker != NULL)
381 : {
382 0 : rc += rtl::OUString::valueOf( pBlocker->getBufferId() );
383 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(SecId=" ));
384 0 : rc += rtl::OUString::valueOf( pBlocker->getSecurityId() );
385 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ));
386 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
387 : }
388 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
389 :
390 0 : std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
391 0 : std::vector< const BufferNode* >::const_iterator jj = vChildren->begin();
392 0 : for( ; jj != vChildren->end(); ++jj )
393 : {
394 0 : rc += printBufferNode((BufferNode *)*jj, nIndent+4);
395 : }
396 :
397 0 : delete vChildren;
398 :
399 0 : return rc;
400 : }
401 :
402 : cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >
403 0 : SAXEventKeeperImpl::collectChildWorkingElement(BufferNode* pBufferNode) const
404 : /****** SAXEventKeeperImpl/collectChildWorkingElement ************************
405 : *
406 : * NAME
407 : * collectChildWorkingElement -- collects a BufferNode's all child
408 : * Elements.
409 : *
410 : * SYNOPSIS
411 : * list = collectChildWorkingElement( pBufferNode );
412 : *
413 : * FUNCTION
414 : * see NAME.
415 : *
416 : * INPUTS
417 : * pBufferNode - the BufferNode whose child Elements will be collected.
418 : *
419 : * RESULT
420 : * list - the child Elements list.
421 : *
422 : * AUTHOR
423 : * Michael Mi
424 : * Email: michael.mi@sun.com
425 : ******************************************************************************/
426 : {
427 0 : std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
428 :
429 : cssu::Sequence < cssu::Reference<
430 0 : cssxw::XXMLElementWrapper > > aChildrenCollection ( vChildren->size());
431 :
432 0 : std::vector< const BufferNode* >::const_iterator ii = vChildren->begin();
433 :
434 0 : sal_Int32 nIndex = 0;
435 0 : for( ; ii != vChildren->end(); ++ii )
436 : {
437 0 : aChildrenCollection[nIndex] = (*ii)->getXMLElement();
438 0 : nIndex++;
439 : }
440 :
441 0 : delete vChildren;
442 :
443 0 : return aChildrenCollection;
444 : }
445 :
446 0 : void SAXEventKeeperImpl::smashBufferNode(
447 : BufferNode* pBufferNode, bool bClearRoot) const
448 : /****** SAXEventKeeperImpl/smashBufferNode ***********************************
449 : *
450 : * NAME
451 : * smashBufferNode -- removes a BufferNode along with its working
452 : * element.
453 : *
454 : * SYNOPSIS
455 : * smashBufferNode( pBufferNode, bClearRoot );
456 : *
457 : * FUNCTION
458 : * removes the BufferNode's working element from the DOM document, while
459 : * reserves all ancestor paths for its child BufferNodes.
460 : * when any of the BufferNode's ancestor element is useless, removes it
461 : * too.
462 : * removes the BufferNode from the BufferNode tree.
463 : *
464 : * INPUTS
465 : * pBufferNode - the BufferNode to be removed
466 : * bClearRoot - whether the root element also needs to be cleared up.
467 : *
468 : * RESULT
469 : * empty
470 : *
471 : * NOTES
472 : * when removeing a Blocker's BufferNode, the bClearRoot flag should be
473 : * true. Because a Blocker can buffer many SAX events which are not used
474 : * by any other ElementCollector or Blocker.
475 : * When the bClearRoot is set to true, the root BufferNode will be first
476 : * cleared, with a stop flag seting at the next Blocking BufferNode. This
477 : * operation can delete all useless bufferred SAX events which are only
478 : * needed by the Blocker to be deleted.
479 : *
480 : * AUTHOR
481 : * Michael Mi
482 : * Email: michael.mi@sun.com
483 : ******************************************************************************/
484 : {
485 0 : if (!pBufferNode->hasAnything())
486 : {
487 0 : BufferNode* pParent = (BufferNode*)pBufferNode->getParent();
488 :
489 : /*
490 : * delete the XML data
491 : */
492 0 : if (pParent == m_pRootBufferNode)
493 : {
494 0 : bool bIsNotBlocking = (m_pCurrentBlockingBufferNode == NULL);
495 0 : bool bIsBlockInside = false;
496 0 : bool bIsBlockingAfterward = false;
497 :
498 : /*
499 : * If this is a blocker, then remove any out-element data
500 : * which caused by blocking. The removal process will stop
501 : * at the next blokcer to avoid removing any useful data.
502 : */
503 0 : if (bClearRoot)
504 : {
505 : cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >
506 0 : aChildElements = collectChildWorkingElement(m_pRootBufferNode);
507 :
508 : /*
509 : * the clearUselessData only clearup the content in the
510 : * node, not the node itself.
511 : */
512 0 : m_xXMLDocument->clearUselessData(m_pRootBufferNode->getXMLElement(),
513 : aChildElements,
514 : bIsNotBlocking?(NULL):
515 0 : (m_pCurrentBlockingBufferNode->getXMLElement()));
516 :
517 : /*
518 : * remove the node if it is empty, then if its parent is also
519 : * empty, remove it, then if the next parent is also empty,
520 : * remove it,..., until parent become null.
521 : */
522 0 : m_xXMLDocument->collapse( m_pRootBufferNode->getXMLElement() );
523 : }
524 :
525 : /*
526 : * if blocking, check the relationship between this BufferNode and
527 : * the current blocking BufferNode.
528 : */
529 0 : if ( !bIsNotBlocking )
530 : {
531 : /*
532 : * the current blocking BufferNode is a descendant of this BufferNode.
533 : */
534 0 : bIsBlockInside = (NULL != pBufferNode->isAncestor(m_pCurrentBlockingBufferNode));
535 :
536 : /*
537 : * the current blocking BufferNode locates behind this BufferNode in tree
538 : * order.
539 : */
540 0 : bIsBlockingAfterward = pBufferNode->isPrevious(m_pCurrentBlockingBufferNode);
541 : }
542 :
543 : /*
544 : * this BufferNode's working element needs to be deleted only when
545 : * 1. there is no blocking, or
546 : * 2. the current blocking BufferNode is a descendant of this BufferNode,
547 : * (then in the BufferNode's working element, the useless data before the blocking
548 : * element should be deleted.) or
549 : * 3. the current blocking BufferNode is locates behind this BufferNode in tree,
550 : * (then the useless data between the blocking element and the working element
551 : * should be deleted.).
552 : * Otherwise, this working element should not be deleted.
553 : */
554 0 : if ( bIsNotBlocking || bIsBlockInside || bIsBlockingAfterward )
555 : {
556 : cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >
557 0 : aChildElements = collectChildWorkingElement(pBufferNode);
558 :
559 : /*
560 : * the clearUselessData only clearup the content in the
561 : * node, not the node itself.
562 : */
563 0 : m_xXMLDocument->clearUselessData(pBufferNode->getXMLElement(),
564 : aChildElements,
565 : bIsBlockInside?(m_pCurrentBlockingBufferNode->getXMLElement()):
566 0 : (NULL));
567 :
568 : /*
569 : * remove the node if it is empty, then if its parent is also
570 : * empty, remove it, then if the next parent is also empty,
571 : * remove it,..., until parent become null.
572 : */
573 0 : m_xXMLDocument->collapse( pBufferNode->getXMLElement() );
574 : }
575 : }
576 :
577 0 : sal_Int32 nIndex = pParent->indexOfChild(pBufferNode);
578 :
579 0 : std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
580 0 : pParent->removeChild(pBufferNode);
581 0 : pBufferNode->setParent(NULL);
582 :
583 0 : std::vector< const BufferNode * >::const_iterator ii = vChildren->begin();
584 0 : for( ; ii != vChildren->end(); ++ii )
585 : {
586 0 : ((BufferNode *)(*ii))->setParent(pParent);
587 0 : pParent->addChild(*ii, nIndex);
588 0 : nIndex++;
589 : }
590 :
591 0 : delete vChildren;
592 :
593 : /*
594 : * delete the BufferNode
595 : */
596 0 : delete pBufferNode;
597 : }
598 0 : }
599 :
600 0 : BufferNode* SAXEventKeeperImpl::findNextBlockingBufferNode(
601 : BufferNode* pStartBufferNode) const
602 : /****** SAXEventKeeperImpl/findNextBlockingBufferNode ************************
603 : *
604 : * NAME
605 : * findNextBlockingBufferNode -- finds the next blocking BufferNode
606 : * behind the particular BufferNode.
607 : *
608 : * SYNOPSIS
609 : * pBufferNode = findNextBlockingBufferNode( pStartBufferNode );
610 : *
611 : * FUNCTION
612 : * see NAME.
613 : *
614 : * INPUTS
615 : * pStartBufferNode - the BufferNode from where to search the next
616 : * blocking BufferNode.
617 : *
618 : * RESULT
619 : * pBufferNode - the next blocking BufferNode, or NULL if no such
620 : * BufferNode exists.
621 : *
622 : * AUTHOR
623 : * Michael Mi
624 : * Email: michael.mi@sun.com
625 : ******************************************************************************/
626 : {
627 0 : BufferNode* pNext = NULL;
628 :
629 0 : if (pStartBufferNode != NULL)
630 : {
631 0 : pNext = pStartBufferNode;
632 :
633 0 : while (NULL != (pNext = (BufferNode*)pNext->getNextNodeByTreeOrder()))
634 : {
635 0 : if (pNext->getBlocker() != NULL)
636 : {
637 0 : break;
638 : }
639 : }
640 : }
641 :
642 0 : return pNext;
643 : }
644 :
645 0 : void SAXEventKeeperImpl::diffuse(BufferNode* pBufferNode) const
646 : /****** SAXEventKeeperImpl/diffuse *******************************************
647 : *
648 : * NAME
649 : * diffuse -- diffuse the notification.
650 : *
651 : * SYNOPSIS
652 : * diffuse( pBufferNode );
653 : *
654 : * FUNCTION
655 : * diffuse the collecting completion notification from the specific
656 : * BufferNode along its parent link, until an ancestor which is not
657 : * completely received is met.
658 : *
659 : * INPUTS
660 : * pBufferNode - the BufferNode from which the notification will be
661 : * diffused.
662 : *
663 : * RESULT
664 : * empty
665 : *
666 : * AUTHOR
667 : * Michael Mi
668 : * Email: michael.mi@sun.com
669 : ******************************************************************************/
670 : {
671 0 : BufferNode* pParent = pBufferNode;
672 :
673 0 : while(pParent->isAllReceived())
674 : {
675 0 : pParent->elementCollectorNotify();
676 0 : pParent = (BufferNode*)pParent->getParent();
677 : }
678 0 : }
679 :
680 0 : void SAXEventKeeperImpl::releaseElementMarkBuffer()
681 : /****** SAXEventKeeperImpl/releaseElementMarkBuffer **************************
682 : *
683 : * NAME
684 : * releaseElementMarkBuffer -- releases useless ElementMarks
685 : *
686 : * SYNOPSIS
687 : * releaseElementMarkBuffer( );
688 : *
689 : * FUNCTION
690 : * releases each ElementMark in the releasing list
691 : * m_vReleasedElementMarkBuffers.
692 : * The operation differs between an ElementCollector and a Blocker.
693 : *
694 : * INPUTS
695 : * empty
696 : *
697 : * RESULT
698 : * empty
699 : *
700 : * AUTHOR
701 : * Michael Mi
702 : * Email: michael.mi@sun.com
703 : ******************************************************************************/
704 : {
705 0 : m_bIsReleasing = true;
706 0 : while (!m_vReleasedElementMarkBuffers.empty())
707 : {
708 0 : std::vector< sal_Int32 >::iterator pId = m_vReleasedElementMarkBuffers.begin();
709 0 : sal_Int32 nId = *pId;
710 0 : m_vReleasedElementMarkBuffers.erase( pId );
711 :
712 0 : ElementMark* pElementMark = findElementMarkBuffer(nId);
713 :
714 0 : if (pElementMark != NULL)
715 : {
716 0 : if (cssxc::sax::ElementMarkType_ELEMENTCOLLECTOR
717 0 : == pElementMark->getType())
718 : /*
719 : * it is a EC
720 : */
721 : {
722 0 : ElementCollector* pElementCollector = (ElementCollector*)pElementMark;
723 :
724 0 : cssxc::sax::ElementMarkPriority nPriority = pElementCollector->getPriority();
725 0 : bool bToModify = pElementCollector->getModify();
726 :
727 : /*
728 : * Delete the EC from the buffer node.
729 : */
730 0 : BufferNode* pBufferNode = pElementCollector->getBufferNode();
731 0 : pBufferNode->removeElementCollector(pElementCollector);
732 :
733 0 : if ( nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY)
734 : {
735 0 : pBufferNode->notifyBranch();
736 : }
737 :
738 0 : if (bToModify)
739 : {
740 0 : pBufferNode->notifyAncestor();
741 : }
742 :
743 : /*
744 : * delete the ElementMark
745 : */
746 0 : pElementCollector = NULL;
747 0 : pElementMark = NULL;
748 0 : removeElementMarkBuffer(nId);
749 :
750 : /*
751 : * delete the BufferNode
752 : */
753 0 : diffuse(pBufferNode);
754 0 : smashBufferNode(pBufferNode, false);
755 : }
756 : else
757 : /*
758 : * it is a Blocker
759 : */
760 : {
761 : /*
762 : * Delete the TH from the buffer node.
763 : */
764 0 : BufferNode *pBufferNode = pElementMark->getBufferNode();
765 0 : pBufferNode->setBlocker(NULL);
766 :
767 : /*
768 : * If there is a following handler and no blocking now, then
769 : * forward this event
770 : */
771 0 : if (m_pCurrentBlockingBufferNode == pBufferNode)
772 : {
773 : /*
774 : * Before forwarding, the next blocking point needs to be
775 : * found.
776 : */
777 0 : m_pCurrentBlockingBufferNode = findNextBlockingBufferNode(pBufferNode);
778 :
779 : /*
780 : * Forward the blocked events between these two STHs.
781 : */
782 0 : if (m_xNextHandler.is())
783 : {
784 0 : BufferNode* pTempCurrentBufferNode = m_pCurrentBufferNode;
785 0 : BufferNode* pTempCurrentBlockingBufferNode = m_pCurrentBlockingBufferNode;
786 :
787 0 : m_pCurrentBufferNode = pBufferNode;
788 0 : m_pCurrentBlockingBufferNode = NULL;
789 :
790 0 : m_bIsForwarding = true;
791 :
792 0 : m_xXMLDocument->generateSAXEvents(
793 : m_xNextHandler,
794 : this,
795 : pBufferNode->getXMLElement(),
796 0 : (pTempCurrentBlockingBufferNode == NULL)?NULL:(pTempCurrentBlockingBufferNode->getXMLElement()));
797 :
798 0 : m_bIsForwarding = false;
799 :
800 0 : m_pCurrentBufferNode = pTempCurrentBufferNode;
801 0 : if (m_pCurrentBlockingBufferNode == NULL)
802 : {
803 0 : m_pCurrentBlockingBufferNode = pTempCurrentBlockingBufferNode;
804 : }
805 : }
806 :
807 0 : if (m_pCurrentBlockingBufferNode == NULL &&
808 0 : m_xSAXEventKeeperStatusChangeListener.is())
809 : {
810 0 : m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_False);
811 : }
812 : }
813 :
814 : /*
815 : * delete the ElementMark
816 : */
817 0 : pElementMark = NULL;
818 0 : removeElementMarkBuffer(nId);
819 :
820 : /*
821 : * delete the BufferNode
822 : */
823 0 : diffuse(pBufferNode);
824 0 : smashBufferNode(pBufferNode, true);
825 : }
826 : }
827 : }
828 :
829 0 : m_bIsReleasing = false;
830 :
831 0 : if (!m_pRootBufferNode->hasAnything() &&
832 0 : !m_pRootBufferNode->hasChildren() &&
833 0 : m_xSAXEventKeeperStatusChangeListener.is())
834 : {
835 0 : m_xSAXEventKeeperStatusChangeListener->bufferStatusChanged(sal_True);
836 : }
837 0 : }
838 :
839 0 : void SAXEventKeeperImpl::markElementMarkBuffer(sal_Int32 nId)
840 : /****** SAXEventKeeperImpl/markElementMarkBuffer *****************************
841 : *
842 : * NAME
843 : * markElementMarkBuffer -- marks an ElementMark to be released
844 : *
845 : * SYNOPSIS
846 : * markElementMarkBuffer( nId );
847 : *
848 : * FUNCTION
849 : * puts the ElementMark with the particular Id into the releasing list,
850 : * checks whether the releasing process is runing, if not then launch
851 : * this process.
852 : *
853 : * INPUTS
854 : * nId - the Id of the ElementMark which will be released
855 : *
856 : * RESULT
857 : * empty
858 : *
859 : * AUTHOR
860 : * Michael Mi
861 : * Email: michael.mi@sun.com
862 : ******************************************************************************/
863 : {
864 0 : m_vReleasedElementMarkBuffers.push_back( nId );
865 0 : if ( !m_bIsReleasing )
866 : {
867 0 : releaseElementMarkBuffer();
868 : }
869 0 : }
870 :
871 0 : sal_Int32 SAXEventKeeperImpl::createElementCollector(
872 : sal_Int32 nSecurityId,
873 : cssxc::sax::ElementMarkPriority nPriority,
874 : bool bModifyElement,
875 : const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& xReferenceResolvedListener)
876 : /****** SAXEventKeeperImpl/createElementCollector ****************************
877 : *
878 : * NAME
879 : * createElementCollector -- creates a new ElementCollector on the
880 : * incoming element.
881 : *
882 : * SYNOPSIS
883 : * nId = createElementCollector( nSecurityId, nPriority,
884 : * bModifyElement,
885 : * xReferenceResolvedListener );
886 : *
887 : * FUNCTION
888 : * allocs a new Id, then create an ElementCollector with this Id value.
889 : * Add the new created ElementCollector to the new ElementCollecotor list.
890 : *
891 : * INPUTS
892 : * nSecurityId - the security Id of the new ElementCollector
893 : * nPriority - the prirority of the new ElementCollector
894 : * bModifyElement -whether this BufferNode will modify the content of
895 : * the corresponding element it works on
896 : * xReferenceResolvedListener - the listener for the new ElementCollector.
897 : *
898 : * RESULT
899 : * nId - the Id of the new ElementCollector
900 : *
901 : * AUTHOR
902 : * Michael Mi
903 : * Email: michael.mi@sun.com
904 : ******************************************************************************/
905 : {
906 0 : sal_Int32 nId = m_nNextElementMarkId;
907 0 : m_nNextElementMarkId ++;
908 :
909 : ElementCollector* pElementCollector
910 : = new ElementCollector(
911 : nSecurityId,
912 : nId,
913 : nPriority,
914 : bModifyElement,
915 0 : xReferenceResolvedListener);
916 :
917 0 : m_vElementMarkBuffers.push_back( pElementCollector );
918 :
919 : /*
920 : * All the new EC to initial EC array.
921 : */
922 0 : m_vNewElementCollectors.push_back( pElementCollector );
923 :
924 0 : return nId;
925 : }
926 :
927 :
928 0 : sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId)
929 : /****** SAXEventKeeperImpl/createBlocker *************************************
930 : *
931 : * NAME
932 : * createBlocker -- creates a new Blocker on the incoming element.
933 : *
934 : * SYNOPSIS
935 : * nId = createBlocker( nSecurityId );
936 : *
937 : * FUNCTION
938 : * see NAME.
939 : *
940 : * INPUTS
941 : * nSecurityId - the security Id of the new Blocker
942 : *
943 : * RESULT
944 : * nId - the Id of the new Blocker
945 : *
946 : * AUTHOR
947 : * Michael Mi
948 : * Email: michael.mi@sun.com
949 : ******************************************************************************/
950 : {
951 0 : sal_Int32 nId = m_nNextElementMarkId;
952 0 : m_nNextElementMarkId ++;
953 :
954 : OSL_ASSERT(m_pNewBlocker == NULL);
955 :
956 0 : m_pNewBlocker = new ElementMark(nSecurityId, nId);
957 0 : m_vElementMarkBuffers.push_back( m_pNewBlocker );
958 :
959 0 : return nId;
960 : }
961 :
962 : /* XSAXEventKeeper */
963 0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::addElementCollector( )
964 : throw (cssu::RuntimeException)
965 : {
966 : return createElementCollector(
967 : cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
968 : cssxc::sax::ElementMarkPriority_AFTERMODIFY,
969 : false,
970 0 : NULL);
971 : }
972 :
973 0 : void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id )
974 : throw (cssu::RuntimeException)
975 : {
976 0 : markElementMarkBuffer(id);
977 0 : }
978 :
979 0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker( )
980 : throw (cssu::RuntimeException)
981 : {
982 0 : return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID);
983 : }
984 :
985 0 : void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id )
986 : throw (cssu::RuntimeException)
987 : {
988 0 : markElementMarkBuffer(id);
989 0 : }
990 :
991 0 : sal_Bool SAL_CALL SAXEventKeeperImpl::isBlocking( )
992 : throw (cssu::RuntimeException)
993 : {
994 0 : return (m_pCurrentBlockingBufferNode != NULL);
995 : }
996 :
997 : cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL
998 0 : SAXEventKeeperImpl::getElement( sal_Int32 id )
999 : throw (cssu::RuntimeException)
1000 : {
1001 0 : cssu::Reference< cssxw::XXMLElementWrapper > rc;
1002 :
1003 0 : ElementMark* pElementMark = findElementMarkBuffer(id);
1004 0 : if (pElementMark != NULL)
1005 : {
1006 0 : rc = pElementMark->getBufferNode()->getXMLElement();
1007 : }
1008 :
1009 0 : return rc;
1010 : }
1011 :
1012 0 : void SAL_CALL SAXEventKeeperImpl::setElement(
1013 : sal_Int32 id,
1014 : const cssu::Reference< cssxw::XXMLElementWrapper >& aElement )
1015 : throw (cssu::RuntimeException)
1016 : {
1017 0 : if (aElement.is())
1018 : {
1019 0 : m_xXMLDocument->rebuildIDLink(aElement);
1020 :
1021 0 : ElementMark* pElementMark = findElementMarkBuffer(id);
1022 :
1023 0 : if (pElementMark != NULL)
1024 : {
1025 0 : BufferNode* pBufferNode = pElementMark->getBufferNode();
1026 0 : if (pBufferNode != NULL)
1027 : {
1028 0 : bool bIsCurrent = m_xXMLDocument->isCurrent(pBufferNode->getXMLElement());
1029 0 : pBufferNode->setXMLElement(aElement);
1030 :
1031 0 : if (bIsCurrent)
1032 : {
1033 0 : m_xXMLDocument->setCurrentElement(aElement);
1034 : }
1035 : }
1036 : }
1037 : }
1038 : else
1039 : {
1040 0 : removeElementCollector( id );
1041 : }
1042 0 : }
1043 :
1044 0 : cssu::Reference< cssxs::XDocumentHandler > SAL_CALL SAXEventKeeperImpl::setNextHandler(
1045 : const cssu::Reference< cssxs::XDocumentHandler >& xNewHandler )
1046 : throw (cssu::RuntimeException)
1047 : {
1048 0 : cssu::Reference< cssxs::XDocumentHandler > xOldHandler = m_xNextHandler;
1049 :
1050 0 : m_xNextHandler = xNewHandler;
1051 0 : return xOldHandler;
1052 : }
1053 :
1054 0 : rtl::OUString SAL_CALL SAXEventKeeperImpl::printBufferNodeTree()
1055 : throw (cssu::RuntimeException)
1056 : {
1057 0 : rtl::OUString rc;
1058 :
1059 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ElementMarkBuffers: size = " ));
1060 0 : rc += rtl::OUString::valueOf((sal_Int32)m_vElementMarkBuffers.size());
1061 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\nCurrentBufferNode: " ));
1062 0 : rc += m_xXMLDocument->getNodeName(m_pCurrentBufferNode->getXMLElement());
1063 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
1064 0 : rc += printBufferNode(m_pRootBufferNode, 0);
1065 :
1066 0 : return rc;
1067 : }
1068 :
1069 0 : cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL SAXEventKeeperImpl::getCurrentBlockingNode()
1070 : throw (cssu::RuntimeException)
1071 : {
1072 0 : cssu::Reference< cssxw::XXMLElementWrapper > rc;
1073 :
1074 0 : if (m_pCurrentBlockingBufferNode != NULL)
1075 : {
1076 0 : rc = m_pCurrentBlockingBufferNode->getXMLElement();
1077 : }
1078 :
1079 0 : return rc;
1080 : }
1081 :
1082 : /* XSecuritySAXEventKeeper */
1083 0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::addSecurityElementCollector(
1084 : cssxc::sax::ElementMarkPriority priority,
1085 : sal_Bool modifyElement )
1086 : throw (cssu::RuntimeException)
1087 : {
1088 : return createElementCollector(
1089 : cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
1090 : priority,
1091 : modifyElement,
1092 0 : NULL);
1093 : }
1094 :
1095 0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::cloneElementCollector(
1096 : sal_Int32 referenceId,
1097 : cssxc::sax::ElementMarkPriority priority )
1098 : throw (cssu::RuntimeException)
1099 : {
1100 0 : sal_Int32 nId = -1;
1101 :
1102 0 : ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
1103 0 : if (pElementCollector != NULL)
1104 : {
1105 0 : nId = m_nNextElementMarkId;
1106 0 : m_nNextElementMarkId ++;
1107 :
1108 : ElementCollector* pClonedOne
1109 0 : = pElementCollector->clone(nId, priority);
1110 :
1111 : /*
1112 : * add this EC into the security data buffer array.
1113 : */
1114 0 : m_vElementMarkBuffers.push_back(pClonedOne);
1115 :
1116 : /*
1117 : * If the reference EC is still in initial EC array, add
1118 : * this cloned one into the initial EC array too.
1119 : */
1120 0 : if (pElementCollector->getBufferNode() == NULL)
1121 : {
1122 0 : m_vNewElementCollectors.push_back(pClonedOne);
1123 : }
1124 : }
1125 :
1126 0 : return nId;
1127 : }
1128 :
1129 0 : void SAL_CALL SAXEventKeeperImpl::setSecurityId( sal_Int32 id, sal_Int32 securityId )
1130 : throw (cssu::RuntimeException)
1131 : {
1132 0 : ElementMark* pElementMark = findElementMarkBuffer(id);
1133 0 : if (pElementMark != NULL)
1134 : {
1135 0 : pElementMark->setSecurityId(securityId);
1136 : }
1137 0 : }
1138 :
1139 :
1140 : /* XReferenceResolvedBroadcaster */
1141 0 : void SAL_CALL SAXEventKeeperImpl::addReferenceResolvedListener(
1142 : sal_Int32 referenceId,
1143 : const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& listener )
1144 : throw (cssu::RuntimeException)
1145 : {
1146 0 : ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
1147 0 : if (pElementCollector != NULL)
1148 : {
1149 0 : pElementCollector->setReferenceResolvedListener(listener);
1150 : }
1151 0 : }
1152 :
1153 0 : void SAL_CALL SAXEventKeeperImpl::removeReferenceResolvedListener(
1154 : sal_Int32 /*referenceId*/,
1155 : const cssu::Reference< cssxc::sax::XReferenceResolvedListener >&)
1156 : throw (cssu::RuntimeException)
1157 : {
1158 0 : }
1159 :
1160 : /* XSAXEventKeeperStatusChangeBroadcaster */
1161 0 : void SAL_CALL SAXEventKeeperImpl::addSAXEventKeeperStatusChangeListener(
1162 : const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >& listener )
1163 : throw (cssu::RuntimeException)
1164 : {
1165 0 : m_xSAXEventKeeperStatusChangeListener = listener;
1166 0 : }
1167 :
1168 0 : void SAL_CALL SAXEventKeeperImpl::removeSAXEventKeeperStatusChangeListener(
1169 : const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >&)
1170 : throw (cssu::RuntimeException)
1171 : {
1172 0 : }
1173 :
1174 : /* XDocumentHandler */
1175 0 : void SAL_CALL SAXEventKeeperImpl::startDocument( )
1176 : throw (cssxs::SAXException, cssu::RuntimeException)
1177 : {
1178 0 : if ( m_xNextHandler.is())
1179 : {
1180 0 : m_xNextHandler->startDocument();
1181 : }
1182 0 : }
1183 :
1184 0 : void SAL_CALL SAXEventKeeperImpl::endDocument( )
1185 : throw (cssxs::SAXException, cssu::RuntimeException)
1186 : {
1187 0 : if ( m_xNextHandler.is())
1188 : {
1189 0 : m_xNextHandler->endDocument();
1190 : }
1191 0 : }
1192 :
1193 0 : void SAL_CALL SAXEventKeeperImpl::startElement(
1194 : const rtl::OUString& aName,
1195 : const cssu::Reference< cssxs::XAttributeList >& xAttribs )
1196 : throw (cssxs::SAXException, cssu::RuntimeException)
1197 : {
1198 : /*
1199 : * If there is a following handler and no blocking now, then
1200 : * forward this event
1201 : */
1202 0 : if ((m_pCurrentBlockingBufferNode == NULL) &&
1203 0 : (m_xNextHandler.is()) &&
1204 0 : (!m_bIsForwarding) &&
1205 : (m_pNewBlocker == NULL))
1206 : {
1207 0 : m_xNextHandler->startElement(aName, xAttribs);
1208 : }
1209 :
1210 : /*
1211 : * If not forwarding, buffer this startElement.
1212 : */
1213 0 : if (!m_bIsForwarding)
1214 : {
1215 : #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1216 : m_xDocumentHandler->startElement(aName, xAttribs);
1217 : #else
1218 0 : sal_Int32 nLength = xAttribs->getLength();
1219 0 : cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
1220 :
1221 0 : for ( int i = 0; i<nLength; ++i )
1222 : {
1223 0 : aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
1224 0 : aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
1225 : }
1226 :
1227 0 : m_xCompressedDocumentHandler->_startElement(aName, aAttributes);
1228 : #endif
1229 :
1230 : }
1231 :
1232 0 : BufferNode* pBufferNode = addNewElementMarkBuffers();
1233 0 : if (pBufferNode != NULL)
1234 : {
1235 0 : setCurrentBufferNode(pBufferNode);
1236 : }
1237 0 : }
1238 :
1239 0 : void SAL_CALL SAXEventKeeperImpl::endElement( const rtl::OUString& aName )
1240 : throw (cssxs::SAXException, cssu::RuntimeException)
1241 : {
1242 0 : sal_Bool bIsCurrent = m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement());
1243 :
1244 : /*
1245 : * If there is a following handler and no blocking now, then
1246 : * forward this event
1247 : */
1248 0 : if ((m_pCurrentBlockingBufferNode == NULL) &&
1249 0 : (m_xNextHandler.is()) &&
1250 0 : (!m_bIsForwarding))
1251 : {
1252 0 : m_xNextHandler->endElement(aName);
1253 : }
1254 :
1255 0 : if ((m_pCurrentBlockingBufferNode != NULL) ||
1256 : (m_pCurrentBufferNode != m_pRootBufferNode) ||
1257 0 : (!m_xXMLDocument->isCurrentElementEmpty()))
1258 : {
1259 0 : if (!m_bIsForwarding)
1260 : {
1261 : #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1262 : m_xDocumentHandler->endElement(aName);
1263 : #else
1264 0 : m_xCompressedDocumentHandler->_endElement(aName);
1265 : #endif
1266 : }
1267 :
1268 : /*
1269 : * If the current buffer node has not notified yet, and
1270 : * the current buffer node is waiting for the current element,
1271 : * then let it notify.
1272 : */
1273 0 : if (bIsCurrent && (m_pCurrentBufferNode != m_pRootBufferNode))
1274 : {
1275 0 : BufferNode* pOldCurrentBufferNode = m_pCurrentBufferNode;
1276 0 : m_pCurrentBufferNode = (BufferNode*)m_pCurrentBufferNode->getParent();
1277 :
1278 0 : pOldCurrentBufferNode->setReceivedAll();
1279 :
1280 0 : if ((m_pCurrentBufferNode == m_pRootBufferNode) &&
1281 0 : m_xSAXEventKeeperStatusChangeListener.is())
1282 : {
1283 0 : m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_False);
1284 : }
1285 : }
1286 : }
1287 : else
1288 : {
1289 0 : if (!m_bIsForwarding)
1290 : {
1291 0 : m_xXMLDocument->removeCurrentElement();
1292 : }
1293 : }
1294 0 : }
1295 :
1296 0 : void SAL_CALL SAXEventKeeperImpl::characters( const rtl::OUString& aChars )
1297 : throw (cssxs::SAXException, cssu::RuntimeException)
1298 : {
1299 0 : if (!m_bIsForwarding)
1300 : {
1301 0 : if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
1302 : {
1303 0 : m_xNextHandler->characters(aChars);
1304 : }
1305 :
1306 0 : if ((m_pCurrentBlockingBufferNode != NULL) ||
1307 : (m_pCurrentBufferNode != m_pRootBufferNode))
1308 : {
1309 : #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1310 : m_xDocumentHandler->characters(aChars);
1311 : #else
1312 0 : m_xCompressedDocumentHandler->_characters(aChars);
1313 : #endif
1314 : }
1315 : }
1316 0 : }
1317 :
1318 0 : void SAL_CALL SAXEventKeeperImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
1319 : throw (cssxs::SAXException, cssu::RuntimeException)
1320 : {
1321 0 : characters( aWhitespaces );
1322 0 : }
1323 :
1324 0 : void SAL_CALL SAXEventKeeperImpl::processingInstruction(
1325 : const rtl::OUString& aTarget, const rtl::OUString& aData )
1326 : throw (cssxs::SAXException, cssu::RuntimeException)
1327 : {
1328 0 : if (!m_bIsForwarding)
1329 : {
1330 0 : if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
1331 : {
1332 0 : m_xNextHandler->processingInstruction(aTarget, aData);
1333 : }
1334 :
1335 0 : if ((m_pCurrentBlockingBufferNode != NULL) ||
1336 : (m_pCurrentBufferNode != m_pRootBufferNode))
1337 : {
1338 : #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1339 : m_xDocumentHandler->processingInstruction(aTarget, aData);
1340 : #else
1341 0 : m_xCompressedDocumentHandler->_processingInstruction(aTarget, aData);
1342 : #endif
1343 : }
1344 : }
1345 0 : }
1346 :
1347 0 : void SAL_CALL SAXEventKeeperImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >&)
1348 : throw (cssxs::SAXException, cssu::RuntimeException)
1349 : {
1350 0 : }
1351 :
1352 : /* XInitialization */
1353 0 : void SAL_CALL SAXEventKeeperImpl::initialize( const cssu::Sequence< cssu::Any >& aArguments )
1354 : throw (cssu::Exception, cssu::RuntimeException)
1355 : {
1356 : OSL_ASSERT(aArguments.getLength() == 1);
1357 :
1358 0 : aArguments[0] >>= m_xXMLDocument;
1359 : m_xDocumentHandler = cssu::Reference< cssxs::XDocumentHandler >(
1360 0 : m_xXMLDocument, cssu::UNO_QUERY );
1361 : m_xCompressedDocumentHandler = cssu::Reference< cssxcsax::XCompressedDocumentHandler >(
1362 0 : m_xXMLDocument, cssu::UNO_QUERY );
1363 :
1364 0 : m_pRootBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
1365 0 : m_pCurrentBufferNode = m_pRootBufferNode;
1366 0 : }
1367 :
1368 0 : rtl::OUString SAXEventKeeperImpl_getImplementationName ()
1369 : throw (cssu::RuntimeException)
1370 : {
1371 0 : return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
1372 : }
1373 :
1374 0 : sal_Bool SAL_CALL SAXEventKeeperImpl_supportsService( const rtl::OUString& ServiceName )
1375 : throw (cssu::RuntimeException)
1376 : {
1377 0 : return ServiceName == SERVICE_NAME;
1378 : }
1379 :
1380 0 : cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl_getSupportedServiceNames( )
1381 : throw (cssu::RuntimeException)
1382 : {
1383 0 : cssu::Sequence < rtl::OUString > aRet(1);
1384 0 : rtl::OUString* pArray = aRet.getArray();
1385 0 : pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
1386 0 : return aRet;
1387 : }
1388 : #undef SERVICE_NAME
1389 :
1390 0 : cssu::Reference< cssu::XInterface > SAL_CALL SAXEventKeeperImpl_createInstance(
1391 : const cssu::Reference< cssl::XMultiServiceFactory > &)
1392 : throw( cssu::Exception )
1393 : {
1394 0 : return (cppu::OWeakObject*) new SAXEventKeeperImpl();
1395 : }
1396 :
1397 : /* XServiceInfo */
1398 0 : rtl::OUString SAL_CALL SAXEventKeeperImpl::getImplementationName( )
1399 : throw (cssu::RuntimeException)
1400 : {
1401 0 : return SAXEventKeeperImpl_getImplementationName();
1402 : }
1403 0 : sal_Bool SAL_CALL SAXEventKeeperImpl::supportsService( const rtl::OUString& rServiceName )
1404 : throw (cssu::RuntimeException)
1405 : {
1406 0 : return SAXEventKeeperImpl_supportsService( rServiceName );
1407 : }
1408 0 : cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl::getSupportedServiceNames( )
1409 : throw (cssu::RuntimeException)
1410 : {
1411 0 : return SAXEventKeeperImpl_getSupportedServiceNames();
1412 : }
1413 :
1414 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|