Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "elementmark.hxx"
22 : #include "elementcollector.hxx"
23 : #include "buffernode.hxx"
24 : #include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp>
25 :
26 : namespace cssu = com::sun::star::uno;
27 : namespace cssxw = com::sun::star::xml::wrapper;
28 : namespace cssxc = com::sun::star::xml::crypto;
29 :
30 0 : BufferNode::BufferNode( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
31 : :m_pParent(NULL),
32 : m_pBlocker(NULL),
33 : m_bAllReceived(false),
34 0 : m_xXMLElement(xXMLElement)
35 : {
36 0 : }
37 :
38 0 : bool BufferNode::isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId) const
39 : /****** BufferNode/isECOfBeforeModifyIncluded ********************************
40 : *
41 : * NAME
42 : * isECOfBeforeModifyIncluded -- checks whether there is some
43 : * ElementCollector on this BufferNode, that has BEFORE-MODIFY priority.
44 : *
45 : * SYNOPSIS
46 : * bExist = isECOfBeforeModifyIncluded(nIgnoredSecurityId);
47 : *
48 : * FUNCTION
49 : * checks each ElementCollector on this BufferNode, if all following
50 : * conditions are satisfied, then returns true:
51 : * 1. the ElementCollector's priority is BEFOREMODIFY;
52 : * 2. the ElementCollector's securityId can't be ignored.
53 : * otherwise, returns false.
54 : *
55 : * INPUTS
56 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
57 : * to UNDEFINEDSECURITYID, then no security Id
58 : * will be ignored.
59 : *
60 : * RESULT
61 : * bExist - true if a match found, false otherwise
62 : *
63 : * AUTHOR
64 : * Michael Mi
65 : * Email: michael.mi@sun.com
66 : ******************************************************************************/
67 : {
68 0 : bool rc = false;
69 0 : std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
70 :
71 0 : for( ; ii != m_vElementCollectors.end() ; ++ii )
72 : {
73 0 : ElementCollector* pElementCollector = (ElementCollector*)*ii;
74 :
75 0 : if ((nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
76 0 : pElementCollector->getSecurityId() != nIgnoredSecurityId) &&
77 0 : (pElementCollector->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY))
78 : {
79 0 : rc = true;
80 0 : break;
81 : }
82 : }
83 :
84 0 : return rc;
85 : }
86 :
87 0 : void BufferNode::setReceivedAll()
88 : /****** BufferNode/setReceiveAll *********************************************
89 : *
90 : * NAME
91 : * setReceivedAll -- indicates that the element in this BufferNode has
92 : * been compeletely bufferred.
93 : *
94 : * SYNOPSIS
95 : * setReceivedAll();
96 : *
97 : * FUNCTION
98 : * sets the all-received flag and launches ElementCollector's notify
99 : * process.
100 : *
101 : * INPUTS
102 : * empty
103 : *
104 : * RESULT
105 : * empty
106 : *
107 : * AUTHOR
108 : * Michael Mi
109 : * Email: michael.mi@sun.com
110 : ******************************************************************************/
111 : {
112 0 : m_bAllReceived = true;
113 0 : elementCollectorNotify();
114 0 : }
115 :
116 :
117 0 : void BufferNode::addElementCollector(const ElementCollector* pElementCollector)
118 : /****** BufferNode/addElementCollector ***************************************
119 : *
120 : * NAME
121 : * addElementCollector -- adds a new ElementCollector to this BufferNode.
122 : *
123 : * SYNOPSIS
124 : * addElementCollector(pElementCollector);
125 : *
126 : * FUNCTION
127 : * see NAME
128 : *
129 : * INPUTS
130 : * pElementCollector - the ElementCollector to be added
131 : *
132 : * RESULT
133 : * empty
134 : *
135 : * AUTHOR
136 : * Michael Mi
137 : * Email: michael.mi@sun.com
138 : ******************************************************************************/
139 : {
140 0 : m_vElementCollectors.push_back( pElementCollector );
141 0 : ((ElementCollector*)pElementCollector)->setBufferNode(this);
142 0 : }
143 :
144 0 : void BufferNode::removeElementCollector(const ElementCollector* pElementCollector)
145 : /****** BufferNode/removeElementCollector ************************************
146 : *
147 : * NAME
148 : * removeElementCollector -- removes an ElementCollector from this
149 : * BufferNode.
150 : *
151 : * SYNOPSIS
152 : * removeElementCollector(pElementCollector);
153 : *
154 : * FUNCTION
155 : * see NAME
156 : *
157 : * INPUTS
158 : * pElementCollector - the ElementCollector to be removed
159 : *
160 : * RESULT
161 : * empty
162 : *
163 : * AUTHOR
164 : * Michael Mi
165 : * Email: michael.mi@sun.com
166 : ******************************************************************************/
167 : {
168 0 : std::vector< const ElementCollector* >::iterator ii = m_vElementCollectors.begin();
169 :
170 0 : for( ; ii != m_vElementCollectors.end() ; ++ii )
171 : {
172 0 : if( *ii == pElementCollector )
173 : {
174 0 : m_vElementCollectors.erase( ii );
175 0 : ((ElementCollector*)pElementCollector)->setBufferNode(NULL);
176 0 : break;
177 : }
178 : }
179 0 : }
180 :
181 :
182 0 : void BufferNode::setBlocker(const ElementMark* pBlocker)
183 : /****** BufferNode/setBlocker ************************************************
184 : *
185 : * NAME
186 : * setBlocker -- adds a blocker to this BufferNode.
187 : *
188 : * SYNOPSIS
189 : * setBlocker(pBlocker);
190 : *
191 : * FUNCTION
192 : * see NAME
193 : *
194 : * INPUTS
195 : * pBlocker - the new blocker to be attached
196 : *
197 : * RESULT
198 : * empty
199 : *
200 : * NOTES
201 : * Because there is only one blocker permited for a BufferNode, so the
202 : * old blocker on this BufferNode, if there is one, will be overcasted.
203 : *
204 : * AUTHOR
205 : * Michael Mi
206 : * Email: michael.mi@sun.com
207 : ******************************************************************************/
208 : {
209 : OSL_ASSERT(!(m_pBlocker != NULL && pBlocker != NULL));
210 :
211 0 : m_pBlocker = (ElementMark*)pBlocker;
212 0 : if (m_pBlocker != NULL)
213 : {
214 0 : m_pBlocker->setBufferNode(this);
215 : }
216 0 : }
217 :
218 0 : OUString BufferNode::printChildren() const
219 : /****** BufferNode/printChildren *********************************************
220 : *
221 : * NAME
222 : * printChildren -- prints children information into a string.
223 : *
224 : * SYNOPSIS
225 : * result = printChildren();
226 : *
227 : * FUNCTION
228 : * see NAME
229 : *
230 : * INPUTS
231 : * empty
232 : *
233 : * RESULT
234 : * result - the information string
235 : *
236 : * AUTHOR
237 : * Michael Mi
238 : * Email: michael.mi@sun.com
239 : ******************************************************************************/
240 : {
241 0 : OUString rc;
242 0 : std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
243 :
244 0 : for( ; ii != m_vElementCollectors.end() ; ++ii )
245 : {
246 0 : rc += OUString( "BufID=" );
247 0 : rc += OUString::number((*ii)->getBufferId());
248 :
249 0 : if (((ElementCollector*)(*ii))->getModify())
250 : {
251 0 : rc += OUString( "[M]" );
252 : }
253 :
254 0 : rc += OUString( ",Pri=" );
255 :
256 0 : switch (((ElementCollector*)(*ii))->getPriority())
257 : {
258 : case cssxc::sax::ElementMarkPriority_BEFOREMODIFY:
259 0 : rc += OUString( "BEFOREMODIFY" );
260 0 : break;
261 : case cssxc::sax::ElementMarkPriority_AFTERMODIFY:
262 0 : rc += OUString( "AFTERMODIFY" );
263 0 : break;
264 : default:
265 0 : rc += OUString( "UNKNOWN" );
266 0 : break;
267 : }
268 :
269 0 : rc += OUString( "(" );
270 0 : rc += OUString( "SecID=" );
271 0 : rc += OUString::number(((ElementCollector*)(*ii))->getSecurityId());
272 0 : rc += OUString( ")" );
273 0 : rc += OUString( " " );
274 : }
275 :
276 0 : return rc;
277 : }
278 :
279 0 : bool BufferNode::hasAnything() const
280 : /****** BufferNode/hasAnything ***********************************************
281 : *
282 : * NAME
283 : * hasAnything -- checks whether there is any ElementCollector or blocker
284 : * on this BufferNode.
285 : *
286 : * SYNOPSIS
287 : * bExist = hasAnything();
288 : *
289 : * FUNCTION
290 : * see NAME
291 : *
292 : * INPUTS
293 : * empty
294 : *
295 : * RESULT
296 : * bExist - true if there is, false otherwise.
297 : *
298 : * AUTHOR
299 : * Michael Mi
300 : * Email: michael.mi@sun.com
301 : ******************************************************************************/
302 : {
303 0 : return (m_pBlocker || !m_vElementCollectors.empty());
304 : }
305 :
306 0 : bool BufferNode::hasChildren() const
307 : /****** BufferNode/hasChildren ***********************************************
308 : *
309 : * NAME
310 : * hasChildren -- checks whether this BufferNode has any child
311 : * BufferNode.
312 : *
313 : * SYNOPSIS
314 : * bExist = hasChildren();
315 : *
316 : * FUNCTION
317 : * see NAME
318 : *
319 : * INPUTS
320 : * empty
321 : *
322 : * RESULT
323 : * bExist - true if there is, false otherwise.
324 : *
325 : * AUTHOR
326 : * Michael Mi
327 : * Email: michael.mi@sun.com
328 : ******************************************************************************/
329 : {
330 0 : return (!m_vChildren.empty());
331 : }
332 :
333 0 : std::vector< const BufferNode* >* BufferNode::getChildren() const
334 : {
335 0 : return new std::vector< const BufferNode* >( m_vChildren );
336 : }
337 :
338 0 : const BufferNode* BufferNode::getFirstChild() const
339 : /****** BufferNode/getFirstChild *********************************************
340 : *
341 : * NAME
342 : * getFirstChild -- retrieves the first child BufferNode.
343 : *
344 : * SYNOPSIS
345 : * child = getFirstChild();
346 : *
347 : * FUNCTION
348 : * see NAME
349 : *
350 : * INPUTS
351 : * empty
352 : *
353 : * RESULT
354 : * child - the first child BufferNode, or NULL if there is no child
355 : * BufferNode.
356 : *
357 : * AUTHOR
358 : * Michael Mi
359 : * Email: michael.mi@sun.com
360 : ******************************************************************************/
361 : {
362 0 : BufferNode* rc = NULL;
363 :
364 0 : if (!m_vChildren.empty())
365 : {
366 0 : rc = (BufferNode*)m_vChildren.front();
367 : }
368 :
369 0 : return (const BufferNode*)rc;
370 : }
371 :
372 0 : void BufferNode::addChild(const BufferNode* pChild, sal_Int32 nPosition)
373 : /****** BufferNode/addChild(pChild,nPosition) ********************************
374 : *
375 : * NAME
376 : * addChild -- inserts a child BufferNode at specific position.
377 : *
378 : * SYNOPSIS
379 : * addChild(pChild, nPosition);
380 : *
381 : * FUNCTION
382 : * see NAME
383 : *
384 : * INPUTS
385 : * pChild - the child BufferNode to be added.
386 : * nPosition - the position where the new child locates.
387 : *
388 : * RESULT
389 : * empty
390 : *
391 : * NOTES
392 : * If the nPosition is -1, then the new child BufferNode is appended
393 : * at the end.
394 : *
395 : * AUTHOR
396 : * Michael Mi
397 : * Email: michael.mi@sun.com
398 : ******************************************************************************/
399 : {
400 0 : if (nPosition == -1)
401 : {
402 0 : m_vChildren.push_back( pChild );
403 : }
404 : else
405 : {
406 0 : std::vector< const BufferNode* >::iterator ii = m_vChildren.begin();
407 0 : ii += nPosition;
408 0 : m_vChildren.insert(ii, pChild);
409 : }
410 0 : }
411 :
412 0 : void BufferNode::addChild(const BufferNode* pChild)
413 : /****** BufferNode/addChild() ************************************************
414 : *
415 : * NAME
416 : * addChild -- add a new child BufferNode.
417 : *
418 : * SYNOPSIS
419 : * addChild(pChild);
420 : *
421 : * FUNCTION
422 : * see NAME
423 : *
424 : * INPUTS
425 : * pChild - the child BufferNode to be added.
426 : *
427 : * RESULT
428 : * empty
429 : *
430 : * NOTES
431 : * The new child BufferNode is appended at the end.
432 : *
433 : * AUTHOR
434 : * Michael Mi
435 : * Email: michael.mi@sun.com
436 : ******************************************************************************/
437 : {
438 0 : addChild(pChild, -1);
439 0 : }
440 :
441 0 : void BufferNode::removeChild(const BufferNode* pChild)
442 : /****** BufferNode/removeChild ***********************************************
443 : *
444 : * NAME
445 : * removeChild -- removes a child BufferNode from the children list.
446 : *
447 : * SYNOPSIS
448 : * removeChild(pChild);
449 : *
450 : * FUNCTION
451 : * see NAME
452 : *
453 : * INPUTS
454 : * pChild - the child BufferNode to be removed
455 : *
456 : * RESULT
457 : * empty
458 : *
459 : * AUTHOR
460 : * Michael Mi
461 : * Email: michael.mi@sun.com
462 : ******************************************************************************/
463 : {
464 0 : std::vector< const BufferNode* >::iterator ii = m_vChildren.begin();
465 :
466 0 : for( ; ii != m_vChildren.end() ; ++ii )
467 : {
468 0 : if( *ii == pChild )
469 : {
470 0 : m_vChildren.erase( ii );
471 0 : break;
472 : }
473 : }
474 0 : }
475 :
476 0 : sal_Int32 BufferNode::indexOfChild(const BufferNode* pChild) const
477 : /****** BufferNode/indexOfChild **********************************************
478 : *
479 : * NAME
480 : * indexOfChild -- gets the index of a child BufferNode.
481 : *
482 : * SYNOPSIS
483 : * index = indexOfChild(pChild);
484 : *
485 : * FUNCTION
486 : * see NAME
487 : *
488 : * INPUTS
489 : * pChild - the child BufferNode whose index to be gotten
490 : *
491 : * RESULT
492 : * index - the index of that child BufferNode. If that child BufferNode
493 : * is not found, -1 is returned.
494 : *
495 : * AUTHOR
496 : * Michael Mi
497 : * Email: michael.mi@sun.com
498 : ******************************************************************************/
499 : {
500 0 : sal_Int32 nIndex = 0;
501 0 : bool bFound = false;
502 :
503 0 : std::vector< const BufferNode * >::const_iterator ii = m_vChildren.begin();
504 :
505 0 : for( ; ii != m_vChildren.end() ; ++ii )
506 : {
507 0 : if( *ii == pChild )
508 : {
509 0 : bFound = true;
510 0 : break;
511 : }
512 0 : nIndex++;
513 : }
514 :
515 0 : if (!bFound )
516 : {
517 0 : nIndex = -1;
518 : }
519 :
520 0 : return nIndex;
521 : }
522 :
523 :
524 0 : void BufferNode::setParent(const BufferNode* pParent)
525 : {
526 0 : m_pParent = (BufferNode*)pParent;
527 0 : }
528 :
529 0 : const BufferNode* BufferNode::getNextSibling() const
530 : /****** BufferNode/getNextSibling ********************************************
531 : *
532 : * NAME
533 : * getNextSibling -- retrieves the next sibling BufferNode.
534 : *
535 : * SYNOPSIS
536 : * sibling = getNextSibling();
537 : *
538 : * FUNCTION
539 : * see NAME
540 : *
541 : * INPUTS
542 : * empty
543 : *
544 : * RESULT
545 : * sibling - the next sibling BufferNode, or NULL if there is none.
546 : *
547 : * AUTHOR
548 : * Michael Mi
549 : * Email: michael.mi@sun.com
550 : ******************************************************************************/
551 : {
552 0 : BufferNode* rc = NULL;
553 :
554 0 : if (m_pParent != NULL)
555 : {
556 0 : rc = (BufferNode*)m_pParent->getNextChild(this);
557 : }
558 :
559 0 : return (const BufferNode*)rc;
560 : }
561 :
562 0 : const BufferNode* BufferNode::isAncestor(const BufferNode* pDescendant) const
563 : /****** BufferNode/isAncestor ************************************************
564 : *
565 : * NAME
566 : * isAncestor -- checks whether this BufferNode is an ancestor of another
567 : * BufferNode.
568 : *
569 : * SYNOPSIS
570 : * bIs = isAncestor(pDescendant);
571 : *
572 : * FUNCTION
573 : * see NAME
574 : *
575 : * INPUTS
576 : * pDescendant - the BufferNode to be checked as a descendant
577 : *
578 : * RESULT
579 : * bIs - true if this BufferNode is an ancestor of the pDescendant,
580 : * false otherwise.
581 : *
582 : * AUTHOR
583 : * Michael Mi
584 : * Email: michael.mi@sun.com
585 : ******************************************************************************/
586 : {
587 0 : BufferNode* rc = NULL;
588 :
589 0 : if (pDescendant != NULL)
590 : {
591 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
592 :
593 0 : for( ; ii != m_vChildren.end() ; ++ii )
594 : {
595 0 : BufferNode* pChild = (BufferNode*)*ii;
596 :
597 0 : if (pChild == pDescendant)
598 : {
599 0 : rc = pChild;
600 0 : break;
601 : }
602 :
603 0 : if (pChild->isAncestor(pDescendant) != NULL)
604 : {
605 0 : rc = pChild;
606 0 : break;
607 : }
608 : }
609 : }
610 :
611 0 : return (const BufferNode*)rc;
612 : }
613 :
614 0 : bool BufferNode::isPrevious(const BufferNode* pFollowing) const
615 : /****** BufferNode/isPrevious ************************************************
616 : *
617 : * NAME
618 : * isPrevious -- checks whether this BufferNode is ahead of another
619 : * BufferNode in the tree order.
620 : *
621 : * SYNOPSIS
622 : * bIs = isPrevious(pFollowing);
623 : *
624 : * FUNCTION
625 : * see NAME
626 : *
627 : * INPUTS
628 : * pFollowing - the BufferNode to be checked as a following
629 : *
630 : * RESULT
631 : * bIs - true if this BufferNode is ahead in the tree order, false
632 : * otherwise.
633 : *
634 : * AUTHOR
635 : * Michael Mi
636 : * Email: michael.mi@sun.com
637 : ******************************************************************************/
638 : {
639 0 : bool rc = false;
640 :
641 0 : BufferNode* pNextBufferNode = (BufferNode*)getNextNodeByTreeOrder();
642 0 : while (pNextBufferNode != NULL)
643 : {
644 0 : if (pNextBufferNode == pFollowing)
645 : {
646 0 : rc = true;
647 0 : break;
648 : }
649 :
650 0 : pNextBufferNode = (BufferNode*)(pNextBufferNode->getNextNodeByTreeOrder());
651 : }
652 :
653 0 : return rc;
654 : }
655 :
656 0 : const BufferNode* BufferNode::getNextNodeByTreeOrder() const
657 : /****** BufferNode/getNextNodeByTreeOrder ************************************
658 : *
659 : * NAME
660 : * getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree
661 : * order.
662 : *
663 : * SYNOPSIS
664 : * next = getNextNodeByTreeOrder();
665 : *
666 : * FUNCTION
667 : * see NAME
668 : *
669 : * INPUTS
670 : * empty
671 : *
672 : * RESULT
673 : * next - the BufferNode following this BufferNode in the tree order,
674 : * or NULL if there is none.
675 : *
676 : * NOTES
677 : * The "next" node in tree order is defined as:
678 : * 1. If a node has children, then the first child is;
679 : * 2. otherwise, if it has a following sibling, then this sibling node is;
680 : * 3. otherwise, if it has a parent node, the parent's next sibling
681 : * node is;
682 : * 4. otherwise, no "next" node exists.
683 : *
684 : * AUTHOR
685 : * Michael Mi
686 : * Email: michael.mi@sun.com
687 : ******************************************************************************/
688 : {
689 : /*
690 : * If this buffer node has m_vChildren, then return the first
691 : * child.
692 : */
693 0 : if (hasChildren())
694 : {
695 0 : return getFirstChild();
696 : }
697 :
698 : /*
699 : * Otherwise, it this buffer node has a following sibling,
700 : * then return that sibling.
701 : */
702 0 : BufferNode* pNextSibling = (BufferNode*)getNextSibling();
703 0 : if (pNextSibling != NULL)
704 : {
705 0 : return pNextSibling;
706 : }
707 :
708 : /*
709 : * Otherwise, it this buffer node has parent, then return
710 : * its parent's following sibling.
711 : */
712 0 : BufferNode* pNode = (BufferNode*)this;
713 : BufferNode* pParent;
714 0 : BufferNode* pNextSiblingParent = NULL;
715 :
716 0 : do
717 : {
718 0 : if (pNode == NULL)
719 : {
720 0 : break;
721 : }
722 :
723 0 : pParent = (BufferNode*)pNode->getParent();
724 0 : if (pParent != NULL)
725 : {
726 0 : pNextSiblingParent = (BufferNode*)pParent->getNextSibling();
727 : }
728 0 : pNode = pParent;
729 :
730 : }while (pNextSiblingParent == NULL);
731 :
732 0 : return pNextSiblingParent;
733 : }
734 :
735 :
736 0 : void BufferNode::setXMLElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement )
737 : {
738 0 : m_xXMLElement = xXMLElement;
739 0 : }
740 :
741 0 : void BufferNode::notifyBranch()
742 : /****** BufferNode/notifyBranch **********************************************
743 : *
744 : * NAME
745 : * notifyBranch -- notifies each BufferNode in the branch of this
746 : * BufferNode in the tree order.
747 : *
748 : * SYNOPSIS
749 : * notifyBranch();
750 : *
751 : * FUNCTION
752 : * see NAME
753 : *
754 : * INPUTS
755 : * empty
756 : *
757 : * RESULT
758 : * empty
759 : *
760 : * AUTHOR
761 : * Michael Mi
762 : * Email: michael.mi@sun.com
763 : ******************************************************************************/
764 : {
765 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
766 :
767 0 : for( ; ii != m_vChildren.end() ; ++ii )
768 : {
769 0 : BufferNode* pBufferNode = (BufferNode*)*ii;
770 0 : pBufferNode->elementCollectorNotify();
771 0 : pBufferNode->notifyBranch();
772 : }
773 0 : }
774 :
775 0 : void BufferNode::elementCollectorNotify()
776 : /****** BufferNode/elementCollectorNotify ************************************
777 : *
778 : * NAME
779 : * elementCollectorNotify -- notifies this BufferNode.
780 : *
781 : * SYNOPSIS
782 : * elementCollectorNotify();
783 : *
784 : * FUNCTION
785 : * Notifies this BufferNode if the notification is not suppressed.
786 : *
787 : * INPUTS
788 : * empty
789 : *
790 : * RESULT
791 : * child - the first child BufferNode, or NULL if there is no child
792 : * BufferNode.
793 : *
794 : * AUTHOR
795 : * Michael Mi
796 : * Email: michael.mi@sun.com
797 : ******************************************************************************/
798 : {
799 0 : if (!m_vElementCollectors.empty())
800 : {
801 0 : cssxc::sax::ElementMarkPriority nMaxPriority = cssxc::sax::ElementMarkPriority_MINIMUM;
802 : cssxc::sax::ElementMarkPriority nPriority;
803 :
804 : /*
805 : * get the max priority among ElementCollectors on this BufferNode
806 : */
807 0 : std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
808 0 : for( ; ii != m_vElementCollectors.end() ; ++ii )
809 : {
810 0 : ElementCollector* pElementCollector = (ElementCollector*)*ii;
811 0 : nPriority = pElementCollector->getPriority();
812 0 : if (nPriority > nMaxPriority)
813 : {
814 0 : nMaxPriority = nPriority;
815 : }
816 : }
817 :
818 0 : std::vector< const ElementCollector* > vElementCollectors( m_vElementCollectors );
819 0 : ii = vElementCollectors.begin();
820 :
821 0 : for( ; ii != vElementCollectors.end() ; ++ii )
822 : {
823 0 : ElementCollector* pElementCollector = (ElementCollector*)*ii;
824 0 : nPriority = pElementCollector->getPriority();
825 0 : bool bToModify = pElementCollector->getModify();
826 :
827 : /*
828 : * Only ElementCollector with the max priority can
829 : * perform notify operation.
830 : * Moreover, if any blocker exists in the subtree of
831 : * this BufferNode, this ElementCollector can't do notify
832 : * unless its priority is BEFOREMODIFY.
833 : */
834 0 : if (nPriority == nMaxPriority &&
835 0 : (nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY ||
836 0 : !isBlockerInSubTreeIncluded(pElementCollector->getSecurityId())))
837 : {
838 : /*
839 : * If this ElementCollector will modify the bufferred element, then
840 : * special attention must be paid.
841 : *
842 : * If there is any ElementCollector in the subtree or any ancestor
843 : * ElementCollector with PRI_BEFPREMODIFY priority, this
844 : * ElementCollector can't perform notify operation, otherwise, it
845 : * will destroy the bufferred element, in turn, ElementCollectors
846 : * mentioned above can't perform their mission.
847 : */
848 : //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY &&
849 0 : if (!(bToModify &&
850 0 : (isECInSubTreeIncluded(pElementCollector->getSecurityId()) ||
851 0 : isECOfBeforeModifyInAncestorIncluded(pElementCollector->getSecurityId()))
852 0 : ))
853 : {
854 0 : pElementCollector->notifyListener();
855 : }
856 : }
857 0 : }
858 : }
859 0 : }
860 :
861 0 : bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
862 : /****** BufferNode/isECInSubTreeIncluded *************************************
863 : *
864 : * NAME
865 : * isECInSubTreeIncluded -- checks whether there is any ElementCollector
866 : * in the branch of this BufferNode.
867 : *
868 : * SYNOPSIS
869 : * bExist = isECInSubTreeIncluded(nIgnoredSecurityId);
870 : *
871 : * FUNCTION
872 : * checks each BufferNode in the branch of this BufferNode, if there is
873 : * an ElementCollector whose signatureId is not ignored, then return
874 : * true, otherwise, false returned.
875 : *
876 : * INPUTS
877 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
878 : * to UNDEFINEDSECURITYID, then no security Id
879 : * will be ignored.
880 : *
881 : * RESULT
882 : * bExist - true if a match found, false otherwise.
883 : *
884 : * AUTHOR
885 : * Michael Mi
886 : * Email: michael.mi@sun.com
887 : ******************************************************************************/
888 : {
889 0 : bool rc = false;
890 :
891 0 : std::vector< const ElementCollector* >::const_iterator jj = m_vElementCollectors.begin();
892 :
893 0 : for( ; jj != m_vElementCollectors.end() ; ++jj )
894 : {
895 0 : ElementCollector* pElementCollector = (ElementCollector*)*jj;
896 0 : if (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
897 0 : pElementCollector->getSecurityId() != nIgnoredSecurityId)
898 : {
899 0 : rc = true;
900 0 : break;
901 : }
902 : }
903 :
904 0 : if ( !rc )
905 : {
906 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
907 :
908 0 : for( ; ii != m_vChildren.end() ; ++ii )
909 : {
910 0 : BufferNode* pBufferNode = (BufferNode*)*ii;
911 :
912 0 : if ( pBufferNode->isECInSubTreeIncluded(nIgnoredSecurityId))
913 : {
914 0 : rc = true;
915 0 : break;
916 : }
917 : }
918 : }
919 :
920 0 : return rc;
921 : }
922 :
923 0 : bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const
924 : /****** BufferNode/isECOfBeforeModifyInAncestorIncluded **********************
925 : *
926 : * NAME
927 : * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some
928 : * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY
929 : * priority.
930 : *
931 : * SYNOPSIS
932 : * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId);
933 : *
934 : * FUNCTION
935 : * checks each ancestor BufferNode through the parent link, if there is
936 : * an ElementCollector with PRI_BEFPREMODIFY priority and its
937 : * signatureId is not ignored, then return true, otherwise, false
938 : * returned.
939 : *
940 : * INPUTS
941 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
942 : * to UNDEFINEDSECURITYID, then no security Id
943 : * will be ignored.
944 : *
945 : * RESULT
946 : * bExist - true if a match found, false otherwise.
947 : *
948 : * AUTHOR
949 : * Michael Mi
950 : * Email: michael.mi@sun.com
951 : ******************************************************************************/
952 : {
953 0 : bool rc = false;
954 :
955 0 : BufferNode* pParentNode = m_pParent;
956 0 : while (pParentNode != NULL)
957 : {
958 0 : if (pParentNode->isECOfBeforeModifyIncluded(nIgnoredSecurityId))
959 : {
960 0 : rc = true;
961 0 : break;
962 : }
963 :
964 0 : pParentNode = (BufferNode*)pParentNode->getParent();
965 : }
966 :
967 0 : return rc;
968 : }
969 :
970 0 : bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
971 : /****** BufferNode/isBlockerInSubTreeIncluded ********************************
972 : *
973 : * NAME
974 : * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode
975 : * which has blocker on it
976 : *
977 : * SYNOPSIS
978 : * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId);
979 : *
980 : * FUNCTION
981 : * checks each BufferNode in the branch of this BufferNode, if one has
982 : * a blocker on it, and the blocker's securityId is not ignored, then
983 : * returns true; otherwise, false returns.
984 : *
985 : * INPUTS
986 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
987 : * to UNDEFINEDSECURITYID, then no security Id
988 : * will be ignored.
989 : *
990 : * RESULT
991 : * bExist - true if a match found, false otherwise.
992 : *
993 : * AUTHOR
994 : * Michael Mi
995 : * Email: michael.mi@sun.com
996 : ******************************************************************************/
997 : {
998 0 : bool rc = false;
999 :
1000 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1001 :
1002 0 : for( ; ii != m_vChildren.end() ; ++ii )
1003 : {
1004 0 : BufferNode* pBufferNode = (BufferNode*)*ii;
1005 0 : ElementMark* pBlocker = pBufferNode->getBlocker();
1006 :
1007 0 : if (pBlocker != NULL &&
1008 0 : (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
1009 0 : pBlocker->getSecurityId() != nIgnoredSecurityId ))
1010 : {
1011 0 : rc = true;
1012 0 : break;
1013 : }
1014 :
1015 0 : if (rc || pBufferNode->isBlockerInSubTreeIncluded(nIgnoredSecurityId))
1016 : {
1017 0 : rc = true;
1018 0 : break;
1019 : }
1020 : }
1021 :
1022 0 : return rc;
1023 : }
1024 :
1025 0 : const BufferNode* BufferNode::getNextChild(const BufferNode* pChild) const
1026 : /****** BufferNode/getNextChild **********************************************
1027 : *
1028 : * NAME
1029 : * getNextChild -- get the next child BufferNode.
1030 : *
1031 : * SYNOPSIS
1032 : * nextChild = getNextChild();
1033 : *
1034 : * FUNCTION
1035 : * see NAME
1036 : *
1037 : * INPUTS
1038 : * pChild - the child BufferNode whose next node is retrieved.
1039 : *
1040 : * RESULT
1041 : * nextChild - the next child BufferNode after the pChild, or NULL if
1042 : * there is none.
1043 : *
1044 : * AUTHOR
1045 : * Michael Mi
1046 : * Email: michael.mi@sun.com
1047 : ******************************************************************************/
1048 : {
1049 0 : BufferNode* rc = NULL;
1050 0 : bool bChildFound = false;
1051 :
1052 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1053 0 : for( ; ii != m_vChildren.end() ; ++ii )
1054 : {
1055 0 : if (bChildFound)
1056 : {
1057 0 : rc = (BufferNode*)*ii;
1058 0 : break;
1059 : }
1060 :
1061 0 : if( *ii == pChild )
1062 : {
1063 0 : bChildFound = true;
1064 : }
1065 : }
1066 :
1067 0 : return (const BufferNode*)rc;
1068 : }
1069 :
1070 :
1071 0 : void BufferNode::freeAllChildren()
1072 : /****** BufferNode/freeAllChildren *******************************************
1073 : *
1074 : * NAME
1075 : * freeAllChildren -- free all his child BufferNode.
1076 : *
1077 : * SYNOPSIS
1078 : * freeAllChildren();
1079 : *
1080 : * FUNCTION
1081 : * see NAME
1082 : *
1083 : * INPUTS
1084 : * empty
1085 : *
1086 : * RESULT
1087 : * empty
1088 : *
1089 : * AUTHOR
1090 : * Michael Mi
1091 : * Email: michael.mi@sun.com
1092 : ******************************************************************************/
1093 : {
1094 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1095 0 : for( ; ii != m_vChildren.end() ; ++ii )
1096 : {
1097 0 : BufferNode *pChild = (BufferNode *)(*ii);
1098 0 : pChild->freeAllChildren();
1099 0 : delete pChild;
1100 : }
1101 :
1102 0 : m_vChildren.clear();
1103 0 : }
1104 :
1105 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|