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