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