merge the formfield patch from ooo-build
[ooovba.git] / configmgr / source / backend / updatedispatch.cxx
blobd4c44846cc5ebdec50dfe67f4476739ca40c165b
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: updatedispatch.cxx,v $
10 * $Revision: 1.12 $
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 "treefragment.hxx"
35 #include "updatedispatch.hxx"
36 #include "configpath.hxx"
37 #include "node.hxx"
38 #include "matchlocale.hxx"
40 #include <com/sun/star/configuration/backend/XUpdateHandler.hpp>
41 #include <com/sun/star/configuration/backend/NodeAttribute.hpp>
43 namespace configmgr
45 // -----------------------------------------------------------------------------
46 namespace backend
48 // -----------------------------------------------------------------------------
50 UpdateDispatcher::UpdateDispatcher(uno::Reference< backenduno::XUpdateHandler > const & _xUpdateHandler, rtl::OUString const & _aLocale)
51 : m_pContextPath(NULL)
52 , m_xUpdateHandler(_xUpdateHandler)
53 , m_aLocale(_aLocale)
54 , m_aElementName()
55 , m_bInValueSet(false)
56 , m_bInLocalizedValues(false)
59 // -----------------------------------------------------------------------------
61 UpdateDispatcher::~UpdateDispatcher()
64 // -----------------------------------------------------------------------------
66 void UpdateDispatcher::dispatchUpdate(configuration::AbsolutePath const & _aRootPath, SubtreeChange const& _anUpdate)
68 if (!m_xUpdateHandler.is())
70 rtl::OUString sMsg( RTL_CONSTASCII_USTRINGPARAM("ERROR: Cannot dispatch update - no handler found") );
71 throw uno::RuntimeException(sMsg,NULL);
74 OSL_PRECOND( !_aRootPath.isRoot(), "Cannot apply update, where root is outside a component" );
76 OSL_PRECOND( m_pContextPath == NULL, "Update Dispatcher already has a context path" );
77 if (!_aRootPath.getParentPath().isRoot())
79 OSL_ENSURE(false,"Obsolete functionality used: starting update with non-empty context");
80 m_pContextPath = &_aRootPath;
83 this->startUpdate();
84 this->applyToChange(_anUpdate);
85 this->endUpdate();
87 m_pContextPath = NULL;
89 // -----------------------------------------------------------------------------
91 void UpdateDispatcher::startUpdate()
93 m_xUpdateHandler->startUpdate();
94 m_bInValueSet = false;
95 m_bInLocalizedValues = false;
96 m_aElementName = rtl::OUString();
98 if (m_pContextPath)
100 std::vector<configuration::Path::Component>::const_reverse_iterator it = m_pContextPath->begin();
101 std::vector<configuration::Path::Component>::const_reverse_iterator stop = m_pContextPath->end();
103 OSL_ASSERT(it != stop);
104 --stop;
106 for ( ; it != stop; ++it)
108 m_xUpdateHandler->modifyNode(it->getName(),0,0,false);
112 // -----------------------------------------------------------------------------
114 void UpdateDispatcher::endUpdate()
116 if (m_pContextPath)
118 std::vector<configuration::Path::Component>::const_reverse_iterator it = m_pContextPath->begin();
119 std::vector<configuration::Path::Component>::const_reverse_iterator stop = m_pContextPath->end();
121 OSL_ASSERT(it != stop);
122 --stop;
124 for ( ; it != stop; ++it)
126 m_xUpdateHandler->endNode();
129 m_xUpdateHandler->endUpdate();
131 // -----------------------------------------------------------------------------
133 void UpdateDispatcher::handle(ValueChange const& aValueNode)
135 // special case: doing members of a localized property (as set)
136 if (m_bInLocalizedValues)
138 rtl::OUString aLocale = aValueNode.getNodeName();
140 if (aLocale.getLength())
142 if ( aValueNode.isToDefault() )
143 m_xUpdateHandler->resetPropertyValueForLocale( aLocale );
144 else
145 m_xUpdateHandler->setPropertyValueForLocale( aValueNode.getNewValue(), aLocale );
147 else
149 if ( aValueNode.isToDefault() )
150 m_xUpdateHandler->resetPropertyValue( );
151 else
152 m_xUpdateHandler->setPropertyValue( aValueNode.getNewValue() );
154 return;
157 // normal case: updating a single property
158 switch (aValueNode.getMode())
160 case ValueChange::wasDefault:
161 if (aValueNode.isReplacedValue())
164 OSL_ENSURE(m_bInValueSet, "UpdateDispatcher: Cannot add/replace a value in a nonextensible node");
165 OSL_ENSURE(!aValueNode.isLocalizedValue(), "UpdateDispatcher: Cannot add a localized value in a layer");
167 sal_Int16 nAttr = getUpdateAttributes(aValueNode.getAttributes(),true);
169 if (aValueNode.getNewValue().hasValue())
171 m_xUpdateHandler->addOrReplacePropertyWithValue( aValueNode.getNodeName(),
172 nAttr,
173 aValueNode.getNewValue());
175 else
177 m_xUpdateHandler->addOrReplaceProperty( aValueNode.getNodeName(),
178 nAttr,
179 aValueNode.getValueType());
182 break;
184 // else fall thru to changeValue case
186 case ValueChange::changeValue:
188 sal_Int16 nAttr = getUpdateAttributes(aValueNode.getAttributes(),false);
189 sal_Int16 nAttrMask = getUpdateAttributeMask(aValueNode.getAttributes());
191 m_xUpdateHandler->modifyProperty( aValueNode.getNodeName(),
192 nAttr, nAttrMask,
193 aValueNode.getValueType() );
195 if (aValueNode.isLocalizedValue() && m_aLocale.getLength())
197 m_xUpdateHandler->setPropertyValueForLocale( aValueNode.getNewValue(), m_aLocale );
199 else
201 m_xUpdateHandler->setPropertyValue( aValueNode.getNewValue() );
204 m_xUpdateHandler->endProperty();
206 break;
208 case ValueChange::setToDefault:
209 m_xUpdateHandler->resetProperty( aValueNode.getNodeName() );
210 break;
212 case ValueChange::changeDefault:
213 OSL_ENSURE(false, "Illegal mode in ValueChange");
214 break;
216 default:
217 OSL_ENSURE(false, "Illegal mode in ValueChange");
218 break;
221 // -----------------------------------------------------------------------------
223 void UpdateDispatcher::handle(AddNode const& aAddNode)
225 rtl::Reference< data::TreeSegment > aAddedTree = aAddNode.getNewTree();
227 OSL_ENSURE(aAddedTree.is(), "AddNode has no new data -> cannot add anything");
229 OSL_ENSURE( ((m_bInValueSet||m_bInLocalizedValues) == aAddedTree->fragment->nodes[0].isValue()),
230 "Found added subtree in value set (extensible group)\n" );
232 this->visitTree(aAddedTree->fragment);
234 // -----------------------------------------------------------------------------
236 void UpdateDispatcher::handle(RemoveNode const& aRemoveNode)
238 OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: Removing values for a specific locale is currently not supported");
240 rtl::Reference< data::TreeSegment > aRemovedTree = aRemoveNode.getRemovedTree();
242 OSL_ENSURE( !aRemovedTree.is() ||
243 ((m_bInValueSet||m_bInLocalizedValues) == aRemovedTree->fragment->nodes[0].isValue()),
244 "Found removed subtree in value set (extensible group)\n" );
246 if (m_bInLocalizedValues)
247 OSL_TRACE("configmgr: UpdateDispatcher - Removing value for locale ignored");
249 else if (m_bInValueSet)
250 m_xUpdateHandler->removeProperty( aRemoveNode.getNodeName() );
252 else
253 m_xUpdateHandler->removeNode( aRemoveNode.getNodeName() );
255 // -----------------------------------------------------------------------------
257 void UpdateDispatcher::handle(SubtreeChange const& aSubtree)
259 OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: A localized value cannot be a complete subtree");
260 OSL_ENSURE( !m_bInValueSet, "UpdateDispatcher: A dynamic property cannot be a complete subtree");
262 sal_Int16 nAttr = getUpdateAttributes(aSubtree.getAttributes(),false);
263 sal_Int16 nAttrMask = getUpdateAttributeMask(aSubtree.getAttributes());
265 if (isLocalizedValueSet(aSubtree))
267 m_xUpdateHandler->modifyProperty( aSubtree.getNodeName(),
268 nAttr, nAttrMask,
269 uno::Type() );
271 m_bInLocalizedValues = true;
272 this->applyToChildren(aSubtree);
273 m_bInLocalizedValues = false;
275 m_xUpdateHandler->endProperty();
278 else
280 m_xUpdateHandler->modifyNode( aSubtree.getNodeName(),
281 nAttr, nAttrMask,
282 aSubtree.isToDefault() );
284 m_bInValueSet = isValueSet(aSubtree);
285 this->applyToChildren(aSubtree);
286 m_bInValueSet = false;
288 m_xUpdateHandler->endNode();
291 // -----------------------------------------------------------------------------
293 bool UpdateDispatcher::handle(sharable::ValueNode * node)
295 rtl::OUString aName;
297 // special case: doing members of a localized property (as set)
298 if (m_bInLocalizedValues)
300 // the node name is the locale
301 rtl::OUString aLocale;
302 OSL_VERIFY(testReplacedAndGetName(sharable::node(node), aLocale)); // "Adding a localized subvalue but not as root of element tree"
304 if (aLocale.getLength() && ! localehelper::isDefaultLanguage(aLocale))
306 m_xUpdateHandler->setPropertyValueForLocale(node->getValue(), aLocale);
308 else
310 m_xUpdateHandler->setPropertyValue(node->getValue());
313 else if (testReplacedAndGetName(sharable::node(node), aName) && sharable::node(node)->getAttributes().isRemovable()) // we must be inside a set of values
316 OSL_ENSURE(!node->info.isLocalized(), "UpdateDispatcher: Cannot add a localized value in a layer .");
318 sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),true);
320 if (!node->isNull())
322 m_xUpdateHandler->addOrReplacePropertyWithValue( aName,
323 nAttr,
324 node->getValue());
326 else
328 m_xUpdateHandler->addOrReplaceProperty( aName,
329 nAttr,
330 node->getValueType());
333 else // normal case: updating a single property //Inserting set
335 sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),false);
336 sal_Int16 nAttrMask = getUpdateAttributeMask(sharable::node(node)->getAttributes());
338 m_xUpdateHandler->modifyProperty( aName, nAttr, nAttrMask, node->getValueType() );
340 if (node->info.isLocalized() && m_aLocale.getLength())
342 m_xUpdateHandler->setPropertyValueForLocale(node->getValue(), m_aLocale);
344 else
346 m_xUpdateHandler->setPropertyValue(node->getValue());
349 m_xUpdateHandler->endProperty();
351 return false;
353 // -----------------------------------------------------------------------------
355 bool UpdateDispatcher::handle(sharable::GroupNode * node)
357 OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: A localized value cannot be a complete group");
359 rtl::OUString aName;
361 if ( testReplacedAndGetName(sharable::node(node), aName) )
363 sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),true);
365 m_xUpdateHandler->addOrReplaceNode( aName, nAttr );
367 this->visitChildren(node);
369 m_xUpdateHandler->endNode();
371 else
373 sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),false);
374 sal_Int16 nAttrMask = getUpdateAttributeMask(sharable::node(node)->getAttributes());
376 m_xUpdateHandler->modifyNode( aName, nAttr, nAttrMask, false );
378 this->visitChildren(node);
380 m_xUpdateHandler->endNode();
382 return false;
384 // -----------------------------------------------------------------------------
386 bool UpdateDispatcher::handle(sharable::SetNode * node)
388 OSL_ENSURE( !m_bInLocalizedValues, "UpdateDispatcher: A localized value cannot be a complete set");
390 rtl::OUString aName;
392 if ( testReplacedAndGetName(sharable::node(node), aName) )
394 OSL_ENSURE( !node->info.isLocalized(), "UpdateDispatcher: Cannot add a localized value in a layer." );
396 sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),true);
398 m_xUpdateHandler->addOrReplaceNode( aName, nAttr );
400 this->visitElements(node);
402 m_xUpdateHandler->endNode();
404 else
406 sal_Int16 nAttr = getUpdateAttributes(sharable::node(node)->getAttributes(),false);
407 sal_Int16 nAttrMask = getUpdateAttributeMask(sharable::node(node)->getAttributes());
409 if (node->info.isLocalized())
411 m_xUpdateHandler->modifyProperty( aName, nAttr, nAttrMask, uno::Type() );
413 m_bInLocalizedValues = true;
414 this->visitElements(node);
415 m_bInLocalizedValues = false;
417 m_xUpdateHandler->endProperty();
420 else
422 m_xUpdateHandler->modifyNode( aName, nAttr, nAttrMask, false );
424 this->visitElements(node);
426 m_xUpdateHandler->endNode();
429 return false;
431 // -----------------------------------------------------------------------------
433 bool UpdateDispatcher::testReplacedAndGetName(sharable::Node * node, rtl::OUString & _aName)
435 if (m_aElementName.getLength())
437 OSL_ENSURE( node->isFragmentRoot(), "ERROR - UpdateDispatcher: Found orphaned 'element' name for inner node");
438 _aName = m_aElementName;
439 m_aElementName = rtl::OUString();
440 return true;
442 else
444 OSL_ENSURE(!node->isFragmentRoot(), "ERROR - UpdateDispatcher: Found no 'element' name for fragment root node");
445 _aName = node->getName();
446 return false;
449 // -----------------------------------------------------------------------------
451 bool UpdateDispatcher::handle(sharable::TreeFragment * tree)
453 m_aElementName = tree->getName();
454 bool done = SetVisitor::handle(tree); // dispatch to root node
455 m_aElementName = rtl::OUString(); // clear - just to be safe
456 return done;
458 // -----------------------------------------------------------------------------
460 sal_Int16 UpdateDispatcher::getUpdateAttributes(node::Attributes const & _aAttributes, bool bAdded)
462 namespace NodeAttribute = backenduno::NodeAttribute;
464 // no support for post-creation attribute changes yet
465 if (!bAdded)
467 OSL_ENSURE( getUpdateAttributeMask(_aAttributes) == 0,
468 "Incomplete support for attribute changes" );
469 return 0;
472 sal_Int16 nResult = 0;
474 if (_aAttributes.isReadonly())
475 nResult = NodeAttribute::READONLY;
477 if (_aAttributes.isFinalized())
478 nResult |= NodeAttribute::FINALIZED;
480 if (!_aAttributes.isNullable())
481 nResult |= NodeAttribute::MANDATORY;
483 return nResult;
485 // -----------------------------------------------------------------------------
487 sal_Int16 UpdateDispatcher::getUpdateAttributeMask(node::Attributes const & /*_aAttributes*/)
489 // no support for post-creation attribute changes yet
490 return 0;
492 // -----------------------------------------------------------------------------
494 // -----------------------------------------------------------------------------
495 // -----------------------------------------------------------------------------
496 } // namespace backend
498 // -------------------------------------------------------------------------
499 } // namespace configmgr