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