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
63 ******************************************************************************/
66 std::vector
< const ElementCollector
* >::const_iterator ii
= m_vElementCollectors
.begin();
68 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
70 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*ii
);
72 if ((nIgnoredSecurityId
== cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID
||
73 pElementCollector
->getSecurityId() != nIgnoredSecurityId
) &&
74 (pElementCollector
->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY
))
84 void BufferNode::setReceivedAll()
85 /****** BufferNode/setReceiveAll *********************************************
88 * setReceivedAll -- indicates that the element in this BufferNode has
89 * been completely bufferred.
95 * sets the all-received flag and launches ElementCollector's notify
103 ******************************************************************************/
105 m_bAllReceived
= true;
106 elementCollectorNotify();
110 void BufferNode::addElementCollector(const ElementCollector
* pElementCollector
)
111 /****** BufferNode/addElementCollector ***************************************
114 * addElementCollector -- adds a new ElementCollector to this BufferNode.
117 * addElementCollector(pElementCollector);
123 * pElementCollector - the ElementCollector to be added
127 ******************************************************************************/
129 m_vElementCollectors
.push_back( pElementCollector
);
130 const_cast<ElementCollector
*>(pElementCollector
)->setBufferNode(this);
133 void BufferNode::removeElementCollector(const ElementCollector
* pElementCollector
)
134 /****** BufferNode/removeElementCollector ************************************
137 * removeElementCollector -- removes an ElementCollector from this
141 * removeElementCollector(pElementCollector);
147 * pElementCollector - the ElementCollector to be removed
151 ******************************************************************************/
153 std::vector
< const ElementCollector
* >::iterator ii
= m_vElementCollectors
.begin();
155 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
157 if( *ii
== pElementCollector
)
159 m_vElementCollectors
.erase( ii
);
160 const_cast<ElementCollector
*>(pElementCollector
)->setBufferNode(nullptr);
167 void BufferNode::setBlocker(const ElementMark
* pBlocker
)
168 /****** BufferNode/setBlocker ************************************************
171 * setBlocker -- adds a blocker to this BufferNode.
174 * setBlocker(pBlocker);
180 * pBlocker - the new blocker to be attached
186 * Because there is only one blocker permitted for a BufferNode, so the
187 * old blocker on this BufferNode, if there is one, will be overcasted.
188 ******************************************************************************/
190 OSL_ASSERT(!(m_pBlocker
!= nullptr && pBlocker
!= nullptr));
192 m_pBlocker
= const_cast<ElementMark
*>(pBlocker
);
193 if (m_pBlocker
!= nullptr)
195 m_pBlocker
->setBufferNode(this);
199 OUString
BufferNode::printChildren() const
200 /****** BufferNode/printChildren *********************************************
203 * printChildren -- prints children information into a string.
206 * result = printChildren();
215 * result - the information string
216 ******************************************************************************/
219 std::vector
< const ElementCollector
* >::const_iterator ii
= m_vElementCollectors
.begin();
221 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
223 rc
+= "BufID=" + OUString::number((*ii
)->getBufferId());
225 if ((*ii
)->getModify())
232 switch ((*ii
)->getPriority())
234 case cssxc::sax::ElementMarkPriority_BEFOREMODIFY
:
235 rc
+= "BEFOREMODIFY";
237 case cssxc::sax::ElementMarkPriority_AFTERMODIFY
:
245 rc
+= "(SecID=" + OUString::number((*ii
)->getSecurityId()) + ") ";
251 bool BufferNode::hasAnything() const
252 /****** BufferNode/hasAnything ***********************************************
255 * hasAnything -- checks whether there is any ElementCollector or blocker
256 * on this BufferNode.
259 * bExist = hasAnything();
268 * bExist - true if there is, false otherwise.
269 ******************************************************************************/
271 return (m_pBlocker
|| !m_vElementCollectors
.empty());
274 bool BufferNode::hasChildren() const
275 /****** BufferNode/hasChildren ***********************************************
278 * hasChildren -- checks whether this BufferNode has any child
282 * bExist = hasChildren();
291 * bExist - true if there is, false otherwise.
292 ******************************************************************************/
294 return (!m_vChildren
.empty());
297 std::vector
< const BufferNode
* >* BufferNode::getChildren() const
299 return new std::vector
< const BufferNode
* >( m_vChildren
);
302 const BufferNode
* BufferNode::getFirstChild() const
303 /****** BufferNode/getFirstChild *********************************************
306 * getFirstChild -- retrieves the first child BufferNode.
309 * child = getFirstChild();
318 * child - the first child BufferNode, or NULL if there is no child
320 ******************************************************************************/
322 BufferNode
* rc
= nullptr;
324 if (!m_vChildren
.empty())
326 rc
= const_cast<BufferNode
*>(m_vChildren
.front());
332 void BufferNode::addChild(const BufferNode
* pChild
, sal_Int32 nPosition
)
333 /****** BufferNode/addChild(pChild,nPosition) ********************************
336 * addChild -- inserts a child BufferNode at specific position.
339 * addChild(pChild, nPosition);
345 * pChild - the child BufferNode to be added.
346 * nPosition - the position where the new child locates.
352 * If the nPosition is -1, then the new child BufferNode is appended
354 ******************************************************************************/
358 m_vChildren
.push_back( pChild
);
362 std::vector
< const BufferNode
* >::iterator ii
= m_vChildren
.begin();
364 m_vChildren
.insert(ii
, pChild
);
368 void BufferNode::addChild(const BufferNode
* pChild
)
369 /****** BufferNode/addChild() ************************************************
372 * addChild -- add a new child BufferNode.
381 * pChild - the child BufferNode to be added.
387 * The new child BufferNode is appended at the end.
388 ******************************************************************************/
390 addChild(pChild
, -1);
393 void BufferNode::removeChild(const BufferNode
* pChild
)
394 /****** BufferNode/removeChild ***********************************************
397 * removeChild -- removes a child BufferNode from the children list.
400 * removeChild(pChild);
406 * pChild - the child BufferNode to be removed
410 ******************************************************************************/
412 std::vector
< const BufferNode
* >::iterator ii
= m_vChildren
.begin();
414 for( ; ii
!= m_vChildren
.end() ; ++ii
)
418 m_vChildren
.erase( ii
);
424 sal_Int32
BufferNode::indexOfChild(const BufferNode
* pChild
) const
425 /****** BufferNode/indexOfChild **********************************************
428 * indexOfChild -- gets the index of a child BufferNode.
431 * index = indexOfChild(pChild);
437 * pChild - the child BufferNode whose index to be gotten
440 * index - the index of that child BufferNode. If that child BufferNode
441 * is not found, -1 is returned.
442 ******************************************************************************/
444 sal_Int32 nIndex
= 0;
447 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
449 for( ; ii
!= m_vChildren
.end() ; ++ii
)
468 void BufferNode::setParent(const BufferNode
* pParent
)
470 m_pParent
= const_cast<BufferNode
*>(pParent
);
473 const BufferNode
* BufferNode::getNextSibling() const
474 /****** BufferNode/getNextSibling ********************************************
477 * getNextSibling -- retrieves the next sibling BufferNode.
480 * sibling = getNextSibling();
489 * sibling - the next sibling BufferNode, or NULL if there is none.
490 ******************************************************************************/
492 BufferNode
* rc
= nullptr;
494 if (m_pParent
!= nullptr)
496 rc
= const_cast<BufferNode
*>(m_pParent
->getNextChild(this));
502 const BufferNode
* BufferNode::isAncestor(const BufferNode
* pDescendant
) const
503 /****** BufferNode/isAncestor ************************************************
506 * isAncestor -- checks whether this BufferNode is an ancestor of another
510 * bIs = isAncestor(pDescendant);
516 * pDescendant - the BufferNode to be checked as a descendant
519 * bIs - true if this BufferNode is an ancestor of the pDescendant,
521 ******************************************************************************/
523 BufferNode
* rc
= nullptr;
525 if (pDescendant
!= nullptr)
527 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
529 for( ; ii
!= m_vChildren
.end() ; ++ii
)
531 BufferNode
* pChild
= const_cast<BufferNode
*>(*ii
);
533 if (pChild
== pDescendant
)
539 if (pChild
->isAncestor(pDescendant
) != nullptr)
550 bool BufferNode::isPrevious(const BufferNode
* pFollowing
) const
551 /****** BufferNode/isPrevious ************************************************
554 * isPrevious -- checks whether this BufferNode is ahead of another
555 * BufferNode in the tree order.
558 * bIs = isPrevious(pFollowing);
564 * pFollowing - the BufferNode to be checked as a following
567 * bIs - true if this BufferNode is ahead in the tree order, false
569 ******************************************************************************/
573 BufferNode
* pNextBufferNode
= const_cast<BufferNode
*>(getNextNodeByTreeOrder());
574 while (pNextBufferNode
!= nullptr)
576 if (pNextBufferNode
== pFollowing
)
582 pNextBufferNode
= const_cast<BufferNode
*>(pNextBufferNode
->getNextNodeByTreeOrder());
588 const BufferNode
* BufferNode::getNextNodeByTreeOrder() const
589 /****** BufferNode/getNextNodeByTreeOrder ************************************
592 * getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree
596 * next = getNextNodeByTreeOrder();
605 * next - the BufferNode following this BufferNode in the tree order,
606 * or NULL if there is none.
609 * The "next" node in tree order is defined as:
610 * 1. If a node has children, then the first child is;
611 * 2. otherwise, if it has a following sibling, then this sibling node is;
612 * 3. otherwise, if it has a parent node, the parent's next sibling
614 * 4. otherwise, no "next" node exists.
615 ******************************************************************************/
618 * If this buffer node has m_vChildren, then return the first
623 return getFirstChild();
627 * Otherwise, it this buffer node has a following sibling,
628 * then return that sibling.
630 BufferNode
* pNextSibling
= const_cast<BufferNode
*>(getNextSibling());
631 if (pNextSibling
!= nullptr)
637 * Otherwise, it this buffer node has parent, then return
638 * its parent's following sibling.
640 BufferNode
* pNode
= const_cast<BufferNode
*>(this);
642 BufferNode
* pNextSiblingParent
= nullptr;
646 if (pNode
== nullptr)
651 pParent
= const_cast<BufferNode
*>(pNode
->getParent());
652 if (pParent
!= nullptr)
654 pNextSiblingParent
= const_cast<BufferNode
*>(pParent
->getNextSibling());
658 } while (pNextSiblingParent
== nullptr);
660 return pNextSiblingParent
;
664 void BufferNode::setXMLElement( const cssu::Reference
< cssxw::XXMLElementWrapper
>& xXMLElement
)
666 m_xXMLElement
= xXMLElement
;
669 void BufferNode::notifyBranch()
670 /****** BufferNode/notifyBranch **********************************************
673 * notifyBranch -- notifies each BufferNode in the branch of this
674 * BufferNode in the tree order.
687 ******************************************************************************/
689 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
691 for( ; ii
!= m_vChildren
.end() ; ++ii
)
693 BufferNode
* pBufferNode
= const_cast<BufferNode
*>(*ii
);
694 pBufferNode
->elementCollectorNotify();
695 pBufferNode
->notifyBranch();
699 void BufferNode::elementCollectorNotify()
700 /****** BufferNode/elementCollectorNotify ************************************
703 * elementCollectorNotify -- notifies this BufferNode.
706 * elementCollectorNotify();
709 * Notifies this BufferNode if the notification is not suppressed.
715 * child - the first child BufferNode, or NULL if there is no child
717 ******************************************************************************/
719 if (!m_vElementCollectors
.empty())
721 cssxc::sax::ElementMarkPriority nMaxPriority
= cssxc::sax::ElementMarkPriority_MINIMUM
;
722 cssxc::sax::ElementMarkPriority nPriority
;
725 * get the max priority among ElementCollectors on this BufferNode
727 std::vector
< const ElementCollector
* >::const_iterator ii
= m_vElementCollectors
.begin();
728 for( ; ii
!= m_vElementCollectors
.end() ; ++ii
)
730 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*ii
);
731 nPriority
= pElementCollector
->getPriority();
732 if (nPriority
> nMaxPriority
)
734 nMaxPriority
= nPriority
;
738 std::vector
< const ElementCollector
* > vElementCollectors( m_vElementCollectors
);
739 ii
= vElementCollectors
.begin();
741 for( ; ii
!= vElementCollectors
.end() ; ++ii
)
743 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*ii
);
744 nPriority
= pElementCollector
->getPriority();
745 bool bToModify
= pElementCollector
->getModify();
748 * Only ElementCollector with the max priority can
749 * perform notify operation.
750 * Moreover, if any blocker exists in the subtree of
751 * this BufferNode, this ElementCollector can't do notify
752 * unless its priority is BEFOREMODIFY.
754 if (nPriority
== nMaxPriority
&&
755 (nPriority
== cssxc::sax::ElementMarkPriority_BEFOREMODIFY
||
756 !isBlockerInSubTreeIncluded(pElementCollector
->getSecurityId())))
759 * If this ElementCollector will modify the bufferred element, then
760 * special attention must be paid.
762 * If there is any ElementCollector in the subtree or any ancestor
763 * ElementCollector with PRI_BEFPREMODIFY priority, this
764 * ElementCollector can't perform notify operation, otherwise, it
765 * will destroy the bufferred element, in turn, ElementCollectors
766 * mentioned above can't perform their mission.
768 //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY &&
770 (isECInSubTreeIncluded(pElementCollector
->getSecurityId()) ||
771 isECOfBeforeModifyInAncestorIncluded(pElementCollector
->getSecurityId()))
774 pElementCollector
->notifyListener();
781 bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId
) const
782 /****** BufferNode/isECInSubTreeIncluded *************************************
785 * isECInSubTreeIncluded -- checks whether there is any ElementCollector
786 * in the branch of this BufferNode.
789 * bExist = isECInSubTreeIncluded(nIgnoredSecurityId);
792 * checks each BufferNode in the branch of this BufferNode, if there is
793 * an ElementCollector whose signatureId is not ignored, then return
794 * true, otherwise, false returned.
797 * nIgnoredSecurityId - the security Id to be ignored. If it equals
798 * to UNDEFINEDSECURITYID, then no security Id
802 * bExist - true if a match found, false otherwise.
803 ******************************************************************************/
807 std::vector
< const ElementCollector
* >::const_iterator jj
= m_vElementCollectors
.begin();
809 for( ; jj
!= m_vElementCollectors
.end() ; ++jj
)
811 ElementCollector
* pElementCollector
= const_cast<ElementCollector
*>(*jj
);
812 if (nIgnoredSecurityId
== cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID
||
813 pElementCollector
->getSecurityId() != nIgnoredSecurityId
)
822 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
824 for( ; ii
!= m_vChildren
.end() ; ++ii
)
826 BufferNode
* pBufferNode
= const_cast<BufferNode
*>(*ii
);
828 if ( pBufferNode
->isECInSubTreeIncluded(nIgnoredSecurityId
))
839 bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId
) const
840 /****** BufferNode/isECOfBeforeModifyInAncestorIncluded **********************
843 * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some
844 * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY
848 * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId);
851 * checks each ancestor BufferNode through the parent link, if there is
852 * an ElementCollector with PRI_BEFPREMODIFY priority and its
853 * signatureId is not ignored, then return true, otherwise, false
857 * nIgnoredSecurityId - the security Id to be ignored. If it equals
858 * to UNDEFINEDSECURITYID, then no security Id
862 * bExist - true if a match found, false otherwise.
863 ******************************************************************************/
867 BufferNode
* pParentNode
= m_pParent
;
868 while (pParentNode
!= nullptr)
870 if (pParentNode
->isECOfBeforeModifyIncluded(nIgnoredSecurityId
))
876 pParentNode
= const_cast<BufferNode
*>(pParentNode
->getParent());
882 bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId
) const
883 /****** BufferNode/isBlockerInSubTreeIncluded ********************************
886 * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode
887 * which has blocker on it
890 * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId);
893 * checks each BufferNode in the branch of this BufferNode, if one has
894 * a blocker on it, and the blocker's securityId is not ignored, then
895 * returns true; otherwise, false returns.
898 * nIgnoredSecurityId - the security Id to be ignored. If it equals
899 * to UNDEFINEDSECURITYID, then no security Id
903 * bExist - true if a match found, false otherwise.
904 ******************************************************************************/
908 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
910 for( ; ii
!= m_vChildren
.end() ; ++ii
)
912 BufferNode
* pBufferNode
= const_cast<BufferNode
*>(*ii
);
913 ElementMark
* pBlocker
= pBufferNode
->getBlocker();
915 if (pBlocker
!= nullptr &&
916 (nIgnoredSecurityId
== cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID
||
917 pBlocker
->getSecurityId() != nIgnoredSecurityId
))
923 if (rc
|| pBufferNode
->isBlockerInSubTreeIncluded(nIgnoredSecurityId
))
933 const BufferNode
* BufferNode::getNextChild(const BufferNode
* pChild
) const
934 /****** BufferNode/getNextChild **********************************************
937 * getNextChild -- get the next child BufferNode.
940 * nextChild = getNextChild();
946 * pChild - the child BufferNode whose next node is retrieved.
949 * nextChild - the next child BufferNode after the pChild, or NULL if
951 ******************************************************************************/
953 BufferNode
* rc
= nullptr;
954 bool bChildFound
= false;
956 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
957 for( ; ii
!= m_vChildren
.end() ; ++ii
)
961 rc
= const_cast<BufferNode
*>(*ii
);
975 void BufferNode::freeAllChildren()
976 /****** BufferNode/freeAllChildren *******************************************
979 * freeAllChildren -- free all his child BufferNode.
992 ******************************************************************************/
994 std::vector
< const BufferNode
* >::const_iterator ii
= m_vChildren
.begin();
995 for( ; ii
!= m_vChildren
.end() ; ++ii
)
997 BufferNode
*pChild
= const_cast<BufferNode
*>(*ii
);
998 pChild
->freeAllChildren();
1002 m_vChildren
.clear();
1005 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */