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