Update ooo320-m1
[ooovba.git] / configmgr / source / backend / layerupdatemerger.cxx
blobc6bfcfc7f117ae4a672803a422ec25978932ba3c
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: layerupdatemerger.cxx,v $
10 * $Revision: 1.13 $
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 "layerupdatemerger.hxx"
35 #include "layerupdatebuilder.hxx"
36 #include "updatedata.hxx"
37 // -----------------------------------------------------------------------------
39 namespace configmgr
41 // -----------------------------------------------------------------------------
42 namespace backend
44 // -----------------------------------------------------------------------------
46 LayerUpdateMerger::LayerUpdateMerger(uno::Reference< backenduno::XLayer > const & _xSourceLayer, LayerUpdate const & _aLayerUpdate)
47 : BasicUpdateMerger(_xSourceLayer)
48 , m_aLayerUpdate(_aLayerUpdate)
49 , m_xCurrentNode()
52 // -----------------------------------------------------------------------------
54 LayerUpdateMerger::~LayerUpdateMerger()
57 // -----------------------------------------------------------------------------
59 void LayerUpdateMerger::flushUpdate()
61 OSL_ENSURE(!BasicUpdateMerger::isHandling(), "LayerUpdateMerger: Unexpected: flushing data, while base implementation is active");
62 OSL_ENSURE(m_xCurrentNode.is(),"LayerUpdateMerger: No data for flushing.");
64 if (m_xCurrentNode.is())
66 m_xCurrentNode->writeChildrenToLayer(getResultWriter().get());
67 m_xCurrentNode.clear();
70 // -----------------------------------------------------------------------------
72 void SAL_CALL LayerUpdateMerger::startLayer( )
73 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
75 BasicUpdateMerger::startLayer();
77 m_xCurrentNode = m_aLayerUpdate.getContextNode();
79 BasicUpdateMerger::findContext(m_aLayerUpdate.getContextPath());
81 // -----------------------------------------------------------------------------
83 void SAL_CALL LayerUpdateMerger::endLayer( )
84 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
86 BasicUpdateMerger::endLayer();
88 OSL_ENSURE(!m_xCurrentNode.is(), "Path being updated not found in data - update not written");
90 // -----------------------------------------------------------------------------
92 void SAL_CALL LayerUpdateMerger::overrideNode( const rtl::OUString& aName, sal_Int16 aAttributes, sal_Bool bClear )
93 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
95 if (BasicUpdateMerger::isHandling())
97 BasicUpdateMerger::overrideNode(aName, aAttributes, bClear);
98 return;
101 OSL_ASSERT(m_xCurrentNode.is());
103 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
104 if (!xUpdate.is())
106 BasicUpdateMerger::overrideNode(aName, aAttributes, bClear);
107 OSL_ASSERT(BasicUpdateMerger::isHandling());
108 return;
110 m_xCurrentNode->removeNodeByName(aName);
112 if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate(true))
114 getResultWriter()->overrideNode(aName, pNodeUpdate->updateFlags(aAttributes), bClear);
115 m_xCurrentNode.set(pNodeUpdate);
117 else
119 xUpdate->writeToLayer(getResultWriter().get());
120 BasicUpdateMerger::startSkipping();
123 // -----------------------------------------------------------------------------
125 void SAL_CALL LayerUpdateMerger::addOrReplaceNode( const rtl::OUString& aName, sal_Int16 aAttributes )
126 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
128 if (BasicUpdateMerger::isHandling())
130 BasicUpdateMerger::addOrReplaceNode(aName, aAttributes);
131 return;
134 OSL_ASSERT(m_xCurrentNode.is());
136 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
137 if (!xUpdate.is())
139 BasicUpdateMerger::addOrReplaceNode(aName, aAttributes);
140 OSL_ASSERT(BasicUpdateMerger::isHandling());
141 return;
143 m_xCurrentNode->removeNodeByName(aName);
145 if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate(true))
147 getResultWriter()->addOrReplaceNode(aName, pNodeUpdate->updateFlags(aAttributes));
148 m_xCurrentNode.set(pNodeUpdate);
150 else
152 xUpdate->writeToLayer(getResultWriter().get());
153 BasicUpdateMerger::startSkipping();
156 // -----------------------------------------------------------------------------
158 void SAL_CALL LayerUpdateMerger::addOrReplaceNodeFromTemplate( const rtl::OUString& aName, const backenduno::TemplateIdentifier& aTemplate, sal_Int16 aAttributes )
159 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
161 if (BasicUpdateMerger::isHandling())
163 BasicUpdateMerger::addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
164 return;
167 OSL_ASSERT(m_xCurrentNode.is());
169 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
170 if (!xUpdate.is())
172 BasicUpdateMerger::addOrReplaceNodeFromTemplate(aName, aTemplate, aAttributes);
173 OSL_ASSERT(BasicUpdateMerger::isHandling());
174 return;
176 m_xCurrentNode->removeNodeByName(aName);
178 if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate(true))
180 getResultWriter()->addOrReplaceNodeFromTemplate(aName, aTemplate, pNodeUpdate->updateFlags(aAttributes));
181 m_xCurrentNode.set(pNodeUpdate);
183 else
185 xUpdate->writeToLayer(getResultWriter().get());
186 BasicUpdateMerger::startSkipping();
189 // -----------------------------------------------------------------------------
191 void SAL_CALL LayerUpdateMerger::endNode( )
192 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
194 if (BasicUpdateMerger::isHandling())
196 BasicUpdateMerger::endNode();
197 return;
200 OSL_ASSERT(m_xCurrentNode.is());
202 // write unhandled so far changes
203 m_xCurrentNode->writeChildrenToLayer( getResultWriter().get() );
205 rtl::Reference<NodeUpdate> xParent( m_xCurrentNode->getParent() );
207 if (xParent.is())
208 getResultWriter()->endNode();
210 else
211 BasicUpdateMerger::leaveContext();
213 m_xCurrentNode = xParent;
215 // -----------------------------------------------------------------------------
217 void SAL_CALL LayerUpdateMerger::dropNode( const rtl::OUString& aName )
218 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
220 if (BasicUpdateMerger::isHandling())
222 BasicUpdateMerger::dropNode(aName);
223 return;
226 OSL_ASSERT(m_xCurrentNode.is());
228 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getNodeByName(aName);
229 if (xUpdate.is())
231 m_xCurrentNode->removeNodeByName(aName);
233 if (NodeUpdate * pNodeUpdate = xUpdate->asNodeUpdate())
235 if (pNodeUpdate-> getOperation() == NodeUpdate::replace)
237 xUpdate->writeToLayer( getResultWriter().get() );
238 return;
240 else
242 malformedUpdate("LayerUpdateMerger: Applying modification to dropped node");
247 getResultWriter()->dropNode(aName);
249 // -----------------------------------------------------------------------------
251 void SAL_CALL LayerUpdateMerger::overrideProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType, sal_Bool bClear )
252 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
254 if (BasicUpdateMerger::isHandling())
256 BasicUpdateMerger::overrideProperty(aName, aAttributes, aType, bClear);
257 return;
260 OSL_ASSERT( m_xCurrentNode.is());
262 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getPropertyByName(aName);
263 if (!xUpdate.is())
265 BasicUpdateMerger::overrideProperty(aName, aAttributes, aType, bClear);
266 OSL_ASSERT(BasicUpdateMerger::isHandling());
267 return;
270 m_xCurrentNode->removePropertyByName(aName);
272 if (PropertyUpdate * pPropUpdate = xUpdate->asPropertyUpdate())
274 OSL_ENSURE( aType == pPropUpdate->getValueType() ||
275 aType == uno::Type() ||
276 pPropUpdate->getValueType() == uno::Type(),
277 "Error in update merger: type mismatch overriding property ...");
279 getResultWriter()->overrideProperty(aName, pPropUpdate->updateFlags(aAttributes), aType, bClear);
280 m_xCurrentProp.set(pPropUpdate);
282 else
284 xUpdate->writeToLayer(getResultWriter().get());
285 BasicUpdateMerger::startSkipping();
288 // -----------------------------------------------------------------------------
290 void SAL_CALL LayerUpdateMerger::endProperty( )
291 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
293 if (BasicUpdateMerger::isHandling())
295 BasicUpdateMerger::endProperty();
296 return;
299 OSL_ASSERT(m_xCurrentNode.is());
301 if (!m_xCurrentProp.is())
303 rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("LayerUpdateMerger: Invalid data: Ending property that wasn't started.") );
304 throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
307 // write unhandled so far values
308 m_xCurrentProp->writeValuesToLayer( getResultWriter().get() );
310 getResultWriter()->endProperty();
312 m_xCurrentProp.clear();
314 // -----------------------------------------------------------------------------
316 void SAL_CALL LayerUpdateMerger::setPropertyValue( const uno::Any& aValue )
317 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
319 if (BasicUpdateMerger::isHandling())
321 BasicUpdateMerger::setPropertyValue(aValue);
322 return;
325 OSL_ASSERT(m_xCurrentNode.is());
327 if (!m_xCurrentProp.is())
329 rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("LayerUpdateMerger: Invalid data: setting value, but no property is started.") );
330 throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
333 if (!m_xCurrentProp->hasChange())
335 BasicUpdateMerger::setPropertyValue(aValue);
336 return;
339 #ifndef CFG_UPDATEMERGER_BATCHWRITE_PROPERTIES
340 if (m_xCurrentProp->hasValue())
342 getResultWriter()->setPropertyValue(m_xCurrentProp->getValue());
344 else
346 OSL_ENSURE(m_xCurrentProp->hasReset(),"LayerUpdateMerger: ERROR: Unknown change type in PropertyUpdate");
347 // write nothing to result
350 // mark handled
351 m_xCurrentProp->removeValue();
352 #endif
354 // -----------------------------------------------------------------------------
356 void SAL_CALL LayerUpdateMerger::setPropertyValueForLocale( const uno::Any& aValue, const rtl::OUString & aLocale )
357 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
359 if (BasicUpdateMerger::isHandling())
361 BasicUpdateMerger::setPropertyValueForLocale(aValue, aLocale);
362 return;
365 OSL_ASSERT(m_xCurrentNode.is());
367 if (!m_xCurrentProp.is())
369 rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("LayerUpdateMerger: Invalid data: setting value, but no property is started.") );
370 throw backenduno::MalformedDataException( sMsg, *this, uno::Any() );
373 if (!m_xCurrentProp->hasChangeFor(aLocale))
375 BasicUpdateMerger::setPropertyValueForLocale(aValue, aLocale);
376 return;
379 #ifndef CFG_UPDATEMERGER_BATCHWRITE_PROPERTIES
380 if (m_xCurrentProp->hasValueFor(aLocale))
382 getResultWriter()->setPropertyValueForLocale(m_xCurrentProp->getValueFor(aLocale),aLocale);
384 else
386 OSL_ENSURE(m_xCurrentProp->hasResetFor(aLocale),"LayerUpdateMerger: ERROR: Unknown change type in PropertyUpdate");
387 // write nothing to result
390 // mark handled
391 m_xCurrentProp->removeValueFor(aLocale);
392 #endif
394 // -----------------------------------------------------------------------------
396 void SAL_CALL LayerUpdateMerger::addProperty( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Type& aType )
397 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
399 if (BasicUpdateMerger::isHandling())
401 BasicUpdateMerger::addProperty(aName, aAttributes, aType);
402 return;
404 OSL_ASSERT( m_xCurrentNode.is());
406 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getPropertyByName(aName);
407 if (!xUpdate.is())
409 BasicUpdateMerger::addProperty(aName, aAttributes, aType);
410 return;
413 m_xCurrentNode->removePropertyByName(aName);
415 if (PropertyUpdate * pPropUpdate = xUpdate->asPropertyUpdate())
417 if (pPropUpdate->hasValue() && pPropUpdate->getValue().hasValue())
419 // TODO: validate value-type
420 uno::Any aNewValue = pPropUpdate->getValue();
421 OSL_ASSERT( aNewValue.hasValue() );
423 if (aNewValue.getValueType() != aType)
424 malformedUpdate("LayerUpdateMerger: cannot do type conversion while writing updates");
426 getResultWriter()->addPropertyWithValue(aName, pPropUpdate->updateFlags(aAttributes), aNewValue);
428 else
430 // TODO: validate type
431 if (pPropUpdate->getValueType() != aType && pPropUpdate->getValueType() != uno::Type())
432 malformedUpdate("LayerUpdateMerger: types for property update do not match");
434 OSL_ENSURE(!pPropUpdate->hasReset(),"Warning: resetting the value of an added property is undefined - reverting to NULL");
435 getResultWriter()->addProperty(aName, pPropUpdate->updateFlags(aAttributes), aType);
438 else
440 xUpdate->writeToLayer(getResultWriter().get());
443 // -----------------------------------------------------------------------------
445 void SAL_CALL LayerUpdateMerger::addPropertyWithValue( const rtl::OUString& aName, sal_Int16 aAttributes, const uno::Any& aValue )
446 throw (backenduno::MalformedDataException, lang::WrappedTargetException, uno::RuntimeException)
448 if (BasicUpdateMerger::isHandling())
450 BasicUpdateMerger::addPropertyWithValue(aName, aAttributes, aValue);
451 return;
453 OSL_ASSERT( m_xCurrentNode.is());
455 rtl::Reference<ElementUpdate> xUpdate = m_xCurrentNode->getPropertyByName(aName);
456 if (!xUpdate.is())
458 BasicUpdateMerger::addPropertyWithValue(aName, aAttributes, aValue);
459 return;
462 m_xCurrentNode->removePropertyByName(aName);
464 if (PropertyUpdate * pPropUpdate = xUpdate->asPropertyUpdate())
466 if (!pPropUpdate->hasChange()) // attribute change only
468 getResultWriter()->addPropertyWithValue(aName, pPropUpdate->updateFlags(aAttributes), aValue);
470 else if (pPropUpdate->hasReset())
472 // write nothing
474 else if (pPropUpdate->getValue().hasValue()) // setting to non-NULL value
476 OSL_ASSERT(pPropUpdate->hasValue());
478 // TODO: validate value-type
479 uno::Any aNewValue = pPropUpdate->getValue();
481 if (aNewValue.getValueType() != aValue.getValueType())
482 malformedUpdate("LayerUpdateMerger: cannot do type conversion while writing updates");
484 getResultWriter()->addPropertyWithValue(aName, pPropUpdate->updateFlags(aAttributes), aNewValue);
486 else // setting to null value
488 OSL_ASSERT(pPropUpdate->hasValue());
490 // TODO: validate type
491 if (pPropUpdate->getValueType() != aValue.getValueType() && pPropUpdate->getValueType() != uno::Type())
492 malformedUpdate("LayerUpdateMerger: types for property update do not match");
494 getResultWriter()->addProperty(aName, pPropUpdate->updateFlags(aAttributes), aValue.getValueType());
497 else
499 xUpdate->writeToLayer(getResultWriter().get());
502 // -----------------------------------------------------------------------------
504 void LayerUpdateMerger::malformedUpdate(sal_Char const * pMsg)
506 { (void)pMsg; }
507 OSL_ENSURE(false,pMsg);
509 // -----------------------------------------------------------------------------
510 // -----------------------------------------------------------------------------
511 } // namespace
513 // -----------------------------------------------------------------------------
514 } // namespace