| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the 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(); |
| } |