1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
27 namespace cssu
= com::sun::star::uno
;
28 namespace cssxw
= com::sun::star::xml::wrapper
;
29 namespace cssxc
= com::sun::star::xml::crypto
;
31 BufferNode::BufferNode( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
)
34 m_bAllReceived(false),
35 m_xXMLElement(xXMLElement
)
39 bool BufferNode::isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId
) const
40 /****** BufferNode/isECOfBeforeModifyIncluded ********************************
43 * isECOfBeforeModifyIncluded -- checks whether there is some
44 * ElementCollector on this BufferNode, that has BEFORE-MODIFY priority.
47 * bExist = isECOfBeforeModifyIncluded(nIgnoredSecurityId);
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.
57 * nIgnoredSecurityId - the security Id to be ignored. If it equals
58 * to UNDEFINEDSECURITYID, then no security Id
62 * bExist - true if a match found, false otherwise
66 * Email: michael.mi@sun.com
67 ******************************************************************************/
70 std::vector
< const ElementCollector
* >::const_iterator ii
= m_vElementCollectors
.begin();
72 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
74 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*ii
);
76 if ((nIgnoredSecurityId
== cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID
||
77 pElementCollector
->getSecurityId() != nIgnoredSecurityId
) &&
78 (pElementCollector
->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY
))
88 void BufferNode::setReceivedAll()
89 /****** BufferNode/setReceiveAll *********************************************
92 * setReceivedAll -- indicates that the element in this BufferNode has
93 * been compeletely bufferred.
99 * sets the all-received flag and launches ElementCollector's notify
110 * Email: michael.mi@sun.com
111 ******************************************************************************/
113 m_bAllReceived
= true;
114 elementCollectorNotify();
118 void BufferNode::addElementCollector(const ElementCollector
* pElementCollector
)
119 /****** BufferNode/addElementCollector ***************************************
122 * addElementCollector -- adds a new ElementCollector to this BufferNode.
125 * addElementCollector(pElementCollector);
131 * pElementCollector - the ElementCollector to be added
138 * Email: michael.mi@sun.com
139 ******************************************************************************/
141 m_vElementCollectors
.push_back( pElementCollector
);
142 const_cast<ElementCollector
*>(pElementCollector
)->setBufferNode(this);
145 void BufferNode::removeElementCollector(const ElementCollector
* pElementCollector
)
146 /****** BufferNode/removeElementCollector ************************************
149 * removeElementCollector -- removes an ElementCollector from this
153 * removeElementCollector(pElementCollector);
159 * pElementCollector - the ElementCollector to be removed
166 * Email: michael.mi@sun.com
167 ******************************************************************************/
169 std::vector
< const ElementCollector
* >::iterator ii
= m_vElementCollectors
.begin();
171 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
173 if( *ii
== pElementCollector
)
175 m_vElementCollectors
.erase( ii
);
176 const_cast<ElementCollector
*>(pElementCollector
)->setBufferNode(NULL
);
183 void BufferNode::setBlocker(const ElementMark
* pBlocker
)
184 /****** BufferNode/setBlocker ************************************************
187 * setBlocker -- adds a blocker to this BufferNode.
190 * setBlocker(pBlocker);
196 * pBlocker - the new blocker to be attached
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.
207 * Email: michael.mi@sun.com
208 ******************************************************************************/
210 OSL_ASSERT(!(m_pBlocker
!= NULL
&& pBlocker
!= NULL
));
212 m_pBlocker
= const_cast<ElementMark
*>(pBlocker
);
213 if (m_pBlocker
!= NULL
)
215 m_pBlocker
->setBufferNode(this);
219 OUString
BufferNode::printChildren() const
220 /****** BufferNode/printChildren *********************************************
223 * printChildren -- prints children information into a string.
226 * result = printChildren();
235 * result - the information string
239 * Email: michael.mi@sun.com
240 ******************************************************************************/
243 std::vector
< const ElementCollector
* >::const_iterator ii
= m_vElementCollectors
.begin();
245 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
247 rc
+= OUString( "BufID=" );
248 rc
+= OUString::number((*ii
)->getBufferId());
250 if ((*ii
)->getModify())
252 rc
+= OUString( "[M]" );
255 rc
+= OUString( ",Pri=" );
257 switch ((*ii
)->getPriority())
259 case cssxc::sax::ElementMarkPriority_BEFOREMODIFY
:
260 rc
+= OUString( "BEFOREMODIFY" );
262 case cssxc::sax::ElementMarkPriority_AFTERMODIFY
:
263 rc
+= OUString( "AFTERMODIFY" );
266 rc
+= OUString( "UNKNOWN" );
270 rc
+= OUString( "(" );
271 rc
+= OUString( "SecID=" );
272 rc
+= OUString::number((*ii
)->getSecurityId());
273 rc
+= OUString( ")" );
274 rc
+= OUString( " " );
280 bool BufferNode::hasAnything() const
281 /****** BufferNode/hasAnything ***********************************************
284 * hasAnything -- checks whether there is any ElementCollector or blocker
285 * on this BufferNode.
288 * bExist = hasAnything();
297 * bExist - true if there is, false otherwise.
301 * Email: michael.mi@sun.com
302 ******************************************************************************/
304 return (m_pBlocker
|| !m_vElementCollectors
.empty());
307 bool BufferNode::hasChildren() const
308 /****** BufferNode/hasChildren ***********************************************
311 * hasChildren -- checks whether this BufferNode has any child
315 * bExist = hasChildren();
324 * bExist - true if there is, false otherwise.
328 * Email: michael.mi@sun.com
329 ******************************************************************************/
331 return (!m_vChildren
.empty());
334 std::vector
< const BufferNode
* >* BufferNode::getChildren() const
336 return new std::vector
< const BufferNode
* >( m_vChildren
);
339 const BufferNode
* BufferNode::getFirstChild() const
340 /****** BufferNode/getFirstChild *********************************************
343 * getFirstChild -- retrieves the first child BufferNode.
346 * child = getFirstChild();
355 * child - the first child BufferNode, or NULL if there is no child
360 * Email: michael.mi@sun.com
361 ******************************************************************************/
363 BufferNode
* rc
= NULL
;
365 if (!m_vChildren
.empty())
367 rc
= const_cast<BufferNode
*>(m_vChildren
.front());
370 return (const BufferNode
*)rc
;
373 void BufferNode::addChild(const BufferNode
* pChild
, sal_Int32 nPosition
)
374 /****** BufferNode/addChild(pChild,nPosition) ********************************
377 * addChild -- inserts a child BufferNode at specific position.
380 * addChild(pChild, nPosition);
386 * pChild - the child BufferNode to be added.
387 * nPosition - the position where the new child locates.
393 * If the nPosition is -1, then the new child BufferNode is appended
398 * Email: michael.mi@sun.com
399 ******************************************************************************/
403 m_vChildren
.push_back( pChild
);
407 std::vector
< const BufferNode
* >::iterator ii
= m_vChildren
.begin();
409 m_vChildren
.insert(ii
, pChild
);
413 void BufferNode::addChild(const BufferNode
* pChild
)
414 /****** BufferNode/addChild() ************************************************
417 * addChild -- add a new child BufferNode.
426 * pChild - the child BufferNode to be added.
432 * The new child BufferNode is appended at the end.
436 * Email: michael.mi@sun.com
437 ******************************************************************************/
439 addChild(pChild
, -1);
442 void BufferNode::removeChild(const BufferNode
* pChild
)
443 /****** BufferNode/removeChild ***********************************************
446 * removeChild -- removes a child BufferNode from the children list.
449 * removeChild(pChild);
455 * pChild - the child BufferNode to be removed
462 * Email: michael.mi@sun.com
463 ******************************************************************************/
465 std::vector
< const BufferNode
* >::iterator ii
= m_vChildren
.begin();
467 for( ; ii
!= m_vChildren
.end() ; ++ii
)
471 m_vChildren
.erase( ii
);
477 sal_Int32
BufferNode::indexOfChild(const BufferNode
* pChild
) const
478 /****** BufferNode/indexOfChild **********************************************
481 * indexOfChild -- gets the index of a child BufferNode.
484 * index = indexOfChild(pChild);
490 * pChild - the child BufferNode whose index to be gotten
493 * index - the index of that child BufferNode. If that child BufferNode
494 * is not found, -1 is returned.
498 * Email: michael.mi@sun.com
499 ******************************************************************************/
501 sal_Int32 nIndex
= 0;
504 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
506 for( ; ii
!= m_vChildren
.end() ; ++ii
)
525 void BufferNode::setParent(const BufferNode
* pParent
)
527 m_pParent
= const_cast<BufferNode
*>(pParent
);
530 const BufferNode
* BufferNode::getNextSibling() const
531 /****** BufferNode/getNextSibling ********************************************
534 * getNextSibling -- retrieves the next sibling BufferNode.
537 * sibling = getNextSibling();
546 * sibling - the next sibling BufferNode, or NULL if there is none.
550 * Email: michael.mi@sun.com
551 ******************************************************************************/
553 BufferNode
* rc
= NULL
;
555 if (m_pParent
!= NULL
)
557 rc
= const_cast<BufferNode
*>(m_pParent
->getNextChild(this));
560 return (const BufferNode
*)rc
;
563 const BufferNode
* BufferNode::isAncestor(const BufferNode
* pDescendant
) const
564 /****** BufferNode/isAncestor ************************************************
567 * isAncestor -- checks whether this BufferNode is an ancestor of another
571 * bIs = isAncestor(pDescendant);
577 * pDescendant - the BufferNode to be checked as a descendant
580 * bIs - true if this BufferNode is an ancestor of the pDescendant,
585 * Email: michael.mi@sun.com
586 ******************************************************************************/
588 BufferNode
* rc
= NULL
;
590 if (pDescendant
!= NULL
)
592 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
594 for( ; ii
!= m_vChildren
.end() ; ++ii
)
596 BufferNode
* pChild
= const_cast<BufferNode
*>(*ii
);
598 if (pChild
== pDescendant
)
604 if (pChild
->isAncestor(pDescendant
) != NULL
)
612 return (const BufferNode
*)rc
;
615 bool BufferNode::isPrevious(const BufferNode
* pFollowing
) const
616 /****** BufferNode/isPrevious ************************************************
619 * isPrevious -- checks whether this BufferNode is ahead of another
620 * BufferNode in the tree order.
623 * bIs = isPrevious(pFollowing);
629 * pFollowing - the BufferNode to be checked as a following
632 * bIs - true if this BufferNode is ahead in the tree order, false
637 * Email: michael.mi@sun.com
638 ******************************************************************************/
642 BufferNode
* pNextBufferNode
= const_cast<BufferNode
*>(getNextNodeByTreeOrder());
643 while (pNextBufferNode
!= NULL
)
645 if (pNextBufferNode
== pFollowing
)
651 pNextBufferNode
= const_cast<BufferNode
*>(pNextBufferNode
->getNextNodeByTreeOrder());
657 const BufferNode
* BufferNode::getNextNodeByTreeOrder() const
658 /****** BufferNode/getNextNodeByTreeOrder ************************************
661 * getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree
665 * next = getNextNodeByTreeOrder();
674 * next - the BufferNode following this BufferNode in the tree order,
675 * or NULL if there is none.
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
683 * 4. otherwise, no "next" node exists.
687 * Email: michael.mi@sun.com
688 ******************************************************************************/
691 * If this buffer node has m_vChildren, then return the first
696 return getFirstChild();
700 * Otherwise, it this buffer node has a following sibling,
701 * then return that sibling.
703 BufferNode
* pNextSibling
= const_cast<BufferNode
*>(getNextSibling());
704 if (pNextSibling
!= NULL
)
710 * Otherwise, it this buffer node has parent, then return
711 * its parent's following sibling.
713 BufferNode
* pNode
= const_cast<BufferNode
*>(this);
715 BufferNode
* pNextSiblingParent
= NULL
;
724 pParent
= const_cast<BufferNode
*>(pNode
->getParent());
727 pNextSiblingParent
= const_cast<BufferNode
*>(pParent
->getNextSibling());
731 }while (pNextSiblingParent
== NULL
);
733 return pNextSiblingParent
;
737 void BufferNode::setXMLElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
)
739 m_xXMLElement
= xXMLElement
;
742 void BufferNode::notifyBranch()
743 /****** BufferNode/notifyBranch **********************************************
746 * notifyBranch -- notifies each BufferNode in the branch of this
747 * BufferNode in the tree order.
763 * Email: michael.mi@sun.com
764 ******************************************************************************/
766 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
768 for( ; ii
!= m_vChildren
.end() ; ++ii
)
770 BufferNode
* pBufferNode
= const_cast<BufferNode
*>(*ii
);
771 pBufferNode
->elementCollectorNotify();
772 pBufferNode
->notifyBranch();
776 void BufferNode::elementCollectorNotify()
777 /****** BufferNode/elementCollectorNotify ************************************
780 * elementCollectorNotify -- notifies this BufferNode.
783 * elementCollectorNotify();
786 * Notifies this BufferNode if the notification is not suppressed.
792 * child - the first child BufferNode, or NULL if there is no child
797 * Email: michael.mi@sun.com
798 ******************************************************************************/
800 if (!m_vElementCollectors
.empty())
802 cssxc::sax::ElementMarkPriority nMaxPriority
= cssxc::sax::ElementMarkPriority_MINIMUM
;
803 cssxc::sax::ElementMarkPriority nPriority
;
806 * get the max priority among ElementCollectors on this BufferNode
808 std::vector
< const ElementCollector
* >::const_iterator ii
= m_vElementCollectors
.begin();
809 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
811 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*ii
);
812 nPriority
= pElementCollector
->getPriority();
813 if (nPriority
> nMaxPriority
)
815 nMaxPriority
= nPriority
;
819 std::vector
< const ElementCollector
* > vElementCollectors( m_vElementCollectors
);
820 ii
= vElementCollectors
.begin();
822 for( ; ii
!= vElementCollectors
.end() ; ++ii
)
824 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*ii
);
825 nPriority
= pElementCollector
->getPriority();
826 bool bToModify
= pElementCollector
->getModify();
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.
835 if (nPriority
== nMaxPriority
&&
836 (nPriority
== cssxc::sax::ElementMarkPriority_BEFOREMODIFY
||
837 !isBlockerInSubTreeIncluded(pElementCollector
->getSecurityId())))
840 * If this ElementCollector will modify the bufferred element, then
841 * special attention must be paid.
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.
849 //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY &&
851 (isECInSubTreeIncluded(pElementCollector
->getSecurityId()) ||
852 isECOfBeforeModifyInAncestorIncluded(pElementCollector
->getSecurityId()))
855 pElementCollector
->notifyListener();
862 bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId
) const
863 /****** BufferNode/isECInSubTreeIncluded *************************************
866 * isECInSubTreeIncluded -- checks whether there is any ElementCollector
867 * in the branch of this BufferNode.
870 * bExist = isECInSubTreeIncluded(nIgnoredSecurityId);
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.
878 * nIgnoredSecurityId - the security Id to be ignored. If it equals
879 * to UNDEFINEDSECURITYID, then no security Id
883 * bExist - true if a match found, false otherwise.
887 * Email: michael.mi@sun.com
888 ******************************************************************************/
892 std::vector
< const ElementCollector
* >::const_iterator jj
= m_vElementCollectors
.begin();
894 for( ; jj
!= m_vElementCollectors
.end() ; ++jj
)
896 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*jj
);
897 if (nIgnoredSecurityId
== cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID
||
898 pElementCollector
->getSecurityId() != nIgnoredSecurityId
)
907 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
909 for( ; ii
!= m_vChildren
.end() ; ++ii
)
911 BufferNode
* pBufferNode
= const_cast<BufferNode
*>(*ii
);
913 if ( pBufferNode
->isECInSubTreeIncluded(nIgnoredSecurityId
))
924 bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId
) const
925 /****** BufferNode/isECOfBeforeModifyInAncestorIncluded **********************
928 * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some
929 * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY
933 * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId);
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
942 * nIgnoredSecurityId - the security Id to be ignored. If it equals
943 * to UNDEFINEDSECURITYID, then no security Id
947 * bExist - true if a match found, false otherwise.
951 * Email: michael.mi@sun.com
952 ******************************************************************************/
956 BufferNode
* pParentNode
= m_pParent
;
957 while (pParentNode
!= NULL
)
959 if (pParentNode
->isECOfBeforeModifyIncluded(nIgnoredSecurityId
))
965 pParentNode
= const_cast<BufferNode
*>(pParentNode
->getParent());
971 bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId
) const
972 /****** BufferNode/isBlockerInSubTreeIncluded ********************************
975 * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode
976 * which has blocker on it
979 * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId);
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.
987 * nIgnoredSecurityId - the security Id to be ignored. If it equals
988 * to UNDEFINEDSECURITYID, then no security Id
992 * bExist - true if a match found, false otherwise.
996 * Email: michael.mi@sun.com
997 ******************************************************************************/
1001 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
1003 for( ; ii
!= m_vChildren
.end() ; ++ii
)
1005 BufferNode
* pBufferNode
= const_cast<BufferNode
*>(*ii
);
1006 ElementMark
* pBlocker
= pBufferNode
->getBlocker();
1008 if (pBlocker
!= NULL
&&
1009 (nIgnoredSecurityId
== cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID
||
1010 pBlocker
->getSecurityId() != nIgnoredSecurityId
))
1016 if (rc
|| pBufferNode
->isBlockerInSubTreeIncluded(nIgnoredSecurityId
))
1026 const BufferNode
* BufferNode::getNextChild(const BufferNode
* pChild
) const
1027 /****** BufferNode/getNextChild **********************************************
1030 * getNextChild -- get the next child BufferNode.
1033 * nextChild = getNextChild();
1039 * pChild - the child BufferNode whose next node is retrieved.
1042 * nextChild - the next child BufferNode after the pChild, or NULL if
1047 * Email: michael.mi@sun.com
1048 ******************************************************************************/
1050 BufferNode
* rc
= NULL
;
1051 bool bChildFound
= false;
1053 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
1054 for( ; ii
!= m_vChildren
.end() ; ++ii
)
1058 rc
= const_cast<BufferNode
*>(*ii
);
1068 return (const BufferNode
*)rc
;
1072 void BufferNode::freeAllChildren()
1073 /****** BufferNode/freeAllChildren *******************************************
1076 * freeAllChildren -- free all his child BufferNode.
1079 * freeAllChildren();
1092 * Email: michael.mi@sun.com
1093 ******************************************************************************/
1095 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
1096 for( ; ii
!= m_vChildren
.end() ; ++ii
)
1098 BufferNode
*pChild
= const_cast<BufferNode
*>(*ii
);
1099 pChild
->freeAllChildren();
1103 m_vChildren
.clear();
1106 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */