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 blocker 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 running, 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 {
1011 return createElementCollector(
1012 cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
1013 cssxc::sax::ElementMarkPriority_AFTERMODIFY,
1014 false,
1015 NULL);
1016 }
1017
removeElementCollector(sal_Int32 id)1018 void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id )
1019 {
1020 markElementMarkBuffer(id);
1021 }
1022
addBlocker()1023 sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker( )
1024 {
1025 return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID);
1026 }
1027
removeBlocker(sal_Int32 id)1028 void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id )
1029 {
1030 markElementMarkBuffer(id);
1031 }
1032
isBlocking()1033 sal_Bool SAL_CALL SAXEventKeeperImpl::isBlocking( )
1034 {
1035 return (m_pCurrentBlockingBufferNode != NULL);
1036 }
1037
1038 cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL
getElement(sal_Int32 id)1039 SAXEventKeeperImpl::getElement( sal_Int32 id )
1040 {
1041 cssu::Reference< cssxw::XXMLElementWrapper > rc;
1042
1043 ElementMark* pElementMark = findElementMarkBuffer(id);
1044 if (pElementMark != NULL)
1045 {
1046 rc = pElementMark->getBufferNode()->getXMLElement();
1047 }
1048
1049 return rc;
1050 }
1051
setElement(sal_Int32 id,const cssu::Reference<cssxw::XXMLElementWrapper> & aElement)1052 void SAL_CALL SAXEventKeeperImpl::setElement(
1053 sal_Int32 id,
1054 const cssu::Reference< cssxw::XXMLElementWrapper >& aElement )
1055 {
1056 if (aElement.is())
1057 {
1058 m_xXMLDocument->rebuildIDLink(aElement);
1059
1060 ElementMark* pElementMark = findElementMarkBuffer(id);
1061
1062 if (pElementMark != NULL)
1063 {
1064 BufferNode* pBufferNode = pElementMark->getBufferNode();
1065 if (pBufferNode != NULL)
1066 {
1067 bool bIsCurrent = m_xXMLDocument->isCurrent(pBufferNode->getXMLElement());
1068 pBufferNode->setXMLElement(aElement);
1069
1070 if (bIsCurrent)
1071 {
1072 m_xXMLDocument->setCurrentElement(aElement);
1073 }
1074 }
1075 }
1076 }
1077 else
1078 {
1079 removeElementCollector( id );
1080 }
1081 }
1082
setNextHandler(const cssu::Reference<cssxs::XDocumentHandler> & xNewHandler)1083 cssu::Reference< cssxs::XDocumentHandler > SAL_CALL SAXEventKeeperImpl::setNextHandler(
1084 const cssu::Reference< cssxs::XDocumentHandler >& xNewHandler )
1085 {
1086 cssu::Reference< cssxs::XDocumentHandler > xOldHandler = m_xNextHandler;
1087
1088 m_xNextHandler = xNewHandler;
1089 return xOldHandler;
1090 }
1091
printBufferNodeTree()1092 rtl::OUString SAL_CALL SAXEventKeeperImpl::printBufferNodeTree()
1093 {
1094 rtl::OUString rc;
1095
1096 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ElementMarkBuffers: size = " ));
1097 rc += rtl::OUString::valueOf((sal_Int32)m_vElementMarkBuffers.size());
1098 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\nCurrentBufferNode: " ));
1099 rc += m_xXMLDocument->getNodeName(m_pCurrentBufferNode->getXMLElement());
1100 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
1101 rc += printBufferNode(m_pRootBufferNode, 0);
1102
1103 return rc;
1104 }
1105
getCurrentBlockingNode()1106 cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL SAXEventKeeperImpl::getCurrentBlockingNode()
1107 {
1108 cssu::Reference< cssxw::XXMLElementWrapper > rc;
1109
1110 if (m_pCurrentBlockingBufferNode != NULL)
1111 {
1112 rc = m_pCurrentBlockingBufferNode->getXMLElement();
1113 }
1114
1115 return rc;
1116 }
1117
1118 /* XSecuritySAXEventKeeper */
addSecurityElementCollector(cssxc::sax::ElementMarkPriority priority,sal_Bool modifyElement)1119 sal_Int32 SAL_CALL SAXEventKeeperImpl::addSecurityElementCollector(
1120 cssxc::sax::ElementMarkPriority priority,
1121 sal_Bool modifyElement )
1122 {
1123 return createElementCollector(
1124 cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
1125 priority,
1126 modifyElement,
1127 NULL);
1128 }
1129
cloneElementCollector(sal_Int32 referenceId,cssxc::sax::ElementMarkPriority priority)1130 sal_Int32 SAL_CALL SAXEventKeeperImpl::cloneElementCollector(
1131 sal_Int32 referenceId,
1132 cssxc::sax::ElementMarkPriority priority )
1133 {
1134 sal_Int32 nId = -1;
1135
1136 ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
1137 if (pElementCollector != NULL)
1138 {
1139 nId = m_nNextElementMarkId;
1140 m_nNextElementMarkId ++;
1141
1142 ElementCollector* pClonedOne
1143 = pElementCollector->clone(nId, priority);
1144
1145 /*
1146 * add this EC into the security data buffer array.
1147 */
1148 m_vElementMarkBuffers.push_back(pClonedOne);
1149
1150 /*
1151 * If the reference EC is still in initial EC array, add
1152 * this cloned one into the initial EC array too.
1153 */
1154 if (pElementCollector->getBufferNode() == NULL)
1155 {
1156 m_vNewElementCollectors.push_back(pClonedOne);
1157 }
1158 }
1159
1160 return nId;
1161 }
1162
setSecurityId(sal_Int32 id,sal_Int32 securityId)1163 void SAL_CALL SAXEventKeeperImpl::setSecurityId( sal_Int32 id, sal_Int32 securityId )
1164 {
1165 ElementMark* pElementMark = findElementMarkBuffer(id);
1166 if (pElementMark != NULL)
1167 {
1168 pElementMark->setSecurityId(securityId);
1169 }
1170 }
1171
1172
1173 /* XReferenceResolvedBroadcaster */
addReferenceResolvedListener(sal_Int32 referenceId,const cssu::Reference<cssxc::sax::XReferenceResolvedListener> & listener)1174 void SAL_CALL SAXEventKeeperImpl::addReferenceResolvedListener(
1175 sal_Int32 referenceId,
1176 const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& listener )
1177 {
1178 ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
1179 if (pElementCollector != NULL)
1180 {
1181 pElementCollector->setReferenceResolvedListener(listener);
1182 }
1183 }
1184
removeReferenceResolvedListener(sal_Int32,const cssu::Reference<cssxc::sax::XReferenceResolvedListener> &)1185 void SAL_CALL SAXEventKeeperImpl::removeReferenceResolvedListener(
1186 sal_Int32 /*referenceId*/,
1187 const cssu::Reference< cssxc::sax::XReferenceResolvedListener >&)
1188 {
1189 }
1190
1191 /* XSAXEventKeeperStatusChangeBroadcaster */
addSAXEventKeeperStatusChangeListener(const cssu::Reference<cssxc::sax::XSAXEventKeeperStatusChangeListener> & listener)1192 void SAL_CALL SAXEventKeeperImpl::addSAXEventKeeperStatusChangeListener(
1193 const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >& listener )
1194 {
1195 m_xSAXEventKeeperStatusChangeListener = listener;
1196 }
1197
removeSAXEventKeeperStatusChangeListener(const cssu::Reference<cssxc::sax::XSAXEventKeeperStatusChangeListener> &)1198 void SAL_CALL SAXEventKeeperImpl::removeSAXEventKeeperStatusChangeListener(
1199 const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >&)
1200 {
1201 }
1202
1203 /* XDocumentHandler */
startDocument()1204 void SAL_CALL SAXEventKeeperImpl::startDocument( )
1205 {
1206 if ( m_xNextHandler.is())
1207 {
1208 m_xNextHandler->startDocument();
1209 }
1210 }
1211
endDocument()1212 void SAL_CALL SAXEventKeeperImpl::endDocument( )
1213 {
1214 if ( m_xNextHandler.is())
1215 {
1216 m_xNextHandler->endDocument();
1217 }
1218 }
1219
startElement(const rtl::OUString & aName,const cssu::Reference<cssxs::XAttributeList> & xAttribs)1220 void SAL_CALL SAXEventKeeperImpl::startElement(
1221 const rtl::OUString& aName,
1222 const cssu::Reference< cssxs::XAttributeList >& xAttribs )
1223 {
1224 /*
1225 * If there is a following handler and no blocking now, then
1226 * forward this event
1227 */
1228 if ((m_pCurrentBlockingBufferNode == NULL) &&
1229 (m_xNextHandler.is()) &&
1230 (!m_bIsForwarding) &&
1231 (m_pNewBlocker == NULL))
1232 {
1233 m_xNextHandler->startElement(aName, xAttribs);
1234 }
1235
1236 /*
1237 * If not forwarding, buffer this startElement.
1238 */
1239 if (!m_bIsForwarding)
1240 {
1241 #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1242 m_xDocumentHandler->startElement(aName, xAttribs);
1243 #else
1244 sal_Int32 nLength = xAttribs->getLength();
1245 cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
1246
1247 for ( int i = 0; i<nLength; ++i )
1248 {
1249 aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
1250 aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
1251 }
1252
1253 m_xCompressedDocumentHandler->_startElement(aName, aAttributes);
1254 #endif
1255
1256 }
1257
1258 BufferNode* pBufferNode = addNewElementMarkBuffers();
1259 if (pBufferNode != NULL)
1260 {
1261 setCurrentBufferNode(pBufferNode);
1262 }
1263 }
1264
endElement(const rtl::OUString & aName)1265 void SAL_CALL SAXEventKeeperImpl::endElement( const rtl::OUString& aName )
1266 {
1267 sal_Bool bIsCurrent = m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement());
1268
1269 /*
1270 * If there is a following handler and no blocking now, then
1271 * forward this event
1272 */
1273 if ((m_pCurrentBlockingBufferNode == NULL) &&
1274 (m_xNextHandler.is()) &&
1275 (!m_bIsForwarding))
1276 {
1277 m_xNextHandler->endElement(aName);
1278 }
1279
1280 if ((m_pCurrentBlockingBufferNode != NULL) ||
1281 (m_pCurrentBufferNode != m_pRootBufferNode) ||
1282 (!m_xXMLDocument->isCurrentElementEmpty()))
1283 {
1284 if (!m_bIsForwarding)
1285 {
1286 #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1287 m_xDocumentHandler->endElement(aName);
1288 #else
1289 m_xCompressedDocumentHandler->_endElement(aName);
1290 #endif
1291 }
1292
1293 /*
1294 * If the current buffer node has not notified yet, and
1295 * the current buffer node is waiting for the current element,
1296 * then let it notify.
1297 */
1298 if (bIsCurrent && (m_pCurrentBufferNode != m_pRootBufferNode))
1299 {
1300 BufferNode* pOldCurrentBufferNode = m_pCurrentBufferNode;
1301 m_pCurrentBufferNode = (BufferNode*)m_pCurrentBufferNode->getParent();
1302
1303 pOldCurrentBufferNode->setReceivedAll();
1304
1305 if ((m_pCurrentBufferNode == m_pRootBufferNode) &&
1306 m_xSAXEventKeeperStatusChangeListener.is())
1307 {
1308 m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_False);
1309 }
1310 }
1311 }
1312 else
1313 {
1314 if (!m_bIsForwarding)
1315 {
1316 m_xXMLDocument->removeCurrentElement();
1317 }
1318 }
1319 }
1320
characters(const rtl::OUString & aChars)1321 void SAL_CALL SAXEventKeeperImpl::characters( const rtl::OUString& aChars )
1322 {
1323 if (!m_bIsForwarding)
1324 {
1325 if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
1326 {
1327 m_xNextHandler->characters(aChars);
1328 }
1329
1330 if ((m_pCurrentBlockingBufferNode != NULL) ||
1331 (m_pCurrentBufferNode != m_pRootBufferNode))
1332 {
1333 #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1334 m_xDocumentHandler->characters(aChars);
1335 #else
1336 m_xCompressedDocumentHandler->_characters(aChars);
1337 #endif
1338 }
1339 }
1340 }
1341
ignorableWhitespace(const rtl::OUString & aWhitespaces)1342 void SAL_CALL SAXEventKeeperImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
1343 {
1344 characters( aWhitespaces );
1345 }
1346
processingInstruction(const rtl::OUString & aTarget,const rtl::OUString & aData)1347 void SAL_CALL SAXEventKeeperImpl::processingInstruction(
1348 const rtl::OUString& aTarget, const rtl::OUString& aData )
1349 {
1350 if (!m_bIsForwarding)
1351 {
1352 if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
1353 {
1354 m_xNextHandler->processingInstruction(aTarget, aData);
1355 }
1356
1357 if ((m_pCurrentBlockingBufferNode != NULL) ||
1358 (m_pCurrentBufferNode != m_pRootBufferNode))
1359 {
1360 #ifndef _USECOMPRESSEDDOCUMENTHANDLER
1361 m_xDocumentHandler->processingInstruction(aTarget, aData);
1362 #else
1363 m_xCompressedDocumentHandler->_processingInstruction(aTarget, aData);
1364 #endif
1365 }
1366 }
1367 }
1368
setDocumentLocator(const cssu::Reference<cssxs::XLocator> &)1369 void SAL_CALL SAXEventKeeperImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >&)
1370 {
1371 }
1372
1373 /* XInitialization */
initialize(const cssu::Sequence<cssu::Any> & aArguments)1374 void SAL_CALL SAXEventKeeperImpl::initialize( const cssu::Sequence< cssu::Any >& aArguments )
1375 {
1376 OSL_ASSERT(aArguments.getLength() == 1);
1377
1378 aArguments[0] >>= m_xXMLDocument;
1379 m_xDocumentHandler = cssu::Reference< cssxs::XDocumentHandler >(
1380 m_xXMLDocument, cssu::UNO_QUERY );
1381 m_xCompressedDocumentHandler = cssu::Reference< cssxcsax::XCompressedDocumentHandler >(
1382 m_xXMLDocument, cssu::UNO_QUERY );
1383
1384 m_pRootBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
1385 m_pCurrentBufferNode = m_pRootBufferNode;
1386 }
1387
SAXEventKeeperImpl_getImplementationName()1388 rtl::OUString SAXEventKeeperImpl_getImplementationName ()
1389 {
1390 return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
1391 }
1392
SAXEventKeeperImpl_supportsService(const rtl::OUString & ServiceName)1393 sal_Bool SAL_CALL SAXEventKeeperImpl_supportsService( const rtl::OUString& ServiceName )
1394 {
1395 return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM ( SERVICE_NAME ));
1396 }
1397
SAXEventKeeperImpl_getSupportedServiceNames()1398 cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl_getSupportedServiceNames( )
1399 {
1400 cssu::Sequence < rtl::OUString > aRet(1);
1401 rtl::OUString* pArray = aRet.getArray();
1402 pArray[0] = rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
1403 return aRet;
1404 }
1405 #undef SERVICE_NAME
1406
SAXEventKeeperImpl_createInstance(const cssu::Reference<cssl::XMultiServiceFactory> &)1407 cssu::Reference< cssu::XInterface > SAL_CALL SAXEventKeeperImpl_createInstance(
1408 const cssu::Reference< cssl::XMultiServiceFactory > &)
1409 {
1410 return (cppu::OWeakObject*) new SAXEventKeeperImpl();
1411 }
1412
1413 /* XServiceInfo */
getImplementationName()1414 rtl::OUString SAL_CALL SAXEventKeeperImpl::getImplementationName( )
1415 {
1416 return SAXEventKeeperImpl_getImplementationName();
1417 }
supportsService(const rtl::OUString & rServiceName)1418 sal_Bool SAL_CALL SAXEventKeeperImpl::supportsService( const rtl::OUString& rServiceName )
1419 {
1420 return SAXEventKeeperImpl_supportsService( rServiceName );
1421 }
getSupportedServiceNames()1422 cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl::getSupportedServiceNames( )
1423 {
1424 return SAXEventKeeperImpl_getSupportedServiceNames();
1425 }
1426