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