merged tag ooo/OOO330_m14
[LibreOffice.git] / xmlsecurity / source / framework / buffernode.cxx
blob5e06d3fbc3b6aba7c79a08a9769a1613ef500c90
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_xmlsecurity.hxx"
31 #include "elementmark.hxx"
32 #include "elementcollector.hxx"
33 #include "buffernode.hxx"
34 #include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp>
36 namespace cssu = com::sun::star::uno;
37 namespace cssxw = com::sun::star::xml::wrapper;
38 namespace cssxc = com::sun::star::xml::crypto;
40 BufferNode::BufferNode( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
41 :m_pParent(NULL),
42 m_pBlocker(NULL),
43 m_bAllReceived(false),
44 m_xXMLElement(xXMLElement)
48 bool BufferNode::isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId) const
49 /****** BufferNode/isECOfBeforeModifyIncluded ********************************
51 * NAME
52 * isECOfBeforeModifyIncluded -- checks whether there is some
53 * ElementCollector on this BufferNode, that has BEFORE-MODIFY priority.
55 * SYNOPSIS
56 * bExist = isECOfBeforeModifyIncluded(nIgnoredSecurityId);
58 * FUNCTION
59 * checks each ElementCollector on this BufferNode, if all following
60 * conditions are satisfied, then returns true:
61 * 1. the ElementCollector's priority is BEFOREMODIFY;
62 * 2. the ElementCollector's securityId can't be ignored.
63 * otherwise, returns false.
65 * INPUTS
66 * nIgnoredSecurityId - the security Id to be ignored. If it equals
67 * to UNDEFINEDSECURITYID, then no security Id
68 * will be ignored.
70 * RESULT
71 * bExist - true if a match found, false otherwise
73 * HISTORY
74 * 05.01.2004 - implemented
76 * AUTHOR
77 * Michael Mi
78 * Email: michael.mi@sun.com
79 ******************************************************************************/
81 bool rc = false;
82 std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
84 for( ; ii != m_vElementCollectors.end() ; ++ii )
86 ElementCollector* pElementCollector = (ElementCollector*)*ii;
88 if ((nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
89 pElementCollector->getSecurityId() != nIgnoredSecurityId) &&
90 (pElementCollector->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY))
92 rc = true;
93 break;
97 return rc;
100 void BufferNode::setReceivedAll()
101 /****** BufferNode/setReceiveAll *********************************************
103 * NAME
104 * setReceivedAll -- indicates that the element in this BufferNode has
105 * been compeletely bufferred.
107 * SYNOPSIS
108 * setReceivedAll();
110 * FUNCTION
111 * sets the all-received flag and launches ElementCollector's notify
112 * process.
114 * INPUTS
115 * empty
117 * RESULT
118 * empty
120 * HISTORY
121 * 05.01.2004 - implemented
123 * AUTHOR
124 * Michael Mi
125 * Email: michael.mi@sun.com
126 ******************************************************************************/
128 m_bAllReceived = true;
129 elementCollectorNotify();
132 bool BufferNode::isAllReceived() const
134 return m_bAllReceived;
137 void BufferNode::addElementCollector(const ElementCollector* pElementCollector)
138 /****** BufferNode/addElementCollector ***************************************
140 * NAME
141 * addElementCollector -- adds a new ElementCollector to this BufferNode.
143 * SYNOPSIS
144 * addElementCollector(pElementCollector);
146 * FUNCTION
147 * see NAME
149 * INPUTS
150 * pElementCollector - the ElementCollector to be added
152 * RESULT
153 * empty
155 * HISTORY
156 * 05.01.2004 - implemented
158 * AUTHOR
159 * Michael Mi
160 * Email: michael.mi@sun.com
161 ******************************************************************************/
163 m_vElementCollectors.push_back( pElementCollector );
164 ((ElementCollector*)pElementCollector)->setBufferNode(this);
167 void BufferNode::removeElementCollector(const ElementCollector* pElementCollector)
168 /****** BufferNode/removeElementCollector ************************************
170 * NAME
171 * removeElementCollector -- removes an ElementCollector from this
172 * BufferNode.
174 * SYNOPSIS
175 * removeElementCollector(pElementCollector);
177 * FUNCTION
178 * see NAME
180 * INPUTS
181 * pElementCollector - the ElementCollector to be removed
183 * RESULT
184 * empty
186 * HISTORY
187 * 05.01.2004 - implemented
189 * AUTHOR
190 * Michael Mi
191 * Email: michael.mi@sun.com
192 ******************************************************************************/
194 std::vector< const ElementCollector* >::iterator ii = m_vElementCollectors.begin();
196 for( ; ii != m_vElementCollectors.end() ; ++ii )
198 if( *ii == pElementCollector )
200 m_vElementCollectors.erase( ii );
201 ((ElementCollector*)pElementCollector)->setBufferNode(NULL);
202 break;
207 ElementMark* BufferNode::getBlocker() const
209 return m_pBlocker;
212 void BufferNode::setBlocker(const ElementMark* pBlocker)
213 /****** BufferNode/setBlocker ************************************************
215 * NAME
216 * setBlocker -- adds a blocker to this BufferNode.
218 * SYNOPSIS
219 * setBlocker(pBlocker);
221 * FUNCTION
222 * see NAME
224 * INPUTS
225 * pBlocker - the new blocker to be attached
227 * RESULT
228 * empty
230 * NOTES
231 * Because there is only one blocker permited for a BufferNode, so the
232 * old blocker on this BufferNode, if there is one, will be overcasted.
234 * HISTORY
235 * 05.01.2004 - implemented
237 * AUTHOR
238 * Michael Mi
239 * Email: michael.mi@sun.com
240 ******************************************************************************/
242 OSL_ASSERT(!(m_pBlocker != NULL && pBlocker != NULL));
244 m_pBlocker = (ElementMark*)pBlocker;
245 if (m_pBlocker != NULL)
247 m_pBlocker->setBufferNode(this);
251 rtl::OUString BufferNode::printChildren() const
252 /****** BufferNode/printChildren *********************************************
254 * NAME
255 * printChildren -- prints children information into a string.
257 * SYNOPSIS
258 * result = printChildren();
260 * FUNCTION
261 * see NAME
263 * INPUTS
264 * empty
266 * RESULT
267 * result - the information string
269 * HISTORY
270 * 05.01.2004 - implemented
272 * AUTHOR
273 * Michael Mi
274 * Email: michael.mi@sun.com
275 ******************************************************************************/
277 rtl::OUString rc;
278 std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
280 for( ; ii != m_vElementCollectors.end() ; ++ii )
282 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BufID=" ));
283 rc += rtl::OUString::valueOf((*ii)->getBufferId());
285 if (((ElementCollector*)(*ii))->getModify())
287 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[M]" ));
290 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ",Pri=" ));
292 switch (((ElementCollector*)(*ii))->getPriority())
294 case cssxc::sax::ElementMarkPriority_BEFOREMODIFY:
295 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BEFOREMODIFY" ));
296 break;
297 case cssxc::sax::ElementMarkPriority_AFTERMODIFY:
298 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFTERMODIFY" ));
299 break;
300 default:
301 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNKNOWN" ));
302 break;
305 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(" ));
307 if (((ElementCollector*)(*ii))->isInternalNotificationSuppressed())
309 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*IN-Suppressed* " ));
312 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SecID=" ));
313 rc += rtl::OUString::valueOf(((ElementCollector*)(*ii))->getSecurityId());
314 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ));
315 rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
318 return rc;
321 bool BufferNode::hasAnything() const
322 /****** BufferNode/hasAnything ***********************************************
324 * NAME
325 * hasAnything -- checks whether there is any ElementCollector or blocker
326 * on this BufferNode.
328 * SYNOPSIS
329 * bExist = hasAnything();
331 * FUNCTION
332 * see NAME
334 * INPUTS
335 * empty
337 * RESULT
338 * bExist - true if there is, false otherwise.
340 * HISTORY
341 * 05.01.2004 - implemented
343 * AUTHOR
344 * Michael Mi
345 * Email: michael.mi@sun.com
346 ******************************************************************************/
348 return (m_pBlocker != NULL || m_vElementCollectors.size() > 0);
351 bool BufferNode::hasChildren() const
352 /****** BufferNode/hasChildren ***********************************************
354 * NAME
355 * hasChildren -- checks whether this BufferNode has any child
356 * BufferNode.
358 * SYNOPSIS
359 * bExist = hasChildren();
361 * FUNCTION
362 * see NAME
364 * INPUTS
365 * empty
367 * RESULT
368 * bExist - true if there is, false otherwise.
370 * HISTORY
371 * 05.01.2004 - implemented
373 * AUTHOR
374 * Michael Mi
375 * Email: michael.mi@sun.com
376 ******************************************************************************/
378 return (m_vChildren.size() > 0);
381 std::vector< const BufferNode* >* BufferNode::getChildren() const
383 return new std::vector< const BufferNode* >( m_vChildren );
386 const BufferNode* BufferNode::getFirstChild() const
387 /****** BufferNode/getFirstChild *********************************************
389 * NAME
390 * getFirstChild -- retrieves the first child BufferNode.
392 * SYNOPSIS
393 * child = getFirstChild();
395 * FUNCTION
396 * see NAME
398 * INPUTS
399 * empty
401 * RESULT
402 * child - the first child BufferNode, or NULL if there is no child
403 * BufferNode.
405 * HISTORY
406 * 05.01.2004 - implemented
408 * AUTHOR
409 * Michael Mi
410 * Email: michael.mi@sun.com
411 ******************************************************************************/
413 BufferNode* rc = NULL;
415 if (m_vChildren.size() > 0)
417 rc = (BufferNode*)m_vChildren.front();
420 return (const BufferNode*)rc;
423 void BufferNode::addChild(const BufferNode* pChild, sal_Int32 nPosition)
424 /****** BufferNode/addChild(pChild,nPosition) ********************************
426 * NAME
427 * addChild -- inserts a child BufferNode at specific position.
429 * SYNOPSIS
430 * addChild(pChild, nPosition);
432 * FUNCTION
433 * see NAME
435 * INPUTS
436 * pChild - the child BufferNode to be added.
437 * nPosition - the position where the new child locates.
439 * RESULT
440 * empty
442 * NOTES
443 * If the nPosition is -1, then the new child BufferNode is appended
444 * at the end.
446 * HISTORY
447 * 05.01.2004 - implemented
449 * AUTHOR
450 * Michael Mi
451 * Email: michael.mi@sun.com
452 ******************************************************************************/
454 if (nPosition == -1)
456 m_vChildren.push_back( pChild );
458 else
460 std::vector< const BufferNode* >::iterator ii = m_vChildren.begin();
461 ii += nPosition;
462 m_vChildren.insert(ii, pChild);
466 void BufferNode::addChild(const BufferNode* pChild)
467 /****** BufferNode/addChild() ************************************************
469 * NAME
470 * addChild -- add a new child BufferNode.
472 * SYNOPSIS
473 * addChild(pChild);
475 * FUNCTION
476 * see NAME
478 * INPUTS
479 * pChild - the child BufferNode to be added.
481 * RESULT
482 * empty
484 * NOTES
485 * The new child BufferNode is appended at the end.
487 * HISTORY
488 * 05.01.2004 - implemented
490 * AUTHOR
491 * Michael Mi
492 * Email: michael.mi@sun.com
493 ******************************************************************************/
495 addChild(pChild, -1);
498 void BufferNode::removeChild(const BufferNode* pChild)
499 /****** BufferNode/removeChild ***********************************************
501 * NAME
502 * removeChild -- removes a child BufferNode from the children list.
504 * SYNOPSIS
505 * removeChild(pChild);
507 * FUNCTION
508 * see NAME
510 * INPUTS
511 * pChild - the child BufferNode to be removed
513 * RESULT
514 * empty
516 * HISTORY
517 * 05.01.2004 - implemented
519 * AUTHOR
520 * Michael Mi
521 * Email: michael.mi@sun.com
522 ******************************************************************************/
524 std::vector< const BufferNode* >::iterator ii = m_vChildren.begin();
526 for( ; ii != m_vChildren.end() ; ++ii )
528 if( *ii == pChild )
530 m_vChildren.erase( ii );
531 break;
536 sal_Int32 BufferNode::indexOfChild(const BufferNode* pChild) const
537 /****** BufferNode/indexOfChild **********************************************
539 * NAME
540 * indexOfChild -- gets the index of a child BufferNode.
542 * SYNOPSIS
543 * index = indexOfChild(pChild);
545 * FUNCTION
546 * see NAME
548 * INPUTS
549 * pChild - the child BufferNode whose index to be gotten
551 * RESULT
552 * index - the index of that child BufferNode. If that child BufferNode
553 * is not found, -1 is returned.
555 * HISTORY
556 * 05.01.2004 - implemented
558 * AUTHOR
559 * Michael Mi
560 * Email: michael.mi@sun.com
561 ******************************************************************************/
563 sal_Int32 nIndex = 0;
564 bool bFound = false;
566 std::vector< const BufferNode * >::const_iterator ii = m_vChildren.begin();
568 for( ; ii != m_vChildren.end() ; ++ii )
570 if( *ii == pChild )
572 bFound = true;
573 break;
575 nIndex++;
578 if (!bFound )
580 nIndex = -1;
583 return nIndex;
586 const BufferNode* BufferNode::childAt(sal_Int32 nIndex) const
587 /****** BufferNode/childAt ***************************************************
589 * NAME
590 * childAt -- retrieves the child BufferNode at specific possition.
592 * SYNOPSIS
593 * child = childAt(nIndex);
595 * FUNCTION
596 * see NAME
598 * INPUTS
599 * nIndex - the index of the child BufferNode to be retrieved
601 * RESULT
602 * child - the child BufferNode at index position, or NULL if the index
603 * is out of the range of children.
605 * HISTORY
606 * 05.01.2004 - implemented
608 * AUTHOR
609 * Michael Mi
610 * Email: michael.mi@sun.com
611 ******************************************************************************/
613 BufferNode* rc = NULL;
615 if (nIndex < ((sal_Int32)m_vChildren.size()) && nIndex >= 0)
617 rc = (BufferNode*)m_vChildren[nIndex];
620 return (const BufferNode*)rc;
623 const BufferNode* BufferNode::getParent() const
625 return m_pParent;
628 void BufferNode::setParent(const BufferNode* pParent)
630 m_pParent = (BufferNode*)pParent;
633 const BufferNode* BufferNode::getNextSibling() const
634 /****** BufferNode/getNextSibling ********************************************
636 * NAME
637 * getNextSibling -- retrieves the next sibling BufferNode.
639 * SYNOPSIS
640 * sibling = getNextSibling();
642 * FUNCTION
643 * see NAME
645 * INPUTS
646 * empty
648 * RESULT
649 * sibling - the next sibling BufferNode, or NULL if there is none.
651 * HISTORY
652 * 05.01.2004 - implemented
654 * AUTHOR
655 * Michael Mi
656 * Email: michael.mi@sun.com
657 ******************************************************************************/
659 BufferNode* rc = NULL;
661 if (m_pParent != NULL)
663 rc = (BufferNode*)m_pParent->getNextChild(this);
666 return (const BufferNode*)rc;
669 const BufferNode* BufferNode::isAncestor(const BufferNode* pDescendant) const
670 /****** BufferNode/isAncestor ************************************************
672 * NAME
673 * isAncestor -- checks whether this BufferNode is an ancestor of another
674 * BufferNode.
676 * SYNOPSIS
677 * bIs = isAncestor(pDescendant);
679 * FUNCTION
680 * see NAME
682 * INPUTS
683 * pDescendant - the BufferNode to be checked as a descendant
685 * RESULT
686 * bIs - true if this BufferNode is an ancestor of the pDescendant,
687 * false otherwise.
689 * HISTORY
690 * 05.01.2004 - implemented
692 * AUTHOR
693 * Michael Mi
694 * Email: michael.mi@sun.com
695 ******************************************************************************/
697 BufferNode* rc = NULL;
699 if (pDescendant != NULL)
701 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
703 for( ; ii != m_vChildren.end() ; ++ii )
705 BufferNode* pChild = (BufferNode*)*ii;
707 if (pChild == pDescendant)
709 rc = pChild;
710 break;
713 if (pChild->isAncestor(pDescendant) != NULL)
715 rc = pChild;
716 break;
721 return (const BufferNode*)rc;
724 bool BufferNode::isPrevious(const BufferNode* pFollowing) const
725 /****** BufferNode/isPrevious ************************************************
727 * NAME
728 * isPrevious -- checks whether this BufferNode is ahead of another
729 * BufferNode in the tree order.
731 * SYNOPSIS
732 * bIs = isPrevious(pFollowing);
734 * FUNCTION
735 * see NAME
737 * INPUTS
738 * pFollowing - the BufferNode to be checked as a following
740 * RESULT
741 * bIs - true if this BufferNode is ahead in the tree order, false
742 * otherwise.
744 * HISTORY
745 * 05.01.2004 - implemented
747 * AUTHOR
748 * Michael Mi
749 * Email: michael.mi@sun.com
750 ******************************************************************************/
752 bool rc = false;
754 BufferNode* pNextBufferNode = (BufferNode*)getNextNodeByTreeOrder();
755 while (pNextBufferNode != NULL)
757 if (pNextBufferNode == pFollowing)
759 rc = true;
760 break;
763 pNextBufferNode = (BufferNode*)(pNextBufferNode->getNextNodeByTreeOrder());
766 return rc;
769 const BufferNode* BufferNode::getNextNodeByTreeOrder() const
770 /****** BufferNode/getNextNodeByTreeOrder ************************************
772 * NAME
773 * getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree
774 * order.
776 * SYNOPSIS
777 * next = getNextNodeByTreeOrder();
779 * FUNCTION
780 * see NAME
782 * INPUTS
783 * empty
785 * RESULT
786 * next - the BufferNode following this BufferNode in the tree order,
787 * or NULL if there is none.
789 * NOTES
790 * The "next" node in tree order is defined as:
791 * 1. If a node has children, then the first child is;
792 * 2. otherwise, if it has a following sibling, then this sibling node is;
793 * 3. otherwise, if it has a parent node, the the parent's next sibling
794 * node is;
795 * 4. otherwise, no "next" node exists.
797 * HISTORY
798 * 05.01.2004 - implemented
800 * AUTHOR
801 * Michael Mi
802 * Email: michael.mi@sun.com
803 ******************************************************************************/
806 * If this buffer node has m_vChildren, then return the first
807 * child.
809 if (hasChildren())
811 return getFirstChild();
815 * Otherwise, it this buffer node has a following sibling,
816 * then return that sibling.
818 BufferNode* pNextSibling = (BufferNode*)getNextSibling();
819 if (pNextSibling != NULL)
821 return pNextSibling;
825 * Otherwise, it this buffer node has parent, then return
826 * its parent's following sibling.
828 BufferNode* pNode = (BufferNode*)this;
829 BufferNode* pParent;
830 BufferNode* pNextSiblingParent = NULL;
834 if (pNode == NULL)
836 break;
839 pParent = (BufferNode*)pNode->getParent();
840 if (pParent != NULL)
842 pNextSiblingParent = (BufferNode*)pParent->getNextSibling();
844 pNode = pParent;
846 }while (pNextSiblingParent == NULL);
848 return pNextSiblingParent;
851 cssu::Reference< cssxw::XXMLElementWrapper > BufferNode::getXMLElement() const
853 return m_xXMLElement;
856 void BufferNode::setXMLElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
858 m_xXMLElement = xXMLElement;
861 void BufferNode::notifyBranch()
862 /****** BufferNode/notifyBranch **********************************************
864 * NAME
865 * notifyBranch -- notifies each BufferNode in the branch of this
866 * BufferNode in the tree order.
868 * SYNOPSIS
869 * notifyBranch();
871 * FUNCTION
872 * see NAME
874 * INPUTS
875 * empty
877 * RESULT
878 * empty
880 * HISTORY
881 * 05.01.2004 - implemented
883 * AUTHOR
884 * Michael Mi
885 * Email: michael.mi@sun.com
886 ******************************************************************************/
888 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
890 for( ; ii != m_vChildren.end() ; ++ii )
892 BufferNode* pBufferNode = (BufferNode*)*ii;
893 pBufferNode->elementCollectorNotify();
894 pBufferNode->notifyBranch();
898 void BufferNode::notifyAncestor()
899 /****** BufferNode/notifyAncestor ********************************************
901 * NAME
902 * notifyAncestor -- notifies each ancestor BufferNode through the parent
903 * link.
905 * SYNOPSIS
906 * notifyAncestor();
908 * FUNCTION
909 * see NAME
911 * INPUTS
912 * empty
914 * RESULT
915 * empty
917 * HISTORY
918 * 05.01.2004 - implemented
920 * AUTHOR
921 * Michael Mi
922 * Email: michael.mi@sun.com
923 ******************************************************************************/
925 BufferNode* pParent = m_pParent;
926 while (pParent != NULL)
928 pParent->notifyAncestor();
929 pParent = (BufferNode*)pParent->getParent();
933 void BufferNode::elementCollectorNotify()
934 /****** BufferNode/elementCollectorNotify ************************************
936 * NAME
937 * elementCollectorNotify -- notifies this BufferNode.
939 * SYNOPSIS
940 * elementCollectorNotify();
942 * FUNCTION
943 * Notifies this BufferNode if the notification is not suppressed.
945 * INPUTS
946 * empty
948 * RESULT
949 * child - the first child BufferNode, or NULL if there is no child
950 * BufferNode.
952 * HISTORY
953 * 05.01.2004 - implemented
955 * AUTHOR
956 * Michael Mi
957 * Email: michael.mi@sun.com
958 ******************************************************************************/
960 if (m_vElementCollectors.size()>0)
962 cssxc::sax::ElementMarkPriority nMaxPriority = cssxc::sax::ElementMarkPriority_MINIMUM;
963 cssxc::sax::ElementMarkPriority nPriority;
966 * get the max priority among ElementCollectors on this BufferNode
968 std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
969 for( ; ii != m_vElementCollectors.end() ; ++ii )
971 ElementCollector* pElementCollector = (ElementCollector*)*ii;
972 nPriority = pElementCollector->getPriority();
973 if (nPriority > nMaxPriority)
975 nMaxPriority = nPriority;
979 std::vector< const ElementCollector* > vElementCollectors( m_vElementCollectors );
980 ii = vElementCollectors.begin();
982 for( ; ii != vElementCollectors.end() ; ++ii )
984 ElementCollector* pElementCollector = (ElementCollector*)*ii;
985 nPriority = pElementCollector->getPriority();
986 bool bToModify = pElementCollector->getModify();
989 * Only ElementCollector with the max priority can
990 * perform notify operation.
991 * Moreover, if any blocker exists in the subtree of
992 * this BufferNode, this ElementCollector can't do notify
993 * unless its priority is BEFOREMODIFY.
995 if (nPriority == nMaxPriority &&
996 (nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY ||
997 !isBlockerInSubTreeIncluded(pElementCollector->getSecurityId())))
1000 * If this ElementCollector will modify the bufferred element, then
1001 * special attention must be paid.
1003 * If there is any ElementCollector in the subtree or any ancestor
1004 * ElementCollector with PRI_BEFPREMODIFY priority, this
1005 * ElementCollector can't perform notify operation, otherwise, it
1006 * will destroy the bufferred element, in turn, ElementCollectors
1007 * mentioned above can't perform their mission.
1009 //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY &&
1010 if (!(bToModify &&
1011 (isECInSubTreeIncluded(pElementCollector->getSecurityId()) ||
1012 isECOfBeforeModifyInAncestorIncluded(pElementCollector->getSecurityId()))
1015 pElementCollector->notifyListener();
1022 bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
1023 /****** BufferNode/isECInSubTreeIncluded *************************************
1025 * NAME
1026 * isECInSubTreeIncluded -- checks whether there is any ElementCollector
1027 * in the branch of this BufferNode.
1029 * SYNOPSIS
1030 * bExist = isECInSubTreeIncluded(nIgnoredSecurityId);
1032 * FUNCTION
1033 * checks each BufferNode in the branch of this BufferNode, if there is
1034 * an ElementCollector whose signatureId is not ignored, then return
1035 * true, otherwise, false returned.
1037 * INPUTS
1038 * nIgnoredSecurityId - the security Id to be ignored. If it equals
1039 * to UNDEFINEDSECURITYID, then no security Id
1040 * will be ignored.
1042 * RESULT
1043 * bExist - true if a match found, false otherwise.
1045 * HISTORY
1046 * 05.01.2004 - implemented
1048 * AUTHOR
1049 * Michael Mi
1050 * Email: michael.mi@sun.com
1051 ******************************************************************************/
1053 bool rc = false;
1055 std::vector< const ElementCollector* >::const_iterator jj = m_vElementCollectors.begin();
1057 for( ; jj != m_vElementCollectors.end() ; ++jj )
1059 ElementCollector* pElementCollector = (ElementCollector*)*jj;
1060 if (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
1061 pElementCollector->getSecurityId() != nIgnoredSecurityId)
1063 rc = true;
1064 break;
1068 if ( !rc )
1070 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1072 for( ; ii != m_vChildren.end() ; ++ii )
1074 BufferNode* pBufferNode = (BufferNode*)*ii;
1076 if ( pBufferNode->isECInSubTreeIncluded(nIgnoredSecurityId))
1078 rc = true;
1079 break;
1084 return rc;
1087 bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const
1088 /****** BufferNode/isECOfBeforeModifyInAncestorIncluded **********************
1090 * NAME
1091 * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some
1092 * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY
1093 * priority.
1095 * SYNOPSIS
1096 * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId);
1098 * FUNCTION
1099 * checks each ancestor BufferNode through the parent link, if there is
1100 * an ElementCollector with PRI_BEFPREMODIFY priority and its
1101 * signatureId is not ignored, then return true, otherwise, false
1102 * returned.
1104 * INPUTS
1105 * nIgnoredSecurityId - the security Id to be ignored. If it equals
1106 * to UNDEFINEDSECURITYID, then no security Id
1107 * will be ignored.
1109 * RESULT
1110 * bExist - true if a match found, false otherwise.
1112 * HISTORY
1113 * 05.01.2004 - implemented
1115 * AUTHOR
1116 * Michael Mi
1117 * Email: michael.mi@sun.com
1118 ******************************************************************************/
1120 bool rc = false;
1122 BufferNode* pParentNode = m_pParent;
1123 while (pParentNode != NULL)
1125 if (pParentNode->isECOfBeforeModifyIncluded(nIgnoredSecurityId))
1127 rc = true;
1128 break;
1131 pParentNode = (BufferNode*)pParentNode->getParent();
1134 return rc;
1137 bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
1138 /****** BufferNode/isBlockerInSubTreeIncluded ********************************
1140 * NAME
1141 * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode
1142 * which has blocker on it
1144 * SYNOPSIS
1145 * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId);
1147 * FUNCTION
1148 * checks each BufferNode in the branch of this BufferNode, if one has
1149 * a blocker on it, and the blocker's securityId is not ignored, then
1150 * returns true; otherwise, false returns.
1152 * INPUTS
1153 * nIgnoredSecurityId - the security Id to be ignored. If it equals
1154 * to UNDEFINEDSECURITYID, then no security Id
1155 * will be ignored.
1157 * RESULT
1158 * bExist - true if a match found, false otherwise.
1160 * HISTORY
1161 * 05.01.2004 - implemented
1163 * AUTHOR
1164 * Michael Mi
1165 * Email: michael.mi@sun.com
1166 ******************************************************************************/
1168 bool rc = false;
1170 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1172 for( ; ii != m_vChildren.end() ; ++ii )
1174 BufferNode* pBufferNode = (BufferNode*)*ii;
1175 ElementMark* pBlocker = pBufferNode->getBlocker();
1177 if (pBlocker != NULL &&
1178 (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
1179 pBlocker->getSecurityId() != nIgnoredSecurityId ))
1181 rc = true;
1182 break;
1185 if (rc || pBufferNode->isBlockerInSubTreeIncluded(nIgnoredSecurityId))
1187 rc = true;
1188 break;
1192 return rc;
1195 const BufferNode* BufferNode::getNextChild(const BufferNode* pChild) const
1196 /****** BufferNode/getNextChild **********************************************
1198 * NAME
1199 * getNextChild -- get the next child BufferNode.
1201 * SYNOPSIS
1202 * nextChild = getNextChild();
1204 * FUNCTION
1205 * see NAME
1207 * INPUTS
1208 * pChild - the child BufferNode whose next node is retrieved.
1210 * RESULT
1211 * nextChild - the next child BufferNode after the pChild, or NULL if
1212 * there is none.
1214 * HISTORY
1215 * 05.01.2004 - implemented
1217 * AUTHOR
1218 * Michael Mi
1219 * Email: michael.mi@sun.com
1220 ******************************************************************************/
1222 BufferNode* rc = NULL;
1223 bool bChildFound = false;
1225 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1226 for( ; ii != m_vChildren.end() ; ++ii )
1228 if (bChildFound)
1230 rc = (BufferNode*)*ii;
1231 break;
1234 if( *ii == pChild )
1236 bChildFound = true;
1240 return (const BufferNode*)rc;
1244 void BufferNode::freeAllChildren()
1245 /****** BufferNode/freeAllChildren *******************************************
1247 * NAME
1248 * freeAllChildren -- free all his child BufferNode.
1250 * SYNOPSIS
1251 * freeAllChildren();
1253 * FUNCTION
1254 * see NAME
1256 * INPUTS
1257 * empty
1259 * RESULT
1260 * empty
1262 * HISTORY
1263 * 30.03.2004 - the correct the memory leak bug
1265 * AUTHOR
1266 * Michael Mi
1267 * Email: michael.mi@sun.com
1268 ******************************************************************************/
1270 std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1271 for( ; ii != m_vChildren.end() ; ++ii )
1273 BufferNode *pChild = (BufferNode *)(*ii);
1274 pChild->freeAllChildren();
1275 delete pChild;
1278 m_vChildren.clear();