diff options
Diffstat (limited to 'xmlsecurity/source/framework/buffernode.cxx')
-rw-r--r-- | xmlsecurity/source/framework/buffernode.cxx | 1279 |
1 files changed, 1279 insertions, 0 deletions
diff --git a/xmlsecurity/source/framework/buffernode.cxx b/xmlsecurity/source/framework/buffernode.cxx new file mode 100644 index 000000000000..5e06d3fbc3b6 --- /dev/null +++ b/xmlsecurity/source/framework/buffernode.cxx @@ -0,0 +1,1279 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_xmlsecurity.hxx" + +#include "elementmark.hxx" +#include "elementcollector.hxx" +#include "buffernode.hxx" +#include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp> + +namespace cssu = com::sun::star::uno; +namespace cssxw = com::sun::star::xml::wrapper; +namespace cssxc = com::sun::star::xml::crypto; + +BufferNode::BufferNode( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement ) + :m_pParent(NULL), + m_pBlocker(NULL), + m_bAllReceived(false), + m_xXMLElement(xXMLElement) +{ +} + +bool BufferNode::isECOfBeforeModifyIncluded(sal_Int32 nIgnoredSecurityId) const +/****** BufferNode/isECOfBeforeModifyIncluded ******************************** + * + * NAME + * isECOfBeforeModifyIncluded -- checks whether there is some + * ElementCollector on this BufferNode, that has BEFORE-MODIFY priority. + * + * SYNOPSIS + * bExist = isECOfBeforeModifyIncluded(nIgnoredSecurityId); + * + * FUNCTION + * checks each ElementCollector on this BufferNode, if all following + * conditions are satisfied, then returns true: + * 1. the ElementCollector's priority is BEFOREMODIFY; + * 2. the ElementCollector's securityId can't be ignored. + * otherwise, returns false. + * + * INPUTS + * nIgnoredSecurityId - the security Id to be ignored. If it equals + * to UNDEFINEDSECURITYID, then no security Id + * will be ignored. + * + * RESULT + * bExist - true if a match found, false otherwise + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + bool rc = false; + std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin(); + + for( ; ii != m_vElementCollectors.end() ; ++ii ) + { + ElementCollector* pElementCollector = (ElementCollector*)*ii; + + if ((nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID || + pElementCollector->getSecurityId() != nIgnoredSecurityId) && + (pElementCollector->getPriority() == cssxc::sax::ElementMarkPriority_BEFOREMODIFY)) + { + rc = true; + break; + } + } + + return rc; +} + +void BufferNode::setReceivedAll() +/****** BufferNode/setReceiveAll ********************************************* + * + * NAME + * setReceivedAll -- indicates that the element in this BufferNode has + * been compeletely bufferred. + * + * SYNOPSIS + * setReceivedAll(); + * + * FUNCTION + * sets the all-received flag and launches ElementCollector's notify + * process. + * + * INPUTS + * empty + * + * RESULT + * empty + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + m_bAllReceived = true; + elementCollectorNotify(); +} + +bool BufferNode::isAllReceived() const +{ + return m_bAllReceived; +} + +void BufferNode::addElementCollector(const ElementCollector* pElementCollector) +/****** BufferNode/addElementCollector *************************************** + * + * NAME + * addElementCollector -- adds a new ElementCollector to this BufferNode. + * + * SYNOPSIS + * addElementCollector(pElementCollector); + * + * FUNCTION + * see NAME + * + * INPUTS + * pElementCollector - the ElementCollector to be added + * + * RESULT + * empty + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + m_vElementCollectors.push_back( pElementCollector ); + ((ElementCollector*)pElementCollector)->setBufferNode(this); +} + +void BufferNode::removeElementCollector(const ElementCollector* pElementCollector) +/****** BufferNode/removeElementCollector ************************************ + * + * NAME + * removeElementCollector -- removes an ElementCollector from this + * BufferNode. + * + * SYNOPSIS + * removeElementCollector(pElementCollector); + * + * FUNCTION + * see NAME + * + * INPUTS + * pElementCollector - the ElementCollector to be removed + * + * RESULT + * empty + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + std::vector< const ElementCollector* >::iterator ii = m_vElementCollectors.begin(); + + for( ; ii != m_vElementCollectors.end() ; ++ii ) + { + if( *ii == pElementCollector ) + { + m_vElementCollectors.erase( ii ); + ((ElementCollector*)pElementCollector)->setBufferNode(NULL); + break; + } + } +} + +ElementMark* BufferNode::getBlocker() const +{ + return m_pBlocker; +} + +void BufferNode::setBlocker(const ElementMark* pBlocker) +/****** BufferNode/setBlocker ************************************************ + * + * NAME + * setBlocker -- adds a blocker to this BufferNode. + * + * SYNOPSIS + * setBlocker(pBlocker); + * + * FUNCTION + * see NAME + * + * INPUTS + * pBlocker - the new blocker to be attached + * + * RESULT + * empty + * + * NOTES + * Because there is only one blocker permited for a BufferNode, so the + * old blocker on this BufferNode, if there is one, will be overcasted. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + OSL_ASSERT(!(m_pBlocker != NULL && pBlocker != NULL)); + + m_pBlocker = (ElementMark*)pBlocker; + if (m_pBlocker != NULL) + { + m_pBlocker->setBufferNode(this); + } +} + +rtl::OUString BufferNode::printChildren() const +/****** BufferNode/printChildren ********************************************* + * + * NAME + * printChildren -- prints children information into a string. + * + * SYNOPSIS + * result = printChildren(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * result - the information string + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + rtl::OUString rc; + std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin(); + + for( ; ii != m_vElementCollectors.end() ; ++ii ) + { + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BufID=" )); + rc += rtl::OUString::valueOf((*ii)->getBufferId()); + + if (((ElementCollector*)(*ii))->getModify()) + { + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[M]" )); + } + + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ",Pri=" )); + + switch (((ElementCollector*)(*ii))->getPriority()) + { + case cssxc::sax::ElementMarkPriority_BEFOREMODIFY: + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BEFOREMODIFY" )); + break; + case cssxc::sax::ElementMarkPriority_AFTERMODIFY: + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "AFTERMODIFY" )); + break; + default: + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UNKNOWN" )); + break; + } + + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(" )); + /* + if (((ElementCollector*)(*ii))->isInternalNotificationSuppressed()) + { + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "*IN-Suppressed* " )); + } + */ + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "SecID=" )); + rc += rtl::OUString::valueOf(((ElementCollector*)(*ii))->getSecurityId()); + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" )); + rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); + } + + return rc; +} + +bool BufferNode::hasAnything() const +/****** BufferNode/hasAnything *********************************************** + * + * NAME + * hasAnything -- checks whether there is any ElementCollector or blocker + * on this BufferNode. + * + * SYNOPSIS + * bExist = hasAnything(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * bExist - true if there is, false otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + return (m_pBlocker != NULL || m_vElementCollectors.size() > 0); +} + +bool BufferNode::hasChildren() const +/****** BufferNode/hasChildren *********************************************** + * + * NAME + * hasChildren -- checks whether this BufferNode has any child + * BufferNode. + * + * SYNOPSIS + * bExist = hasChildren(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * bExist - true if there is, false otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + return (m_vChildren.size() > 0); +} + +std::vector< const BufferNode* >* BufferNode::getChildren() const +{ + return new std::vector< const BufferNode* >( m_vChildren ); +} + +const BufferNode* BufferNode::getFirstChild() const +/****** BufferNode/getFirstChild ********************************************* + * + * NAME + * getFirstChild -- retrieves the first child BufferNode. + * + * SYNOPSIS + * child = getFirstChild(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * child - the first child BufferNode, or NULL if there is no child + * BufferNode. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + BufferNode* rc = NULL; + + if (m_vChildren.size() > 0) + { + rc = (BufferNode*)m_vChildren.front(); + } + + return (const BufferNode*)rc; +} + +void BufferNode::addChild(const BufferNode* pChild, sal_Int32 nPosition) +/****** BufferNode/addChild(pChild,nPosition) ******************************** + * + * NAME + * addChild -- inserts a child BufferNode at specific position. + * + * SYNOPSIS + * addChild(pChild, nPosition); + * + * FUNCTION + * see NAME + * + * INPUTS + * pChild - the child BufferNode to be added. + * nPosition - the position where the new child locates. + * + * RESULT + * empty + * + * NOTES + * If the nPosition is -1, then the new child BufferNode is appended + * at the end. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + if (nPosition == -1) + { + m_vChildren.push_back( pChild ); + } + else + { + std::vector< const BufferNode* >::iterator ii = m_vChildren.begin(); + ii += nPosition; + m_vChildren.insert(ii, pChild); + } +} + +void BufferNode::addChild(const BufferNode* pChild) +/****** BufferNode/addChild() ************************************************ + * + * NAME + * addChild -- add a new child BufferNode. + * + * SYNOPSIS + * addChild(pChild); + * + * FUNCTION + * see NAME + * + * INPUTS + * pChild - the child BufferNode to be added. + * + * RESULT + * empty + * + * NOTES + * The new child BufferNode is appended at the end. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + addChild(pChild, -1); +} + +void BufferNode::removeChild(const BufferNode* pChild) +/****** BufferNode/removeChild *********************************************** + * + * NAME + * removeChild -- removes a child BufferNode from the children list. + * + * SYNOPSIS + * removeChild(pChild); + * + * FUNCTION + * see NAME + * + * INPUTS + * pChild - the child BufferNode to be removed + * + * RESULT + * empty + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + std::vector< const BufferNode* >::iterator ii = m_vChildren.begin(); + + for( ; ii != m_vChildren.end() ; ++ii ) + { + if( *ii == pChild ) + { + m_vChildren.erase( ii ); + break; + } + } +} + +sal_Int32 BufferNode::indexOfChild(const BufferNode* pChild) const +/****** BufferNode/indexOfChild ********************************************** + * + * NAME + * indexOfChild -- gets the index of a child BufferNode. + * + * SYNOPSIS + * index = indexOfChild(pChild); + * + * FUNCTION + * see NAME + * + * INPUTS + * pChild - the child BufferNode whose index to be gotten + * + * RESULT + * index - the index of that child BufferNode. If that child BufferNode + * is not found, -1 is returned. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + sal_Int32 nIndex = 0; + bool bFound = false; + + std::vector< const BufferNode * >::const_iterator ii = m_vChildren.begin(); + + for( ; ii != m_vChildren.end() ; ++ii ) + { + if( *ii == pChild ) + { + bFound = true; + break; + } + nIndex++; + } + + if (!bFound ) + { + nIndex = -1; + } + + return nIndex; +} + +const BufferNode* BufferNode::childAt(sal_Int32 nIndex) const +/****** BufferNode/childAt *************************************************** + * + * NAME + * childAt -- retrieves the child BufferNode at specific possition. + * + * SYNOPSIS + * child = childAt(nIndex); + * + * FUNCTION + * see NAME + * + * INPUTS + * nIndex - the index of the child BufferNode to be retrieved + * + * RESULT + * child - the child BufferNode at index position, or NULL if the index + * is out of the range of children. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + BufferNode* rc = NULL; + + if (nIndex < ((sal_Int32)m_vChildren.size()) && nIndex >= 0) + { + rc = (BufferNode*)m_vChildren[nIndex]; + } + + return (const BufferNode*)rc; +} + +const BufferNode* BufferNode::getParent() const +{ + return m_pParent; +} + +void BufferNode::setParent(const BufferNode* pParent) +{ + m_pParent = (BufferNode*)pParent; +} + +const BufferNode* BufferNode::getNextSibling() const +/****** BufferNode/getNextSibling ******************************************** + * + * NAME + * getNextSibling -- retrieves the next sibling BufferNode. + * + * SYNOPSIS + * sibling = getNextSibling(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * sibling - the next sibling BufferNode, or NULL if there is none. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + BufferNode* rc = NULL; + + if (m_pParent != NULL) + { + rc = (BufferNode*)m_pParent->getNextChild(this); + } + + return (const BufferNode*)rc; +} + +const BufferNode* BufferNode::isAncestor(const BufferNode* pDescendant) const +/****** BufferNode/isAncestor ************************************************ + * + * NAME + * isAncestor -- checks whether this BufferNode is an ancestor of another + * BufferNode. + * + * SYNOPSIS + * bIs = isAncestor(pDescendant); + * + * FUNCTION + * see NAME + * + * INPUTS + * pDescendant - the BufferNode to be checked as a descendant + * + * RESULT + * bIs - true if this BufferNode is an ancestor of the pDescendant, + * false otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + BufferNode* rc = NULL; + + if (pDescendant != NULL) + { + std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); + + for( ; ii != m_vChildren.end() ; ++ii ) + { + BufferNode* pChild = (BufferNode*)*ii; + + if (pChild == pDescendant) + { + rc = pChild; + break; + } + + if (pChild->isAncestor(pDescendant) != NULL) + { + rc = pChild; + break; + } + } + } + + return (const BufferNode*)rc; +} + +bool BufferNode::isPrevious(const BufferNode* pFollowing) const +/****** BufferNode/isPrevious ************************************************ + * + * NAME + * isPrevious -- checks whether this BufferNode is ahead of another + * BufferNode in the tree order. + * + * SYNOPSIS + * bIs = isPrevious(pFollowing); + * + * FUNCTION + * see NAME + * + * INPUTS + * pFollowing - the BufferNode to be checked as a following + * + * RESULT + * bIs - true if this BufferNode is ahead in the tree order, false + * otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + bool rc = false; + + BufferNode* pNextBufferNode = (BufferNode*)getNextNodeByTreeOrder(); + while (pNextBufferNode != NULL) + { + if (pNextBufferNode == pFollowing) + { + rc = true; + break; + } + + pNextBufferNode = (BufferNode*)(pNextBufferNode->getNextNodeByTreeOrder()); + } + + return rc; +} + +const BufferNode* BufferNode::getNextNodeByTreeOrder() const +/****** BufferNode/getNextNodeByTreeOrder ************************************ + * + * NAME + * getNextNodeByTreeOrder -- retrieves the next BufferNode in the tree + * order. + * + * SYNOPSIS + * next = getNextNodeByTreeOrder(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * next - the BufferNode following this BufferNode in the tree order, + * or NULL if there is none. + * + * NOTES + * The "next" node in tree order is defined as: + * 1. If a node has children, then the first child is; + * 2. otherwise, if it has a following sibling, then this sibling node is; + * 3. otherwise, if it has a parent node, the the parent's next sibling + * node is; + * 4. otherwise, no "next" node exists. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + /* + * If this buffer node has m_vChildren, then return the first + * child. + */ + if (hasChildren()) + { + return getFirstChild(); + } + + /* + * Otherwise, it this buffer node has a following sibling, + * then return that sibling. + */ + BufferNode* pNextSibling = (BufferNode*)getNextSibling(); + if (pNextSibling != NULL) + { + return pNextSibling; + } + + /* + * Otherwise, it this buffer node has parent, then return + * its parent's following sibling. + */ + BufferNode* pNode = (BufferNode*)this; + BufferNode* pParent; + BufferNode* pNextSiblingParent = NULL; + + do + { + if (pNode == NULL) + { + break; + } + + pParent = (BufferNode*)pNode->getParent(); + if (pParent != NULL) + { + pNextSiblingParent = (BufferNode*)pParent->getNextSibling(); + } + pNode = pParent; + + }while (pNextSiblingParent == NULL); + + return pNextSiblingParent; +} + +cssu::Reference< cssxw::XXMLElementWrapper > BufferNode::getXMLElement() const +{ + return m_xXMLElement; +} + +void BufferNode::setXMLElement( const cssu::Reference< cssxw::XXMLElementWrapper >& xXMLElement ) +{ + m_xXMLElement = xXMLElement; +} + +void BufferNode::notifyBranch() +/****** BufferNode/notifyBranch ********************************************** + * + * NAME + * notifyBranch -- notifies each BufferNode in the branch of this + * BufferNode in the tree order. + * + * SYNOPSIS + * notifyBranch(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * empty + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); + + for( ; ii != m_vChildren.end() ; ++ii ) + { + BufferNode* pBufferNode = (BufferNode*)*ii; + pBufferNode->elementCollectorNotify(); + pBufferNode->notifyBranch(); + } +} + +void BufferNode::notifyAncestor() +/****** BufferNode/notifyAncestor ******************************************** + * + * NAME + * notifyAncestor -- notifies each ancestor BufferNode through the parent + * link. + * + * SYNOPSIS + * notifyAncestor(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * empty + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + BufferNode* pParent = m_pParent; + while (pParent != NULL) + { + pParent->notifyAncestor(); + pParent = (BufferNode*)pParent->getParent(); + } +} + +void BufferNode::elementCollectorNotify() +/****** BufferNode/elementCollectorNotify ************************************ + * + * NAME + * elementCollectorNotify -- notifies this BufferNode. + * + * SYNOPSIS + * elementCollectorNotify(); + * + * FUNCTION + * Notifies this BufferNode if the notification is not suppressed. + * + * INPUTS + * empty + * + * RESULT + * child - the first child BufferNode, or NULL if there is no child + * BufferNode. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + if (m_vElementCollectors.size()>0) + { + cssxc::sax::ElementMarkPriority nMaxPriority = cssxc::sax::ElementMarkPriority_MINIMUM; + cssxc::sax::ElementMarkPriority nPriority; + + /* + * get the max priority among ElementCollectors on this BufferNode + */ + std::vector< const ElementCollector* >::const_iterator ii = m_vElementCollectors.begin(); + for( ; ii != m_vElementCollectors.end() ; ++ii ) + { + ElementCollector* pElementCollector = (ElementCollector*)*ii; + nPriority = pElementCollector->getPriority(); + if (nPriority > nMaxPriority) + { + nMaxPriority = nPriority; + } + } + + std::vector< const ElementCollector* > vElementCollectors( m_vElementCollectors ); + ii = vElementCollectors.begin(); + + for( ; ii != vElementCollectors.end() ; ++ii ) + { + ElementCollector* pElementCollector = (ElementCollector*)*ii; + nPriority = pElementCollector->getPriority(); + bool bToModify = pElementCollector->getModify(); + + /* + * Only ElementCollector with the max priority can + * perform notify operation. + * Moreover, if any blocker exists in the subtree of + * this BufferNode, this ElementCollector can't do notify + * unless its priority is BEFOREMODIFY. + */ + if (nPriority == nMaxPriority && + (nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY || + !isBlockerInSubTreeIncluded(pElementCollector->getSecurityId()))) + { + /* + * If this ElementCollector will modify the bufferred element, then + * special attention must be paid. + * + * If there is any ElementCollector in the subtree or any ancestor + * ElementCollector with PRI_BEFPREMODIFY priority, this + * ElementCollector can't perform notify operation, otherwise, it + * will destroy the bufferred element, in turn, ElementCollectors + * mentioned above can't perform their mission. + */ + //if (!(nMaxPriority == cssxc::sax::ElementMarkPriority_PRI_MODIFY && + if (!(bToModify && + (isECInSubTreeIncluded(pElementCollector->getSecurityId()) || + isECOfBeforeModifyInAncestorIncluded(pElementCollector->getSecurityId())) + )) + { + pElementCollector->notifyListener(); + } + } + } + } +} + +bool BufferNode::isECInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const +/****** BufferNode/isECInSubTreeIncluded ************************************* + * + * NAME + * isECInSubTreeIncluded -- checks whether there is any ElementCollector + * in the branch of this BufferNode. + * + * SYNOPSIS + * bExist = isECInSubTreeIncluded(nIgnoredSecurityId); + * + * FUNCTION + * checks each BufferNode in the branch of this BufferNode, if there is + * an ElementCollector whose signatureId is not ignored, then return + * true, otherwise, false returned. + * + * INPUTS + * nIgnoredSecurityId - the security Id to be ignored. If it equals + * to UNDEFINEDSECURITYID, then no security Id + * will be ignored. + * + * RESULT + * bExist - true if a match found, false otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + bool rc = false; + + std::vector< const ElementCollector* >::const_iterator jj = m_vElementCollectors.begin(); + + for( ; jj != m_vElementCollectors.end() ; ++jj ) + { + ElementCollector* pElementCollector = (ElementCollector*)*jj; + if (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID || + pElementCollector->getSecurityId() != nIgnoredSecurityId) + { + rc = true; + break; + } + } + + if ( !rc ) + { + std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); + + for( ; ii != m_vChildren.end() ; ++ii ) + { + BufferNode* pBufferNode = (BufferNode*)*ii; + + if ( pBufferNode->isECInSubTreeIncluded(nIgnoredSecurityId)) + { + rc = true; + break; + } + } + } + + return rc; +} + +bool BufferNode::isECOfBeforeModifyInAncestorIncluded(sal_Int32 nIgnoredSecurityId) const +/****** BufferNode/isECOfBeforeModifyInAncestorIncluded ********************** + * + * NAME + * isECOfBeforeModifyInAncestorIncluded -- checks whether there is some + * ancestor BufferNode which has ElementCollector with PRI_BEFPREMODIFY + * priority. + * + * SYNOPSIS + * bExist = isECOfBeforeModifyInAncestorIncluded(nIgnoredSecurityId); + * + * FUNCTION + * checks each ancestor BufferNode through the parent link, if there is + * an ElementCollector with PRI_BEFPREMODIFY priority and its + * signatureId is not ignored, then return true, otherwise, false + * returned. + * + * INPUTS + * nIgnoredSecurityId - the security Id to be ignored. If it equals + * to UNDEFINEDSECURITYID, then no security Id + * will be ignored. + * + * RESULT + * bExist - true if a match found, false otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + bool rc = false; + + BufferNode* pParentNode = m_pParent; + while (pParentNode != NULL) + { + if (pParentNode->isECOfBeforeModifyIncluded(nIgnoredSecurityId)) + { + rc = true; + break; + } + + pParentNode = (BufferNode*)pParentNode->getParent(); + } + + return rc; +} + +bool BufferNode::isBlockerInSubTreeIncluded(sal_Int32 nIgnoredSecurityId) const +/****** BufferNode/isBlockerInSubTreeIncluded ******************************** + * + * NAME + * isBlockerInSubTreeIncluded -- checks whether there is some BufferNode + * which has blocker on it + * + * SYNOPSIS + * bExist = isBlockerInSubTreeIncluded(nIgnoredSecurityId); + * + * FUNCTION + * checks each BufferNode in the branch of this BufferNode, if one has + * a blocker on it, and the blocker's securityId is not ignored, then + * returns true; otherwise, false returns. + * + * INPUTS + * nIgnoredSecurityId - the security Id to be ignored. If it equals + * to UNDEFINEDSECURITYID, then no security Id + * will be ignored. + * + * RESULT + * bExist - true if a match found, false otherwise. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + bool rc = false; + + std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); + + for( ; ii != m_vChildren.end() ; ++ii ) + { + BufferNode* pBufferNode = (BufferNode*)*ii; + ElementMark* pBlocker = pBufferNode->getBlocker(); + + if (pBlocker != NULL && + (nIgnoredSecurityId == cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID || + pBlocker->getSecurityId() != nIgnoredSecurityId )) + { + rc = true; + break; + } + + if (rc || pBufferNode->isBlockerInSubTreeIncluded(nIgnoredSecurityId)) + { + rc = true; + break; + } + } + + return rc; +} + +const BufferNode* BufferNode::getNextChild(const BufferNode* pChild) const +/****** BufferNode/getNextChild ********************************************** + * + * NAME + * getNextChild -- get the next child BufferNode. + * + * SYNOPSIS + * nextChild = getNextChild(); + * + * FUNCTION + * see NAME + * + * INPUTS + * pChild - the child BufferNode whose next node is retrieved. + * + * RESULT + * nextChild - the next child BufferNode after the pChild, or NULL if + * there is none. + * + * HISTORY + * 05.01.2004 - implemented + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + BufferNode* rc = NULL; + bool bChildFound = false; + + std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); + for( ; ii != m_vChildren.end() ; ++ii ) + { + if (bChildFound) + { + rc = (BufferNode*)*ii; + break; + } + + if( *ii == pChild ) + { + bChildFound = true; + } + } + + return (const BufferNode*)rc; +} + + +void BufferNode::freeAllChildren() +/****** BufferNode/freeAllChildren ******************************************* + * + * NAME + * freeAllChildren -- free all his child BufferNode. + * + * SYNOPSIS + * freeAllChildren(); + * + * FUNCTION + * see NAME + * + * INPUTS + * empty + * + * RESULT + * empty + * + * HISTORY + * 30.03.2004 - the correct the memory leak bug + * + * AUTHOR + * Michael Mi + * Email: michael.mi@sun.com + ******************************************************************************/ +{ + std::vector< const BufferNode* >::const_iterator ii = m_vChildren.begin(); + for( ; ii != m_vChildren.end() ; ++ii ) + { + BufferNode *pChild = (BufferNode *)(*ii); + pChild->freeAllChildren(); + delete pChild; + } + + m_vChildren.clear(); +} |