LCOV - code coverage report
Current view: top level - libreoffice/xmlsecurity/source/framework - saxeventkeeperimpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 395 0.0 %
Date: 2012-12-17 Functions: 0 49 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "saxeventkeeperimpl.hxx"
      22             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      23             : #include <com/sun/star/xml/sax/XDocumentHandler.hpp>
      24             : #include <com/sun/star/xml/crypto/sax/ConstOfSecurityId.hpp>
      25             : 
      26             : namespace cssu = com::sun::star::uno;
      27             : namespace cssl = com::sun::star::lang;
      28             : namespace cssxc = com::sun::star::xml::crypto;
      29             : namespace cssxcsax = com::sun::star::xml::csax;
      30             : namespace cssxw = com::sun::star::xml::wrapper;
      31             : namespace cssxs = com::sun::star::xml::sax;
      32             : 
      33             : #define SERVICE_NAME "com.sun.star.xml.crypto.sax.SAXEventKeeper"
      34             : #define IMPLEMENTATION_NAME "com.sun.star.xml.security.framework.SAXEventKeeperImpl"
      35             : 
      36             : #define _USECOMPRESSEDDOCUMENTHANDLER
      37             : 
      38           0 : SAXEventKeeperImpl::SAXEventKeeperImpl( )
      39             :     :m_pRootBufferNode(NULL),
      40             :      m_pCurrentBufferNode(NULL),
      41             :      m_nNextElementMarkId(1),
      42             :      m_pNewBlocker(NULL),
      43             :      m_pCurrentBlockingBufferNode(NULL),
      44             :      m_bIsReleasing(false),
      45           0 :      m_bIsForwarding(false)
      46             : {
      47           0 :     m_vElementMarkBuffers.reserve(2);
      48           0 :     m_vNewElementCollectors.reserve(2);
      49           0 :     m_vReleasedElementMarkBuffers.reserve(2);
      50           0 : }
      51             : 
      52           0 : SAXEventKeeperImpl::~SAXEventKeeperImpl()
      53             : {
      54             :     /*
      55             :      * delete the BufferNode tree
      56             :      */
      57           0 :     if (m_pRootBufferNode != NULL)
      58             :     {
      59           0 :         m_pRootBufferNode->freeAllChildren();
      60           0 :         delete m_pRootBufferNode;
      61             :     }
      62             : 
      63           0 :     m_pRootBufferNode = m_pCurrentBufferNode = m_pCurrentBlockingBufferNode = NULL;
      64             : 
      65             :     /*
      66             :      * delete all unfreed ElementMarks
      67             :      */
      68           0 :     m_vNewElementCollectors.clear();
      69           0 :     m_pNewBlocker = NULL;
      70             : 
      71           0 :     std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin();
      72           0 :     for( ; ii != m_vElementMarkBuffers.end(); ++ii )
      73             :     {
      74           0 :         delete (*ii);
      75             :     }
      76           0 :     m_vElementMarkBuffers.clear();
      77           0 : }
      78             : 
      79           0 : void SAXEventKeeperImpl::setCurrentBufferNode(BufferNode* pBufferNode)
      80             : /****** SAXEventKeeperImpl/setCurrentBufferNode ******************************
      81             :  *
      82             :  *   NAME
      83             :  *  setCurrentBufferNode -- set a new active BufferNode.
      84             :  *
      85             :  *   SYNOPSIS
      86             :  *  setCurrentBufferNode( pBufferNode );
      87             :  *
      88             :  *   FUNCTION
      89             :  *  connects this BufferNode into the BufferNode tree as a child of the
      90             :  *  current active BufferNode. Then makes this BufferNode as the current
      91             :  *  active BufferNode.
      92             :  *  If the previous active BufferNode points to the root
      93             :  *  BufferNode, which means that no buffering operation was proceeding,
      94             :  *  then notifies the status change listener that buffering  operation
      95             :  *  will begin at once.
      96             :  *
      97             :  *   INPUTS
      98             :  *  pBufferNode - a BufferNode which will be the new active BufferNode
      99             :  *
     100             :  *   RESULT
     101             :  *  empty
     102             :  *
     103             :  *   AUTHOR
     104             :  *  Michael Mi
     105             :  *  Email: michael.mi@sun.com
     106             :  ******************************************************************************/
     107             : {
     108           0 :     if (pBufferNode != m_pCurrentBufferNode)
     109             :     {
     110           0 :         if ( m_pCurrentBufferNode == m_pRootBufferNode &&
     111           0 :              m_xSAXEventKeeperStatusChangeListener.is())
     112             :         {
     113           0 :             m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_True);
     114             :         }
     115             : 
     116           0 :         if (pBufferNode->getParent() == NULL)
     117             :         {
     118           0 :             m_pCurrentBufferNode->addChild(pBufferNode);
     119           0 :             pBufferNode->setParent(m_pCurrentBufferNode);
     120             :         }
     121             : 
     122           0 :         m_pCurrentBufferNode = pBufferNode;
     123             :     }
     124           0 : }
     125             : 
     126           0 : BufferNode* SAXEventKeeperImpl::addNewElementMarkBuffers()
     127             : /****** SAXEventKeeperImpl/addNewElementMarkBuffers **************************
     128             :  *
     129             :  *   NAME
     130             :  *  addNewElementMarkBuffers -- add new ElementCollectors and new Blocker.
     131             :  *
     132             :  *   SYNOPSIS
     133             :  *  pBufferNode = addNewElementMarkBuffers( );
     134             :  *
     135             :  *   FUNCTION
     136             :  *  if there are new ElementCollector or new Blocker to be added, then
     137             :  *  connect all of them with the current BufferNode. In case of the
     138             :  *  current BufferNode doesn't exist, creates one.
     139             :  *  Clears up the new ElementCollector list and the new Blocker pointer.
     140             :  *
     141             :  *   INPUTS
     142             :  *  empty
     143             :  *
     144             :  *   RESULT
     145             :  *  pBufferNode - the BufferNode that has been connected with both new
     146             :  *                ElementCollectors and new Blocker.
     147             :  *
     148             :  *   AUTHOR
     149             :  *  Michael Mi
     150             :  *  Email: michael.mi@sun.com
     151             :  ******************************************************************************/
     152             : {
     153           0 :     BufferNode* pBufferNode = NULL;
     154             : 
     155           0 :     if (m_pNewBlocker || !m_vNewElementCollectors.empty() )
     156             :     {
     157             :         /*
     158             :          * When the current BufferNode is right pointing to the current
     159             :          * working element in the XMLDocumentWrapper component, then
     160             :          * no new BufferNode is needed to create.
     161             :          * This situation can only happen in the "Forwarding" mode.
     162             :          */
     163           0 :         if ( (m_pCurrentBufferNode != NULL) &&
     164           0 :              (m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement())))
     165             :         {
     166           0 :             pBufferNode = m_pCurrentBufferNode;
     167             :         }
     168             :         else
     169             :         {
     170           0 :             pBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
     171             :         }
     172             : 
     173           0 :         if (m_pNewBlocker != NULL)
     174             :         {
     175           0 :             pBufferNode->setBlocker(m_pNewBlocker);
     176             : 
     177             :             /*
     178             :              * If no blocking before, then notify the status change listener that
     179             :              * the SAXEventKeeper has entered "blocking" status, during which, no
     180             :              * SAX events will be forwarded to the next document handler.
     181             :              */
     182           0 :             if (m_pCurrentBlockingBufferNode == NULL)
     183             :             {
     184           0 :                 m_pCurrentBlockingBufferNode = pBufferNode;
     185             : 
     186           0 :                 if (m_xSAXEventKeeperStatusChangeListener.is())
     187             :                 {
     188           0 :                     m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_True);
     189             :                 }
     190             :             }
     191             : 
     192           0 :             m_pNewBlocker = NULL;
     193             :         }
     194             : 
     195           0 :         if (!m_vNewElementCollectors.empty())
     196             :         {
     197           0 :             std::vector< const ElementCollector* >::const_iterator ii = m_vNewElementCollectors.begin();
     198             : 
     199           0 :             for( ; ii != m_vNewElementCollectors.end(); ++ii )
     200             :             {
     201           0 :                 pBufferNode->addElementCollector(*ii);
     202             :             }
     203             : 
     204           0 :             m_vNewElementCollectors.clear();
     205             :         }
     206             :     }
     207             : 
     208           0 :     return pBufferNode;
     209             : }
     210             : 
     211           0 : ElementMark* SAXEventKeeperImpl::findElementMarkBuffer(sal_Int32 nId) const
     212             : /****** SAXEventKeeperImpl/findElementMarkBuffer *****************************
     213             :  *
     214             :  *   NAME
     215             :  *  findElementMarkBuffer -- finds an ElementMark.
     216             :  *
     217             :  *   SYNOPSIS
     218             :  *  pElementMark = findElementMarkBuffer( nId );
     219             :  *
     220             :  *   FUNCTION
     221             :  *  searches an ElementMark with the particular Id in the ElementMark
     222             :  *  list.
     223             :  *
     224             :  *   INPUTS
     225             :  *  nId - the Id of the ElementMark to be searched.
     226             :  *
     227             :  *   RESULT
     228             :  *  pElementMark - the ElementMark with the particular Id, or NULL when
     229             :  *                 no such Id exists.
     230             :  *
     231             :  *   AUTHOR
     232             :  *  Michael Mi
     233             :  *  Email: michael.mi@sun.com
     234             :  ******************************************************************************/
     235             : {
     236           0 :     ElementMark* pElementMark = NULL;
     237             : 
     238           0 :     std::vector< const ElementMark* >::const_iterator ii = m_vElementMarkBuffers.begin();
     239             : 
     240           0 :     for( ; ii != m_vElementMarkBuffers.end(); ++ii )
     241             :     {
     242           0 :         if ( nId == (*ii)->getBufferId())
     243             :         {
     244           0 :             pElementMark = (ElementMark*)*ii;
     245           0 :             break;
     246             :         }
     247             :     }
     248             : 
     249           0 :     return pElementMark;
     250             : }
     251             : 
     252           0 : void SAXEventKeeperImpl::removeElementMarkBuffer(sal_Int32 nId)
     253             : /****** SAXEventKeeperImpl/removeElementMarkBuffer ***************************
     254             :  *
     255             :  *   NAME
     256             :  *  removeElementMarkBuffer -- removes an ElementMark
     257             :  *
     258             :  *   SYNOPSIS
     259             :  *  removeElementMarkBuffer( nId );
     260             :  *
     261             :  *   FUNCTION
     262             :  *  removes an ElementMark with the particular Id in the ElementMark list.
     263             :  *
     264             :  *   INPUTS
     265             :  *  nId - the Id of the ElementMark to be removed.
     266             :  *
     267             :  *   RESULT
     268             :  *  empty
     269             :  *
     270             :  *   AUTHOR
     271             :  *  Michael Mi
     272             :  *  Email: michael.mi@sun.com
     273             :  ******************************************************************************/
     274             : {
     275           0 :     std::vector< const ElementMark* >::iterator ii = m_vElementMarkBuffers.begin();
     276             : 
     277           0 :     for( ; ii != m_vElementMarkBuffers.end(); ++ii )
     278             :     {
     279           0 :         if ( nId == (*ii)->getBufferId())
     280             :         {
     281             :             /*
     282             :              * checks whether this ElementMark still in the new ElementCollect array
     283             :              */
     284           0 :             std::vector< const ElementCollector* >::iterator jj = m_vNewElementCollectors.begin();
     285           0 :             for( ; jj != m_vNewElementCollectors.end(); ++jj )
     286             :             {
     287           0 :                 if ((*ii) == (*jj))
     288             :                 {
     289           0 :                     m_vNewElementCollectors.erase(jj);
     290           0 :                     break;
     291             :                 }
     292             :             }
     293             : 
     294             :             /*
     295             :              * checks whether this ElementMark is the new Blocker
     296             :              */
     297           0 :             if ((*ii) == m_pNewBlocker)
     298             :             {
     299           0 :                 m_pNewBlocker = NULL;
     300             :             }
     301             : 
     302             :             /*
     303             :              * destory the ElementMark
     304             :              */
     305           0 :             delete (*ii);
     306             : 
     307           0 :             m_vElementMarkBuffers.erase( ii );
     308             :             break;
     309             :         }
     310             :     }
     311           0 : }
     312             : 
     313           0 : rtl::OUString SAXEventKeeperImpl::printBufferNode(
     314             :     BufferNode* pBufferNode, sal_Int32 nIndent) const
     315             : /****** SAXEventKeeperImpl/printBufferNode ***********************************
     316             :  *
     317             :  *   NAME
     318             :  *  printBufferNode -- retrieves the information of a BufferNode and its
     319             :  *  branch.
     320             :  *
     321             :  *   SYNOPSIS
     322             :  *  info = printBufferNode( pBufferNode, nIndent );
     323             :  *
     324             :  *   FUNCTION
     325             :  *  all retrieved information includes:
     326             :  *  1. whether it is the current BufferNode;
     327             :  *  2. whether it is the current blocking BufferNode;
     328             :  *  3. the name of the parent element;
     329             :  *  4. the name of this element;
     330             :  *  5. all ElementCollectors working on this BufferNode;
     331             :  *  6. the Blocker working on this BufferNode;
     332             :  *  7. all child BufferNodes' information.
     333             :  *
     334             :  *   INPUTS
     335             :  *  pBufferNode -   the BufferNode from where information will be retrieved.
     336             :  *  nIndent -   how many space characters prefixed before the output
     337             :  *              message.
     338             :  *
     339             :  *   RESULT
     340             :  *  info - the information string
     341             :  *
     342             :  *   AUTHOR
     343             :  *  Michael Mi
     344             :  *  Email: michael.mi@sun.com
     345             :  ******************************************************************************/
     346             : {
     347           0 :     rtl::OUString rc;
     348             : 
     349           0 :     for ( int i=0; i<nIndent; ++i )
     350             :     {
     351           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
     352             :     }
     353             : 
     354           0 :     if (pBufferNode == m_pCurrentBufferNode)
     355             :     {
     356           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[%]" ));
     357             :     }
     358             : 
     359           0 :     if (pBufferNode == m_pCurrentBlockingBufferNode)
     360             :     {
     361           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[B]" ));
     362             :     }
     363             : 
     364           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
     365           0 :     rc += m_xXMLDocument->getNodeName(pBufferNode->getXMLElement());
     366             : 
     367           0 :     BufferNode* pParent = (BufferNode*)pBufferNode->getParent();
     368           0 :     if (pParent != NULL)
     369             :     {
     370           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "[" ));
     371           0 :         rc += m_xXMLDocument->getNodeName(pParent->getXMLElement());
     372           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "]" ));
     373             :     }
     374             : 
     375           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ":EC=" ));
     376           0 :     rc += pBufferNode->printChildren();
     377           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " BR=" ));
     378             : 
     379           0 :     ElementMark * pBlocker = pBufferNode->getBlocker();
     380           0 :     if (pBlocker != NULL)
     381             :     {
     382           0 :         rc += rtl::OUString::valueOf( pBlocker->getBufferId() );
     383           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "(SecId=" ));
     384           0 :         rc += rtl::OUString::valueOf( pBlocker->getSecurityId() );
     385           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( ")" ));
     386           0 :         rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
     387             :     }
     388           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
     389             : 
     390           0 :     std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
     391           0 :     std::vector< const BufferNode* >::const_iterator jj = vChildren->begin();
     392           0 :     for( ; jj != vChildren->end(); ++jj )
     393             :     {
     394           0 :         rc += printBufferNode((BufferNode *)*jj, nIndent+4);
     395             :     }
     396             : 
     397           0 :     delete vChildren;
     398             : 
     399           0 :     return rc;
     400             : }
     401             : 
     402             : cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >
     403           0 :     SAXEventKeeperImpl::collectChildWorkingElement(BufferNode* pBufferNode) const
     404             : /****** SAXEventKeeperImpl/collectChildWorkingElement ************************
     405             :  *
     406             :  *   NAME
     407             :  *  collectChildWorkingElement -- collects a BufferNode's all child
     408             :  *  Elements.
     409             :  *
     410             :  *   SYNOPSIS
     411             :  *  list = collectChildWorkingElement( pBufferNode );
     412             :  *
     413             :  *   FUNCTION
     414             :  *  see NAME.
     415             :  *
     416             :  *   INPUTS
     417             :  *  pBufferNode - the BufferNode whose child Elements will be collected.
     418             :  *
     419             :  *   RESULT
     420             :  *  list - the child Elements list.
     421             :  *
     422             :  *   AUTHOR
     423             :  *  Michael Mi
     424             :  *  Email: michael.mi@sun.com
     425             :  ******************************************************************************/
     426             : {
     427           0 :     std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
     428             : 
     429             :     cssu::Sequence < cssu::Reference<
     430           0 :         cssxw::XXMLElementWrapper > > aChildrenCollection ( vChildren->size());
     431             : 
     432           0 :     std::vector< const BufferNode* >::const_iterator ii = vChildren->begin();
     433             : 
     434           0 :     sal_Int32 nIndex = 0;
     435           0 :     for( ; ii != vChildren->end(); ++ii )
     436             :     {
     437           0 :         aChildrenCollection[nIndex] = (*ii)->getXMLElement();
     438           0 :         nIndex++;
     439             :     }
     440             : 
     441           0 :     delete vChildren;
     442             : 
     443           0 :     return aChildrenCollection;
     444             : }
     445             : 
     446           0 : void SAXEventKeeperImpl::smashBufferNode(
     447             :     BufferNode* pBufferNode, bool bClearRoot) const
     448             : /****** SAXEventKeeperImpl/smashBufferNode ***********************************
     449             :  *
     450             :  *   NAME
     451             :  *  smashBufferNode -- removes a BufferNode along with its working
     452             :  *  element.
     453             :  *
     454             :  *   SYNOPSIS
     455             :  *  smashBufferNode( pBufferNode, bClearRoot );
     456             :  *
     457             :  *   FUNCTION
     458             :  *  removes the BufferNode's working element from the DOM document, while
     459             :  *  reserves all ancestor paths for its child BufferNodes.
     460             :  *  when any of the BufferNode's ancestor element is useless, removes it
     461             :  *  too.
     462             :  *  removes the BufferNode from the BufferNode tree.
     463             :  *
     464             :  *   INPUTS
     465             :  *  pBufferNode -   the BufferNode to be removed
     466             :  *  bClearRoot -    whether the root element also needs to be cleared up.
     467             :  *
     468             :  *   RESULT
     469             :  *  empty
     470             :  *
     471             :  *   NOTES
     472             :  *  when removeing a Blocker's BufferNode, the bClearRoot flag should be
     473             :  *  true. Because a Blocker can buffer many SAX events which are not used
     474             :  *  by any other ElementCollector or Blocker.
     475             :  *  When the bClearRoot is set to true, the root BufferNode will be first
     476             :  *  cleared, with a stop flag seting at the next Blocking BufferNode. This
     477             :  *  operation can delete all useless bufferred SAX events which are only
     478             :  *  needed by the Blocker to be deleted.
     479             :  *
     480             :  *   AUTHOR
     481             :  *  Michael Mi
     482             :  *  Email: michael.mi@sun.com
     483             :  ******************************************************************************/
     484             : {
     485           0 :     if (!pBufferNode->hasAnything())
     486             :     {
     487           0 :         BufferNode* pParent = (BufferNode*)pBufferNode->getParent();
     488             : 
     489             :             /*
     490             :              * delete the XML data
     491             :              */
     492           0 :         if (pParent == m_pRootBufferNode)
     493             :         {
     494           0 :             bool bIsNotBlocking = (m_pCurrentBlockingBufferNode == NULL);
     495           0 :             bool bIsBlockInside = false;
     496           0 :             bool bIsBlockingAfterward = false;
     497             : 
     498             :                 /*
     499             :                  * If this is a blocker, then remove any out-element data
     500             :                  * which caused by blocking. The removal process will stop
     501             :                  * at the next blokcer to avoid removing any useful data.
     502             :                  */
     503           0 :             if (bClearRoot)
     504             :             {
     505             :                 cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >
     506           0 :                     aChildElements = collectChildWorkingElement(m_pRootBufferNode);
     507             : 
     508             :                     /*
     509             :                      * the clearUselessData only clearup the content in the
     510             :                      * node, not the node itself.
     511             :                      */
     512           0 :                 m_xXMLDocument->clearUselessData(m_pRootBufferNode->getXMLElement(),
     513             :                     aChildElements,
     514             :                     bIsNotBlocking?(NULL):
     515           0 :                                    (m_pCurrentBlockingBufferNode->getXMLElement()));
     516             : 
     517             :                     /*
     518             :                      * remove the node if it is empty, then if its parent is also
     519             :                      * empty, remove it, then if the next parent is also empty,
     520             :                      * remove it,..., until parent become null.
     521             :                      */
     522           0 :                 m_xXMLDocument->collapse( m_pRootBufferNode->getXMLElement() );
     523             :             }
     524             : 
     525             :             /*
     526             :              * if blocking, check the relationship between this BufferNode and
     527             :              * the current blocking BufferNode.
     528             :              */
     529           0 :             if ( !bIsNotBlocking )
     530             :             {
     531             :                 /*
     532             :                  * the current blocking BufferNode is a descendant of this BufferNode.
     533             :                  */
     534           0 :                 bIsBlockInside = (NULL != pBufferNode->isAncestor(m_pCurrentBlockingBufferNode));
     535             : 
     536             :                 /*
     537             :                  * the current blocking BufferNode locates behind this BufferNode in tree
     538             :                  * order.
     539             :                  */
     540           0 :                 bIsBlockingAfterward = pBufferNode->isPrevious(m_pCurrentBlockingBufferNode);
     541             :             }
     542             : 
     543             :             /*
     544             :              * this BufferNode's working element needs to be deleted only when
     545             :              * 1. there is no blocking, or
     546             :              * 2. the current blocking BufferNode is a descendant of this BufferNode,
     547             :              *    (then in the BufferNode's working element, the useless data before the blocking
     548             :              *     element should be deleted.) or
     549             :              * 3. the current blocking BufferNode is locates behind this BufferNode in tree,
     550             :              *    (then the useless data between the blocking element and the working element
     551             :              *     should be deleted.).
     552             :              * Otherwise, this working element should not be deleted.
     553             :              */
     554           0 :             if ( bIsNotBlocking || bIsBlockInside || bIsBlockingAfterward )
     555             :             {
     556             :                 cssu::Sequence< cssu::Reference< cssxw::XXMLElementWrapper > >
     557           0 :                     aChildElements = collectChildWorkingElement(pBufferNode);
     558             : 
     559             :                     /*
     560             :                      * the clearUselessData only clearup the content in the
     561             :                      * node, not the node itself.
     562             :                      */
     563           0 :                 m_xXMLDocument->clearUselessData(pBufferNode->getXMLElement(),
     564             :                     aChildElements,
     565             :                     bIsBlockInside?(m_pCurrentBlockingBufferNode->getXMLElement()):
     566           0 :                                (NULL));
     567             : 
     568             :                     /*
     569             :                      * remove the node if it is empty, then if its parent is also
     570             :                      * empty, remove it, then if the next parent is also empty,
     571             :                      * remove it,..., until parent become null.
     572             :                      */
     573           0 :                 m_xXMLDocument->collapse( pBufferNode->getXMLElement() );
     574             :             }
     575             :         }
     576             : 
     577           0 :         sal_Int32 nIndex = pParent->indexOfChild(pBufferNode);
     578             : 
     579           0 :         std::vector< const BufferNode* >* vChildren = pBufferNode->getChildren();
     580           0 :         pParent->removeChild(pBufferNode);
     581           0 :         pBufferNode->setParent(NULL);
     582             : 
     583           0 :         std::vector< const BufferNode * >::const_iterator ii = vChildren->begin();
     584           0 :         for( ; ii != vChildren->end(); ++ii )
     585             :         {
     586           0 :             ((BufferNode *)(*ii))->setParent(pParent);
     587           0 :             pParent->addChild(*ii, nIndex);
     588           0 :             nIndex++;
     589             :         }
     590             : 
     591           0 :         delete vChildren;
     592             : 
     593             :         /*
     594             :          * delete the BufferNode
     595             :          */
     596           0 :         delete pBufferNode;
     597             :     }
     598           0 : }
     599             : 
     600           0 : BufferNode* SAXEventKeeperImpl::findNextBlockingBufferNode(
     601             :     BufferNode* pStartBufferNode) const
     602             : /****** SAXEventKeeperImpl/findNextBlockingBufferNode ************************
     603             :  *
     604             :  *   NAME
     605             :  *  findNextBlockingBufferNode -- finds the next blocking BufferNode
     606             :  *  behind the particular BufferNode.
     607             :  *
     608             :  *   SYNOPSIS
     609             :  *  pBufferNode = findNextBlockingBufferNode( pStartBufferNode );
     610             :  *
     611             :  *   FUNCTION
     612             :  *  see NAME.
     613             :  *
     614             :  *   INPUTS
     615             :  *  pStartBufferNode - the BufferNode from where to search the next
     616             :  *                     blocking BufferNode.
     617             :  *
     618             :  *   RESULT
     619             :  *  pBufferNode - the next blocking BufferNode, or NULL if no such
     620             :  *                BufferNode exists.
     621             :  *
     622             :  *   AUTHOR
     623             :  *  Michael Mi
     624             :  *  Email: michael.mi@sun.com
     625             :  ******************************************************************************/
     626             : {
     627           0 :     BufferNode* pNext = NULL;
     628             : 
     629           0 :     if (pStartBufferNode != NULL)
     630             :     {
     631           0 :         pNext = pStartBufferNode;
     632             : 
     633           0 :         while (NULL != (pNext = (BufferNode*)pNext->getNextNodeByTreeOrder()))
     634             :         {
     635           0 :             if (pNext->getBlocker() != NULL)
     636             :             {
     637           0 :                 break;
     638             :             }
     639             :         }
     640             :     }
     641             : 
     642           0 :     return pNext;
     643             : }
     644             : 
     645           0 : void SAXEventKeeperImpl::diffuse(BufferNode* pBufferNode) const
     646             : /****** SAXEventKeeperImpl/diffuse *******************************************
     647             :  *
     648             :  *   NAME
     649             :  *  diffuse -- diffuse the notification.
     650             :  *
     651             :  *   SYNOPSIS
     652             :  *  diffuse( pBufferNode );
     653             :  *
     654             :  *   FUNCTION
     655             :  *  diffuse the collecting completion notification from the specific
     656             :  *  BufferNode along its parent link, until an ancestor which is not
     657             :  *  completely received is met.
     658             :  *
     659             :  *   INPUTS
     660             :  *  pBufferNode - the BufferNode from which the notification will be
     661             :  *                diffused.
     662             :  *
     663             :  *   RESULT
     664             :  *  empty
     665             :  *
     666             :  *   AUTHOR
     667             :  *  Michael Mi
     668             :  *  Email: michael.mi@sun.com
     669             :  ******************************************************************************/
     670             : {
     671           0 :     BufferNode* pParent = pBufferNode;
     672             : 
     673           0 :     while(pParent->isAllReceived())
     674             :     {
     675           0 :         pParent->elementCollectorNotify();
     676           0 :         pParent = (BufferNode*)pParent->getParent();
     677             :     }
     678           0 : }
     679             : 
     680           0 : void SAXEventKeeperImpl::releaseElementMarkBuffer()
     681             : /****** SAXEventKeeperImpl/releaseElementMarkBuffer **************************
     682             :  *
     683             :  *   NAME
     684             :  *  releaseElementMarkBuffer -- releases useless ElementMarks
     685             :  *
     686             :  *   SYNOPSIS
     687             :  *  releaseElementMarkBuffer( );
     688             :  *
     689             :  *   FUNCTION
     690             :  *  releases each ElementMark in the releasing list
     691             :  *  m_vReleasedElementMarkBuffers.
     692             :  *  The operation differs between an ElementCollector and a Blocker.
     693             :  *
     694             :  *   INPUTS
     695             :  *  empty
     696             :  *
     697             :  *   RESULT
     698             :  *  empty
     699             :  *
     700             :  *   AUTHOR
     701             :  *  Michael Mi
     702             :  *  Email: michael.mi@sun.com
     703             :  ******************************************************************************/
     704             : {
     705           0 :     m_bIsReleasing = true;
     706           0 :     while (!m_vReleasedElementMarkBuffers.empty())
     707             :     {
     708           0 :         std::vector< sal_Int32 >::iterator pId = m_vReleasedElementMarkBuffers.begin();
     709           0 :         sal_Int32 nId = *pId;
     710           0 :         m_vReleasedElementMarkBuffers.erase( pId );
     711             : 
     712           0 :         ElementMark* pElementMark = findElementMarkBuffer(nId);
     713             : 
     714           0 :         if (pElementMark != NULL)
     715             :         {
     716           0 :             if (cssxc::sax::ElementMarkType_ELEMENTCOLLECTOR
     717           0 :                 == pElementMark->getType())
     718             :             /*
     719             :              * it is a EC
     720             :              */
     721             :             {
     722           0 :                 ElementCollector* pElementCollector = (ElementCollector*)pElementMark;
     723             : 
     724           0 :                 cssxc::sax::ElementMarkPriority nPriority = pElementCollector->getPriority();
     725           0 :                 bool bToModify = pElementCollector->getModify();
     726             : 
     727             :                 /*
     728             :                      * Delete the EC from the buffer node.
     729             :                      */
     730           0 :                 BufferNode* pBufferNode = pElementCollector->getBufferNode();
     731           0 :                 pBufferNode->removeElementCollector(pElementCollector);
     732             : 
     733           0 :                 if ( nPriority == cssxc::sax::ElementMarkPriority_BEFOREMODIFY)
     734             :                 {
     735           0 :                     pBufferNode->notifyBranch();
     736             :                 }
     737             : 
     738           0 :                 if (bToModify)
     739             :                 {
     740           0 :                     pBufferNode->notifyAncestor();
     741             :                 }
     742             : 
     743             :                 /*
     744             :                  * delete the ElementMark
     745             :                  */
     746           0 :                 pElementCollector = NULL;
     747           0 :                 pElementMark = NULL;
     748           0 :                 removeElementMarkBuffer(nId);
     749             : 
     750             :                 /*
     751             :                  * delete the BufferNode
     752             :                  */
     753           0 :                 diffuse(pBufferNode);
     754           0 :                 smashBufferNode(pBufferNode, false);
     755             :             }
     756             :             else
     757             :             /*
     758             :              * it is a Blocker
     759             :              */
     760             :             {
     761             :                     /*
     762             :                      * Delete the TH from the buffer node.
     763             :                      */
     764           0 :                 BufferNode *pBufferNode = pElementMark->getBufferNode();
     765           0 :                 pBufferNode->setBlocker(NULL);
     766             : 
     767             :                     /*
     768             :                      * If there is a following handler and no blocking now, then
     769             :                      * forward this event
     770             :                      */
     771           0 :                 if (m_pCurrentBlockingBufferNode == pBufferNode)
     772             :                 {
     773             :                         /*
     774             :                          * Before forwarding, the next blocking point needs to be
     775             :                          * found.
     776             :                          */
     777           0 :                     m_pCurrentBlockingBufferNode = findNextBlockingBufferNode(pBufferNode);
     778             : 
     779             :                         /*
     780             :                          * Forward the blocked events between these two STHs.
     781             :                          */
     782           0 :                            if (m_xNextHandler.is())
     783             :                            {
     784           0 :                                BufferNode* pTempCurrentBufferNode = m_pCurrentBufferNode;
     785           0 :                                BufferNode* pTempCurrentBlockingBufferNode = m_pCurrentBlockingBufferNode;
     786             : 
     787           0 :                                m_pCurrentBufferNode = pBufferNode;
     788           0 :                                m_pCurrentBlockingBufferNode = NULL;
     789             : 
     790           0 :                         m_bIsForwarding = true;
     791             : 
     792           0 :                         m_xXMLDocument->generateSAXEvents(
     793             :                             m_xNextHandler,
     794             :                             this,
     795             :                             pBufferNode->getXMLElement(),
     796           0 :                             (pTempCurrentBlockingBufferNode == NULL)?NULL:(pTempCurrentBlockingBufferNode->getXMLElement()));
     797             : 
     798           0 :                         m_bIsForwarding = false;
     799             : 
     800           0 :                         m_pCurrentBufferNode = pTempCurrentBufferNode;
     801           0 :                         if (m_pCurrentBlockingBufferNode == NULL)
     802             :                         {
     803           0 :                             m_pCurrentBlockingBufferNode = pTempCurrentBlockingBufferNode;
     804             :                         }
     805             :                     }
     806             : 
     807           0 :                     if (m_pCurrentBlockingBufferNode == NULL &&
     808           0 :                         m_xSAXEventKeeperStatusChangeListener.is())
     809             :                     {
     810           0 :                         m_xSAXEventKeeperStatusChangeListener->blockingStatusChanged(sal_False);
     811             :                     }
     812             :                 }
     813             : 
     814             :                 /*
     815             :                  * delete the ElementMark
     816             :                  */
     817           0 :                 pElementMark = NULL;
     818           0 :                 removeElementMarkBuffer(nId);
     819             : 
     820             :                 /*
     821             :                  * delete the BufferNode
     822             :                  */
     823           0 :                 diffuse(pBufferNode);
     824           0 :                 smashBufferNode(pBufferNode, true);
     825             :             }
     826             :         }
     827             :     }
     828             : 
     829           0 :     m_bIsReleasing = false;
     830             : 
     831           0 :     if (!m_pRootBufferNode->hasAnything() &&
     832           0 :         !m_pRootBufferNode->hasChildren() &&
     833           0 :         m_xSAXEventKeeperStatusChangeListener.is())
     834             :     {
     835           0 :         m_xSAXEventKeeperStatusChangeListener->bufferStatusChanged(sal_True);
     836             :     }
     837           0 : }
     838             : 
     839           0 : void SAXEventKeeperImpl::markElementMarkBuffer(sal_Int32 nId)
     840             : /****** SAXEventKeeperImpl/markElementMarkBuffer *****************************
     841             :  *
     842             :  *   NAME
     843             :  *  markElementMarkBuffer -- marks an ElementMark to be released
     844             :  *
     845             :  *   SYNOPSIS
     846             :  *  markElementMarkBuffer( nId );
     847             :  *
     848             :  *   FUNCTION
     849             :  *  puts the ElementMark with the particular Id into the releasing list,
     850             :  *  checks whether the releasing process is runing, if not then launch
     851             :  *  this process.
     852             :  *
     853             :  *   INPUTS
     854             :  *  nId - the Id of the ElementMark which will be released
     855             :  *
     856             :  *   RESULT
     857             :  *  empty
     858             :  *
     859             :  *   AUTHOR
     860             :  *  Michael Mi
     861             :  *  Email: michael.mi@sun.com
     862             :  ******************************************************************************/
     863             : {
     864           0 :     m_vReleasedElementMarkBuffers.push_back( nId );
     865           0 :     if ( !m_bIsReleasing )
     866             :     {
     867           0 :         releaseElementMarkBuffer();
     868             :     }
     869           0 : }
     870             : 
     871           0 : sal_Int32 SAXEventKeeperImpl::createElementCollector(
     872             :     sal_Int32 nSecurityId,
     873             :     cssxc::sax::ElementMarkPriority nPriority,
     874             :     bool bModifyElement,
     875             :     const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& xReferenceResolvedListener)
     876             : /****** SAXEventKeeperImpl/createElementCollector ****************************
     877             :  *
     878             :  *   NAME
     879             :  *  createElementCollector -- creates a new ElementCollector on the
     880             :  *  incoming element.
     881             :  *
     882             :  *   SYNOPSIS
     883             :  *  nId = createElementCollector( nSecurityId, nPriority,
     884             :  *                               bModifyElement,
     885             :  *                               xReferenceResolvedListener );
     886             :  *
     887             :  *   FUNCTION
     888             :  *  allocs a new Id, then create an ElementCollector with this Id value.
     889             :  *  Add the new created ElementCollector to the new ElementCollecotor list.
     890             :  *
     891             :  *   INPUTS
     892             :  *  nSecurityId -   the security Id of the new ElementCollector
     893             :  *  nPriority -     the prirority of the new ElementCollector
     894             :  *  bModifyElement -whether this BufferNode will modify the content of
     895             :  *                  the corresponding element it works on
     896             :  *  xReferenceResolvedListener - the listener for the new ElementCollector.
     897             :  *
     898             :  *   RESULT
     899             :  *  nId - the Id of the new ElementCollector
     900             :  *
     901             :  *   AUTHOR
     902             :  *  Michael Mi
     903             :  *  Email: michael.mi@sun.com
     904             :  ******************************************************************************/
     905             : {
     906           0 :     sal_Int32 nId = m_nNextElementMarkId;
     907           0 :     m_nNextElementMarkId ++;
     908             : 
     909             :     ElementCollector* pElementCollector
     910             :         = new ElementCollector(
     911             :             nSecurityId,
     912             :             nId,
     913             :             nPriority,
     914             :             bModifyElement,
     915           0 :             xReferenceResolvedListener);
     916             : 
     917           0 :     m_vElementMarkBuffers.push_back( pElementCollector );
     918             : 
     919             :         /*
     920             :          * All the new EC to initial EC array.
     921             :          */
     922           0 :     m_vNewElementCollectors.push_back( pElementCollector );
     923             : 
     924           0 :     return nId;
     925             : }
     926             : 
     927             : 
     928           0 : sal_Int32 SAXEventKeeperImpl::createBlocker(sal_Int32 nSecurityId)
     929             : /****** SAXEventKeeperImpl/createBlocker *************************************
     930             :  *
     931             :  *   NAME
     932             :  *  createBlocker -- creates a new Blocker on the incoming element.
     933             :  *
     934             :  *   SYNOPSIS
     935             :  *  nId = createBlocker( nSecurityId );
     936             :  *
     937             :  *   FUNCTION
     938             :  *  see NAME.
     939             :  *
     940             :  *   INPUTS
     941             :  *  nSecurityId -   the security Id of the new Blocker
     942             :  *
     943             :  *   RESULT
     944             :  *  nId - the Id of the new Blocker
     945             :  *
     946             :  *   AUTHOR
     947             :  *  Michael Mi
     948             :  *  Email: michael.mi@sun.com
     949             :  ******************************************************************************/
     950             : {
     951           0 :     sal_Int32 nId = m_nNextElementMarkId;
     952           0 :     m_nNextElementMarkId ++;
     953             : 
     954             :     OSL_ASSERT(m_pNewBlocker == NULL);
     955             : 
     956           0 :     m_pNewBlocker = new ElementMark(nSecurityId, nId);
     957           0 :     m_vElementMarkBuffers.push_back( m_pNewBlocker );
     958             : 
     959           0 :     return nId;
     960             : }
     961             : 
     962             : /* XSAXEventKeeper */
     963           0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::addElementCollector(  )
     964             :     throw (cssu::RuntimeException)
     965             : {
     966             :     return createElementCollector(
     967             :         cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
     968             :         cssxc::sax::ElementMarkPriority_AFTERMODIFY,
     969             :         false,
     970           0 :         NULL);
     971             : }
     972             : 
     973           0 : void SAL_CALL SAXEventKeeperImpl::removeElementCollector( sal_Int32 id )
     974             :     throw (cssu::RuntimeException)
     975             : {
     976           0 :     markElementMarkBuffer(id);
     977           0 : }
     978             : 
     979           0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::addBlocker(  )
     980             :     throw (cssu::RuntimeException)
     981             : {
     982           0 :     return createBlocker(cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID);
     983             : }
     984             : 
     985           0 : void SAL_CALL SAXEventKeeperImpl::removeBlocker( sal_Int32 id )
     986             :     throw (cssu::RuntimeException)
     987             : {
     988           0 :     markElementMarkBuffer(id);
     989           0 : }
     990             : 
     991           0 : sal_Bool SAL_CALL SAXEventKeeperImpl::isBlocking(  )
     992             :     throw (cssu::RuntimeException)
     993             : {
     994           0 :     return (m_pCurrentBlockingBufferNode != NULL);
     995             : }
     996             : 
     997             : cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL
     998           0 :     SAXEventKeeperImpl::getElement( sal_Int32 id )
     999             :     throw (cssu::RuntimeException)
    1000             : {
    1001           0 :     cssu::Reference< cssxw::XXMLElementWrapper > rc;
    1002             : 
    1003           0 :     ElementMark* pElementMark = findElementMarkBuffer(id);
    1004           0 :     if (pElementMark != NULL)
    1005             :     {
    1006           0 :         rc = pElementMark->getBufferNode()->getXMLElement();
    1007             :     }
    1008             : 
    1009           0 :     return rc;
    1010             : }
    1011             : 
    1012           0 : void SAL_CALL SAXEventKeeperImpl::setElement(
    1013             :     sal_Int32 id,
    1014             :     const cssu::Reference< cssxw::XXMLElementWrapper >& aElement )
    1015             :     throw (cssu::RuntimeException)
    1016             : {
    1017           0 :     if (aElement.is())
    1018             :     {
    1019           0 :         m_xXMLDocument->rebuildIDLink(aElement);
    1020             : 
    1021           0 :         ElementMark* pElementMark = findElementMarkBuffer(id);
    1022             : 
    1023           0 :         if (pElementMark != NULL)
    1024             :         {
    1025           0 :             BufferNode* pBufferNode = pElementMark->getBufferNode();
    1026           0 :             if (pBufferNode != NULL)
    1027             :             {
    1028           0 :                     bool bIsCurrent = m_xXMLDocument->isCurrent(pBufferNode->getXMLElement());
    1029           0 :                 pBufferNode->setXMLElement(aElement);
    1030             : 
    1031           0 :                 if (bIsCurrent)
    1032             :                 {
    1033           0 :                     m_xXMLDocument->setCurrentElement(aElement);
    1034             :                 }
    1035             :             }
    1036             :         }
    1037             :     }
    1038             :     else
    1039             :     {
    1040           0 :         removeElementCollector( id );
    1041             :     }
    1042           0 : }
    1043             : 
    1044           0 : cssu::Reference< cssxs::XDocumentHandler > SAL_CALL SAXEventKeeperImpl::setNextHandler(
    1045             :     const cssu::Reference< cssxs::XDocumentHandler >& xNewHandler )
    1046             :     throw (cssu::RuntimeException)
    1047             : {
    1048           0 :     cssu::Reference< cssxs::XDocumentHandler > xOldHandler = m_xNextHandler;
    1049             : 
    1050           0 :     m_xNextHandler = xNewHandler;
    1051           0 :     return xOldHandler;
    1052             : }
    1053             : 
    1054           0 : rtl::OUString SAL_CALL SAXEventKeeperImpl::printBufferNodeTree()
    1055             :     throw (cssu::RuntimeException)
    1056             : {
    1057           0 :     rtl::OUString rc;
    1058             : 
    1059           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ElementMarkBuffers: size = " ));
    1060           0 :     rc += rtl::OUString::valueOf((sal_Int32)m_vElementMarkBuffers.size());
    1061           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\nCurrentBufferNode: " ));
    1062           0 :     rc += m_xXMLDocument->getNodeName(m_pCurrentBufferNode->getXMLElement());
    1063           0 :     rc += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "\n" ));
    1064           0 :     rc += printBufferNode(m_pRootBufferNode, 0);
    1065             : 
    1066           0 :     return rc;
    1067             : }
    1068             : 
    1069           0 : cssu::Reference< cssxw::XXMLElementWrapper > SAL_CALL SAXEventKeeperImpl::getCurrentBlockingNode()
    1070             :     throw (cssu::RuntimeException)
    1071             : {
    1072           0 :     cssu::Reference< cssxw::XXMLElementWrapper > rc;
    1073             : 
    1074           0 :     if (m_pCurrentBlockingBufferNode != NULL)
    1075             :     {
    1076           0 :         rc = m_pCurrentBlockingBufferNode->getXMLElement();
    1077             :     }
    1078             : 
    1079           0 :     return rc;
    1080             : }
    1081             : 
    1082             : /* XSecuritySAXEventKeeper */
    1083           0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::addSecurityElementCollector(
    1084             :     cssxc::sax::ElementMarkPriority priority,
    1085             :     sal_Bool modifyElement )
    1086             :     throw (cssu::RuntimeException)
    1087             : {
    1088             :     return createElementCollector(
    1089             :         cssxc::sax::ConstOfSecurityId::UNDEFINEDSECURITYID,
    1090             :         priority,
    1091             :         modifyElement,
    1092           0 :         NULL);
    1093             : }
    1094             : 
    1095           0 : sal_Int32 SAL_CALL SAXEventKeeperImpl::cloneElementCollector(
    1096             :     sal_Int32 referenceId,
    1097             :     cssxc::sax::ElementMarkPriority priority )
    1098             :     throw (cssu::RuntimeException)
    1099             : {
    1100           0 :     sal_Int32 nId = -1;
    1101             : 
    1102           0 :     ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
    1103           0 :     if (pElementCollector != NULL)
    1104             :     {
    1105           0 :         nId = m_nNextElementMarkId;
    1106           0 :         m_nNextElementMarkId ++;
    1107             : 
    1108             :         ElementCollector* pClonedOne
    1109           0 :             = pElementCollector->clone(nId, priority);
    1110             : 
    1111             :             /*
    1112             :              * add this EC into the security data buffer array.
    1113             :              */
    1114           0 :         m_vElementMarkBuffers.push_back(pClonedOne);
    1115             : 
    1116             :             /*
    1117             :              * If the reference EC is still in initial EC array, add
    1118             :              * this cloned one into the initial EC array too.
    1119             :              */
    1120           0 :             if (pElementCollector->getBufferNode() == NULL)
    1121             :         {
    1122           0 :             m_vNewElementCollectors.push_back(pClonedOne);
    1123             :         }
    1124             :     }
    1125             : 
    1126           0 :     return nId;
    1127             : }
    1128             : 
    1129           0 : void SAL_CALL SAXEventKeeperImpl::setSecurityId( sal_Int32 id, sal_Int32 securityId )
    1130             :     throw (cssu::RuntimeException)
    1131             : {
    1132           0 :     ElementMark* pElementMark = findElementMarkBuffer(id);
    1133           0 :     if (pElementMark != NULL)
    1134             :     {
    1135           0 :         pElementMark->setSecurityId(securityId);
    1136             :     }
    1137           0 : }
    1138             : 
    1139             : 
    1140             : /* XReferenceResolvedBroadcaster */
    1141           0 : void SAL_CALL SAXEventKeeperImpl::addReferenceResolvedListener(
    1142             :     sal_Int32 referenceId,
    1143             :     const cssu::Reference< cssxc::sax::XReferenceResolvedListener >& listener )
    1144             :     throw (cssu::RuntimeException)
    1145             : {
    1146           0 :     ElementCollector* pElementCollector = (ElementCollector*)findElementMarkBuffer(referenceId);
    1147           0 :     if (pElementCollector != NULL)
    1148             :     {
    1149           0 :         pElementCollector->setReferenceResolvedListener(listener);
    1150             :     }
    1151           0 : }
    1152             : 
    1153           0 : void SAL_CALL SAXEventKeeperImpl::removeReferenceResolvedListener(
    1154             :     sal_Int32 /*referenceId*/,
    1155             :     const cssu::Reference< cssxc::sax::XReferenceResolvedListener >&)
    1156             :     throw (cssu::RuntimeException)
    1157             : {
    1158           0 : }
    1159             : 
    1160             : /* XSAXEventKeeperStatusChangeBroadcaster */
    1161           0 : void SAL_CALL SAXEventKeeperImpl::addSAXEventKeeperStatusChangeListener(
    1162             :     const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >& listener )
    1163             :     throw (cssu::RuntimeException)
    1164             : {
    1165           0 :     m_xSAXEventKeeperStatusChangeListener = listener;
    1166           0 : }
    1167             : 
    1168           0 : void SAL_CALL SAXEventKeeperImpl::removeSAXEventKeeperStatusChangeListener(
    1169             :     const cssu::Reference< cssxc::sax::XSAXEventKeeperStatusChangeListener >&)
    1170             :     throw (cssu::RuntimeException)
    1171             : {
    1172           0 : }
    1173             : 
    1174             : /* XDocumentHandler */
    1175           0 : void SAL_CALL SAXEventKeeperImpl::startDocument(  )
    1176             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1177             : {
    1178           0 :     if ( m_xNextHandler.is())
    1179             :     {
    1180           0 :         m_xNextHandler->startDocument();
    1181             :     }
    1182           0 : }
    1183             : 
    1184           0 : void SAL_CALL SAXEventKeeperImpl::endDocument(  )
    1185             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1186             : {
    1187           0 :     if ( m_xNextHandler.is())
    1188             :     {
    1189           0 :         m_xNextHandler->endDocument();
    1190             :     }
    1191           0 : }
    1192             : 
    1193           0 : void SAL_CALL SAXEventKeeperImpl::startElement(
    1194             :     const rtl::OUString& aName,
    1195             :     const cssu::Reference< cssxs::XAttributeList >& xAttribs )
    1196             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1197             : {
    1198             :         /*
    1199             :          * If there is a following handler and no blocking now, then
    1200             :          * forward this event
    1201             :          */
    1202           0 :     if ((m_pCurrentBlockingBufferNode == NULL) &&
    1203           0 :         (m_xNextHandler.is()) &&
    1204           0 :         (!m_bIsForwarding) &&
    1205             :         (m_pNewBlocker == NULL))
    1206             :     {
    1207           0 :         m_xNextHandler->startElement(aName, xAttribs);
    1208             :     }
    1209             : 
    1210             :         /*
    1211             :          * If not forwarding, buffer this startElement.
    1212             :          */
    1213           0 :            if (!m_bIsForwarding)
    1214             :            {
    1215             :     #ifndef _USECOMPRESSEDDOCUMENTHANDLER
    1216             :         m_xDocumentHandler->startElement(aName, xAttribs);
    1217             :     #else
    1218           0 :         sal_Int32 nLength = xAttribs->getLength();
    1219           0 :         cssu::Sequence< cssxcsax::XMLAttribute > aAttributes (nLength);
    1220             : 
    1221           0 :         for ( int i = 0; i<nLength; ++i )
    1222             :         {
    1223           0 :             aAttributes[i].sName = xAttribs->getNameByIndex((short)i);
    1224           0 :             aAttributes[i].sValue =xAttribs->getValueByIndex((short)i);
    1225             :         }
    1226             : 
    1227           0 :         m_xCompressedDocumentHandler->_startElement(aName, aAttributes);
    1228             :     #endif
    1229             : 
    1230             :     }
    1231             : 
    1232           0 :     BufferNode* pBufferNode = addNewElementMarkBuffers();
    1233           0 :         if (pBufferNode != NULL)
    1234             :         {
    1235           0 :         setCurrentBufferNode(pBufferNode);
    1236             :     }
    1237           0 : }
    1238             : 
    1239           0 : void SAL_CALL SAXEventKeeperImpl::endElement( const rtl::OUString& aName )
    1240             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1241             : {
    1242           0 :         sal_Bool bIsCurrent = m_xXMLDocument->isCurrent(m_pCurrentBufferNode->getXMLElement());
    1243             : 
    1244             :         /*
    1245             :          * If there is a following handler and no blocking now, then
    1246             :          * forward this event
    1247             :          */
    1248           0 :     if ((m_pCurrentBlockingBufferNode == NULL) &&
    1249           0 :         (m_xNextHandler.is()) &&
    1250           0 :         (!m_bIsForwarding))
    1251             :     {
    1252           0 :         m_xNextHandler->endElement(aName);
    1253             :     }
    1254             : 
    1255           0 :     if ((m_pCurrentBlockingBufferNode != NULL) ||
    1256             :         (m_pCurrentBufferNode != m_pRootBufferNode) ||
    1257           0 :         (!m_xXMLDocument->isCurrentElementEmpty()))
    1258             :     {
    1259           0 :             if (!m_bIsForwarding)
    1260             :             {
    1261             :         #ifndef _USECOMPRESSEDDOCUMENTHANDLER
    1262             :             m_xDocumentHandler->endElement(aName);
    1263             :         #else
    1264           0 :             m_xCompressedDocumentHandler->_endElement(aName);
    1265             :         #endif
    1266             :         }
    1267             : 
    1268             :         /*
    1269             :         * If the current buffer node has not notified yet, and
    1270             :         * the current buffer node is waiting for the current element,
    1271             :         * then let it notify.
    1272             :         */
    1273           0 :            if (bIsCurrent && (m_pCurrentBufferNode != m_pRootBufferNode))
    1274             :         {
    1275           0 :             BufferNode* pOldCurrentBufferNode = m_pCurrentBufferNode;
    1276           0 :             m_pCurrentBufferNode = (BufferNode*)m_pCurrentBufferNode->getParent();
    1277             : 
    1278           0 :             pOldCurrentBufferNode->setReceivedAll();
    1279             : 
    1280           0 :             if ((m_pCurrentBufferNode == m_pRootBufferNode) &&
    1281           0 :                 m_xSAXEventKeeperStatusChangeListener.is())
    1282             :             {
    1283           0 :                 m_xSAXEventKeeperStatusChangeListener->collectionStatusChanged(sal_False);
    1284             :             }
    1285             :         }
    1286             :     }
    1287             :     else
    1288             :     {
    1289           0 :         if (!m_bIsForwarding)
    1290             :         {
    1291           0 :             m_xXMLDocument->removeCurrentElement();
    1292             :         }
    1293             :     }
    1294           0 : }
    1295             : 
    1296           0 : void SAL_CALL SAXEventKeeperImpl::characters( const rtl::OUString& aChars )
    1297             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1298             : {
    1299           0 :     if (!m_bIsForwarding)
    1300             :     {
    1301           0 :         if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
    1302             :         {
    1303           0 :             m_xNextHandler->characters(aChars);
    1304             :         }
    1305             : 
    1306           0 :         if ((m_pCurrentBlockingBufferNode != NULL) ||
    1307             :             (m_pCurrentBufferNode != m_pRootBufferNode))
    1308             :         {
    1309             :         #ifndef _USECOMPRESSEDDOCUMENTHANDLER
    1310             :                 m_xDocumentHandler->characters(aChars);
    1311             :         #else
    1312           0 :             m_xCompressedDocumentHandler->_characters(aChars);
    1313             :         #endif
    1314             :             }
    1315             :         }
    1316           0 : }
    1317             : 
    1318           0 : void SAL_CALL SAXEventKeeperImpl::ignorableWhitespace( const rtl::OUString& aWhitespaces )
    1319             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1320             : {
    1321           0 :     characters( aWhitespaces );
    1322           0 : }
    1323             : 
    1324           0 : void SAL_CALL SAXEventKeeperImpl::processingInstruction(
    1325             :     const rtl::OUString& aTarget, const rtl::OUString& aData )
    1326             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1327             : {
    1328           0 :     if (!m_bIsForwarding)
    1329             :     {
    1330           0 :         if ((m_pCurrentBlockingBufferNode == NULL) && m_xNextHandler.is())
    1331             :         {
    1332           0 :             m_xNextHandler->processingInstruction(aTarget, aData);
    1333             :         }
    1334             : 
    1335           0 :         if ((m_pCurrentBlockingBufferNode != NULL) ||
    1336             :             (m_pCurrentBufferNode != m_pRootBufferNode))
    1337             :         {
    1338             :         #ifndef _USECOMPRESSEDDOCUMENTHANDLER
    1339             :             m_xDocumentHandler->processingInstruction(aTarget, aData);
    1340             :         #else
    1341           0 :             m_xCompressedDocumentHandler->_processingInstruction(aTarget, aData);
    1342             :         #endif
    1343             :             }
    1344             :         }
    1345           0 : }
    1346             : 
    1347           0 : void SAL_CALL SAXEventKeeperImpl::setDocumentLocator( const cssu::Reference< cssxs::XLocator >&)
    1348             :     throw (cssxs::SAXException, cssu::RuntimeException)
    1349             : {
    1350           0 : }
    1351             : 
    1352             : /* XInitialization */
    1353           0 : void SAL_CALL SAXEventKeeperImpl::initialize( const cssu::Sequence< cssu::Any >& aArguments )
    1354             :     throw (cssu::Exception, cssu::RuntimeException)
    1355             : {
    1356             :     OSL_ASSERT(aArguments.getLength() == 1);
    1357             : 
    1358           0 :     aArguments[0] >>= m_xXMLDocument;
    1359             :     m_xDocumentHandler = cssu::Reference< cssxs::XDocumentHandler >(
    1360           0 :         m_xXMLDocument, cssu::UNO_QUERY );
    1361             :     m_xCompressedDocumentHandler = cssu::Reference< cssxcsax::XCompressedDocumentHandler >(
    1362           0 :         m_xXMLDocument, cssu::UNO_QUERY );
    1363             : 
    1364           0 :     m_pRootBufferNode = new BufferNode(m_xXMLDocument->getCurrentElement());
    1365           0 :     m_pCurrentBufferNode = m_pRootBufferNode;
    1366           0 : }
    1367             : 
    1368           0 : rtl::OUString SAXEventKeeperImpl_getImplementationName ()
    1369             :     throw (cssu::RuntimeException)
    1370             : {
    1371           0 :     return rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( IMPLEMENTATION_NAME ) );
    1372             : }
    1373             : 
    1374           0 : sal_Bool SAL_CALL SAXEventKeeperImpl_supportsService( const rtl::OUString& ServiceName )
    1375             :     throw (cssu::RuntimeException)
    1376             : {
    1377           0 :     return ServiceName == SERVICE_NAME;
    1378             : }
    1379             : 
    1380           0 : cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl_getSupportedServiceNames(  )
    1381             :     throw (cssu::RuntimeException)
    1382             : {
    1383           0 :     cssu::Sequence < rtl::OUString > aRet(1);
    1384           0 :     rtl::OUString* pArray = aRet.getArray();
    1385           0 :     pArray[0] =  rtl::OUString ( RTL_CONSTASCII_USTRINGPARAM ( SERVICE_NAME ) );
    1386           0 :     return aRet;
    1387             : }
    1388             : #undef SERVICE_NAME
    1389             : 
    1390           0 : cssu::Reference< cssu::XInterface > SAL_CALL SAXEventKeeperImpl_createInstance(
    1391             :     const cssu::Reference< cssl::XMultiServiceFactory > &)
    1392             :     throw( cssu::Exception )
    1393             : {
    1394           0 :     return (cppu::OWeakObject*) new SAXEventKeeperImpl();
    1395             : }
    1396             : 
    1397             : /* XServiceInfo */
    1398           0 : rtl::OUString SAL_CALL SAXEventKeeperImpl::getImplementationName(  )
    1399             :     throw (cssu::RuntimeException)
    1400             : {
    1401           0 :     return SAXEventKeeperImpl_getImplementationName();
    1402             : }
    1403           0 : sal_Bool SAL_CALL SAXEventKeeperImpl::supportsService( const rtl::OUString& rServiceName )
    1404             :     throw (cssu::RuntimeException)
    1405             : {
    1406           0 :     return SAXEventKeeperImpl_supportsService( rServiceName );
    1407             : }
    1408           0 : cssu::Sequence< rtl::OUString > SAL_CALL SAXEventKeeperImpl::getSupportedServiceNames(  )
    1409             :     throw (cssu::RuntimeException)
    1410             : {
    1411           0 :     return SAXEventKeeperImpl_getSupportedServiceNames();
    1412             : }
    1413             : 
    1414             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10