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