Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <sal/config.h>
21 :
22 : #include <cassert>
23 : #include <vector>
24 :
25 : #include <com/sun/star/beans/Property.hpp>
26 : #include <com/sun/star/beans/PropertyAttribute.hpp>
27 : #include <com/sun/star/beans/PropertyChangeEvent.hpp>
28 : #include <com/sun/star/beans/PropertyVetoException.hpp>
29 : #include <com/sun/star/beans/UnknownPropertyException.hpp>
30 : #include <com/sun/star/beans/XExactName.hpp>
31 : #include <com/sun/star/beans/XHierarchicalPropertySet.hpp>
32 : #include <com/sun/star/beans/XHierarchicalPropertySetInfo.hpp>
33 : #include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp>
34 : #include <com/sun/star/beans/XMultiPropertySet.hpp>
35 : #include <com/sun/star/beans/XPropertiesChangeListener.hpp>
36 : #include <com/sun/star/beans/XProperty.hpp>
37 : #include <com/sun/star/beans/XPropertyChangeListener.hpp>
38 : #include <com/sun/star/beans/XPropertySet.hpp>
39 : #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 : #include <com/sun/star/beans/XVetoableChangeListener.hpp>
41 : #include <com/sun/star/container/ContainerEvent.hpp>
42 : #include <com/sun/star/container/NoSuchElementException.hpp>
43 : #include <com/sun/star/container/XContainer.hpp>
44 : #include <com/sun/star/container/XContainerListener.hpp>
45 : #include <com/sun/star/container/XElementAccess.hpp>
46 : #include <com/sun/star/container/XHierarchicalName.hpp>
47 : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
48 : #include <com/sun/star/container/XHierarchicalNameReplace.hpp>
49 : #include <com/sun/star/container/XNameAccess.hpp>
50 : #include <com/sun/star/container/XNameContainer.hpp>
51 : #include <com/sun/star/container/XNamed.hpp>
52 : #include <com/sun/star/lang/DisposedException.hpp>
53 : #include <com/sun/star/lang/EventObject.hpp>
54 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
55 : #include <com/sun/star/lang/NoSupportException.hpp>
56 : #include <com/sun/star/lang/WrappedTargetException.hpp>
57 : #include <com/sun/star/lang/XComponent.hpp>
58 : #include <com/sun/star/lang/XEventListener.hpp>
59 : #include <com/sun/star/lang/XServiceInfo.hpp>
60 : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
61 : #include <com/sun/star/lang/XTypeProvider.hpp>
62 : #include <com/sun/star/lang/XUnoTunnel.hpp>
63 : #include <com/sun/star/uno/Any.hxx>
64 : #include <com/sun/star/uno/Reference.hxx>
65 : #include <com/sun/star/uno/RuntimeException.hpp>
66 : #include <com/sun/star/uno/Sequence.hxx>
67 : #include <com/sun/star/uno/Type.hxx>
68 : #include <com/sun/star/uno/TypeClass.hpp>
69 : #include <com/sun/star/uno/XInterface.hpp>
70 : #include <com/sun/star/uno/XWeak.hpp>
71 : #include <com/sun/star/util/ElementChange.hpp>
72 : #include <comphelper/sequence.hxx>
73 : #include <cppu/unotype.hxx>
74 : #include <cppuhelper/queryinterface.hxx>
75 : #include <cppuhelper/supportsservice.hxx>
76 : #include <cppuhelper/weak.hxx>
77 : #include <osl/interlck.h>
78 : #include <osl/mutex.hxx>
79 : #include <rtl/ref.hxx>
80 : #include <rtl/ustrbuf.hxx>
81 : #include <rtl/ustring.h>
82 : #include <rtl/ustring.hxx>
83 : #include <sal/log.hxx>
84 : #include <sal/types.h>
85 :
86 : #include "access.hxx"
87 : #include "broadcaster.hxx"
88 : #include "childaccess.hxx"
89 : #include "components.hxx"
90 : #include "data.hxx"
91 : #include "groupnode.hxx"
92 : #include "localizedpropertynode.hxx"
93 : #include "localizedvaluenode.hxx"
94 : #include "lock.hxx"
95 : #include "modifications.hxx"
96 : #include "node.hxx"
97 : #include "nodemap.hxx"
98 : #include "path.hxx"
99 : #include "propertynode.hxx"
100 : #include "rootaccess.hxx"
101 : #include "setnode.hxx"
102 : #include "type.hxx"
103 :
104 : namespace configmgr {
105 :
106 2392980 : oslInterlockedCount Access::acquireCounting() {
107 2392980 : return osl_atomic_increment(&m_refCount);
108 : }
109 :
110 2392980 : void Access::releaseNondeleting() {
111 2392980 : osl_atomic_decrement(&m_refCount);
112 2392980 : }
113 :
114 30439192 : bool Access::isValue() {
115 30439192 : rtl::Reference< Node > p(getNode());
116 30439192 : switch (p->kind()) {
117 : case Node::KIND_PROPERTY:
118 : case Node::KIND_LOCALIZED_VALUE:
119 933927 : return true;
120 : case Node::KIND_LOCALIZED_PROPERTY:
121 46525 : return !Components::allLocales(getRootAccess()->getLocale());
122 : default:
123 29458740 : return false;
124 30439192 : }
125 : }
126 :
127 113973 : void Access::markChildAsModified(rtl::Reference< ChildAccess > const & child) {
128 : assert(child.is() && child->getParentAccess() == this);
129 113973 : modifiedChildren_[child->getNameInternal()] = ModifiedChild(child, true);
130 113973 : for (rtl::Reference< Access > p(this);;) {
131 383358 : rtl::Reference< Access > parent(p->getParentAccess());
132 383358 : if (!parent.is()) {
133 113973 : break;
134 : }
135 : assert(dynamic_cast< ChildAccess * >(p.get()) != 0);
136 269385 : parent->modifiedChildren_.insert(
137 : ModifiedChildren::value_type(
138 269385 : p->getNameInternal(),
139 808155 : ModifiedChild(static_cast< ChildAccess * >(p.get()), false)));
140 269385 : p = parent;
141 269385 : }
142 113973 : }
143 :
144 61510988 : void Access::releaseChild(OUString const & name) {
145 61510988 : cachedChildren_.erase(name);
146 61510988 : }
147 :
148 0 : void Access::initBroadcaster(
149 : Modifications::Node const & modifications, Broadcaster * broadcaster)
150 : {
151 0 : initBroadcasterAndChanges(modifications, broadcaster, 0);
152 0 : }
153 :
154 0 : css::uno::Sequence< css::uno::Type > Access::getTypes()
155 : throw (css::uno::RuntimeException, std::exception)
156 : {
157 : assert(thisIs(IS_ANY));
158 0 : osl::MutexGuard g(*lock_);
159 0 : checkLocalizedPropertyAccess();
160 0 : std::vector< css::uno::Type > types;
161 0 : types.push_back(cppu::UnoType< css::uno::XInterface >::get());
162 0 : types.push_back(cppu::UnoType< css::uno::XWeak >::get());
163 0 : types.push_back(cppu::UnoType< css::lang::XTypeProvider >::get());
164 0 : types.push_back(cppu::UnoType< css::lang::XServiceInfo >::get());
165 0 : types.push_back(cppu::UnoType< css::lang::XComponent >::get());
166 0 : types.push_back(cppu::UnoType< css::container::XContainer >::get());
167 0 : types.push_back(cppu::UnoType< css::beans::XExactName >::get());
168 0 : types.push_back(cppu::UnoType< css::container::XHierarchicalName >::get());
169 0 : types.push_back(cppu::UnoType< css::container::XNamed >::get());
170 0 : types.push_back(cppu::UnoType< css::beans::XProperty >::get());
171 0 : types.push_back(cppu::UnoType< css::container::XElementAccess >::get());
172 0 : types.push_back(cppu::UnoType< css::container::XNameAccess >::get());
173 0 : if (getNode()->kind() == Node::KIND_GROUP) {
174 0 : types.push_back(cppu::UnoType< css::beans::XPropertySetInfo >::get());
175 0 : types.push_back(cppu::UnoType< css::beans::XPropertySet >::get());
176 0 : types.push_back(cppu::UnoType< css::beans::XMultiPropertySet >::get());
177 : types.push_back(
178 0 : cppu::UnoType< css::beans::XHierarchicalPropertySet >::get());
179 : types.push_back(
180 0 : cppu::UnoType< css::beans::XMultiHierarchicalPropertySet >::get());
181 : types.push_back(
182 0 : cppu::UnoType< css::beans::XHierarchicalPropertySetInfo >::get());
183 : }
184 0 : if (getRootAccess()->isUpdate()) {
185 0 : types.push_back(cppu::UnoType< css::container::XNameReplace >::get());
186 : types.push_back(
187 0 : cppu::UnoType< css::container::XHierarchicalNameReplace >::get());
188 0 : if (getNode()->kind() != Node::KIND_GROUP ||
189 0 : static_cast< GroupNode * >(getNode().get())->isExtensible())
190 : {
191 : types.push_back(
192 0 : cppu::UnoType< css::container::XNameContainer >::get());
193 : }
194 0 : if (getNode()->kind() == Node::KIND_SET) {
195 : types.push_back(
196 0 : cppu::UnoType< css::lang::XSingleServiceFactory >::get());
197 : }
198 : } else {
199 : types.push_back(
200 0 : cppu::UnoType< css::container::XHierarchicalNameAccess >::get());
201 : }
202 0 : addTypes(&types);
203 0 : return comphelper::containerToSequence(types);
204 : }
205 :
206 0 : css::uno::Sequence< sal_Int8 > Access::getImplementationId()
207 : throw (css::uno::RuntimeException, std::exception)
208 : {
209 : assert(thisIs(IS_ANY));
210 0 : osl::MutexGuard g(*lock_);
211 0 : checkLocalizedPropertyAccess();
212 0 : return css::uno::Sequence< sal_Int8 >();
213 : }
214 :
215 0 : OUString Access::getImplementationName() throw (css::uno::RuntimeException, std::exception)
216 : {
217 : assert(thisIs(IS_ANY));
218 0 : osl::MutexGuard g(*lock_);
219 0 : checkLocalizedPropertyAccess();
220 0 : return OUString("org.openoffice-configmgr::Access");
221 : }
222 :
223 10844 : sal_Bool Access::supportsService(OUString const & ServiceName)
224 : throw (css::uno::RuntimeException, std::exception)
225 : {
226 10844 : return cppu::supportsService(this, ServiceName);
227 : }
228 :
229 10844 : css::uno::Sequence< OUString > Access::getSupportedServiceNames()
230 : throw (css::uno::RuntimeException, std::exception)
231 : {
232 : assert(thisIs(IS_ANY));
233 10844 : osl::MutexGuard g(*lock_);
234 10844 : checkLocalizedPropertyAccess();
235 21688 : std::vector< OUString > services;
236 10844 : services.push_back("com.sun.star.configuration.ConfigurationAccess");
237 10844 : if (getRootAccess()->isUpdate()) {
238 : services.push_back(
239 3024 : "com.sun.star.configuration.ConfigurationUpdateAccess");
240 : }
241 10844 : services.push_back("com.sun.star.configuration.HierarchyAccess");
242 10844 : services.push_back("com.sun.star.configuration.HierarchyElement");
243 10844 : if (getNode()->kind() == Node::KIND_GROUP) {
244 6831 : services.push_back("com.sun.star.configuration.GroupAccess");
245 6831 : services.push_back("com.sun.star.configuration.PropertyHierarchy");
246 6831 : if (getRootAccess()->isUpdate()) {
247 2202 : services.push_back("com.sun.star.configuration.GroupUpdate");
248 : }
249 : } else {
250 4013 : services.push_back("com.sun.star.configuration.SetAccess");
251 4013 : services.push_back("com.sun.star.configuration.SimpleSetAccess");
252 4013 : if (getRootAccess()->isUpdate()) {
253 822 : services.push_back("com.sun.star.configuration.SetUpdate");
254 822 : services.push_back("com.sun.star.configuration.SimpleSetUpdate");
255 : }
256 : }
257 10844 : addSupportedServiceNames(&services);
258 21688 : return comphelper::containerToSequence(services);
259 : }
260 :
261 121 : void Access::dispose() throw (css::uno::RuntimeException, std::exception) {
262 : assert(thisIs(IS_ANY));
263 121 : Broadcaster bc;
264 : {
265 121 : osl::MutexGuard g(*lock_);
266 121 : checkLocalizedPropertyAccess();
267 121 : if (getParentAccess().is()) {
268 : throw css::uno::RuntimeException(
269 : "configmgr dispose inappropriate Access",
270 0 : static_cast< cppu::OWeakObject * >(this));
271 : }
272 121 : if (disposed_) {
273 121 : return;
274 : }
275 121 : initDisposeBroadcaster(&bc);
276 121 : clearListeners();
277 121 : disposed_ = true;
278 : }
279 121 : bc.send();
280 : }
281 :
282 11767 : void Access::addEventListener(
283 : css::uno::Reference< css::lang::XEventListener > const & xListener)
284 : throw (css::uno::RuntimeException, std::exception)
285 : {
286 : assert(thisIs(IS_ANY));
287 : {
288 11767 : osl::MutexGuard g(*lock_);
289 11767 : checkLocalizedPropertyAccess();
290 11767 : if (!xListener.is()) {
291 : throw css::uno::RuntimeException(
292 0 : "null listener", static_cast< cppu::OWeakObject * >(this));
293 : }
294 11767 : if (!disposed_) {
295 11767 : disposeListeners_.insert(xListener);
296 23534 : return;
297 0 : }
298 : }
299 : try {
300 0 : xListener->disposing(
301 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
302 0 : } catch (css::lang::DisposedException &) {}
303 : }
304 :
305 11746 : void Access::removeEventListener(
306 : css::uno::Reference< css::lang::XEventListener > const & aListener)
307 : throw (css::uno::RuntimeException, std::exception)
308 : {
309 : assert(thisIs(IS_ANY));
310 11746 : osl::MutexGuard g(*lock_);
311 11746 : checkLocalizedPropertyAccess();
312 11746 : DisposeListeners::iterator i(disposeListeners_.find(aListener));
313 11746 : if (i != disposeListeners_.end()) {
314 11746 : disposeListeners_.erase(i);
315 11746 : }
316 11746 : }
317 :
318 0 : css::uno::Type Access::getElementType() throw (css::uno::RuntimeException, std::exception) {
319 : assert(thisIs(IS_ANY));
320 0 : osl::MutexGuard g(*lock_);
321 0 : checkLocalizedPropertyAccess();
322 0 : rtl::Reference< Node > p(getNode());
323 0 : switch (p->kind()) {
324 : case Node::KIND_LOCALIZED_PROPERTY:
325 : return mapType(
326 0 : static_cast< LocalizedPropertyNode * >(p.get())->getStaticType());
327 : case Node::KIND_GROUP:
328 : //TODO: Should a specific type be returned for a non-extensible group
329 : // with homogeneous members or for an extensible group that currently
330 : // has only homegeneous members?
331 0 : return cppu::UnoType<void>::get();
332 : case Node::KIND_SET:
333 0 : return cppu::UnoType<void>::get(); //TODO: correct?
334 : default:
335 : assert(false);
336 : throw css::uno::RuntimeException(
337 0 : "this cannot happen", static_cast< cppu::OWeakObject * >(this));
338 0 : }
339 : }
340 :
341 116 : sal_Bool Access::hasElements() throw (css::uno::RuntimeException, std::exception) {
342 : assert(thisIs(IS_ANY));
343 116 : osl::MutexGuard g(*lock_);
344 116 : checkLocalizedPropertyAccess();
345 116 : return !getAllChildren().empty(); //TODO: optimize
346 : }
347 :
348 55986324 : bool Access::getByNameFast(const OUString & name, css::uno::Any & value)
349 : {
350 55986324 : bool bGotValue = false;
351 55986324 : rtl::Reference< ChildAccess > child;
352 :
353 55986324 : if (getNode()->kind() != Node::KIND_LOCALIZED_PROPERTY)
354 : { // try to get it directly
355 55882038 : ModifiedChildren::iterator i(modifiedChildren_.find(name));
356 55882038 : if (i != modifiedChildren_.end())
357 : {
358 617 : child = getModifiedChild(i);
359 617 : if (child.is())
360 : {
361 617 : value = child->asValue();
362 617 : bGotValue = true;
363 : }
364 : }
365 : else
366 : {
367 55881421 : rtl::Reference< Node > node(getNode()->getMember(name));
368 55881421 : if (!node.is())
369 131 : return false;
370 55881290 : bGotValue = ChildAccess::asSimpleValue(node, value, components_);
371 : }
372 : }
373 :
374 55986193 : if (!bGotValue)
375 : {
376 54354720 : child = getChild(name);
377 54354720 : if (!child.is())
378 0 : return false;
379 54354720 : value = child->asValue();
380 : }
381 55986193 : return true;
382 : }
383 :
384 55337761 : css::uno::Any Access::getByName(OUString const & aName)
385 : throw (
386 : css::container::NoSuchElementException,
387 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
388 : {
389 : assert(thisIs(IS_ANY));
390 55337761 : osl::MutexGuard g(*lock_);
391 55337761 : checkLocalizedPropertyAccess();
392 55337761 : css::uno::Any value;
393 55337761 : if (!getByNameFast(aName, value))
394 : throw css::container::NoSuchElementException(
395 131 : aName, static_cast< cppu::OWeakObject * >(this));
396 55337761 : return value;
397 : }
398 :
399 26923570 : css::uno::Sequence< OUString > Access::getElementNames()
400 : throw (css::uno::RuntimeException, std::exception)
401 : {
402 : assert(thisIs(IS_ANY));
403 26923570 : osl::MutexGuard g(*lock_);
404 26923570 : checkLocalizedPropertyAccess();
405 53847140 : std::vector< rtl::Reference< ChildAccess > > children(getAllChildren());
406 53847140 : std::vector< OUString > names;
407 84136128 : for (std::vector< rtl::Reference< ChildAccess > >::iterator i(
408 26923570 : children.begin());
409 56090752 : i != children.end(); ++i)
410 : {
411 1121806 : names.push_back((*i)->getNameInternal());
412 : }
413 53847140 : return comphelper::containerToSequence(names);
414 : }
415 :
416 1916811 : sal_Bool Access::hasByName(OUString const & aName)
417 : throw (css::uno::RuntimeException, std::exception)
418 : {
419 : assert(thisIs(IS_ANY));
420 1916811 : osl::MutexGuard g(*lock_);
421 1916811 : checkLocalizedPropertyAccess();
422 1916811 : return getChild(aName).is();
423 : }
424 :
425 1067704 : css::uno::Any Access::getByHierarchicalName(OUString const & aName)
426 : throw (css::container::NoSuchElementException, css::uno::RuntimeException, std::exception)
427 : {
428 : assert(thisIs(IS_ANY));
429 1067704 : osl::MutexGuard g(*lock_);
430 1067704 : checkLocalizedPropertyAccess();
431 2135408 : rtl::Reference< ChildAccess > child(getSubChild(aName));
432 1067704 : if (!child.is()) {
433 : throw css::container::NoSuchElementException(
434 37 : aName, static_cast< cppu::OWeakObject * >(this));
435 : }
436 2135371 : return child->asValue();
437 : }
438 :
439 625 : sal_Bool Access::hasByHierarchicalName(OUString const & aName)
440 : throw (css::uno::RuntimeException, std::exception)
441 : {
442 : assert(thisIs(IS_ANY));
443 625 : osl::MutexGuard g(*lock_);
444 625 : checkLocalizedPropertyAccess();
445 625 : return getSubChild(aName).is();
446 : }
447 :
448 517 : void Access::replaceByHierarchicalName(
449 : OUString const & aName, css::uno::Any const & aElement)
450 : throw (
451 : css::lang::IllegalArgumentException,
452 : css::container::NoSuchElementException,
453 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
454 : {
455 : //TODO: Actually support sets and combine with replaceByName:
456 : assert(thisIs(IS_UPDATE));
457 517 : Broadcaster bc;
458 : {
459 517 : osl::MutexGuard g(*lock_);
460 517 : checkLocalizedPropertyAccess();
461 1034 : rtl::Reference< ChildAccess > child(getSubChild(aName));
462 517 : if (!child.is()) {
463 : throw css::container::NoSuchElementException(
464 0 : aName, static_cast< cppu::OWeakObject * >(this));
465 : }
466 517 : child->checkFinalized();
467 1034 : rtl::Reference< Node > parent(child->getParentNode());
468 : assert(parent.is());
469 1034 : Modifications localMods;
470 517 : switch (parent->kind()) {
471 : case Node::KIND_LOCALIZED_PROPERTY:
472 : case Node::KIND_GROUP:
473 517 : child->setProperty(aElement, &localMods);
474 517 : break;
475 : case Node::KIND_SET:
476 : throw css::lang::IllegalArgumentException(
477 : ("configmgr::Access::replaceByHierarchicalName does not"
478 : " currently support set members"),
479 0 : static_cast< cppu::OWeakObject * >(this), 0);
480 : case Node::KIND_ROOT:
481 : throw css::lang::IllegalArgumentException(
482 : ("configmgr::Access::replaceByHierarchicalName does not allow"
483 0 : " changing component " + aName),
484 0 : static_cast< cppu::OWeakObject * >(this), 0);
485 : default:
486 : assert(false); // this cannot happen
487 0 : break;
488 : }
489 1034 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
490 : }
491 517 : bc.send();
492 517 : }
493 :
494 859 : void Access::addContainerListener(
495 : css::uno::Reference< css::container::XContainerListener > const & xListener)
496 : throw (css::uno::RuntimeException, std::exception)
497 : {
498 : assert(thisIs(IS_ANY));
499 : {
500 859 : osl::MutexGuard g(*lock_);
501 859 : checkLocalizedPropertyAccess();
502 859 : if (!xListener.is()) {
503 : throw css::uno::RuntimeException(
504 0 : "null listener", static_cast< cppu::OWeakObject * >(this));
505 : }
506 859 : if (!disposed_) {
507 859 : containerListeners_.insert(xListener);
508 1718 : return;
509 0 : }
510 : }
511 : try {
512 0 : xListener->disposing(
513 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
514 0 : } catch (css::lang::DisposedException &) {}
515 : }
516 :
517 833 : void Access::removeContainerListener(
518 : css::uno::Reference< css::container::XContainerListener > const & xListener)
519 : throw (css::uno::RuntimeException, std::exception)
520 : {
521 : assert(thisIs(IS_ANY));
522 833 : osl::MutexGuard g(*lock_);
523 833 : checkLocalizedPropertyAccess();
524 833 : ContainerListeners::iterator i(containerListeners_.find(xListener));
525 833 : if (i != containerListeners_.end()) {
526 833 : containerListeners_.erase(i);
527 833 : }
528 833 : }
529 :
530 0 : OUString Access::getExactName(OUString const & aApproximateName)
531 : throw (css::uno::RuntimeException, std::exception)
532 : {
533 : assert(thisIs(IS_ANY));
534 0 : osl::MutexGuard g(*lock_);
535 0 : checkLocalizedPropertyAccess();
536 0 : return aApproximateName;
537 : }
538 :
539 0 : css::uno::Sequence< css::beans::Property > Access::getProperties()
540 : throw (css::uno::RuntimeException, std::exception)
541 : {
542 : assert(thisIs(IS_GROUP));
543 0 : osl::MutexGuard g(*lock_);
544 0 : std::vector< rtl::Reference< ChildAccess > > children(getAllChildren());
545 0 : std::vector< css::beans::Property > properties;
546 0 : for (std::vector< rtl::Reference< ChildAccess > >::iterator i(
547 0 : children.begin());
548 0 : i != children.end(); ++i)
549 : {
550 0 : properties.push_back((*i)->asProperty());
551 : }
552 0 : return comphelper::containerToSequence(properties);
553 : }
554 :
555 13158 : css::beans::Property Access::getPropertyByName(OUString const & aName)
556 : throw (css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception)
557 : {
558 : assert(thisIs(IS_GROUP));
559 13158 : osl::MutexGuard g(*lock_);
560 26316 : rtl::Reference< ChildAccess > child(getChild(aName));
561 13158 : if (!child.is()) {
562 : throw css::beans::UnknownPropertyException(
563 0 : aName, static_cast< cppu::OWeakObject * >(this));
564 : }
565 26316 : return child->asProperty();
566 : }
567 :
568 0 : sal_Bool Access::hasPropertyByName(OUString const & Name)
569 : throw (css::uno::RuntimeException, std::exception)
570 : {
571 : assert(thisIs(IS_GROUP));
572 0 : osl::MutexGuard g(*lock_);
573 0 : return getChild(Name).is();
574 : }
575 :
576 0 : OUString Access::getHierarchicalName() throw (css::uno::RuntimeException, std::exception) {
577 : assert(thisIs(IS_ANY));
578 0 : osl::MutexGuard g(*lock_);
579 0 : checkLocalizedPropertyAccess();
580 : // For backwards compatibility, return an absolute path representation where
581 : // available:
582 0 : OUString rootPath;
583 0 : rtl::Reference< RootAccess > root(getRootAccess());
584 0 : if (root.is()) {
585 0 : rootPath = root->getAbsolutePathRepresentation();
586 : }
587 0 : OUString rel(getRelativePathRepresentation());
588 0 : OUStringBuffer path(rootPath);
589 0 : if (!rootPath.isEmpty() && rootPath != "/" && !rel.isEmpty()) {
590 0 : path.append('/');
591 : }
592 0 : path.append(rel);
593 0 : return path.makeStringAndClear();
594 : }
595 :
596 0 : OUString Access::composeHierarchicalName(
597 : OUString const & aRelativeName)
598 : throw (
599 : css::lang::IllegalArgumentException, css::lang::NoSupportException,
600 : css::uno::RuntimeException, std::exception)
601 : {
602 : assert(thisIs(IS_ANY));
603 0 : osl::MutexGuard g(*lock_);
604 0 : checkLocalizedPropertyAccess();
605 0 : if (aRelativeName.isEmpty() || aRelativeName[0] == '/') {
606 : throw css::lang::IllegalArgumentException(
607 : "configmgr composeHierarchicalName inappropriate relative name",
608 0 : static_cast< cppu::OWeakObject * >(this), -1);
609 : }
610 0 : OUStringBuffer path(getRelativePathRepresentation());
611 0 : if (!path.isEmpty()) {
612 0 : path.append('/');
613 : }
614 0 : path.append(aRelativeName);
615 0 : return path.makeStringAndClear();
616 : }
617 :
618 84 : OUString Access::getName() throw (css::uno::RuntimeException, std::exception) {
619 : assert(thisIs(IS_ANY));
620 84 : osl::MutexGuard g(*lock_);
621 84 : checkLocalizedPropertyAccess();
622 84 : return getNameInternal();
623 : }
624 :
625 1 : void Access::setName(OUString const & aName)
626 : throw (css::uno::RuntimeException, std::exception)
627 : {
628 : assert(thisIs(IS_ANY));
629 1 : Broadcaster bc;
630 : {
631 1 : osl::MutexGuard g(*lock_);
632 1 : checkLocalizedPropertyAccess();
633 1 : checkFinalized();
634 2 : Modifications localMods;
635 1 : switch (getNode()->kind()) {
636 : case Node::KIND_GROUP:
637 : case Node::KIND_SET:
638 : {
639 1 : rtl::Reference< Access > parent(getParentAccess());
640 1 : if (parent.is()) {
641 1 : rtl::Reference< Node > node(getNode());
642 1 : if (! node->getTemplateName().isEmpty()) {
643 : rtl::Reference< ChildAccess > other(
644 1 : parent->getChild(aName));
645 1 : if (other.get() == this) {
646 0 : break;
647 : }
648 3 : if (node->getMandatory() == Data::NO_LAYER &&
649 2 : !(other.is() && other->isFinalized()))
650 : {
651 1 : rtl::Reference< RootAccess > root(getRootAccess());
652 : rtl::Reference< ChildAccess > childAccess(
653 2 : static_cast< ChildAccess * >(this));
654 1 : localMods.add(getRelativePath());
655 : // unbind() modifies the parent chain that
656 : // markChildAsModified() walks, so order is
657 : // important:
658 1 : parent->markChildAsModified(childAccess);
659 : //TODO: must not throw
660 1 : childAccess->unbind(); // must not throw
661 1 : if (other.is()) {
662 1 : other->unbind(); // must not throw
663 : }
664 1 : childAccess->bind(root, parent, aName);
665 : // must not throw
666 1 : parent->markChildAsModified(childAccess);
667 : //TODO: must not throw
668 1 : localMods.add(getRelativePath());
669 2 : break;
670 0 : }
671 0 : }
672 0 : }
673 : }
674 : // fall through
675 : case Node::KIND_LOCALIZED_PROPERTY:
676 : // renaming a property could only work for an extension property,
677 : // but a localized property is never an extension property
678 : throw css::uno::RuntimeException(
679 : "configmgr setName inappropriate node",
680 0 : static_cast< cppu::OWeakObject * >(this));
681 : default:
682 : assert(false); // this cannot happen
683 0 : break;
684 : }
685 2 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
686 : }
687 1 : bc.send();
688 1 : }
689 :
690 25773 : css::beans::Property Access::getAsProperty() throw (css::uno::RuntimeException, std::exception)
691 : {
692 : assert(thisIs(IS_ANY));
693 25773 : osl::MutexGuard g(*lock_);
694 25773 : checkLocalizedPropertyAccess();
695 25773 : return asProperty();
696 : }
697 :
698 13158 : css::uno::Reference< css::beans::XPropertySetInfo > Access::getPropertySetInfo()
699 : throw (css::uno::RuntimeException, std::exception)
700 : {
701 : assert(thisIs(IS_GROUP));
702 13158 : return this;
703 : }
704 :
705 83452 : void Access::setPropertyValue(
706 : OUString const & aPropertyName, css::uno::Any const & aValue)
707 : throw (
708 : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
709 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
710 : css::uno::RuntimeException, std::exception)
711 : {
712 : assert(thisIs(IS_GROUP));
713 83452 : Broadcaster bc;
714 : {
715 83452 : osl::MutexGuard g(*lock_);
716 83452 : if (!getRootAccess()->isUpdate()) {
717 : throw css::uno::RuntimeException(
718 : "configmgr setPropertyValue on non-update access",
719 0 : static_cast< cppu::OWeakObject * >(this));
720 : }
721 166904 : Modifications localMods;
722 83452 : if (!setChildProperty(aPropertyName, aValue, &localMods)) {
723 : throw css::beans::UnknownPropertyException(
724 0 : aPropertyName, static_cast< cppu::OWeakObject * >(this));
725 : }
726 166904 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
727 : }
728 83452 : bc.send();
729 83452 : }
730 :
731 227623 : css::uno::Any Access::getPropertyValue(OUString const & PropertyName)
732 : throw (
733 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
734 : css::uno::RuntimeException, std::exception)
735 : {
736 : assert(thisIs(IS_GROUP));
737 227623 : osl::MutexGuard g(*lock_);
738 :
739 227623 : css::uno::Any value;
740 227623 : if (!getByNameFast(PropertyName, value))
741 : throw css::beans::UnknownPropertyException(
742 0 : PropertyName, static_cast< cppu::OWeakObject * >(this));
743 227623 : return value;
744 : }
745 :
746 20 : void Access::addPropertyChangeListener(
747 : OUString const & aPropertyName,
748 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
749 : xListener)
750 : throw (
751 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
752 : css::uno::RuntimeException, std::exception)
753 : {
754 : assert(thisIs(IS_GROUP));
755 : {
756 20 : osl::MutexGuard g(*lock_);
757 20 : if (!xListener.is()) {
758 : throw css::uno::RuntimeException(
759 0 : "null listener", static_cast< cppu::OWeakObject * >(this));
760 : }
761 20 : checkKnownProperty(aPropertyName);
762 20 : if (!disposed_) {
763 20 : propertyChangeListeners_[aPropertyName].insert(xListener);
764 40 : return;
765 0 : }
766 : }
767 : try {
768 0 : xListener->disposing(
769 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
770 0 : } catch (css::lang::DisposedException &) {}
771 : }
772 :
773 0 : void Access::removePropertyChangeListener(
774 : OUString const & aPropertyName,
775 : css::uno::Reference< css::beans::XPropertyChangeListener > const &
776 : aListener)
777 : throw (
778 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
779 : css::uno::RuntimeException, std::exception)
780 : {
781 : assert(thisIs(IS_GROUP));
782 0 : osl::MutexGuard g(*lock_);
783 0 : checkKnownProperty(aPropertyName);
784 : PropertyChangeListeners::iterator i(
785 0 : propertyChangeListeners_.find(aPropertyName));
786 0 : if (i != propertyChangeListeners_.end()) {
787 0 : PropertyChangeListenersElement::iterator j(i->second.find(aListener));
788 0 : if (j != i->second.end()) {
789 0 : i->second.erase(j);
790 0 : if (i->second.empty()) {
791 0 : propertyChangeListeners_.erase(i);
792 : }
793 : }
794 0 : }
795 0 : }
796 :
797 0 : void Access::addVetoableChangeListener(
798 : OUString const & PropertyName,
799 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
800 : aListener)
801 : throw (
802 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
803 : css::uno::RuntimeException, std::exception)
804 : {
805 : assert(thisIs(IS_GROUP));
806 : {
807 0 : osl::MutexGuard g(*lock_);
808 0 : if (!aListener.is()) {
809 : throw css::uno::RuntimeException(
810 0 : "null listener", static_cast< cppu::OWeakObject * >(this));
811 : }
812 0 : checkKnownProperty(PropertyName);
813 0 : if (!disposed_) {
814 0 : vetoableChangeListeners_[PropertyName].insert(aListener);
815 : //TODO: actually call vetoableChangeListeners_
816 0 : return;
817 0 : }
818 : }
819 : try {
820 0 : aListener->disposing(
821 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
822 0 : } catch (css::lang::DisposedException &) {}
823 : }
824 :
825 0 : void Access::removeVetoableChangeListener(
826 : OUString const & PropertyName,
827 : css::uno::Reference< css::beans::XVetoableChangeListener > const &
828 : aListener)
829 : throw (
830 : css::beans::UnknownPropertyException, css::lang::WrappedTargetException,
831 : css::uno::RuntimeException, std::exception)
832 : {
833 : assert(thisIs(IS_GROUP));
834 0 : osl::MutexGuard g(*lock_);
835 0 : checkKnownProperty(PropertyName);
836 : VetoableChangeListeners::iterator i(
837 0 : vetoableChangeListeners_.find(PropertyName));
838 0 : if (i != vetoableChangeListeners_.end()) {
839 0 : VetoableChangeListenersElement::iterator j(i->second.find(aListener));
840 0 : if (j != i->second.end()) {
841 0 : i->second.erase(j);
842 0 : if (i->second.empty()) {
843 0 : vetoableChangeListeners_.erase(i);
844 : }
845 : }
846 0 : }
847 0 : }
848 :
849 0 : void Access::setPropertyValues(
850 : css::uno::Sequence< OUString > const & aPropertyNames,
851 : css::uno::Sequence< css::uno::Any > const & aValues)
852 : throw (
853 : css::beans::PropertyVetoException, css::lang::IllegalArgumentException,
854 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
855 : {
856 : assert(thisIs(IS_GROUP));
857 0 : Broadcaster bc;
858 : {
859 0 : osl::MutexGuard g(*lock_);
860 0 : if (!getRootAccess()->isUpdate()) {
861 : throw css::uno::RuntimeException(
862 : "configmgr setPropertyValues on non-update access",
863 0 : static_cast< cppu::OWeakObject * >(this));
864 : }
865 0 : if (aPropertyNames.getLength() != aValues.getLength()) {
866 : throw css::lang::IllegalArgumentException(
867 : ("configmgr setPropertyValues: aPropertyNames/aValues of"
868 : " different length"),
869 0 : static_cast< cppu::OWeakObject * >(this), -1);
870 : }
871 0 : Modifications localMods;
872 0 : for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i) {
873 0 : if (!setChildProperty(aPropertyNames[i], aValues[i], &localMods)) {
874 : throw css::lang::IllegalArgumentException(
875 : "configmgr setPropertyValues inappropriate property name",
876 0 : static_cast< cppu::OWeakObject * >(this), -1);
877 : }
878 : }
879 0 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
880 : }
881 0 : bc.send();
882 0 : }
883 :
884 72868 : css::uno::Sequence< css::uno::Any > Access::getPropertyValues(
885 : css::uno::Sequence< OUString > const & aPropertyNames)
886 : throw (css::uno::RuntimeException, std::exception)
887 : {
888 : assert(thisIs(IS_GROUP));
889 72868 : osl::MutexGuard g(*lock_);
890 72868 : css::uno::Sequence< css::uno::Any > vals(aPropertyNames.getLength());
891 :
892 493808 : for (sal_Int32 i = 0; i < aPropertyNames.getLength(); ++i)
893 : {
894 420940 : if (!getByNameFast(aPropertyNames[i], vals[i]))
895 : throw css::uno::RuntimeException(
896 : "configmgr getPropertyValues inappropriate property name",
897 0 : static_cast< cppu::OWeakObject * >(this));
898 : }
899 :
900 72868 : return vals;
901 : }
902 :
903 0 : void Access::addPropertiesChangeListener(
904 : css::uno::Sequence< OUString > const &,
905 : css::uno::Reference< css::beans::XPropertiesChangeListener > const &
906 : xListener)
907 : throw (css::uno::RuntimeException, std::exception)
908 : {
909 : assert(thisIs(IS_GROUP));
910 : {
911 0 : osl::MutexGuard g(*lock_);
912 0 : if (!xListener.is()) {
913 : throw css::uno::RuntimeException(
914 0 : "null listener", static_cast< cppu::OWeakObject * >(this));
915 : }
916 0 : if (!disposed_) {
917 0 : propertiesChangeListeners_.insert(xListener);
918 0 : return;
919 0 : }
920 : }
921 : try {
922 0 : xListener->disposing(
923 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
924 0 : } catch (css::lang::DisposedException &) {}
925 : }
926 :
927 0 : void Access::removePropertiesChangeListener(
928 : css::uno::Reference< css::beans::XPropertiesChangeListener > const &
929 : xListener)
930 : throw (css::uno::RuntimeException, std::exception)
931 : {
932 : assert(thisIs(IS_GROUP));
933 0 : osl::MutexGuard g(*lock_);
934 : PropertiesChangeListeners::iterator i(
935 0 : propertiesChangeListeners_.find(xListener));
936 0 : if (i != propertiesChangeListeners_.end()) {
937 0 : propertiesChangeListeners_.erase(i);
938 0 : }
939 0 : }
940 :
941 0 : void Access::firePropertiesChangeEvent(
942 : css::uno::Sequence< OUString > const & aPropertyNames,
943 : css::uno::Reference< css::beans::XPropertiesChangeListener > const &
944 : xListener)
945 : throw (css::uno::RuntimeException, std::exception)
946 : {
947 : assert(thisIs(IS_GROUP));
948 : css::uno::Sequence< css::beans::PropertyChangeEvent > events(
949 0 : aPropertyNames.getLength());
950 0 : for (sal_Int32 i = 0; i < events.getLength(); ++i) {
951 0 : events[i].Source = static_cast< cppu::OWeakObject * >(this);
952 0 : events[i].PropertyName = aPropertyNames[i];
953 0 : events[i].Further = false;
954 0 : events[i].PropertyHandle = -1;
955 : }
956 0 : xListener->propertiesChange(events);
957 0 : }
958 :
959 : css::uno::Reference< css::beans::XHierarchicalPropertySetInfo >
960 0 : Access::getHierarchicalPropertySetInfo() throw (css::uno::RuntimeException, std::exception) {
961 : assert(thisIs(IS_GROUP));
962 0 : return this;
963 : }
964 :
965 0 : void Access::setHierarchicalPropertyValue(
966 : OUString const & aHierarchicalPropertyName,
967 : css::uno::Any const & aValue)
968 : throw (
969 : css::beans::UnknownPropertyException, css::beans::PropertyVetoException,
970 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
971 : css::uno::RuntimeException, std::exception)
972 : {
973 : assert(thisIs(IS_GROUP));
974 0 : Broadcaster bc;
975 : {
976 0 : osl::MutexGuard g(*lock_);
977 0 : if (!getRootAccess()->isUpdate()) {
978 : throw css::uno::RuntimeException(
979 : "configmgr setHierarchicalPropertyName on non-update access",
980 0 : static_cast< cppu::OWeakObject * >(this));
981 : }
982 : rtl::Reference< ChildAccess > child(
983 0 : getSubChild(aHierarchicalPropertyName));
984 0 : if (!child.is()) {
985 : throw css::beans::UnknownPropertyException(
986 : aHierarchicalPropertyName,
987 0 : static_cast< cppu::OWeakObject * >(this));
988 : }
989 0 : child->checkFinalized();
990 0 : Modifications localMods;
991 0 : child->setProperty(aValue, &localMods);
992 0 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
993 : }
994 0 : bc.send();
995 0 : }
996 :
997 0 : css::uno::Any Access::getHierarchicalPropertyValue(
998 : OUString const & aHierarchicalPropertyName)
999 : throw (
1000 : css::beans::UnknownPropertyException,
1001 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1002 : css::uno::RuntimeException, std::exception)
1003 : {
1004 : assert(thisIs(IS_GROUP));
1005 0 : osl::MutexGuard g(*lock_);
1006 0 : rtl::Reference< ChildAccess > child(getSubChild(aHierarchicalPropertyName));
1007 0 : if (!child.is()) {
1008 : throw css::beans::UnknownPropertyException(
1009 : aHierarchicalPropertyName,
1010 0 : static_cast< cppu::OWeakObject * >(this));
1011 : }
1012 0 : return child->asValue();
1013 : }
1014 :
1015 0 : void Access::setHierarchicalPropertyValues(
1016 : css::uno::Sequence< OUString > const & aHierarchicalPropertyNames,
1017 : css::uno::Sequence< css::uno::Any > const & Values)
1018 : throw (
1019 : css::beans::PropertyVetoException, css::lang::IllegalArgumentException,
1020 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
1021 : {
1022 : assert(thisIs(IS_GROUP));
1023 0 : Broadcaster bc;
1024 : {
1025 0 : osl::MutexGuard g(*lock_);
1026 0 : if (!getRootAccess()->isUpdate()) {
1027 : throw css::uno::RuntimeException(
1028 : "configmgr setPropertyValues on non-update access",
1029 0 : static_cast< cppu::OWeakObject * >(this));
1030 : }
1031 0 : if (aHierarchicalPropertyNames.getLength() != Values.getLength()) {
1032 : throw css::lang::IllegalArgumentException(
1033 : ("configmgr setHierarchicalPropertyValues:"
1034 : " aHierarchicalPropertyNames/Values of different length"),
1035 0 : static_cast< cppu::OWeakObject * >(this), -1);
1036 : }
1037 0 : Modifications localMods;
1038 0 : for (sal_Int32 i = 0; i < aHierarchicalPropertyNames.getLength(); ++i) {
1039 : rtl::Reference< ChildAccess > child(
1040 0 : getSubChild(aHierarchicalPropertyNames[i]));
1041 0 : if (!child.is()) {
1042 : throw css::lang::IllegalArgumentException(
1043 : ("configmgr setHierarchicalPropertyValues inappropriate"
1044 : " property name"),
1045 0 : static_cast< cppu::OWeakObject * >(this), -1);
1046 : }
1047 0 : child->checkFinalized();
1048 0 : child->setProperty(Values[i], &localMods);
1049 0 : }
1050 0 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
1051 : }
1052 0 : bc.send();
1053 0 : }
1054 :
1055 0 : css::uno::Sequence< css::uno::Any > Access::getHierarchicalPropertyValues(
1056 : css::uno::Sequence< OUString > const & aHierarchicalPropertyNames)
1057 : throw (
1058 : css::lang::IllegalArgumentException, css::lang::WrappedTargetException,
1059 : css::uno::RuntimeException, std::exception)
1060 : {
1061 : assert(thisIs(IS_GROUP));
1062 0 : osl::MutexGuard g(*lock_);
1063 : css::uno::Sequence< css::uno::Any > vals(
1064 0 : aHierarchicalPropertyNames.getLength());
1065 0 : for (sal_Int32 i = 0; i < aHierarchicalPropertyNames.getLength(); ++i) {
1066 : rtl::Reference< ChildAccess > child(
1067 0 : getSubChild(aHierarchicalPropertyNames[i]));
1068 0 : if (!child.is()) {
1069 : throw css::lang::IllegalArgumentException(
1070 : ("configmgr getHierarchicalPropertyValues inappropriate"
1071 : " hierarchical property name"),
1072 0 : static_cast< cppu::OWeakObject * >(this), -1);
1073 : }
1074 0 : vals[i] = child->asValue();
1075 0 : }
1076 0 : return vals;
1077 : }
1078 :
1079 0 : css::beans::Property Access::getPropertyByHierarchicalName(
1080 : OUString const & aHierarchicalName)
1081 : throw (css::beans::UnknownPropertyException, css::uno::RuntimeException, std::exception)
1082 : {
1083 : assert(thisIs(IS_GROUP));
1084 0 : osl::MutexGuard g(*lock_);
1085 0 : rtl::Reference< ChildAccess > child(getSubChild(aHierarchicalName));
1086 0 : if (!child.is()) {
1087 : throw css::beans::UnknownPropertyException(
1088 0 : aHierarchicalName, static_cast< cppu::OWeakObject * >(this));
1089 : }
1090 0 : return child->asProperty();
1091 : }
1092 :
1093 0 : sal_Bool Access::hasPropertyByHierarchicalName(
1094 : OUString const & aHierarchicalName)
1095 : throw (css::uno::RuntimeException, std::exception)
1096 : {
1097 : assert(thisIs(IS_GROUP));
1098 0 : osl::MutexGuard g(*lock_);
1099 0 : return getSubChild(aHierarchicalName).is();
1100 : }
1101 :
1102 24287 : void Access::replaceByName(
1103 : OUString const & aName, css::uno::Any const & aElement)
1104 : throw (
1105 : css::lang::IllegalArgumentException,
1106 : css::container::NoSuchElementException,
1107 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
1108 : {
1109 : assert(thisIs(IS_UPDATE));
1110 24287 : Broadcaster bc;
1111 : {
1112 24287 : osl::MutexGuard g(*lock_);
1113 24287 : checkLocalizedPropertyAccess();
1114 48574 : rtl::Reference< ChildAccess > child(getChild(aName));
1115 24287 : if (!child.is()) {
1116 : throw css::container::NoSuchElementException(
1117 0 : aName, static_cast< cppu::OWeakObject * >(this));
1118 : }
1119 24287 : child->checkFinalized();
1120 48574 : Modifications localMods;
1121 24287 : switch (getNode()->kind()) {
1122 : case Node::KIND_LOCALIZED_PROPERTY:
1123 : case Node::KIND_GROUP:
1124 24287 : child->setProperty(aElement, &localMods);
1125 24284 : break;
1126 : case Node::KIND_SET:
1127 : {
1128 : rtl::Reference< ChildAccess > freeAcc(
1129 0 : getFreeSetMember(aElement));
1130 0 : rtl::Reference< RootAccess > root(getRootAccess());
1131 0 : localMods.add(child->getRelativePath());
1132 0 : child->unbind(); // must not throw
1133 0 : freeAcc->bind(root, this, aName); // must not throw
1134 0 : markChildAsModified(freeAcc); //TODO: must not throw
1135 : }
1136 0 : break;
1137 : default:
1138 : assert(false); // this cannot happen
1139 0 : break;
1140 : }
1141 48571 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
1142 : }
1143 24287 : bc.send();
1144 24284 : }
1145 :
1146 4363 : void Access::insertByName(
1147 : OUString const & aName, css::uno::Any const & aElement)
1148 : throw (
1149 : css::lang::IllegalArgumentException,
1150 : css::container::ElementExistException,
1151 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
1152 : {
1153 : assert(thisIs(IS_EXTENSIBLE|IS_UPDATE));
1154 4363 : Broadcaster bc;
1155 : {
1156 4363 : osl::MutexGuard g(*lock_);
1157 4363 : checkLocalizedPropertyAccess();
1158 4363 : checkFinalized();
1159 4363 : if (getChild(aName).is()) {
1160 : throw css::container::ElementExistException(
1161 3 : aName, static_cast< cppu::OWeakObject * >(this));
1162 : }
1163 8720 : Modifications localMods;
1164 4360 : switch (getNode()->kind()) {
1165 : case Node::KIND_LOCALIZED_PROPERTY:
1166 0 : insertLocalizedValueChild(aName, aElement, &localMods);
1167 0 : break;
1168 : case Node::KIND_GROUP:
1169 : {
1170 1239 : checkValue(aElement, TYPE_ANY, true);
1171 : rtl::Reference< ChildAccess > child(
1172 : new ChildAccess(
1173 1239 : components_, getRootAccess(), this, aName,
1174 : new PropertyNode(
1175 1239 : Data::NO_LAYER, TYPE_ANY, true, aElement, true)));
1176 1239 : markChildAsModified(child);
1177 1239 : localMods.add(child->getRelativePath());
1178 : }
1179 1239 : break;
1180 : case Node::KIND_SET:
1181 : {
1182 : rtl::Reference< ChildAccess > freeAcc(
1183 3121 : getFreeSetMember(aElement));
1184 3121 : freeAcc->bind(getRootAccess(), this, aName); // must not throw
1185 3121 : markChildAsModified(freeAcc); //TODO: must not throw
1186 3121 : localMods.add(freeAcc->getRelativePath());
1187 : }
1188 3121 : break;
1189 : default:
1190 : assert(false); // this cannot happen
1191 0 : break;
1192 : }
1193 8723 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
1194 : }
1195 4363 : bc.send();
1196 4360 : }
1197 :
1198 1373 : void Access::removeByName(OUString const & aName)
1199 : throw (
1200 : css::container::NoSuchElementException,
1201 : css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception)
1202 : {
1203 : assert(thisIs(IS_EXTENSIBLE|IS_UPDATE));
1204 1373 : Broadcaster bc;
1205 : {
1206 1373 : osl::MutexGuard g(*lock_);
1207 1373 : checkLocalizedPropertyAccess();
1208 2746 : rtl::Reference< ChildAccess > child(getChild(aName));
1209 5477 : if (!child.is() || child->isFinalized() ||
1210 5447 : child->getNode()->getMandatory() != Data::NO_LAYER)
1211 : {
1212 : throw css::container::NoSuchElementException(
1213 15 : aName, static_cast< cppu::OWeakObject * >(this));
1214 : }
1215 1358 : if (getNode()->kind() == Node::KIND_GROUP) {
1216 0 : rtl::Reference< Node > p(child->getNode());
1217 0 : if (p->kind() != Node::KIND_PROPERTY ||
1218 0 : !static_cast< PropertyNode * >(p.get())->isExtension())
1219 : {
1220 : throw css::container::NoSuchElementException(
1221 0 : aName, static_cast< cppu::OWeakObject * >(this));
1222 0 : }
1223 : }
1224 2716 : Modifications localMods;
1225 1358 : localMods.add(child->getRelativePath());
1226 : // unbind() modifies the parent chain that markChildAsModified() walks,
1227 : // so order is important:
1228 1358 : markChildAsModified(child); //TODO: must not throw
1229 1358 : child->unbind();
1230 2731 : getNotificationRoot()->initBroadcaster(localMods.getRoot(), &bc);
1231 : }
1232 1373 : bc.send();
1233 1358 : }
1234 :
1235 3121 : css::uno::Reference< css::uno::XInterface > Access::createInstance()
1236 : throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
1237 : {
1238 : assert(thisIs(IS_SET|IS_UPDATE));
1239 : OUString tmplName(
1240 3121 : static_cast< SetNode * >(getNode().get())->getDefaultTemplateName());
1241 : rtl::Reference< Node > tmpl(
1242 6242 : components_.getTemplate(Data::NO_LAYER, tmplName));
1243 3121 : if (!tmpl.is()) {
1244 : throw css::uno::Exception(
1245 0 : "unknown template " + tmplName,
1246 0 : static_cast< cppu::OWeakObject * >(this));
1247 : }
1248 6242 : rtl::Reference< Node > node(tmpl->clone(true));
1249 3121 : node->setLayer(Data::NO_LAYER);
1250 : return static_cast< cppu::OWeakObject * >(
1251 6242 : new ChildAccess(components_, getRootAccess(), node));
1252 : }
1253 :
1254 0 : css::uno::Reference< css::uno::XInterface > Access::createInstanceWithArguments(
1255 : css::uno::Sequence< css::uno::Any > const & aArguments)
1256 : throw (css::uno::Exception, css::uno::RuntimeException, std::exception)
1257 : {
1258 : assert(thisIs(IS_SET|IS_UPDATE));
1259 0 : if (aArguments.getLength() != 0) {
1260 : throw css::uno::Exception(
1261 : ("configuration SimpleSetUpdate createInstanceWithArguments"
1262 : " must not specify any arguments"),
1263 0 : static_cast< cppu::OWeakObject * >(this));
1264 : }
1265 0 : return createInstance();
1266 : }
1267 :
1268 88338089 : Access::Access(Components & components):
1269 88338089 : components_(components), disposed_(false)
1270 : {
1271 88338089 : lock_ = lock();
1272 88338089 : }
1273 :
1274 88335917 : Access::~Access() {}
1275 :
1276 121 : void Access::initDisposeBroadcaster(Broadcaster * broadcaster) {
1277 : assert(broadcaster != 0);
1278 363 : for (DisposeListeners::iterator i(disposeListeners_.begin());
1279 242 : i != disposeListeners_.end(); ++i)
1280 : {
1281 : broadcaster->addDisposeNotification(
1282 0 : *i,
1283 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
1284 : }
1285 363 : for (ContainerListeners::iterator i(containerListeners_.begin());
1286 242 : i != containerListeners_.end(); ++i)
1287 : {
1288 : broadcaster->addDisposeNotification(
1289 0 : i->get(),
1290 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
1291 : }
1292 369 : for (PropertyChangeListeners::iterator i(propertyChangeListeners_.begin());
1293 246 : i != propertyChangeListeners_.end(); ++i)
1294 : {
1295 12 : for (PropertyChangeListenersElement::iterator j(i->second.begin());
1296 8 : j != i->second.end(); ++j)
1297 : {
1298 : broadcaster->addDisposeNotification(
1299 2 : j->get(),
1300 : css::lang::EventObject(
1301 4 : static_cast< cppu::OWeakObject * >(this)));
1302 : }
1303 : }
1304 363 : for (VetoableChangeListeners::iterator i(vetoableChangeListeners_.begin());
1305 242 : i != vetoableChangeListeners_.end(); ++i)
1306 : {
1307 0 : for (VetoableChangeListenersElement::iterator j(i->second.begin());
1308 0 : j != i->second.end(); ++j)
1309 : {
1310 : broadcaster->addDisposeNotification(
1311 0 : j->get(),
1312 : css::lang::EventObject(
1313 0 : static_cast< cppu::OWeakObject * >(this)));
1314 : }
1315 : }
1316 363 : for (PropertiesChangeListeners::iterator i(
1317 121 : propertiesChangeListeners_.begin());
1318 242 : i != propertiesChangeListeners_.end(); ++i)
1319 : {
1320 : broadcaster->addDisposeNotification(
1321 0 : i->get(),
1322 0 : css::lang::EventObject(static_cast< cppu::OWeakObject * >(this)));
1323 : }
1324 : //TODO: iterate over children w/ listeners (incl. unmodified ones):
1325 363 : for (ModifiedChildren::iterator i(modifiedChildren_.begin());
1326 242 : i != modifiedChildren_.end(); ++i)
1327 : {
1328 0 : rtl::Reference< ChildAccess > child(getModifiedChild(i));
1329 0 : if (child.is()) {
1330 0 : child->initDisposeBroadcaster(broadcaster);
1331 : }
1332 0 : }
1333 121 : }
1334 :
1335 121 : void Access::clearListeners() throw() {
1336 121 : disposeListeners_.clear();
1337 121 : containerListeners_.clear();
1338 121 : propertyChangeListeners_.clear();
1339 121 : vetoableChangeListeners_.clear();
1340 121 : propertiesChangeListeners_.clear();
1341 : //TODO: iterate over children w/ listeners (incl. unmodified ones):
1342 363 : for (ModifiedChildren::iterator i(modifiedChildren_.begin());
1343 242 : i != modifiedChildren_.end(); ++i)
1344 : {
1345 0 : rtl::Reference< ChildAccess > child(getModifiedChild(i));
1346 0 : if (child.is()) {
1347 0 : child->clearListeners();
1348 : }
1349 0 : }
1350 121 : }
1351 :
1352 108327448 : css::uno::Any Access::queryInterface(css::uno::Type const & aType)
1353 : throw (css::uno::RuntimeException, std::exception)
1354 : {
1355 108327448 : css::uno::Any res(OWeakObject::queryInterface(aType));
1356 108327448 : if (res.hasValue()) {
1357 24612 : return res;
1358 : }
1359 216605672 : res = cppu::queryInterface(
1360 : aType, static_cast< css::lang::XTypeProvider * >(this),
1361 : static_cast< css::lang::XServiceInfo * >(this),
1362 : static_cast< css::lang::XComponent * >(this),
1363 : static_cast< css::container::XHierarchicalNameAccess * >(this),
1364 : static_cast< css::container::XContainer * >(this),
1365 : static_cast< css::beans::XExactName * >(this),
1366 : static_cast< css::container::XHierarchicalName * >(this),
1367 : static_cast< css::container::XNamed * >(this),
1368 : static_cast< css::beans::XProperty * >(this),
1369 : static_cast< css::container::XElementAccess * >(this),
1370 108302836 : static_cast< css::container::XNameAccess * >(this));
1371 108302836 : if (res.hasValue()) {
1372 81096602 : return res;
1373 : }
1374 27206234 : if (getNode()->kind() == Node::KIND_GROUP) {
1375 54341490 : res = cppu::queryInterface(
1376 : aType, static_cast< css::beans::XPropertySetInfo * >(this),
1377 : static_cast< css::beans::XPropertySet * >(this),
1378 : static_cast< css::beans::XMultiPropertySet * >(this),
1379 : static_cast< css::beans::XHierarchicalPropertySet * >(this),
1380 : static_cast< css::beans::XMultiHierarchicalPropertySet * >(this),
1381 27170745 : static_cast< css::beans::XHierarchicalPropertySetInfo * >(this));
1382 27170745 : if (res.hasValue()) {
1383 335056 : return res;
1384 : }
1385 : }
1386 26871178 : if (getRootAccess()->isUpdate()) {
1387 53701370 : res = cppu::queryInterface(
1388 : aType, static_cast< css::container::XNameReplace * >(this),
1389 26850685 : static_cast< css::container::XHierarchicalNameReplace * >(this));
1390 26850685 : if (res.hasValue()) {
1391 4698 : return res;
1392 : }
1393 107334216 : if (getNode()->kind() != Node::KIND_GROUP ||
1394 80488229 : static_cast< GroupNode * >(getNode().get())->isExtensible())
1395 : {
1396 92080 : res = cppu::queryInterface(
1397 46040 : aType, static_cast< css::container::XNameContainer * >(this));
1398 46040 : if (res.hasValue()) {
1399 35577 : return res;
1400 : }
1401 : }
1402 26810410 : if (getNode()->kind() == Node::KIND_SET) {
1403 19676 : res = cppu::queryInterface(
1404 9838 : aType, static_cast< css::lang::XSingleServiceFactory * >(this));
1405 : }
1406 : }
1407 26830903 : return res;
1408 : }
1409 :
1410 :
1411 193736170 : void Access::checkLocalizedPropertyAccess() {
1412 388132356 : if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY &&
1413 194396186 : !Components::allLocales(getRootAccess()->getLocale()))
1414 : {
1415 : throw css::uno::RuntimeException(
1416 : "configmgr Access to specialized LocalizedPropertyNode",
1417 0 : static_cast< cppu::OWeakObject * >(this));
1418 : }
1419 193736170 : }
1420 :
1421 37413 : rtl::Reference< Node > Access::getParentNode() {
1422 37413 : rtl::Reference< Access > parent(getParentAccess());
1423 37413 : return parent.is() ? parent->getNode() : rtl::Reference< Node >();
1424 : }
1425 :
1426 61975356 : rtl::Reference< ChildAccess > Access::getChild(OUString const & name) {
1427 61975356 : OUString locale;
1428 185926068 : if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY
1429 185926068 : && name.startsWith("*", &locale))
1430 : {
1431 187558 : if (locale.startsWith("*")) {
1432 : SAL_WARN(
1433 : "configmgr",
1434 : ("access best-matching localized property value via"
1435 : " \"*<locale>\" with <locale> \"")
1436 : << locale << "\" recursively starting with \"*\"");
1437 0 : return getChild(locale);
1438 : }
1439 : SAL_WARN_IF(
1440 : locale.isEmpty(), "configmgr",
1441 : ("access best-matching localized property value via \"*<locale>\""
1442 : " with empty <locale>; falling back to defaults"));
1443 187558 : if (!locale.isEmpty()) {
1444 : // Find best match using an adaption of RFC 4647 lookup matching
1445 : // rules, removing "-" or "_" delimited segments from the end:
1446 : for (;;) {
1447 263852 : rtl::Reference< ChildAccess > child(getChild(locale));
1448 263852 : if (child.is()) {
1449 111042 : return child;
1450 : }
1451 152810 : sal_Int32 i = locale.getLength() - 1;
1452 534835 : while (i > 0 && locale[i] != '-' && locale[i] != '_') {
1453 229215 : --i;
1454 : }
1455 152810 : if (i <= 0) {
1456 76405 : break;
1457 : }
1458 76405 : locale = locale.copy(0, i);
1459 76405 : }
1460 : // As a workaround for broken xcu data that does not use shortest
1461 : // xml:lang attributes, look for the first entry with the same first
1462 : // segment as the requested language tag before falling back to
1463 : // defaults (see fdo#33638):
1464 : assert(
1465 : !locale.isEmpty() && locale.indexOf('-') == -1 &&
1466 : locale.indexOf('_') == -1);
1467 : std::vector< rtl::Reference< ChildAccess > > children(
1468 76405 : getAllChildren());
1469 199088 : for (std::vector< rtl::Reference< ChildAccess > >::iterator i(
1470 76405 : children.begin());
1471 183662 : i != children.end(); ++i)
1472 : {
1473 15426 : OUString name2((*i)->getNameInternal());
1474 15426 : if (name2.startsWith(locale) &&
1475 0 : (name2.getLength() == locale.getLength() ||
1476 0 : name2[locale.getLength()] == '-' ||
1477 0 : name2[locale.getLength()] == '_'))
1478 : {
1479 0 : return *i;
1480 : }
1481 91831 : }
1482 : }
1483 : // Defaults are the "en-US" locale, the "en" locale, the empty string
1484 : // locale, the first child (if any), or a null ChildAccess, in that
1485 : // order:
1486 76516 : rtl::Reference< ChildAccess > child(getChild("en-US"));
1487 76516 : if (child.is()) {
1488 111 : return child;
1489 : }
1490 76405 : child = getChild("en");
1491 76405 : if (child.is()) {
1492 0 : return child;
1493 : }
1494 76405 : child = getChild("");
1495 76405 : if (child.is()) {
1496 15426 : return child;
1497 : }
1498 121958 : std::vector< rtl::Reference< ChildAccess > > children(getAllChildren());
1499 60979 : if (!children.empty()) {
1500 0 : return children.front();
1501 : }
1502 137495 : return rtl::Reference< ChildAccess >();
1503 : }
1504 61787798 : ModifiedChildren::iterator i(modifiedChildren_.find(name));
1505 123575596 : return i == modifiedChildren_.end()
1506 123763154 : ? getUnmodifiedChild(name) : getModifiedChild(i);
1507 : }
1508 :
1509 27061070 : std::vector< rtl::Reference< ChildAccess > > Access::getAllChildren() {
1510 27061070 : std::vector< rtl::Reference< ChildAccess > > vec;
1511 27061070 : NodeMap const & members = getNode()->getMembers();
1512 28198302 : for (NodeMap::const_iterator i(members.begin()); i != members.end(); ++i) {
1513 1137232 : if (modifiedChildren_.find(i->first) == modifiedChildren_.end()) {
1514 1137232 : vec.push_back(getUnmodifiedChild(i->first));
1515 : assert(vec.back().is());
1516 : }
1517 : }
1518 81183210 : for (ModifiedChildren::iterator i(modifiedChildren_.begin());
1519 54122140 : i != modifiedChildren_.end(); ++i)
1520 : {
1521 0 : rtl::Reference< ChildAccess > child(getModifiedChild(i));
1522 0 : if (child.is()) {
1523 0 : vec.push_back(child);
1524 : }
1525 0 : }
1526 27061070 : return vec;
1527 : }
1528 :
1529 109495 : void Access::checkValue(css::uno::Any const & value, Type type, bool nillable) {
1530 : bool ok;
1531 109495 : switch (type) {
1532 : case TYPE_NIL:
1533 : assert(false);
1534 : // fall through (cannot happen)
1535 : case TYPE_ERROR:
1536 0 : ok = false;
1537 0 : break;
1538 : case TYPE_ANY:
1539 20612 : switch (getDynamicType(value)) {
1540 : case TYPE_ANY:
1541 : assert(false);
1542 : // fall through (cannot happen)
1543 : case TYPE_ERROR:
1544 0 : ok = false;
1545 0 : break;
1546 : case TYPE_NIL:
1547 0 : ok = nillable;
1548 0 : break;
1549 : default:
1550 20612 : ok = true;
1551 20612 : break;
1552 : }
1553 20612 : break;
1554 : default:
1555 88883 : ok = value.hasValue() ? value.isExtractableTo(mapType(type)) : nillable;
1556 88883 : break;
1557 : }
1558 109495 : if (!ok) {
1559 : throw css::lang::IllegalArgumentException(
1560 : "configmgr inappropriate property value",
1561 3 : static_cast< cppu::OWeakObject * >(this), -1);
1562 : }
1563 109492 : }
1564 :
1565 0 : void Access::insertLocalizedValueChild(
1566 : OUString const & name, css::uno::Any const & value,
1567 : Modifications * localModifications)
1568 : {
1569 : assert(localModifications != 0);
1570 : LocalizedPropertyNode * locprop = static_cast< LocalizedPropertyNode * >(
1571 0 : getNode().get());
1572 0 : checkValue(value, locprop->getStaticType(), locprop->isNillable());
1573 : rtl::Reference< ChildAccess > child(
1574 : new ChildAccess(
1575 0 : components_, getRootAccess(), this, name,
1576 0 : new LocalizedValueNode(Data::NO_LAYER, value)));
1577 0 : markChildAsModified(child);
1578 0 : localModifications->add(child->getRelativePath());
1579 0 : }
1580 :
1581 0 : void Access::reportChildChanges(
1582 : std::vector< css::util::ElementChange > * changes)
1583 : {
1584 : assert(changes != 0);
1585 0 : for (ModifiedChildren::iterator i(modifiedChildren_.begin());
1586 0 : i != modifiedChildren_.end(); ++i)
1587 : {
1588 0 : rtl::Reference< ChildAccess > child(getModifiedChild(i));
1589 0 : if (child.is()) {
1590 0 : child->reportChildChanges(changes);
1591 0 : changes->push_back(css::util::ElementChange());
1592 : //TODO: changed value and/or inserted node
1593 : } else {
1594 0 : changes->push_back(css::util::ElementChange()); //TODO: removed node
1595 : }
1596 0 : }
1597 0 : }
1598 :
1599 288749 : void Access::commitChildChanges(
1600 : bool valid, Modifications * globalModifications)
1601 : {
1602 : assert(globalModifications != 0);
1603 830130 : while (!modifiedChildren_.empty()) {
1604 252632 : bool childValid = valid;
1605 252632 : ModifiedChildren::iterator i(modifiedChildren_.begin());
1606 252632 : rtl::Reference< ChildAccess > child(getModifiedChild(i));
1607 252632 : if (child.is()) {
1608 251273 : childValid = childValid && !child->isFinalized();
1609 251273 : child->commitChanges(childValid, globalModifications);
1610 : //TODO: currently, this is called here for directly inserted
1611 : // children as well as for children whose sub-children were
1612 : // modified (and should never be called for directly removed
1613 : // children); clarify what exactly should happen here for
1614 : // directly inserted children
1615 : }
1616 252632 : NodeMap & members = getNode()->getMembers();
1617 252632 : NodeMap::iterator j(members.find(i->first));
1618 252632 : if (child.is()) {
1619 : // Inserted:
1620 251273 : if (j != members.end()) {
1621 493826 : childValid = childValid &&
1622 493826 : j->second->getFinalized() == Data::NO_LAYER;
1623 246913 : if (childValid) {
1624 246913 : child->getNode()->setMandatory(j->second->getMandatory());
1625 : }
1626 : }
1627 251273 : if (childValid) {
1628 251273 : members[i->first] = child->getNode();
1629 : }
1630 : } else {
1631 : // Removed:
1632 5436 : childValid = childValid && j != members.end() &&
1633 4077 : j->second->getFinalized() == Data::NO_LAYER &&
1634 2718 : j->second->getMandatory() == Data::NO_LAYER;
1635 1359 : if (childValid) {
1636 1359 : members.erase(j);
1637 : }
1638 : }
1639 252632 : if (childValid && i->second.directlyModified) {
1640 113973 : Path path(getAbsolutePath());
1641 113973 : path.push_back(i->first);
1642 113973 : components_.addModification(path);
1643 113973 : globalModifications->add(path);
1644 : }
1645 252632 : i->second.child->committed();
1646 252632 : modifiedChildren_.erase(i);
1647 252632 : }
1648 288749 : }
1649 :
1650 1134839 : void Access::initBroadcasterAndChanges(
1651 : Modifications::Node const & modifications, Broadcaster * broadcaster,
1652 : std::vector< css::util::ElementChange > * allChanges)
1653 : {
1654 : assert(broadcaster != 0);
1655 1134839 : std::vector< css::beans::PropertyChangeEvent > propChanges;
1656 1134839 : bool collectPropChanges = !propertiesChangeListeners_.empty();
1657 7223463 : for (Modifications::Node::Children::const_iterator i(
1658 1134839 : modifications.children.begin());
1659 4815642 : i != modifications.children.end(); ++i)
1660 : {
1661 1272982 : rtl::Reference< ChildAccess > child(getChild(i->first));
1662 1272982 : if (child.is()) {
1663 1268917 : switch (child->getNode()->kind()) {
1664 : case Node::KIND_LOCALIZED_PROPERTY:
1665 10645 : if (!i->second.children.empty()) {
1666 10645 : if (Components::allLocales(getRootAccess()->getLocale())) {
1667 1772 : child->initBroadcasterAndChanges(
1668 3544 : i->second, broadcaster, allChanges);
1669 : //TODO: if allChanges==0, recurse only into children
1670 : // w/ listeners
1671 : } else {
1672 : //TODO: filter child mods that are irrelevant for
1673 : // locale:
1674 26619 : for (ContainerListeners::iterator j(
1675 8873 : containerListeners_.begin());
1676 17746 : j != containerListeners_.end(); ++j)
1677 : {
1678 : broadcaster->
1679 : addContainerElementReplacedNotification(
1680 0 : *j,
1681 : css::container::ContainerEvent(
1682 : static_cast< cppu::OWeakObject * >(
1683 : this),
1684 0 : css::uno::makeAny(i->first),
1685 0 : css::uno::Any(), css::uno::Any()));
1686 : //TODO: non-void Element, ReplacedElement
1687 : }
1688 : PropertyChangeListeners::iterator j(
1689 8873 : propertyChangeListeners_.find(i->first));
1690 8873 : if (j != propertyChangeListeners_.end()) {
1691 672 : for (PropertyChangeListenersElement::iterator k(
1692 112 : j->second.begin());
1693 448 : k != j->second.end(); ++k)
1694 : {
1695 : broadcaster->addPropertyChangeNotification(
1696 112 : *k,
1697 : css::beans::PropertyChangeEvent(
1698 : static_cast< cppu::OWeakObject * >(
1699 : this),
1700 112 : i->first, false, -1, css::uno::Any(),
1701 336 : css::uno::Any()));
1702 : }
1703 : }
1704 8873 : j = propertyChangeListeners_.find("");
1705 8873 : if (j != propertyChangeListeners_.end()) {
1706 0 : for (PropertyChangeListenersElement::iterator k(
1707 0 : j->second.begin());
1708 0 : k != j->second.end(); ++k)
1709 : {
1710 : broadcaster->addPropertyChangeNotification(
1711 0 : *k,
1712 : css::beans::PropertyChangeEvent(
1713 : static_cast< cppu::OWeakObject * >(
1714 : this),
1715 0 : i->first, false, -1, css::uno::Any(),
1716 0 : css::uno::Any()));
1717 : }
1718 : }
1719 8873 : if (allChanges != 0) {
1720 : allChanges->push_back(
1721 : css::util::ElementChange(
1722 : css::uno::makeAny(
1723 0 : child->getRelativePathRepresentation()),
1724 0 : css::uno::Any(), css::uno::Any()));
1725 : //TODO: non-void Element, ReplacedElement
1726 : }
1727 8873 : if (collectPropChanges) {
1728 : propChanges.push_back(
1729 : css::beans::PropertyChangeEvent(
1730 : static_cast< cppu::OWeakObject * >(this),
1731 0 : i->first, false, -1, css::uno::Any(),
1732 0 : css::uno::Any()));
1733 : }
1734 : }
1735 : }
1736 : // else: spurious Modifications::Node not representing a change
1737 10645 : break;
1738 : case Node::KIND_LOCALIZED_VALUE:
1739 : assert(Components::allLocales(getRootAccess()->getLocale()));
1740 5316 : for (ContainerListeners::iterator j(
1741 1772 : containerListeners_.begin());
1742 3544 : j != containerListeners_.end(); ++j)
1743 : {
1744 : broadcaster->addContainerElementReplacedNotification(
1745 0 : *j,
1746 : css::container::ContainerEvent(
1747 : static_cast< cppu::OWeakObject * >(this),
1748 0 : css::uno::makeAny(i->first), child->asValue(),
1749 0 : css::uno::Any()));
1750 : //TODO: distinguish add/modify; non-void ReplacedElement
1751 : }
1752 1772 : if (allChanges != 0) {
1753 : allChanges->push_back(
1754 : css::util::ElementChange(
1755 : css::uno::makeAny(
1756 0 : child->getRelativePathRepresentation()),
1757 0 : child->asValue(), css::uno::Any()));
1758 : //TODO: non-void ReplacedElement
1759 : }
1760 : assert(!collectPropChanges);
1761 1772 : break;
1762 : case Node::KIND_PROPERTY:
1763 : {
1764 1180488 : for (ContainerListeners::iterator j(
1765 393496 : containerListeners_.begin());
1766 786992 : j != containerListeners_.end(); ++j)
1767 : {
1768 : broadcaster->addContainerElementReplacedNotification(
1769 0 : *j,
1770 : css::container::ContainerEvent(
1771 : static_cast< cppu::OWeakObject * >(this),
1772 0 : css::uno::makeAny(i->first), child->asValue(),
1773 0 : css::uno::Any()));
1774 : //TODO: distinguish add/remove/modify; non-void
1775 : // ReplacedElement
1776 : }
1777 : PropertyChangeListeners::iterator j(
1778 393496 : propertyChangeListeners_.find(i->first));
1779 393496 : if (j != propertyChangeListeners_.end()) {
1780 0 : for (PropertyChangeListenersElement::iterator k(
1781 0 : j->second.begin());
1782 0 : k != j->second.end(); ++k)
1783 : {
1784 : broadcaster->addPropertyChangeNotification(
1785 0 : *k,
1786 : css::beans::PropertyChangeEvent(
1787 : static_cast< cppu::OWeakObject * >(this),
1788 0 : i->first, false, -1, css::uno::Any(),
1789 0 : css::uno::Any()));
1790 : }
1791 : }
1792 393496 : j = propertyChangeListeners_.find("");
1793 393496 : if (j != propertyChangeListeners_.end()) {
1794 0 : for (PropertyChangeListenersElement::iterator k(
1795 0 : j->second.begin());
1796 0 : k != j->second.end(); ++k)
1797 : {
1798 : broadcaster->addPropertyChangeNotification(
1799 0 : *k,
1800 : css::beans::PropertyChangeEvent(
1801 : static_cast< cppu::OWeakObject * >(this),
1802 0 : i->first, false, -1, css::uno::Any(),
1803 0 : css::uno::Any()));
1804 : }
1805 : }
1806 393496 : if (allChanges != 0) {
1807 : allChanges->push_back(
1808 : css::util::ElementChange(
1809 : css::uno::makeAny(
1810 10104 : child->getRelativePathRepresentation()),
1811 20208 : child->asValue(), css::uno::Any()));
1812 : //TODO: non-void ReplacedElement
1813 : }
1814 393496 : if (collectPropChanges) {
1815 : propChanges.push_back(
1816 : css::beans::PropertyChangeEvent(
1817 : static_cast< cppu::OWeakObject * >(this),
1818 0 : i->first, false, -1, css::uno::Any(),
1819 0 : css::uno::Any()));
1820 : }
1821 : }
1822 393496 : break;
1823 : case Node::KIND_GROUP:
1824 : case Node::KIND_SET:
1825 863004 : if (i->second.children.empty()) {
1826 10964 : if (!child->getNode()->getTemplateName().isEmpty()) {
1827 32892 : for (ContainerListeners::iterator j(
1828 10964 : containerListeners_.begin());
1829 21928 : j != containerListeners_.end(); ++j)
1830 : {
1831 : broadcaster->
1832 : addContainerElementInsertedNotification(
1833 0 : *j,
1834 : css::container::ContainerEvent(
1835 : static_cast< cppu::OWeakObject * >(
1836 : this),
1837 0 : css::uno::makeAny(i->first),
1838 0 : child->asValue(), css::uno::Any()));
1839 : }
1840 10964 : if (allChanges != 0) {
1841 : allChanges->push_back(
1842 : css::util::ElementChange(
1843 : css::uno::makeAny(
1844 50 : child->getRelativePathRepresentation()),
1845 100 : css::uno::Any(), css::uno::Any()));
1846 : //TODO: non-void Element, ReplacedElement
1847 : }
1848 : }
1849 : // else: spurious Modifications::Node not representing a
1850 : // change
1851 : } else {
1852 852040 : child->initBroadcasterAndChanges(
1853 1704080 : i->second, broadcaster, allChanges);
1854 : //TODO: if allChanges==0, recurse only into children w/
1855 : // listeners
1856 : }
1857 863004 : break;
1858 : case Node::KIND_ROOT:
1859 : assert(false); // this cannot happen
1860 0 : break;
1861 : }
1862 : } else {
1863 4065 : switch (getNode()->kind()) {
1864 : case Node::KIND_LOCALIZED_PROPERTY:
1865 : // Removed localized property value:
1866 : assert(Components::allLocales(getRootAccess()->getLocale()));
1867 0 : for (ContainerListeners::iterator j(
1868 0 : containerListeners_.begin());
1869 0 : j != containerListeners_.end(); ++j)
1870 : {
1871 : broadcaster->addContainerElementRemovedNotification(
1872 0 : *j,
1873 : css::container::ContainerEvent(
1874 : static_cast< cppu::OWeakObject * >(this),
1875 0 : css::uno::makeAny(i->first), css::uno::Any(),
1876 0 : css::uno::Any()));
1877 : //TODO: non-void ReplacedElement
1878 : }
1879 0 : if (allChanges != 0) {
1880 0 : OUStringBuffer path(getRelativePathRepresentation());
1881 0 : if (!path.isEmpty()) {
1882 0 : path.append('/');
1883 : }
1884 0 : path.append(Data::createSegment("*", i->first));
1885 : allChanges->push_back(
1886 : css::util::ElementChange(
1887 : css::uno::makeAny(path.makeStringAndClear()),
1888 0 : css::uno::Any(), css::uno::Any()));
1889 : //TODO: non-void ReplacedElement
1890 : }
1891 : assert(!collectPropChanges);
1892 0 : break;
1893 : case Node::KIND_GROUP:
1894 : {
1895 : // Removed (non-localized) extension property:
1896 0 : for (ContainerListeners::iterator j(
1897 0 : containerListeners_.begin());
1898 0 : j != containerListeners_.end(); ++j)
1899 : {
1900 : broadcaster->addContainerElementRemovedNotification(
1901 0 : *j,
1902 : css::container::ContainerEvent(
1903 : static_cast< cppu::OWeakObject * >(this),
1904 0 : css::uno::makeAny(i->first), css::uno::Any(),
1905 0 : css::uno::Any()));
1906 : //TODO: non-void ReplacedElement
1907 : }
1908 : PropertyChangeListeners::iterator j(
1909 0 : propertyChangeListeners_.find(i->first));
1910 0 : if (j != propertyChangeListeners_.end()) {
1911 0 : for (PropertyChangeListenersElement::iterator k(
1912 0 : j->second.begin());
1913 0 : k != j->second.end(); ++k)
1914 : {
1915 : broadcaster->addPropertyChangeNotification(
1916 0 : *k,
1917 : css::beans::PropertyChangeEvent(
1918 : static_cast< cppu::OWeakObject * >(this),
1919 0 : i->first, false, -1, css::uno::Any(),
1920 0 : css::uno::Any()));
1921 : }
1922 : }
1923 0 : j = propertyChangeListeners_.find("");
1924 0 : if (j != propertyChangeListeners_.end()) {
1925 0 : for (PropertyChangeListenersElement::iterator k(
1926 0 : j->second.begin());
1927 0 : k != j->second.end(); ++k)
1928 : {
1929 : broadcaster->addPropertyChangeNotification(
1930 0 : *k,
1931 : css::beans::PropertyChangeEvent(
1932 : static_cast< cppu::OWeakObject * >(this),
1933 0 : i->first, false, -1, css::uno::Any(),
1934 0 : css::uno::Any()));
1935 : }
1936 : }
1937 0 : if (allChanges != 0) {
1938 : OUStringBuffer path(
1939 0 : getRelativePathRepresentation());
1940 0 : if (!path.isEmpty()) {
1941 0 : path.append('/');
1942 : }
1943 0 : path.append(i->first);
1944 : allChanges->push_back(
1945 : css::util::ElementChange(
1946 : css::uno::makeAny(path.makeStringAndClear()),
1947 0 : css::uno::Any(), css::uno::Any()));
1948 : //TODO: non-void ReplacedElement
1949 : }
1950 0 : if (collectPropChanges) {
1951 : propChanges.push_back(
1952 : css::beans::PropertyChangeEvent(
1953 : static_cast< cppu::OWeakObject * >(this),
1954 0 : i->first, false, -1, css::uno::Any(),
1955 0 : css::uno::Any()));
1956 : }
1957 : }
1958 0 : break;
1959 : case Node::KIND_SET:
1960 : // Removed set member:
1961 4065 : if (i->second.children.empty()) {
1962 12195 : for (ContainerListeners::iterator j(
1963 4065 : containerListeners_.begin());
1964 8130 : j != containerListeners_.end(); ++j)
1965 : {
1966 : broadcaster->addContainerElementRemovedNotification(
1967 0 : *j,
1968 : css::container::ContainerEvent(
1969 : static_cast< cppu::OWeakObject * >(this),
1970 0 : css::uno::makeAny(i->first),
1971 0 : css::uno::Any(), css::uno::Any()));
1972 : //TODO: non-void ReplacedElement
1973 : }
1974 4065 : if (allChanges != 0) {
1975 : OUStringBuffer path(
1976 50 : getRelativePathRepresentation());
1977 50 : if (!path.isEmpty()) {
1978 50 : path.append('/');
1979 : }
1980 50 : path.append(Data::createSegment("*", i->first));
1981 : allChanges->push_back(
1982 : css::util::ElementChange(
1983 : css::uno::makeAny(path.makeStringAndClear()),
1984 50 : css::uno::Any(), css::uno::Any()));
1985 : //TODO: non-void ReplacedElement
1986 : }
1987 : }
1988 : // else: spurious Modifications::Node not representing a change
1989 4065 : break;
1990 : default:
1991 : assert(false); // this cannot happen
1992 0 : break;
1993 : }
1994 : }
1995 1272982 : }
1996 1134839 : if (!propChanges.empty()) {
1997 : css::uno::Sequence< css::beans::PropertyChangeEvent > seq(
1998 0 : comphelper::containerToSequence(propChanges));
1999 0 : for (PropertiesChangeListeners::iterator i(
2000 0 : propertiesChangeListeners_.begin());
2001 0 : i != propertiesChangeListeners_.end(); ++i)
2002 : {
2003 0 : broadcaster->addPropertiesChangeNotification(*i, seq);
2004 0 : }
2005 1134839 : }
2006 1134839 : }
2007 :
2008 :
2009 113973 : Access::ModifiedChild::ModifiedChild():
2010 113973 : directlyModified(false)
2011 113973 : {}
2012 :
2013 383358 : Access::ModifiedChild::ModifiedChild(
2014 : rtl::Reference< ChildAccess > const & theChild, bool theDirectlyModified):
2015 383358 : child(theChild), directlyModified(theDirectlyModified)
2016 383358 : {}
2017 :
2018 637173 : rtl::Reference< ChildAccess > Access::getModifiedChild(
2019 : ModifiedChildren::iterator const & childIterator)
2020 : {
2021 3817606 : return (childIterator->second.child->getParentAccess() == this &&
2022 1906087 : (childIterator->second.child->getNameInternal() ==
2023 634457 : childIterator->first))
2024 3183147 : ? childIterator->second.child : rtl::Reference< ChildAccess >();
2025 : }
2026 :
2027 61506983 : rtl::Reference< ChildAccess > Access::createUnmodifiedChild(
2028 : const OUString &name, const rtl::Reference< Node > &node)
2029 : {
2030 : rtl::Reference< ChildAccess > child(
2031 61506983 : new ChildAccess(components_, getRootAccess(), this, name, node));
2032 61506983 : cachedChildren_[name] = child.get();
2033 61506983 : return child;
2034 : }
2035 :
2036 62541106 : rtl::Reference< ChildAccess > Access::getUnmodifiedChild(
2037 : OUString const & name)
2038 : {
2039 : assert(modifiedChildren_.find(name) == modifiedChildren_.end());
2040 62541106 : rtl::Reference< Node > node(getNode()->getMember(name));
2041 62541106 : if (!node.is()) {
2042 951081 : return rtl::Reference< ChildAccess >();
2043 : }
2044 61590025 : WeakChildMap::iterator i(cachedChildren_.find(name));
2045 61590025 : if (i != cachedChildren_.end()) {
2046 83042 : rtl::Reference< ChildAccess > child;
2047 83042 : if (i->second->acquireCounting() > 1) {
2048 83042 : child.set(i->second); // must not throw
2049 : }
2050 83042 : i->second->releaseNondeleting();
2051 83042 : if (child.is()) {
2052 83042 : child->setNode(node);
2053 83042 : return child;
2054 0 : }
2055 : }
2056 61506983 : return createUnmodifiedChild(name,node);
2057 : }
2058 :
2059 1068846 : rtl::Reference< ChildAccess > Access::getSubChild(OUString const & path) {
2060 1068846 : sal_Int32 i = 0;
2061 : // For backwards compatibility, allow absolute paths where meaningful:
2062 1068846 : if( path.startsWith("/") ) {
2063 198715 : ++i;
2064 198715 : if (!getRootAccess().is()) {
2065 0 : return rtl::Reference< ChildAccess >();
2066 : }
2067 198715 : Path abs(getAbsolutePath());
2068 198715 : for (Path::iterator j(abs.begin()); j != abs.end(); ++j) {
2069 0 : OUString name1;
2070 : bool setElement1;
2071 0 : OUString templateName1;
2072 : i = Data::parseSegment(
2073 0 : path, i, &name1, &setElement1, &templateName1);
2074 0 : if (i == -1 || (i != path.getLength() && path[i] != '/')) {
2075 0 : return rtl::Reference< ChildAccess >();
2076 : }
2077 0 : OUString name2;
2078 : bool setElement2;
2079 0 : OUString templateName2;
2080 0 : Data::parseSegment(*j, 0, &name2, &setElement2, &templateName2);
2081 0 : if (name1 != name2 || setElement1 != setElement2 ||
2082 0 : (setElement1 &&
2083 0 : !Data::equalTemplateNames(templateName1, templateName2)))
2084 : {
2085 0 : return rtl::Reference< ChildAccess >();
2086 : }
2087 0 : if (i != path.getLength()) {
2088 0 : ++i;
2089 : }
2090 198715 : }
2091 : }
2092 1068846 : for (rtl::Reference< Access > parent(this);;) {
2093 3621569 : OUString name;
2094 : bool setElement;
2095 6174292 : OUString templateName;
2096 3621569 : i = Data::parseSegment(path, i, &name, &setElement, &templateName);
2097 3621569 : if (i == -1 || (i != path.getLength() && path[i] != '/')) {
2098 0 : return rtl::Reference< ChildAccess >();
2099 : }
2100 6174292 : rtl::Reference< ChildAccess > child(parent->getChild(name));
2101 3621569 : if (!child.is()) {
2102 37 : return rtl::Reference< ChildAccess >();
2103 : }
2104 3621532 : if (setElement) {
2105 24512 : rtl::Reference< Node > p(parent->getNode());
2106 24512 : switch (p->kind()) {
2107 : case Node::KIND_LOCALIZED_PROPERTY:
2108 0 : if (!Components::allLocales(getRootAccess()->getLocale()) ||
2109 0 : !templateName.isEmpty())
2110 : {
2111 0 : return rtl::Reference< ChildAccess >();
2112 : }
2113 0 : break;
2114 : case Node::KIND_SET:
2115 24537 : if (!templateName.isEmpty() &&
2116 25 : !static_cast< SetNode * >(p.get())->isValidTemplate(
2117 25 : templateName))
2118 : {
2119 0 : return rtl::Reference< ChildAccess >();
2120 : }
2121 24512 : break;
2122 : default:
2123 0 : return rtl::Reference< ChildAccess >();
2124 24512 : }
2125 : }
2126 : // For backwards compatibility, ignore a final slash after non-value
2127 : // nodes:
2128 3621532 : if (child->isValue()) {
2129 980452 : return i == path.getLength()
2130 980452 : ? child : rtl::Reference< ChildAccess >();
2131 2641080 : } else if (i >= path.getLength() - 1) {
2132 88357 : return child;
2133 : }
2134 2552723 : ++i;
2135 2552723 : parent = child.get();
2136 2552723 : }
2137 : }
2138 :
2139 83452 : bool Access::setChildProperty(
2140 : OUString const & name, css::uno::Any const & value,
2141 : Modifications * localModifications)
2142 : {
2143 : assert(localModifications != 0);
2144 83452 : rtl::Reference< ChildAccess > child(getChild(name));
2145 83452 : if (!child.is()) {
2146 0 : return false;
2147 : }
2148 83452 : child->checkFinalized();
2149 83452 : child->setProperty(value, localModifications);
2150 83452 : return true;
2151 : }
2152 :
2153 38931 : css::beans::Property Access::asProperty() {
2154 38931 : css::uno::Type type;
2155 : bool nillable;
2156 : bool removable;
2157 77862 : rtl::Reference< Node > p(getNode());
2158 38931 : switch (p->kind()) {
2159 : case Node::KIND_PROPERTY:
2160 : {
2161 13023 : PropertyNode * prop = static_cast< PropertyNode * >(p.get());
2162 13023 : type = mapType(prop->getStaticType());
2163 13023 : nillable = prop->isNillable();
2164 13023 : removable = prop->isExtension();
2165 : }
2166 13023 : break;
2167 : case Node::KIND_LOCALIZED_PROPERTY:
2168 : {
2169 : LocalizedPropertyNode * locprop =
2170 0 : static_cast< LocalizedPropertyNode *>(p.get());
2171 0 : if (Components::allLocales(getRootAccess()->getLocale())) {
2172 0 : type = cppu::UnoType< css::uno::XInterface >::get();
2173 : //TODO: correct?
2174 0 : removable = false;
2175 : } else {
2176 0 : type = mapType(locprop->getStaticType());
2177 0 : removable = false; //TODO ???
2178 : }
2179 0 : nillable = locprop->isNillable();
2180 : }
2181 0 : break;
2182 : case Node::KIND_LOCALIZED_VALUE:
2183 : {
2184 : LocalizedPropertyNode * locprop =
2185 0 : static_cast< LocalizedPropertyNode * >(getParentNode().get());
2186 0 : type = mapType(locprop->getStaticType());
2187 0 : nillable = locprop->isNillable();
2188 0 : removable = false; //TODO ???
2189 : }
2190 0 : break;
2191 : default:
2192 25908 : type = cppu::UnoType< css::uno::XInterface >::get(); //TODO: correct?
2193 25908 : nillable = false;
2194 25908 : rtl::Reference< Node > parent(getParentNode());
2195 25908 : removable = parent.is() && parent->kind() == Node::KIND_SET;
2196 25908 : break;
2197 : }
2198 : return css::beans::Property(
2199 38931 : getNameInternal(), -1, type,
2200 : (css::beans::PropertyAttribute::BOUND | //TODO: correct for group/set?
2201 : css::beans::PropertyAttribute::CONSTRAINED |
2202 : (nillable ? css::beans::PropertyAttribute::MAYBEVOID : 0) |
2203 194655 : (getRootAccess()->isUpdate() && removable
2204 : ? css::beans::PropertyAttribute::REMOVABLE : 0) |
2205 155724 : (!getRootAccess()->isUpdate() || p->getFinalized() != Data::NO_LAYER
2206 298340 : ? css::beans::PropertyAttribute::READONLY : 0))); //TODO: MAYBEDEFAULT
2207 : }
2208 :
2209 112620 : void Access::checkFinalized() {
2210 112620 : if (isFinalized()) {
2211 : throw css::lang::IllegalArgumentException(
2212 : "configmgr modification of finalized item",
2213 0 : static_cast< cppu::OWeakObject * >(this), -1);
2214 : }
2215 112620 : }
2216 :
2217 20 : void Access::checkKnownProperty(OUString const & descriptor) {
2218 20 : if (descriptor.isEmpty()) {
2219 0 : return;
2220 : }
2221 20 : rtl::Reference< ChildAccess > child(getChild(descriptor));
2222 20 : if (child.is()) {
2223 20 : switch (child->getNode()->kind()) {
2224 : case Node::KIND_PROPERTY:
2225 18 : return;
2226 : case Node::KIND_LOCALIZED_PROPERTY:
2227 2 : if (!Components::allLocales(getRootAccess()->getLocale())) {
2228 2 : return;
2229 : }
2230 0 : break;
2231 : case Node::KIND_LOCALIZED_VALUE:
2232 0 : if (Components::allLocales(getRootAccess()->getLocale())) {
2233 0 : return;
2234 : }
2235 0 : break;
2236 : default:
2237 0 : break;
2238 : }
2239 : }
2240 : throw css::beans::UnknownPropertyException(
2241 0 : descriptor, static_cast< cppu::OWeakObject * >(this));
2242 : }
2243 :
2244 3121 : rtl::Reference< ChildAccess > Access::getFreeSetMember(
2245 : css::uno::Any const & value)
2246 : {
2247 3121 : rtl::Reference< ChildAccess > freeAcc;
2248 6242 : css::uno::Reference< css::lang::XUnoTunnel > tunnel;
2249 3121 : value >>= tunnel;
2250 3121 : if (tunnel.is()) {
2251 : freeAcc.set(
2252 : reinterpret_cast< ChildAccess * >(
2253 3121 : tunnel->getSomething(ChildAccess::getTunnelId())));
2254 : }
2255 9363 : if (!freeAcc.is() || freeAcc->getParentAccess().is() ||
2256 3121 : (freeAcc->isInTransaction() &&
2257 3121 : freeAcc->getRootAccess() != getRootAccess()))
2258 : {
2259 : throw css::lang::IllegalArgumentException(
2260 : "configmgr inappropriate set element",
2261 0 : static_cast< cppu::OWeakObject * >(this), 1);
2262 : }
2263 : assert(dynamic_cast< SetNode * >(getNode().get()) != 0);
2264 9363 : if (!static_cast< SetNode * >(getNode().get())->isValidTemplate(
2265 9363 : freeAcc->getNode()->getTemplateName()))
2266 : {
2267 : throw css::lang::IllegalArgumentException(
2268 : "configmgr inappropriate set element",
2269 0 : static_cast< cppu::OWeakObject * >(this), 1);
2270 : }
2271 6242 : return freeAcc;
2272 : }
2273 :
2274 113972 : rtl::Reference< Access > Access::getNotificationRoot() {
2275 113972 : for (rtl::Reference< Access > p(this);;) {
2276 380424 : rtl::Reference< Access > parent(p->getParentAccess());
2277 380424 : if (!parent.is()) {
2278 227944 : return p;
2279 : }
2280 266452 : p = parent;
2281 266452 : }
2282 : }
2283 :
2284 : #if !defined NDEBUG
2285 : bool Access::thisIs(int what) {
2286 : osl::MutexGuard g(*lock_);
2287 : rtl::Reference< Node > p(getNode());
2288 : Node::Kind k(p->kind());
2289 : return (k != Node::KIND_PROPERTY && k != Node::KIND_LOCALIZED_VALUE &&
2290 : ((what & IS_GROUP) == 0 || k == Node::KIND_GROUP) &&
2291 : ((what & IS_SET) == 0 || k == Node::KIND_SET) &&
2292 : ((what & IS_EXTENSIBLE) == 0 || k != Node::KIND_GROUP ||
2293 : static_cast< GroupNode * >(p.get())->isExtensible()) &&
2294 : ((what & IS_GROUP_MEMBER) == 0 ||
2295 : getParentNode()->kind() == Node::KIND_GROUP)) ||
2296 : ((what & IS_SET_MEMBER) == 0 ||
2297 : getParentNode()->kind() == Node::KIND_SET) ||
2298 : ((what & IS_UPDATE) == 0 || getRootAccess()->isUpdate());
2299 : }
2300 : #endif
2301 :
2302 : }
2303 :
2304 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|