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