Update ooo320-m1
[ooovba.git] / configmgr / source / backend / basicupdatemerger.cxx
blob205a06265106441c5131ab332ef2e9d46444ce73
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: basicupdatemerger.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_configmgr.hxx"
34 #include "basicupdatemerger.hxx"
35 #include "layerdefaultremover.hxx"
37 #ifndef INCLUDED_ALGORITHM
38 #include <algorithm>
39 #define INCLUDED_ALGORITHM
40 #endif
41 #ifndef INCLUDED_ITERATOR
42 #include <iterator>
43 #define INCLUDED_ITERATOR
44 #endif
46 // -----------------------------------------------------------------------------
48 namespace configmgr
50 // -----------------------------------------------------------------------------
51 namespace backend
53 // -----------------------------------------------------------------------------
55 BasicUpdateMerger::BasicUpdateMerger( uno::Reference< backenduno::XLayer > const & _xSourceLayer )
56 : m_xSourceLayer(_xSourceLayer)
57 , m_xResultHandler()
58 , m_nNesting(0)
59 , m_bSkipping(false)
62 // -----------------------------------------------------------------------------
64 BasicUpdateMerger::~BasicUpdateMerger()
67 // -----------------------------------------------------------------------------
69 void SAL_CALL BasicUpdateMerger::readData( uno::Reference< backenduno::XLayerHandler > const & _xResultHandler )
70 throw ( backenduno::MalformedDataException, lang::NullPointerException,
71 lang::WrappedTargetException, uno::RuntimeException)
73 if (!_xResultHandler.is())
75 rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("UpdateMerger: Error - NULL output handler unexpected") );
76 throw lang::NullPointerException(sMsg,*this);
78 if (!m_xSourceLayer.is())
80 rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("UpdateMerger: Error - No source layer set") );
81 throw lang::NullPointerException(sMsg,*this);
84 try
86 m_xResultHandler = new LayerDefaultRemover(_xResultHandler);
87 m_xSourceLayer->readData( this );
89 catch (uno::Exception & )
91 m_xResultHandler.clear();
92 throw;
95 m_xResultHandler.clear();
97 // -----------------------------------------------------------------------------
99 void SAL_CALL BasicUpdateMerger::startLayer( )
100 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
102 if (m_nNesting)
103 raiseMalformedDataException("UpdateMerger: Cannot start layer - layer already in progress");
105 m_bSkipping = false;
107 m_xResultHandler->startLayer();
109 // -----------------------------------------------------------------------------
111 void SAL_CALL BasicUpdateMerger::endLayer( )
112 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
114 if (m_nNesting > 0)
115 raiseMalformedDataException("UpdateMerger: Cannot end layer - data handling still in progress");
117 this->flushContext();
119 m_xResultHandler->endLayer();
121 // -----------------------------------------------------------------------------
123 void SAL_CALL BasicUpdateMerger::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
124 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
126 if (!isSkipping())
127 m_xResultHandler->overrideNode(aName, aAttributes, bClear);
129 pushLevel(aName);
131 // -----------------------------------------------------------------------------
133 void SAL_CALL BasicUpdateMerger::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
134 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
136 if (!isSkipping())
137 m_xResultHandler->addOrReplaceNode(aName, aAttributes);
139 pushLevel(aName);
141 // -----------------------------------------------------------------------------
143 void SAL_CALL BasicUpdateMerger::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
144 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
146 if (!isSkipping())
147 m_xResultHandler->addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
149 pushLevel(aName);
151 // -----------------------------------------------------------------------------
153 void SAL_CALL BasicUpdateMerger::endNode( )
154 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
156 if (!isSkipping())
157 m_xResultHandler->endNode();
159 popLevel();
161 // -----------------------------------------------------------------------------
163 void SAL_CALL BasicUpdateMerger::dropNode( const rtl::OUString& aName )
164 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
166 if (!isSkipping())
167 m_xResultHandler->dropNode(aName);
169 // -----------------------------------------------------------------------------
171 void SAL_CALL BasicUpdateMerger::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
172 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
174 if (!isSkipping())
175 m_xResultHandler->overrideProperty(aName, aAttributes, aType, bClear);
177 pushLevel( rtl::OUString() ); // do not match context path to property names
179 // -----------------------------------------------------------------------------
181 void SAL_CALL BasicUpdateMerger::endProperty( )
182 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
184 if (!isSkipping())
185 m_xResultHandler->endProperty();
187 popLevel();
189 // -----------------------------------------------------------------------------
191 void SAL_CALL BasicUpdateMerger::setPropertyValue( const uno::Any& aValue )
192 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
194 if (!isSkipping())
195 m_xResultHandler->setPropertyValue(aValue);
197 // -----------------------------------------------------------------------------
199 void SAL_CALL BasicUpdateMerger::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
200 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
202 if (!isSkipping())
203 m_xResultHandler->setPropertyValueForLocale(aValue,aLocale);
205 // -----------------------------------------------------------------------------
207 void SAL_CALL BasicUpdateMerger::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
208 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
210 if (!isSkipping())
211 m_xResultHandler->addProperty(aName, aAttributes, aType);
213 // -----------------------------------------------------------------------------
215 void SAL_CALL BasicUpdateMerger::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
216 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
218 if (!isSkipping())
219 m_xResultHandler->addPropertyWithValue(aName, aAttributes, aValue);
221 // -----------------------------------------------------------------------------
223 void BasicUpdateMerger::raiseMalformedDataException(sal_Char const * pMsg)
225 rtl::OUString sMsg = rtl::OUString::createFromAscii(pMsg);
227 throw backenduno::MalformedDataException(sMsg, *this, uno::Any());
229 // -----------------------------------------------------------------------------
231 void BasicUpdateMerger::startSkipping()
233 OSL_PRECOND( m_nNesting == 0, "BasicUpdateMerger: starting to skip, while already forwarding data");
234 m_nNesting = 1;
235 m_bSkipping = true;
236 OSL_POSTCOND( isHandling(), "BasicUpdateMerger: isHandling() is broken");
237 OSL_POSTCOND( isSkipping(), "BasicUpdateMerger: isSkipping() is broken");
239 // -----------------------------------------------------------------------------
242 void BasicUpdateMerger::pushLevel(rtl::OUString const & _aContext)
244 if (m_nNesting > 0)
246 ++m_nNesting;
247 OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
249 else if (m_nNesting < 0)
251 OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
253 else if (m_aSearchPath.empty())
255 ++m_nNesting;
256 OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
258 else if ( m_aSearchPath.back().equals(_aContext) ) // search path is reverse - see findContext()
260 OSL_ENSURE( m_nNesting == 0, "BasicUpdateMerger: level count while searching must be zero");
262 m_aSearchPath.pop_back();
264 else // start forwarding
266 m_nNesting = 1;
267 OSL_POSTCOND( isHandling(), "BasicUpdateMerger: level counting is broken" );
268 OSL_POSTCOND(!isSkipping(), "BasicUpdateMerger: skip flag set while searching " );
271 // -----------------------------------------------------------------------------
273 void BasicUpdateMerger::popLevel()
275 OSL_PRECOND( isHandling(), "BasicUpdateMerger: ending a node that wasn't handled here");
276 if (m_nNesting > 0)
278 if (--m_nNesting == 0)
279 m_bSkipping = false;
281 else if (m_nNesting == 0) // ending a context level, but the context is not yet gone
283 OSL_ENSURE( !m_aSearchPath.empty(), "BasicUpdateMerger: flushing a context that was already found");
284 flushContext();
285 leaveContext();
287 else
289 OSL_ENSURE( m_aSearchPath.empty(), "BasicUpdateMerger: Left an unfinished context" );
292 // -----------------------------------------------------------------------------
294 void BasicUpdateMerger::findContext(std::vector<rtl::OUString> const & _aContext)
296 // make the context a *reverse* copy of the context path
297 OSL_PRECOND( ! isHandling(), "BasicUpdateMerger: starting context search while still handling data");
298 m_aSearchPath.clear();
299 m_aSearchPath.reserve(_aContext.size());
300 std::copy( _aContext.rbegin(), _aContext.rend(), std::back_inserter(m_aSearchPath) );
302 // -----------------------------------------------------------------------------
304 void BasicUpdateMerger::leaveContext()
306 OSL_PRECOND( !isHandling(), "BasicUpdateMerger: ending the context while still handling data or seaching the context");
308 // force
309 m_nNesting = -1;
311 OSL_POSTCOND( ! isSkipping(), "BasicUpdateMerger: ending the context node while still skipping data");
312 OSL_POSTCOND( isHandling(), "BasicUpdateMerger: cannot mark context as being handled to the end.");
314 // -----------------------------------------------------------------------------
316 void BasicUpdateMerger::flushContext()
318 std::vector<rtl::OUString>::size_type nNesting = m_aSearchPath.size();
320 while (!m_aSearchPath.empty())
322 m_xResultHandler->overrideNode(m_aSearchPath.back(), 0, false);
323 m_aSearchPath.pop_back();
325 this->flushUpdate();
327 while (nNesting > 0)
329 m_xResultHandler->endNode();
330 --nNesting;
333 // -----------------------------------------------------------------------------
335 // -----------------------------------------------------------------------------
336 // -----------------------------------------------------------------------------
337 } // namespace
339 // -----------------------------------------------------------------------------
340 } // namespace