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 : rtl::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 : rtl::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 += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BufID=" ));
255 0 : rc += rtl::OUString::valueOf((*ii)->getBufferId());
256 :
257 0 : if (((ElementCollector*)(*ii))->getModify())
258 : {
259 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[M]" ));
260 : }
261 :
262 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ",Pri=" ));
263 :
264 0 : switch (((ElementCollector*)(*ii))->getPriority())
265 : {
266 : case cssxc::sax::ElementMarkPriority_BEFOREMODIFY:
267 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BEFOREMODIFY" ));
268 0 : break;
269 : case cssxc::sax::ElementMarkPriority_AFTERMODIFY:
270 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFTERMODIFY" ));
271 0 : break;
272 : default:
273 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNKNOWN" ));
274 0 : break;
275 : }
276 :
277 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(" ));
278 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SecID=" ));
279 0 : rc += rtl::OUString::valueOf(((ElementCollector*)(*ii))->getSecurityId());
280 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ));
281 0 : rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
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 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::notifyAncestor()
792 : /****** BufferNode/notifyAncestor ********************************************
793 : *
794 : * NAME
795 : * notifyAncestor -- notifies each ancestor BufferNode through the parent
796 : * link.
797 : *
798 : * SYNOPSIS
799 : * notifyAncestor();
800 : *
801 : * FUNCTION
802 : * see NAME
803 : *
804 : * INPUTS
805 : * empty
806 : *
807 : * RESULT
808 : * empty
809 : *
810 : * AUTHOR
811 : * Michael Mi
812 : * Email: michael.mi@sun.com
813 : ******************************************************************************/
814 : {
815 0 : BufferNode* pParent = m_pParent;
816 0 : while (pParent != NULL)
817 : {
818 0 : pParent->notifyAncestor();
819 0 : pParent = (BufferNode*)pParent->getParent();
820 : }
821 0 : }
822 :
823 0 : void BufferNode::elementCollectorNotify()
824 : /****** BufferNode/elementCollectorNotify ************************************
825 : *
826 : * NAME
827 : * elementCollectorNotify -- notifies this BufferNode.
828 : *
829 : * SYNOPSIS
830 : * elementCollectorNotify();
831 : *
832 : * FUNCTION
833 : * Notifies this BufferNode if the notification is not suppressed.
834 : *
835 : * INPUTS
836 : * empty
837 : *
838 : * RESULT
839 : * child - the first child BufferNode, or NULL if there is no child
840 : * BufferNode.
841 : *
842 : * AUTHOR
843 : * Michael Mi
844 : * Email: michael.mi@sun.com
845 : ******************************************************************************/
846 : {
847 0 : if (!m_vElementCollectors.empty())
848 : {
849 0 : cssxc::sax::ElementMarkPriority nMaxPriority = cssxc::sax::ElementMarkPriority_MINIMUM;
850 : cssxc::sax::ElementMarkPriority nPriority;
851 :
852 : /*
853 : * get the max priority among ElementCollectors on this BufferNode
854 : */
855 0 : std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin();
856 0 : for( ; ii != m_vElementCollectors.end() ; ++ii )
857 : {
858 0 : ElementCollector* pElementCollector = (ElementCollector*)*ii;
859 0 : nPriority = pElementCollector->getPriority();
860 0 : if (nPriority > nMaxPriority)
861 : {
862 0 : nMaxPriority = nPriority;
863 : }
864 : }
865 :
866 0 : std::vector< const ElementCollector* > vElementCollectors( m_vElementCollectors );
867 0 : ii = vElementCollectors.begin();
868 :
869 0 : for( ; ii != vElementCollectors.end() ; ++ii )
870 : {
871 0 : ElementCollector* pElementCollector = (ElementCollector*)*ii;
872 0 : nPriority = pElementCollector->getPriority();
873 0 : bool bToModify = pElementCollector->getModify();
874 :
875 : /*
876 : * Only ElementCollector with the max priority can
877 : * perform notify operation.
878 : * Moreover, if any blocker exists in the subtree of
879 : * this BufferNode, this ElementCollector can't do notify
880 : * unless its priority is BEFOREMODIFY.
881 : */
882 0 : if (nPriority == nMaxPriority &&
883 : (nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY ||
884 0 : !isBlockerInSubTreeIncluded(pElementCollector->getSecurityId())))
885 : {
886 : /*
887 : * If this ElementCollector will modify the bufferred element, then
888 : * special attention must be paid.
889 : *
890 : * If there is any ElementCollector in the subtree or any ancestor
891 : * ElementCollector with PRI_BEFPREMODIFY priority, this
892 : * ElementCollector can't perform notify operation, otherwise, it
893 : * will destroy the bufferred element, in turn, ElementCollectors
894 : * mentioned above can't perform their mission.
895 : */
896 : //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY &&
897 0 : if (!(bToModify &&
898 0 : (isECInSubTreeIncluded(pElementCollector->getSecurityId()) ||
899 0 : isECOfBeforeModifyInAncestorIncluded(pElementCollector->getSecurityId()))
900 0 : ))
901 : {
902 0 : pElementCollector->notifyListener();
903 : }
904 : }
905 0 : }
906 : }
907 0 : }
908 :
909 0 : bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
910 : /****** BufferNode/isECInSubTreeIncluded *************************************
911 : *
912 : * NAME
913 : * isECInSubTreeIncluded -- checks whether there is any ElementCollector
914 : * in the branch of this BufferNode.
915 : *
916 : * SYNOPSIS
917 : * bExist = isECInSubTreeIncluded(nIgnoredSecurityId);
918 : *
919 : * FUNCTION
920 : * checks each BufferNode in the branch of this BufferNode, if there is
921 : * an ElementCollector whose signatureId is not ignored, then return
922 : * true, otherwise, false returned.
923 : *
924 : * INPUTS
925 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
926 : * to UNDEFINEDSECURITYID, then no security Id
927 : * will be ignored.
928 : *
929 : * RESULT
930 : * bExist - true if a match found, false otherwise.
931 : *
932 : * AUTHOR
933 : * Michael Mi
934 : * Email: michael.mi@sun.com
935 : ******************************************************************************/
936 : {
937 0 : bool rc = false;
938 :
939 0 : std::vector< const ElementCollector* >::const_iterator jj = m_vElementCollectors.begin();
940 :
941 0 : for( ; jj != m_vElementCollectors.end() ; ++jj )
942 : {
943 0 : ElementCollector* pElementCollector = (ElementCollector*)*jj;
944 0 : if (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
945 0 : pElementCollector->getSecurityId() != nIgnoredSecurityId)
946 : {
947 0 : rc = true;
948 0 : break;
949 : }
950 : }
951 :
952 0 : if ( !rc )
953 : {
954 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
955 :
956 0 : for( ; ii != m_vChildren.end() ; ++ii )
957 : {
958 0 : BufferNode* pBufferNode = (BufferNode*)*ii;
959 :
960 0 : if ( pBufferNode->isECInSubTreeIncluded(nIgnoredSecurityId))
961 : {
962 0 : rc = true;
963 0 : break;
964 : }
965 : }
966 : }
967 :
968 0 : return rc;
969 : }
970 :
971 0 : bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const
972 : /****** BufferNode/isECOfBeforeModifyInAncestorIncluded **********************
973 : *
974 : * NAME
975 : * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some
976 : * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY
977 : * priority.
978 : *
979 : * SYNOPSIS
980 : * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId);
981 : *
982 : * FUNCTION
983 : * checks each ancestor BufferNode through the parent link, if there is
984 : * an ElementCollector with PRI_BEFPREMODIFY priority and its
985 : * signatureId is not ignored, then return true, otherwise, false
986 : * returned.
987 : *
988 : * INPUTS
989 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
990 : * to UNDEFINEDSECURITYID, then no security Id
991 : * will be ignored.
992 : *
993 : * RESULT
994 : * bExist - true if a match found, false otherwise.
995 : *
996 : * AUTHOR
997 : * Michael Mi
998 : * Email: michael.mi@sun.com
999 : ******************************************************************************/
1000 : {
1001 0 : bool rc = false;
1002 :
1003 0 : BufferNode* pParentNode = m_pParent;
1004 0 : while (pParentNode != NULL)
1005 : {
1006 0 : if (pParentNode->isECOfBeforeModifyIncluded(nIgnoredSecurityId))
1007 : {
1008 0 : rc = true;
1009 0 : break;
1010 : }
1011 :
1012 0 : pParentNode = (BufferNode*)pParentNode->getParent();
1013 : }
1014 :
1015 0 : return rc;
1016 : }
1017 :
1018 0 : bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const
1019 : /****** BufferNode/isBlockerInSubTreeIncluded ********************************
1020 : *
1021 : * NAME
1022 : * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode
1023 : * which has blocker on it
1024 : *
1025 : * SYNOPSIS
1026 : * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId);
1027 : *
1028 : * FUNCTION
1029 : * checks each BufferNode in the branch of this BufferNode, if one has
1030 : * a blocker on it, and the blocker's securityId is not ignored, then
1031 : * returns true; otherwise, false returns.
1032 : *
1033 : * INPUTS
1034 : * nIgnoredSecurityId - the security Id to be ignored. If it equals
1035 : * to UNDEFINEDSECURITYID, then no security Id
1036 : * will be ignored.
1037 : *
1038 : * RESULT
1039 : * bExist - true if a match found, false otherwise.
1040 : *
1041 : * AUTHOR
1042 : * Michael Mi
1043 : * Email: michael.mi@sun.com
1044 : ******************************************************************************/
1045 : {
1046 0 : bool rc = false;
1047 :
1048 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1049 :
1050 0 : for( ; ii != m_vChildren.end() ; ++ii )
1051 : {
1052 0 : BufferNode* pBufferNode = (BufferNode*)*ii;
1053 0 : ElementMark* pBlocker = pBufferNode->getBlocker();
1054 :
1055 0 : if (pBlocker != NULL &&
1056 : (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID ||
1057 0 : pBlocker->getSecurityId() != nIgnoredSecurityId ))
1058 : {
1059 0 : rc = true;
1060 0 : break;
1061 : }
1062 :
1063 0 : if (rc || pBufferNode->isBlockerInSubTreeIncluded(nIgnoredSecurityId))
1064 : {
1065 0 : rc = true;
1066 0 : break;
1067 : }
1068 : }
1069 :
1070 0 : return rc;
1071 : }
1072 :
1073 0 : const BufferNode* BufferNode::getNextChild(const BufferNode* pChild) const
1074 : /****** BufferNode/getNextChild **********************************************
1075 : *
1076 : * NAME
1077 : * getNextChild -- get the next child BufferNode.
1078 : *
1079 : * SYNOPSIS
1080 : * nextChild = getNextChild();
1081 : *
1082 : * FUNCTION
1083 : * see NAME
1084 : *
1085 : * INPUTS
1086 : * pChild - the child BufferNode whose next node is retrieved.
1087 : *
1088 : * RESULT
1089 : * nextChild - the next child BufferNode after the pChild, or NULL if
1090 : * there is none.
1091 : *
1092 : * AUTHOR
1093 : * Michael Mi
1094 : * Email: michael.mi@sun.com
1095 : ******************************************************************************/
1096 : {
1097 0 : BufferNode* rc = NULL;
1098 0 : bool bChildFound = false;
1099 :
1100 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1101 0 : for( ; ii != m_vChildren.end() ; ++ii )
1102 : {
1103 0 : if (bChildFound)
1104 : {
1105 0 : rc = (BufferNode*)*ii;
1106 0 : break;
1107 : }
1108 :
1109 0 : if( *ii == pChild )
1110 : {
1111 0 : bChildFound = true;
1112 : }
1113 : }
1114 :
1115 0 : return (const BufferNode*)rc;
1116 : }
1117 :
1118 :
1119 0 : void BufferNode::freeAllChildren()
1120 : /****** BufferNode/freeAllChildren *******************************************
1121 : *
1122 : * NAME
1123 : * freeAllChildren -- free all his child BufferNode.
1124 : *
1125 : * SYNOPSIS
1126 : * freeAllChildren();
1127 : *
1128 : * FUNCTION
1129 : * see NAME
1130 : *
1131 : * INPUTS
1132 : * empty
1133 : *
1134 : * RESULT
1135 : * empty
1136 : *
1137 : * AUTHOR
1138 : * Michael Mi
1139 : * Email: michael.mi@sun.com
1140 : ******************************************************************************/
1141 : {
1142 0 : std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin();
1143 0 : for( ; ii != m_vChildren.end() ; ++ii )
1144 : {
1145 0 : BufferNode *pChild = (BufferNode *)(*ii);
1146 0 : pChild->freeAllChildren();
1147 0 : delete pChild;
1148 : }
1149 :
1150 0 : m_vChildren.clear();
1151 0 : }
1152 :
1153 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|