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 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