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