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