summaryrefslogtreecommitdiff
path: root/xmlsecurity/source/framework/buffernode.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'xmlsecurity/source/framework/buffernode.cxx')
-rw-r--r--xmlsecurity/source/framework/buffernode.cxx1279
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();
+}