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