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