1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: layerupdatemerger.cxx,v $
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 // -----------------------------------------------------------------------------
41 // -----------------------------------------------------------------------------
44 // -----------------------------------------------------------------------------
46 LayerUpdateMerger::LayerUpdateMerger(uno::Reference
< backenduno::XLayer
> const & _xSourceLayer
, LayerUpdate
const & _aLayerUpdate
)
47 : BasicUpdateMerger(_xSourceLayer
)
48 , m_aLayerUpdate(_aLayerUpdate
)
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
);
101 OSL_ASSERT(m_xCurrentNode
.is());
103 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getNodeByName(aName
);
106 BasicUpdateMerger::overrideNode(aName
, aAttributes
, bClear
);
107 OSL_ASSERT(BasicUpdateMerger::isHandling());
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
);
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
);
134 OSL_ASSERT(m_xCurrentNode
.is());
136 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getNodeByName(aName
);
139 BasicUpdateMerger::addOrReplaceNode(aName
, aAttributes
);
140 OSL_ASSERT(BasicUpdateMerger::isHandling());
143 m_xCurrentNode
->removeNodeByName(aName
);
145 if (NodeUpdate
* pNodeUpdate
= xUpdate
->asNodeUpdate(true))
147 getResultWriter()->addOrReplaceNode(aName
, pNodeUpdate
->updateFlags(aAttributes
));
148 m_xCurrentNode
.set(pNodeUpdate
);
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
);
167 OSL_ASSERT(m_xCurrentNode
.is());
169 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getNodeByName(aName
);
172 BasicUpdateMerger::addOrReplaceNodeFromTemplate(aName
, aTemplate
, aAttributes
);
173 OSL_ASSERT(BasicUpdateMerger::isHandling());
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
);
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();
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() );
208 getResultWriter()->endNode();
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
);
226 OSL_ASSERT(m_xCurrentNode
.is());
228 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getNodeByName(aName
);
231 m_xCurrentNode
->removeNodeByName(aName
);
233 if (NodeUpdate
* pNodeUpdate
= xUpdate
->asNodeUpdate())
235 if (pNodeUpdate
-> getOperation() == NodeUpdate::replace
)
237 xUpdate
->writeToLayer( getResultWriter().get() );
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
);
260 OSL_ASSERT( m_xCurrentNode
.is());
262 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getPropertyByName(aName
);
265 BasicUpdateMerger::overrideProperty(aName
, aAttributes
, aType
, bClear
);
266 OSL_ASSERT(BasicUpdateMerger::isHandling());
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
);
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();
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
);
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
);
339 #ifndef CFG_UPDATEMERGER_BATCHWRITE_PROPERTIES
340 if (m_xCurrentProp
->hasValue())
342 getResultWriter()->setPropertyValue(m_xCurrentProp
->getValue());
346 OSL_ENSURE(m_xCurrentProp
->hasReset(),"LayerUpdateMerger: ERROR: Unknown change type in PropertyUpdate");
347 // write nothing to result
351 m_xCurrentProp
->removeValue();
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
);
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
);
379 #ifndef CFG_UPDATEMERGER_BATCHWRITE_PROPERTIES
380 if (m_xCurrentProp
->hasValueFor(aLocale
))
382 getResultWriter()->setPropertyValueForLocale(m_xCurrentProp
->getValueFor(aLocale
),aLocale
);
386 OSL_ENSURE(m_xCurrentProp
->hasResetFor(aLocale
),"LayerUpdateMerger: ERROR: Unknown change type in PropertyUpdate");
387 // write nothing to result
391 m_xCurrentProp
->removeValueFor(aLocale
);
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
);
404 OSL_ASSERT( m_xCurrentNode
.is());
406 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getPropertyByName(aName
);
409 BasicUpdateMerger::addProperty(aName
, aAttributes
, aType
);
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
);
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
);
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
);
453 OSL_ASSERT( m_xCurrentNode
.is());
455 rtl::Reference
<ElementUpdate
> xUpdate
= m_xCurrentNode
->getPropertyByName(aName
);
458 BasicUpdateMerger::addPropertyWithValue(aName
, aAttributes
, aValue
);
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())
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());
499 xUpdate
->writeToLayer(getResultWriter().get());
502 // -----------------------------------------------------------------------------
504 void LayerUpdateMerger::malformedUpdate(sal_Char
const * pMsg
)
507 OSL_ENSURE(false,pMsg
);
509 // -----------------------------------------------------------------------------
510 // -----------------------------------------------------------------------------
513 // -----------------------------------------------------------------------------