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 "elementmark.hxx" 28 #include "elementcollector.hxx" 29 #include "buffernode.hxx" 30 #include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp> 31 32 namespace cssu = com::sun::star::uno; 33 namespace cssxw = com::sun::star::xml::wrapper; 34 namespace cssxc = com::sun::star::xml::crypto; 35 36 BufferNode::BufferNode( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement ) 37 :m_pParent(NULL), 38 m_pBlocker(NULL), 39 m_bAllReceived(false), 40 m_xXMLElement(xXMLElement) 41 { 42 } 43 44 bool BufferNode::isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId) const 45 /****** BufferNode/isECOfBeforeModifyIncluded ******************************** 46 * 47 * NAME 48 * isECOfBeforeModifyIncluded -- checks whether there is some 49 * ElementCollector on this BufferNode, that has BEFORE-MODIFY priority. 50 * 51 * SYNOPSIS 52 * bExist = isECOfBeforeModifyIncluded(nIgnoredSecurityId); 53 * 54 * FUNCTION 55 * checks each ElementCollector on this BufferNode, if all following 56 * conditions are satisfied, then returns true: 57 * 1. the ElementCollector's priority is BEFOREMODIFY; 58 * 2. the ElementCollector's securityId can't be ignored. 59 * otherwise, returns false. 60 * 61 * INPUTS 62 * nIgnoredSecurityId - the security Id to be ignored. If it equals 63 * to UNDEFINEDSECURITYID, then no security Id 64 * will be ignored. 65 * 66 * RESULT 67 * bExist - true if a match found, false otherwise 68 * 69 * HISTORY 70 * 05.01.2004 - implemented 71 * 72 * AUTHOR 73 * Michael Mi 74 * Email: michael.mi@sun.com 75 ******************************************************************************/ 76 { 77 bool rc = false; 78 std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin(); 79 80 for( ; ii != m_vElementCollectors.end() ; ++ii ) 81 { 82 ElementCollector* pElementCollector = (ElementCollector*)*ii; 83 84 if ((nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID || 85 pElementCollector->getSecurityId() != nIgnoredSecurityId) && 86 (pElementCollector->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY)) 87 { 88 rc = true; 89 break; 90 } 91 } 92 93 return rc; 94 } 95 96 void BufferNode::setReceivedAll() 97 /****** BufferNode/setReceiveAll ********************************************* 98 * 99 * NAME 100 * setReceivedAll -- indicates that the element in this BufferNode has 101 * been compeletely bufferred. 102 * 103 * SYNOPSIS 104 * setReceivedAll(); 105 * 106 * FUNCTION 107 * sets the all-received flag and launches ElementCollector's notify 108 * process. 109 * 110 * INPUTS 111 * empty 112 * 113 * RESULT 114 * empty 115 * 116 * HISTORY 117 * 05.01.2004 - implemented 118 * 119 * AUTHOR 120 * Michael Mi 121 * Email: michael.mi@sun.com 122 ******************************************************************************/ 123 { 124 m_bAllReceived = true; 125 elementCollectorNotify(); 126 } 127 128 bool BufferNode::isAllReceived() const 129 { 130 return m_bAllReceived; 131 } 132 133 void BufferNode::addElementCollector(const ElementCollector* pElementCollector) 134 /****** BufferNode/addElementCollector *************************************** 135 * 136 * NAME 137 * addElementCollector -- adds a new ElementCollector to this BufferNode. 138 * 139 * SYNOPSIS 140 * addElementCollector(pElementCollector); 141 * 142 * FUNCTION 143 * see NAME 144 * 145 * INPUTS 146 * pElementCollector - the ElementCollector to be added 147 * 148 * RESULT 149 * empty 150 * 151 * HISTORY 152 * 05.01.2004 - implemented 153 * 154 * AUTHOR 155 * Michael Mi 156 * Email: michael.mi@sun.com 157 ******************************************************************************/ 158 { 159 m_vElementCollectors.push_back( pElementCollector ); 160 ((ElementCollector*)pElementCollector)->setBufferNode(this); 161 } 162 163 void BufferNode::removeElementCollector(const ElementCollector* pElementCollector) 164 /****** BufferNode/removeElementCollector ************************************ 165 * 166 * NAME 167 * removeElementCollector -- removes an ElementCollector from this 168 * BufferNode. 169 * 170 * SYNOPSIS 171 * removeElementCollector(pElementCollector); 172 * 173 * FUNCTION 174 * see NAME 175 * 176 * INPUTS 177 * pElementCollector - the ElementCollector to be removed 178 * 179 * RESULT 180 * empty 181 * 182 * HISTORY 183 * 05.01.2004 - implemented 184 * 185 * AUTHOR 186 * Michael Mi 187 * Email: michael.mi@sun.com 188 ******************************************************************************/ 189 { 190 std::vector< const ElementCollector* >::iterator ii = m_vElementCollectors.begin(); 191 192 for( ; ii != m_vElementCollectors.end() ; ++ii ) 193 { 194 if( *ii == pElementCollector ) 195 { 196 m_vElementCollectors.erase( ii ); 197 ((ElementCollector*)pElementCollector)->setBufferNode(NULL); 198 break; 199 } 200 } 201 } 202 203 ElementMark* BufferNode::getBlocker() const 204 { 205 return m_pBlocker; 206 } 207 208 void BufferNode::setBlocker(const ElementMark* pBlocker) 209 /****** BufferNode/setBlocker ************************************************ 210 * 211 * NAME 212 * setBlocker -- adds a blocker to this BufferNode. 213 * 214 * SYNOPSIS 215 * setBlocker(pBlocker); 216 * 217 * FUNCTION 218 * see NAME 219 * 220 * INPUTS 221 * pBlocker - the new blocker to be attached 222 * 223 * RESULT 224 * empty 225 * 226 * NOTES 227 * Because there is only one blocker permited for a BufferNode, so the 228 * old blocker on this BufferNode, if there is one, will be overcasted. 229 * 230 * HISTORY 231 * 05.01.2004 - implemented 232 * 233 * AUTHOR 234 * Michael Mi 235 * Email: michael.mi@sun.com 236 ******************************************************************************/ 237 { 238 OSL_ASSERT(!(m_pBlocker != NULL && pBlocker != NULL)); 239 240 m_pBlocker = (ElementMark*)pBlocker; 241 if (m_pBlocker != NULL) 242 { 243 m_pBlocker->setBufferNode(this); 244 } 245 } 246 247 rtl::OUString BufferNode::printChildren() const 248 /****** BufferNode/printChildren ********************************************* 249 * 250 * NAME 251 * printChildren -- prints children information into a string. 252 * 253 * SYNOPSIS 254 * result = printChildren(); 255 * 256 * FUNCTION 257 * see NAME 258 * 259 * INPUTS 260 * empty 261 * 262 * RESULT 263 * result - the information string 264 * 265 * HISTORY 266 * 05.01.2004 - implemented 267 * 268 * AUTHOR 269 * Michael Mi 270 * Email: michael.mi@sun.com 271 ******************************************************************************/ 272 { 273 rtl::OUString rc; 274 std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin(); 275 276 for( ; ii != m_vElementCollectors.end() ; ++ii ) 277 { 278 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BufID=" )); 279 rc += rtl::OUString::valueOf((*ii)->getBufferId()); 280 281 if (((ElementCollector*)(*ii))->getModify()) 282 { 283 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[M]" )); 284 } 285 286 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ",Pri=" )); 287 288 switch (((ElementCollector*)(*ii))->getPriority()) 289 { 290 case cssxc::sax::ElementMarkPriority_BEFOREMODIFY: 291 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BEFOREMODIFY" )); 292 break; 293 case cssxc::sax::ElementMarkPriority_AFTERMODIFY: 294 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFTERMODIFY" )); 295 break; 296 default: 297 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNKNOWN" )); 298 break; 299 } 300 301 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(" )); 302 /* 303 if (((ElementCollector*)(*ii))->isInternalNotificationSuppressed()) 304 { 305 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*IN-Suppressed* " )); 306 } 307 */ 308 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SecID=" )); 309 rc += rtl::OUString::valueOf(((ElementCollector*)(*ii))->getSecurityId()); 310 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" )); 311 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); 312 } 313 314 return rc; 315 } 316 317 bool BufferNode::hasAnything() const 318 /****** BufferNode/hasAnything *********************************************** 319 * 320 * NAME 321 * hasAnything -- checks whether there is any ElementCollector or blocker 322 * on this BufferNode. 323 * 324 * SYNOPSIS 325 * bExist = hasAnything(); 326 * 327 * FUNCTION 328 * see NAME 329 * 330 * INPUTS 331 * empty 332 * 333 * RESULT 334 * bExist - true if there is, false otherwise. 335 * 336 * HISTORY 337 * 05.01.2004 - implemented 338 * 339 * AUTHOR 340 * Michael Mi 341 * Email: michael.mi@sun.com 342 ******************************************************************************/ 343 { 344 return (m_pBlocker != NULL || m_vElementCollectors.size() > 0); 345 } 346 347 bool BufferNode::hasChildren() const 348 /****** BufferNode/hasChildren *********************************************** 349 * 350 * NAME 351 * hasChildren -- checks whether this BufferNode has any child 352 * BufferNode. 353 * 354 * SYNOPSIS 355 * bExist = hasChildren(); 356 * 357 * FUNCTION 358 * see NAME 359 * 360 * INPUTS 361 * empty 362 * 363 * RESULT 364 * bExist - true if there is, false otherwise. 365 * 366 * HISTORY 367 * 05.01.2004 - implemented 368 * 369 * AUTHOR 370 * Michael Mi 371 * Email: michael.mi@sun.com 372 ******************************************************************************/ 373 { 374 return (m_vChildren.size() > 0); 375 } 376 377 std::vector< const BufferNode* >* BufferNode::getChildren() const 378 { 379 return new std::vector< const BufferNode* >( m_vChildren ); 380 } 381 382 const BufferNode* BufferNode::getFirstChild() const 383 /****** BufferNode/getFirstChild ********************************************* 384 * 385 * NAME 386 * getFirstChild -- retrieves the first child BufferNode. 387 * 388 * SYNOPSIS 389 * child = getFirstChild(); 390 * 391 * FUNCTION 392 * see NAME 393 * 394 * INPUTS 395 * empty 396 * 397 * RESULT 398 * child - the first child BufferNode, or NULL if there is no child 399 * BufferNode. 400 * 401 * HISTORY 402 * 05.01.2004 - implemented 403 * 404 * AUTHOR 405 * Michael Mi 406 * Email: michael.mi@sun.com 407 ******************************************************************************/ 408 { 409 BufferNode* rc = NULL; 410 411 if (m_vChildren.size() > 0) 412 { 413 rc = (BufferNode*)m_vChildren.front(); 414 } 415 416 return (const BufferNode*)rc; 417 } 418 419 void BufferNode::addChild(const BufferNode* pChild, sal_Int32 nPosition) 420 /****** BufferNode/addChild(pChild,nPosition) ******************************** 421 * 422 * NAME 423 * addChild -- inserts a child BufferNode at specific position. 424 * 425 * SYNOPSIS 426 * addChild(pChild, nPosition); 427 * 428 * FUNCTION 429 * see NAME 430 * 431 * INPUTS 432 * pChild - the child BufferNode to be added. 433 * nPosition - the position where the new child locates. 434 * 435 * RESULT 436 * empty 437 * 438 * NOTES 439 * If the nPosition is -1, then the new child BufferNode is appended 440 * at the end. 441 * 442 * HISTORY 443 * 05.01.2004 - implemented 444 * 445 * AUTHOR 446 * Michael Mi 447 * Email: michael.mi@sun.com 448 ******************************************************************************/ 449 { 450 if (nPosition == -1) 451 { 452 m_vChildren.push_back( pChild ); 453 } 454 else 455 { 456 std::vector< const BufferNode* >::iterator ii = m_vChildren.begin(); 457 ii += nPosition; 458 m_vChildren.insert(ii, pChild); 459 } 460 } 461 462 void BufferNode::addChild(const BufferNode* pChild) 463 /****** BufferNode/addChild() ************************************************ 464 * 465 * NAME 466 * addChild -- add a new child BufferNode. 467 * 468 * SYNOPSIS 469 * addChild(pChild); 470 * 471 * FUNCTION 472 * see NAME 473 * 474 * INPUTS 475 * pChild - the child BufferNode to be added. 476 * 477 * RESULT 478 * empty 479 * 480 * NOTES 481 * The new child BufferNode is appended at the end. 482 * 483 * HISTORY 484 * 05.01.2004 - implemented 485 * 486 * AUTHOR 487 * Michael Mi 488 * Email: michael.mi@sun.com 489 ******************************************************************************/ 490 { 491 addChild(pChild, -1); 492 } 493 494 void BufferNode::removeChild(const BufferNode* pChild) 495 /****** BufferNode/removeChild *********************************************** 496 * 497 * NAME 498 * removeChild -- removes a child BufferNode from the children list. 499 * 500 * SYNOPSIS 501 * removeChild(pChild); 502 * 503 * FUNCTION 504 * see NAME 505 * 506 * INPUTS 507 * pChild - the child BufferNode to be removed 508 * 509 * RESULT 510 * empty 511 * 512 * HISTORY 513 * 05.01.2004 - implemented 514 * 515 * AUTHOR 516 * Michael Mi 517 * Email: michael.mi@sun.com 518 ******************************************************************************/ 519 { 520 std::vector< const BufferNode* >::iterator ii = m_vChildren.begin(); 521 522 for( ; ii != m_vChildren.end() ; ++ii ) 523 { 524 if( *ii == pChild ) 525 { 526 m_vChildren.erase( ii ); 527 break; 528 } 529 } 530 } 531 532 sal_Int32 BufferNode::indexOfChild(const BufferNode* pChild) const 533 /****** BufferNode/indexOfChild ********************************************** 534 * 535 * NAME 536 * indexOfChild -- gets the index of a child BufferNode. 537 * 538 * SYNOPSIS 539 * index = indexOfChild(pChild); 540 * 541 * FUNCTION 542 * see NAME 543 * 544 * INPUTS 545 * pChild - the child BufferNode whose index to be gotten 546 * 547 * RESULT 548 * index - the index of that child BufferNode. If that child BufferNode 549 * is not found, -1 is returned. 550 * 551 * HISTORY 552 * 05.01.2004 - implemented 553 * 554 * AUTHOR 555 * Michael Mi 556 * Email: michael.mi@sun.com 557 ******************************************************************************/ 558 { 559 sal_Int32 nIndex = 0; 560 bool bFound = false; 561 562 std::vector< const BufferNode * >::const_iterator ii = m_vChildren.begin(); 563 564 for( ; ii != m_vChildren.end() ; ++ii ) 565 { 566 if( *ii == pChild ) 567 { 568 bFound = true; 569 break; 570 } 571 nIndex++; 572 } 573 574 if (!bFound ) 575 { 576 nIndex = -1; 577 } 578 579 return nIndex; 580 } 581 582 const BufferNode* BufferNode::childAt(sal_Int32 nIndex) const 583 /****** BufferNode/childAt *************************************************** 584 * 585 * NAME 586 * childAt -- retrieves the child BufferNode at specific possition. 587 * 588 * SYNOPSIS 589 * child = childAt(nIndex); 590 * 591 * FUNCTION 592 * see NAME 593 * 594 * INPUTS 595 * nIndex - the index of the child BufferNode to be retrieved 596 * 597 * RESULT 598 * child - the child BufferNode at index position, or NULL if the index 599 * is out of the range of children. 600 * 601 * HISTORY 602 * 05.01.2004 - implemented 603 * 604 * AUTHOR 605 * Michael Mi 606 * Email: michael.mi@sun.com 607 ******************************************************************************/ 608 { 609 BufferNode* rc = NULL; 610 611 if (nIndex < ((sal_Int32)m_vChildren.size()) && nIndex >= 0) 612 { 613 rc = (BufferNode*)m_vChildren[nIndex]; 614 } 615 616 return (const BufferNode*)rc; 617 } 618 619 const BufferNode* BufferNode::getParent() const 620 { 621 return m_pParent; 622 } 623 624 void BufferNode::setParent(const BufferNode* pParent) 625 { 626 m_pParent = (BufferNode*)pParent; 627 } 628 629 const BufferNode* BufferNode::getNextSibling() const 630 /****** BufferNode/getNextSibling ******************************************** 631 * 632 * NAME 633 * getNextSibling -- retrieves the next sibling BufferNode. 634 * 635 * SYNOPSIS 636 * sibling = getNextSibling(); 637 * 638 * FUNCTION 639 * see NAME 640 * 641 * INPUTS 642 * empty 643 * 644 * RESULT 645 * sibling - the next sibling BufferNode, or NULL if there is none. 646 * 647 * HISTORY 648 * 05.01.2004 - implemented 649 * 650 * AUTHOR 651 * Michael Mi 652 * Email: michael.mi@sun.com 653 ******************************************************************************/ 654 { 655 BufferNode* rc = NULL; 656 657 if (m_pParent != NULL) 658 { 659 rc = (BufferNode*)m_pParent->getNextChild(this); 660 } 661 662 return (const BufferNode*)rc; 663 } 664 665 const BufferNode* BufferNode::isAncestor(const BufferNode* pDescendant) const 666 /****** BufferNode/isAncestor ************************************************ 667 * 668 * NAME 669 * isAncestor -- checks whether this BufferNode is an ancestor of another 670 * BufferNode. 671 * 672 * SYNOPSIS 673 * bIs = isAncestor(pDescendant); 674 * 675 * FUNCTION 676 * see NAME 677 * 678 * INPUTS 679 * pDescendant - the BufferNode to be checked as a descendant 680 * 681 * RESULT 682 * bIs - true if this BufferNode is an ancestor of the pDescendant, 683 * false otherwise. 684 * 685 * HISTORY 686 * 05.01.2004 - implemented 687 * 688 * AUTHOR 689 * Michael Mi 690 * Email: michael.mi@sun.com 691 ******************************************************************************/ 692 { 693 BufferNode* rc = NULL; 694 695 if (pDescendant != NULL) 696 { 697 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); 698 699 for( ; ii != m_vChildren.end() ; ++ii ) 700 { 701 BufferNode* pChild = (BufferNode*)*ii; 702 703 if (pChild == pDescendant) 704 { 705 rc = pChild; 706 break; 707 } 708 709 if (pChild->isAncestor(pDescendant) != NULL) 710 { 711 rc = pChild; 712 break; 713 } 714 } 715 } 716 717 return (const BufferNode*)rc; 718 } 719 720 bool BufferNode::isPrevious(const BufferNode* pFollowing) const 721 /****** BufferNode/isPrevious ************************************************ 722 * 723 * NAME 724 * isPrevious -- checks whether this BufferNode is ahead of another 725 * BufferNode in the tree order. 726 * 727 * SYNOPSIS 728 * bIs = isPrevious(pFollowing); 729 * 730 * FUNCTION 731 * see NAME 732 * 733 * INPUTS 734 * pFollowing - the BufferNode to be checked as a following 735 * 736 * RESULT 737 * bIs - true if this BufferNode is ahead in the tree order, false 738 * otherwise. 739 * 740 * HISTORY 741 * 05.01.2004 - implemented 742 * 743 * AUTHOR 744 * Michael Mi 745 * Email: michael.mi@sun.com 746 ******************************************************************************/ 747 { 748 bool rc = false; 749 750 BufferNode* pNextBufferNode = (BufferNode*)getNextNodeByTreeOrder(); 751 while (pNextBufferNode != NULL) 752 { 753 if (pNextBufferNode == pFollowing) 754 { 755 rc = true; 756 break; 757 } 758 759 pNextBufferNode = (BufferNode*)(pNextBufferNode->getNextNodeByTreeOrder()); 760 } 761 762 return rc; 763 } 764 765 const BufferNode* BufferNode::getNextNodeByTreeOrder() const 766 /****** BufferNode/getNextNodeByTreeOrder ************************************ 767 * 768 * NAME 769 * getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree 770 * order. 771 * 772 * SYNOPSIS 773 * next = getNextNodeByTreeOrder(); 774 * 775 * FUNCTION 776 * see NAME 777 * 778 * INPUTS 779 * empty 780 * 781 * RESULT 782 * next - the BufferNode following this BufferNode in the tree order, 783 * or NULL if there is none. 784 * 785 * NOTES 786 * The "next" node in tree order is defined as: 787 * 1. If a node has children, then the first child is; 788 * 2. otherwise, if it has a following sibling, then this sibling node is; 789 * 3. otherwise, if it has a parent node, the the parent's next sibling 790 * node is; 791 * 4. otherwise, no "next" node exists. 792 * 793 * HISTORY 794 * 05.01.2004 - implemented 795 * 796 * AUTHOR 797 * Michael Mi 798 * Email: michael.mi@sun.com 799 ******************************************************************************/ 800 { 801 /* 802 * If this buffer node has m_vChildren, then return the first 803 * child. 804 */ 805 if (hasChildren()) 806 { 807 return getFirstChild(); 808 } 809 810 /* 811 * Otherwise, it this buffer node has a following sibling, 812 * then return that sibling. 813 */ 814 BufferNode* pNextSibling = (BufferNode*)getNextSibling(); 815 if (pNextSibling != NULL) 816 { 817 return pNextSibling; 818 } 819 820 /* 821 * Otherwise, it this buffer node has parent, then return 822 * its parent's following sibling. 823 */ 824 BufferNode* pNode = (BufferNode*)this; 825 BufferNode* pParent; 826 BufferNode* pNextSiblingParent = NULL; 827 828 do 829 { 830 if (pNode == NULL) 831 { 832 break; 833 } 834 835 pParent = (BufferNode*)pNode->getParent(); 836 if (pParent != NULL) 837 { 838 pNextSiblingParent = (BufferNode*)pParent->getNextSibling(); 839 } 840 pNode = pParent; 841 842 }while (pNextSiblingParent == NULL); 843 844 return pNextSiblingParent; 845 } 846 847 cssu::Reference< cssxw::XXMLElementWrapper > BufferNode::getXMLElement() const 848 { 849 return m_xXMLElement; 850 } 851 852 void BufferNode::setXMLElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement ) 853 { 854 m_xXMLElement = xXMLElement; 855 } 856 857 void BufferNode::notifyBranch() 858 /****** BufferNode/notifyBranch ********************************************** 859 * 860 * NAME 861 * notifyBranch -- notifies each BufferNode in the branch of this 862 * BufferNode in the tree order. 863 * 864 * SYNOPSIS 865 * notifyBranch(); 866 * 867 * FUNCTION 868 * see NAME 869 * 870 * INPUTS 871 * empty 872 * 873 * RESULT 874 * empty 875 * 876 * HISTORY 877 * 05.01.2004 - implemented 878 * 879 * AUTHOR 880 * Michael Mi 881 * Email: michael.mi@sun.com 882 ******************************************************************************/ 883 { 884 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); 885 886 for( ; ii != m_vChildren.end() ; ++ii ) 887 { 888 BufferNode* pBufferNode = (BufferNode*)*ii; 889 pBufferNode->elementCollectorNotify(); 890 pBufferNode->notifyBranch(); 891 } 892 } 893 894 void BufferNode::notifyAncestor() 895 /****** BufferNode/notifyAncestor ******************************************** 896 * 897 * NAME 898 * notifyAncestor -- notifies each ancestor BufferNode through the parent 899 * link. 900 * 901 * SYNOPSIS 902 * notifyAncestor(); 903 * 904 * FUNCTION 905 * see NAME 906 * 907 * INPUTS 908 * empty 909 * 910 * RESULT 911 * empty 912 * 913 * HISTORY 914 * 05.01.2004 - implemented 915 * 916 * AUTHOR 917 * Michael Mi 918 * Email: michael.mi@sun.com 919 ******************************************************************************/ 920 { 921 BufferNode* pParent = m_pParent; 922 while (pParent != NULL) 923 { 924 pParent->notifyAncestor(); 925 pParent = (BufferNode*)pParent->getParent(); 926 } 927 } 928 929 void BufferNode::elementCollectorNotify() 930 /****** BufferNode/elementCollectorNotify ************************************ 931 * 932 * NAME 933 * elementCollectorNotify -- notifies this BufferNode. 934 * 935 * SYNOPSIS 936 * elementCollectorNotify(); 937 * 938 * FUNCTION 939 * Notifies this BufferNode if the notification is not suppressed. 940 * 941 * INPUTS 942 * empty 943 * 944 * RESULT 945 * child - the first child BufferNode, or NULL if there is no child 946 * BufferNode. 947 * 948 * HISTORY 949 * 05.01.2004 - implemented 950 * 951 * AUTHOR 952 * Michael Mi 953 * Email: michael.mi@sun.com 954 ******************************************************************************/ 955 { 956 if (m_vElementCollectors.size()>0) 957 { 958 cssxc::sax::ElementMarkPriority nMaxPriority = cssxc::sax::ElementMarkPriority_MINIMUM; 959 cssxc::sax::ElementMarkPriority nPriority; 960 961 /* 962 * get the max priority among ElementCollectors on this BufferNode 963 */ 964 std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin(); 965 for( ; ii != m_vElementCollectors.end() ; ++ii ) 966 { 967 ElementCollector* pElementCollector = (ElementCollector*)*ii; 968 nPriority = pElementCollector->getPriority(); 969 if (nPriority > nMaxPriority) 970 { 971 nMaxPriority = nPriority; 972 } 973 } 974 975 std::vector< const ElementCollector* > vElementCollectors( m_vElementCollectors ); 976 ii = vElementCollectors.begin(); 977 978 for( ; ii != vElementCollectors.end() ; ++ii ) 979 { 980 ElementCollector* pElementCollector = (ElementCollector*)*ii; 981 nPriority = pElementCollector->getPriority(); 982 bool bToModify = pElementCollector->getModify(); 983 984 /* 985 * Only ElementCollector with the max priority can 986 * perform notify operation. 987 * Moreover, if any blocker exists in the subtree of 988 * this BufferNode, this ElementCollector can't do notify 989 * unless its priority is BEFOREMODIFY. 990 */ 991 if (nPriority == nMaxPriority && 992 (nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY || 993 !isBlockerInSubTreeIncluded(pElementCollector->getSecurityId()))) 994 { 995 /* 996 * If this ElementCollector will modify the bufferred element, then 997 * special attention must be paid. 998 * 999 * If there is any ElementCollector in the subtree or any ancestor 1000 * ElementCollector with PRI_BEFPREMODIFY priority, this 1001 * ElementCollector can't perform notify operation, otherwise, it 1002 * will destroy the bufferred element, in turn, ElementCollectors 1003 * mentioned above can't perform their mission. 1004 */ 1005 //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY && 1006 if (!(bToModify && 1007 (isECInSubTreeIncluded(pElementCollector->getSecurityId()) || 1008 isECOfBeforeModifyInAncestorIncluded(pElementCollector->getSecurityId())) 1009 )) 1010 { 1011 pElementCollector->notifyListener(); 1012 } 1013 } 1014 } 1015 } 1016 } 1017 1018 bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const 1019 /****** BufferNode/isECInSubTreeIncluded ************************************* 1020 * 1021 * NAME 1022 * isECInSubTreeIncluded -- checks whether there is any ElementCollector 1023 * in the branch of this BufferNode. 1024 * 1025 * SYNOPSIS 1026 * bExist = isECInSubTreeIncluded(nIgnoredSecurityId); 1027 * 1028 * FUNCTION 1029 * checks each BufferNode in the branch of this BufferNode, if there is 1030 * an ElementCollector whose signatureId is not ignored, then return 1031 * true, otherwise, false returned. 1032 * 1033 * INPUTS 1034 * nIgnoredSecurityId - the security Id to be ignored. If it equals 1035 * to UNDEFINEDSECURITYID, then no security Id 1036 * will be ignored. 1037 * 1038 * RESULT 1039 * bExist - true if a match found, false otherwise. 1040 * 1041 * HISTORY 1042 * 05.01.2004 - implemented 1043 * 1044 * AUTHOR 1045 * Michael Mi 1046 * Email: michael.mi@sun.com 1047 ******************************************************************************/ 1048 { 1049 bool rc = false; 1050 1051 std::vector< const ElementCollector* >::const_iterator jj = m_vElementCollectors.begin(); 1052 1053 for( ; jj != m_vElementCollectors.end() ; ++jj ) 1054 { 1055 ElementCollector* pElementCollector = (ElementCollector*)*jj; 1056 if (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID || 1057 pElementCollector->getSecurityId() != nIgnoredSecurityId) 1058 { 1059 rc = true; 1060 break; 1061 } 1062 } 1063 1064 if ( !rc ) 1065 { 1066 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); 1067 1068 for( ; ii != m_vChildren.end() ; ++ii ) 1069 { 1070 BufferNode* pBufferNode = (BufferNode*)*ii; 1071 1072 if ( pBufferNode->isECInSubTreeIncluded(nIgnoredSecurityId)) 1073 { 1074 rc = true; 1075 break; 1076 } 1077 } 1078 } 1079 1080 return rc; 1081 } 1082 1083 bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const 1084 /****** BufferNode/isECOfBeforeModifyInAncestorIncluded ********************** 1085 * 1086 * NAME 1087 * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some 1088 * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY 1089 * priority. 1090 * 1091 * SYNOPSIS 1092 * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId); 1093 * 1094 * FUNCTION 1095 * checks each ancestor BufferNode through the parent link, if there is 1096 * an ElementCollector with PRI_BEFPREMODIFY priority and its 1097 * signatureId is not ignored, then return true, otherwise, false 1098 * returned. 1099 * 1100 * INPUTS 1101 * nIgnoredSecurityId - the security Id to be ignored. If it equals 1102 * to UNDEFINEDSECURITYID, then no security Id 1103 * will be ignored. 1104 * 1105 * RESULT 1106 * bExist - true if a match found, false otherwise. 1107 * 1108 * HISTORY 1109 * 05.01.2004 - implemented 1110 * 1111 * AUTHOR 1112 * Michael Mi 1113 * Email: michael.mi@sun.com 1114 ******************************************************************************/ 1115 { 1116 bool rc = false; 1117 1118 BufferNode* pParentNode = m_pParent; 1119 while (pParentNode != NULL) 1120 { 1121 if (pParentNode->isECOfBeforeModifyIncluded(nIgnoredSecurityId)) 1122 { 1123 rc = true; 1124 break; 1125 } 1126 1127 pParentNode = (BufferNode*)pParentNode->getParent(); 1128 } 1129 1130 return rc; 1131 } 1132 1133 bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const 1134 /****** BufferNode/isBlockerInSubTreeIncluded ******************************** 1135 * 1136 * NAME 1137 * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode 1138 * which has blocker on it 1139 * 1140 * SYNOPSIS 1141 * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId); 1142 * 1143 * FUNCTION 1144 * checks each BufferNode in the branch of this BufferNode, if one has 1145 * a blocker on it, and the blocker's securityId is not ignored, then 1146 * returns true; otherwise, false returns. 1147 * 1148 * INPUTS 1149 * nIgnoredSecurityId - the security Id to be ignored. If it equals 1150 * to UNDEFINEDSECURITYID, then no security Id 1151 * will be ignored. 1152 * 1153 * RESULT 1154 * bExist - true if a match found, false otherwise. 1155 * 1156 * HISTORY 1157 * 05.01.2004 - implemented 1158 * 1159 * AUTHOR 1160 * Michael Mi 1161 * Email: michael.mi@sun.com 1162 ******************************************************************************/ 1163 { 1164 bool rc = false; 1165 1166 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); 1167 1168 for( ; ii != m_vChildren.end() ; ++ii ) 1169 { 1170 BufferNode* pBufferNode = (BufferNode*)*ii; 1171 ElementMark* pBlocker = pBufferNode->getBlocker(); 1172 1173 if (pBlocker != NULL && 1174 (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID || 1175 pBlocker->getSecurityId() != nIgnoredSecurityId )) 1176 { 1177 rc = true; 1178 break; 1179 } 1180 1181 if (rc || pBufferNode->isBlockerInSubTreeIncluded(nIgnoredSecurityId)) 1182 { 1183 rc = true; 1184 break; 1185 } 1186 } 1187 1188 return rc; 1189 } 1190 1191 const BufferNode* BufferNode::getNextChild(const BufferNode* pChild) const 1192 /****** BufferNode/getNextChild ********************************************** 1193 * 1194 * NAME 1195 * getNextChild -- get the next child BufferNode. 1196 * 1197 * SYNOPSIS 1198 * nextChild = getNextChild(); 1199 * 1200 * FUNCTION 1201 * see NAME 1202 * 1203 * INPUTS 1204 * pChild - the child BufferNode whose next node is retrieved. 1205 * 1206 * RESULT 1207 * nextChild - the next child BufferNode after the pChild, or NULL if 1208 * there is none. 1209 * 1210 * HISTORY 1211 * 05.01.2004 - implemented 1212 * 1213 * AUTHOR 1214 * Michael Mi 1215 * Email: michael.mi@sun.com 1216 ******************************************************************************/ 1217 { 1218 BufferNode* rc = NULL; 1219 bool bChildFound = false; 1220 1221 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); 1222 for( ; ii != m_vChildren.end() ; ++ii ) 1223 { 1224 if (bChildFound) 1225 { 1226 rc = (BufferNode*)*ii; 1227 break; 1228 } 1229 1230 if( *ii == pChild ) 1231 { 1232 bChildFound = true; 1233 } 1234 } 1235 1236 return (const BufferNode*)rc; 1237 } 1238 1239 1240 void BufferNode::freeAllChildren() 1241 /****** BufferNode/freeAllChildren ******************************************* 1242 * 1243 * NAME 1244 * freeAllChildren -- free all his child BufferNode. 1245 * 1246 * SYNOPSIS 1247 * freeAllChildren(); 1248 * 1249 * FUNCTION 1250 * see NAME 1251 * 1252 * INPUTS 1253 * empty 1254 * 1255 * RESULT 1256 * empty 1257 * 1258 * HISTORY 1259 * 30.03.2004 - the correct the memory leak bug 1260 * 1261 * AUTHOR 1262 * Michael Mi 1263 * Email: michael.mi@sun.com 1264 ******************************************************************************/ 1265 { 1266 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); 1267 for( ; ii != m_vChildren.end() ; ++ii ) 1268 { 1269 BufferNode *pChild = (BufferNode *)(*ii); 1270 pChild->freeAllChildren(); 1271 delete pChild; 1272 } 1273 1274 m_vChildren.clear(); 1275 } 1276