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 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 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 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 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 224 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 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 332 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 > > 425 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 471 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 628 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 676 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 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 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 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 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 */ 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 1019 void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id ) 1020 throw (cssu::RuntimeException) 1021 { 1022 markElementMarkBuffer(id); 1023 } 1024 1025 sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker( ) 1026 throw (cssu::RuntimeException) 1027 { 1028 return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID); 1029 } 1030 1031 void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id ) 1032 throw (cssu::RuntimeException) 1033 { 1034 markElementMarkBuffer(id); 1035 } 1036 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 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 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 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 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 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 */ 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 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 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 */ 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 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 */ 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 1214 void SAL_CALL SAXEventKeeperImpl::removeSAXEventKeeperStatusChangeListener( 1215 const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >&) 1216 throw (cssu::RuntimeException) 1217 { 1218 } 1219 1220 /* XDocumentHandler */ 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 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 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 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 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 1364 void SAL_CALL SAXEventKeeperImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces ) 1365 throw (cssxs::SAXException, cssu::RuntimeException) 1366 { 1367 characters( aWhitespaces ); 1368 } 1369 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 1393 void SAL_CALL SAXEventKeeperImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >&) 1394 throw (cssxs::SAXException, cssu::RuntimeException) 1395 { 1396 } 1397 1398 /* XInitialization */ 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 1414 rtl::OUString SAXEventKeeperImpl_getImplementationName () 1415 throw (cssu::RuntimeException) 1416 { 1417 return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) ); 1418 } 1419 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 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 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 */ 1444 rtl::OUString SAL_CALL SAXEventKeeperImpl::getImplementationName( ) 1445 throw (cssu::RuntimeException) 1446 { 1447 return SAXEventKeeperImpl_getImplementationName(); 1448 } 1449 sal_Bool SAL_CALL SAXEventKeeperImpl::supportsService( const rtl::OUString& rServiceName ) 1450 throw (cssu::RuntimeException) 1451 { 1452 return SAXEventKeeperImpl_supportsService( rServiceName ); 1453 } 1454 cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl::getSupportedServiceNames( ) 1455 throw (cssu::RuntimeException) 1456 { 1457 return SAXEventKeeperImpl_getSupportedServiceNames(); 1458 } 1459 1460