xref: /AOO41X/main/xmlsecurity/source/framework/buffernode.cxx (revision 06b3ce531745799678cf4bb887ef37436d81238b)
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 
BufferNode(const cssu::Reference<cssxw::XXMLElementWrapper> & xXMLElement)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 
isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId) const44 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 
setReceivedAll()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 
isAllReceived() const128 bool BufferNode::isAllReceived() const
129 {
130     return m_bAllReceived;
131 }
132 
addElementCollector(const ElementCollector * pElementCollector)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 
removeElementCollector(const ElementCollector * pElementCollector)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 
getBlocker() const203 ElementMark* BufferNode::getBlocker() const
204 {
205     return m_pBlocker;
206 }
207 
setBlocker(const ElementMark * pBlocker)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 
printChildren() const247 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 
hasAnything() const317 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 
hasChildren() const347 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 
getChildren() const377 std::vector< const BufferNode* >* BufferNode::getChildren() const
378 {
379     return new std::vector< const BufferNode* >( m_vChildren );
380 }
381 
getFirstChild() const382 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 
addChild(const BufferNode * pChild,sal_Int32 nPosition)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 
addChild(const BufferNode * pChild)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 
removeChild(const BufferNode * pChild)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 
indexOfChild(const BufferNode * pChild) const532 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 
childAt(sal_Int32 nIndex) const582 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 
getParent() const619 const BufferNode* BufferNode::getParent() const
620 {
621     return m_pParent;
622 }
623 
setParent(const BufferNode * pParent)624 void BufferNode::setParent(const BufferNode* pParent)
625 {
626     m_pParent = (BufferNode*)pParent;
627 }
628 
getNextSibling() const629 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 
isAncestor(const BufferNode * pDescendant) const665 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 
isPrevious(const BufferNode * pFollowing) const720 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 
getNextNodeByTreeOrder() const765 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 
getXMLElement() const847 cssu::Reference< cssxw::XXMLElementWrapper > BufferNode::getXMLElement() const
848 {
849     return m_xXMLElement;
850 }
851 
setXMLElement(const cssu::Reference<cssxw::XXMLElementWrapper> & xXMLElement)852 void BufferNode::setXMLElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
853 {
854     m_xXMLElement = xXMLElement;
855 }
856 
notifyBranch()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 
notifyAncestor()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 
elementCollectorNotify()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 
isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const1018 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 
isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const1083 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 
isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const1133 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 
getNextChild(const BufferNode * pChild) const1191 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 
freeAllChildren()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