1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "sal/config.h"
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/weak.hxx"
76 #include "osl/interlck.h"
77 #include "osl/mutex.hxx"
78 #include "rtl/ref.hxx"
79 #include "rtl/ustrbuf.hxx"
80 #include "rtl/ustring.h"
81 #include "rtl/ustring.hxx"
82 #include "sal/types.h"
85 #include "broadcaster.hxx"
86 #include "childaccess.hxx"
87 #include "components.hxx"
89 #include "groupnode.hxx"
90 #include "localizedpropertynode.hxx"
91 #include "localizedvaluenode.hxx"
93 #include "modifications.hxx"
95 #include "nodemap.hxx"
97 #include "propertynode.hxx"
98 #include "rootaccess.hxx"
99 #include "setnode.hxx"
102 namespace configmgr
{
104 oslInterlockedCount
Access::acquireCounting() {
105 return osl_atomic_increment(&m_refCount
);
108 void Access::releaseNondeleting() {
109 osl_atomic_decrement(&m_refCount
);
112 bool Access::isValue() {
113 rtl::Reference
< Node
> p(getNode());
115 case Node::KIND_PROPERTY
:
116 case Node::KIND_LOCALIZED_VALUE
:
118 case Node::KIND_LOCALIZED_PROPERTY
:
119 return !Components::allLocales(getRootAccess()->getLocale());
125 void Access::markChildAsModified(rtl::Reference
< ChildAccess
> const & child
) {
126 assert(child
.is() && child
->getParentAccess() == this);
127 modifiedChildren_
[child
->getNameInternal()] = ModifiedChild(child
, true);
128 for (rtl::Reference
< Access
> p(this);;) {
129 rtl::Reference
< Access
> parent(p
->getParentAccess());
133 assert(dynamic_cast< ChildAccess
* >(p
.get()) != 0);
134 parent
->modifiedChildren_
.insert(
135 ModifiedChildren::value_type(
136 p
->getNameInternal(),
137 ModifiedChild(dynamic_cast< ChildAccess
* >(p
.get()), false)));
142 void Access::releaseChild(OUString
const & name
) {
143 cachedChildren_
.erase(name
);
146 void Access::initBroadcaster(
147 Modifications::Node
const & modifications
, Broadcaster
* broadcaster
)
149 initBroadcasterAndChanges(modifications
, broadcaster
, 0);
152 css::uno::Sequence
< css::uno::Type
> Access::getTypes()
153 throw (css::uno::RuntimeException
)
155 assert(thisIs(IS_ANY
));
156 osl::MutexGuard
g(*lock_
);
157 checkLocalizedPropertyAccess();
158 comphelper::SequenceAsVector
< css::uno::Type
> types
;
159 types
.push_back(cppu::UnoType
< css::uno::XInterface
>::get());
160 types
.push_back(cppu::UnoType
< css::uno::XWeak
>::get());
161 types
.push_back(cppu::UnoType
< css::lang::XTypeProvider
>::get());
162 types
.push_back(cppu::UnoType
< css::lang::XServiceInfo
>::get());
163 types
.push_back(cppu::UnoType
< css::lang::XComponent
>::get());
164 types
.push_back(cppu::UnoType
< css::container::XContainer
>::get());
165 types
.push_back(cppu::UnoType
< css::beans::XExactName
>::get());
166 types
.push_back(cppu::UnoType
< css::container::XHierarchicalName
>::get());
167 types
.push_back(cppu::UnoType
< css::container::XNamed
>::get());
168 types
.push_back(cppu::UnoType
< css::beans::XProperty
>::get());
169 types
.push_back(cppu::UnoType
< css::container::XElementAccess
>::get());
170 types
.push_back(cppu::UnoType
< css::container::XNameAccess
>::get());
171 if (getNode()->kind() == Node::KIND_GROUP
) {
172 types
.push_back(cppu::UnoType
< css::beans::XPropertySetInfo
>::get());
173 types
.push_back(cppu::UnoType
< css::beans::XPropertySet
>::get());
174 types
.push_back(cppu::UnoType
< css::beans::XMultiPropertySet
>::get());
176 cppu::UnoType
< css::beans::XHierarchicalPropertySet
>::get());
178 cppu::UnoType
< css::beans::XMultiHierarchicalPropertySet
>::get());
180 cppu::UnoType
< css::beans::XHierarchicalPropertySetInfo
>::get());
182 if (getRootAccess()->isUpdate()) {
183 types
.push_back(cppu::UnoType
< css::container::XNameReplace
>::get());
185 cppu::UnoType
< css::container::XHierarchicalNameReplace
>::get());
186 if (getNode()->kind() != Node::KIND_GROUP
||
187 dynamic_cast< GroupNode
* >(getNode().get())->isExtensible())
190 cppu::UnoType
< css::container::XNameContainer
>::get());
192 if (getNode()->kind() == Node::KIND_SET
) {
194 cppu::UnoType
< css::lang::XSingleServiceFactory
>::get());
198 cppu::UnoType
< css::container::XHierarchicalNameAccess
>::get());
201 return types
.getAsConstList();
204 css::uno::Sequence
< sal_Int8
> Access::getImplementationId()
205 throw (css::uno::RuntimeException
)
207 assert(thisIs(IS_ANY
));
208 osl::MutexGuard
g(*lock_
);
209 checkLocalizedPropertyAccess();
210 return css::uno::Sequence
< sal_Int8
>();
213 OUString
Access::getImplementationName() throw (css::uno::RuntimeException
)
215 assert(thisIs(IS_ANY
));
216 osl::MutexGuard
g(*lock_
);
217 checkLocalizedPropertyAccess();
218 return OUString("org.openoffice-configmgr::Access");
221 sal_Bool
Access::supportsService(OUString
const & ServiceName
)
222 throw (css::uno::RuntimeException
)
224 assert(thisIs(IS_ANY
));
225 osl::MutexGuard
g(*lock_
);
226 checkLocalizedPropertyAccess();
227 css::uno::Sequence
< OUString
> names(getSupportedServiceNames());
228 for (sal_Int32 i
= 0; i
< names
.getLength(); ++i
) {
229 if (names
[i
] == ServiceName
) {
236 css::uno::Sequence
< OUString
> Access::getSupportedServiceNames()
237 throw (css::uno::RuntimeException
)
239 assert(thisIs(IS_ANY
));
240 osl::MutexGuard
g(*lock_
);
241 checkLocalizedPropertyAccess();
242 comphelper::SequenceAsVector
< OUString
> services
;
244 OUString("com.sun.star.configuration.ConfigurationAccess"));
245 if (getRootAccess()->isUpdate()) {
247 OUString("com.sun.star.configuration.ConfigurationUpdateAccess"));
250 OUString("com.sun.star.configuration.HierarchyAccess"));
252 OUString("com.sun.star.configuration.HierarchyElement"));
253 if (getNode()->kind() == Node::KIND_GROUP
) {
255 OUString("com.sun.star.configuration.GroupAccess"));
257 OUString("com.sun.star.configuration.PropertyHierarchy"));
258 if (getRootAccess()->isUpdate()) {
260 OUString("com.sun.star.configuration.GroupUpdate"));
264 OUString("com.sun.star.configuration.SetAccess"));
266 OUString("com.sun.star.configuration.SimpleSetAccess"));
267 if (getRootAccess()->isUpdate()) {
269 OUString("com.sun.star.configuration.SetUpdate"));
271 OUString("com.sun.star.configuration.SimpleSetUpdate"));
274 addSupportedServiceNames(&services
);
275 return services
.getAsConstList();
278 void Access::dispose() throw (css::uno::RuntimeException
) {
279 assert(thisIs(IS_ANY
));
282 osl::MutexGuard
g(*lock_
);
283 checkLocalizedPropertyAccess();
284 if (getParentAccess().is()) {
285 throw css::uno::RuntimeException(
286 OUString("configmgr dispose inappropriate Access"),
287 static_cast< cppu::OWeakObject
* >(this));
292 initDisposeBroadcaster(&bc
);
299 void Access::addEventListener(
300 css::uno::Reference
< css::lang::XEventListener
> const & xListener
)
301 throw (css::uno::RuntimeException
)
303 assert(thisIs(IS_ANY
));
305 osl::MutexGuard
g(*lock_
);
306 checkLocalizedPropertyAccess();
307 if (!xListener
.is()) {
308 throw css::uno::RuntimeException(
309 OUString("null listener"),
310 static_cast< cppu::OWeakObject
* >(this));
313 disposeListeners_
.insert(xListener
);
318 xListener
->disposing(
319 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
320 } catch (css::lang::DisposedException
&) {}
323 void Access::removeEventListener(
324 css::uno::Reference
< css::lang::XEventListener
> const & aListener
)
325 throw (css::uno::RuntimeException
)
327 assert(thisIs(IS_ANY
));
328 osl::MutexGuard
g(*lock_
);
329 checkLocalizedPropertyAccess();
330 DisposeListeners::iterator
i(disposeListeners_
.find(aListener
));
331 if (i
!= disposeListeners_
.end()) {
332 disposeListeners_
.erase(i
);
336 css::uno::Type
Access::getElementType() throw (css::uno::RuntimeException
) {
337 assert(thisIs(IS_ANY
));
338 osl::MutexGuard
g(*lock_
);
339 checkLocalizedPropertyAccess();
340 rtl::Reference
< Node
> p(getNode());
342 case Node::KIND_LOCALIZED_PROPERTY
:
344 dynamic_cast< LocalizedPropertyNode
* >(p
.get())->getStaticType());
345 case Node::KIND_GROUP
:
346 //TODO: Should a specific type be returned for a non-extensible group
347 // with homogeneous members or for an extensible group that currently
348 // has only homegeneous members?
349 return cppu::UnoType
< cppu::UnoVoidType
>::get();
351 return cppu::UnoType
< cppu::UnoVoidType
>::get(); //TODO: correct?
354 throw css::uno::RuntimeException(
355 OUString("this cannot happen"),
356 static_cast< cppu::OWeakObject
* >(this));
360 sal_Bool
Access::hasElements() throw (css::uno::RuntimeException
) {
361 assert(thisIs(IS_ANY
));
362 osl::MutexGuard
g(*lock_
);
363 checkLocalizedPropertyAccess();
364 return !getAllChildren().empty(); //TODO: optimize
367 css::uno::Any
Access::getByName(OUString
const & aName
)
369 css::container::NoSuchElementException
,
370 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
372 assert(thisIs(IS_ANY
));
373 osl::MutexGuard
g(*lock_
);
374 checkLocalizedPropertyAccess();
375 rtl::Reference
< ChildAccess
> child(getChild(aName
));
377 throw css::container::NoSuchElementException(
378 aName
, static_cast< cppu::OWeakObject
* >(this));
380 return child
->asValue();
383 css::uno::Sequence
< OUString
> Access::getElementNames()
384 throw (css::uno::RuntimeException
)
386 assert(thisIs(IS_ANY
));
387 osl::MutexGuard
g(*lock_
);
388 checkLocalizedPropertyAccess();
389 std::vector
< rtl::Reference
< ChildAccess
> > children(getAllChildren());
390 comphelper::SequenceAsVector
< OUString
> names
;
391 for (std::vector
< rtl::Reference
< ChildAccess
> >::iterator
i(
393 i
!= children
.end(); ++i
)
395 names
.push_back((*i
)->getNameInternal());
397 return names
.getAsConstList();
400 sal_Bool
Access::hasByName(OUString
const & aName
)
401 throw (css::uno::RuntimeException
)
403 assert(thisIs(IS_ANY
));
404 osl::MutexGuard
g(*lock_
);
405 checkLocalizedPropertyAccess();
406 return getChild(aName
).is();
409 css::uno::Any
Access::getByHierarchicalName(OUString
const & aName
)
410 throw (css::container::NoSuchElementException
, css::uno::RuntimeException
)
412 assert(thisIs(IS_ANY
));
413 osl::MutexGuard
g(*lock_
);
414 checkLocalizedPropertyAccess();
415 rtl::Reference
< ChildAccess
> child(getSubChild(aName
));
417 throw css::container::NoSuchElementException(
418 aName
, static_cast< cppu::OWeakObject
* >(this));
420 return child
->asValue();
423 sal_Bool
Access::hasByHierarchicalName(OUString
const & aName
)
424 throw (css::uno::RuntimeException
)
426 assert(thisIs(IS_ANY
));
427 osl::MutexGuard
g(*lock_
);
428 checkLocalizedPropertyAccess();
429 return getSubChild(aName
).is();
432 void Access::replaceByHierarchicalName(
433 OUString
const & aName
, css::uno::Any
const & aElement
)
435 css::lang::IllegalArgumentException
,
436 css::container::NoSuchElementException
,
437 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
439 //TODO: Actually support sets and combine with replaceByName:
440 assert(thisIs(IS_UPDATE
));
443 osl::MutexGuard
g(*lock_
);
444 checkLocalizedPropertyAccess();
445 rtl::Reference
< ChildAccess
> child(getSubChild(aName
));
447 throw css::container::NoSuchElementException(
448 aName
, static_cast< cppu::OWeakObject
* >(this));
450 child
->checkFinalized();
451 rtl::Reference
< Node
> parent(child
->getParentNode());
453 Modifications localMods
;
454 switch (parent
->kind()) {
455 case Node::KIND_LOCALIZED_PROPERTY
:
456 case Node::KIND_GROUP
:
457 child
->setProperty(aElement
, &localMods
);
460 throw css::lang::IllegalArgumentException(
461 OUString("configmgr::Access::replaceByHierarchicalName does not"
462 " currently support set members"),
463 static_cast< cppu::OWeakObject
* >(this), 0);
464 case Node::KIND_ROOT
:
465 throw css::lang::IllegalArgumentException(
466 (OUString("configmgr::Access::replaceByHierarchicalName does not"
467 " allow changing component ")
469 static_cast< cppu::OWeakObject
* >(this), 0);
471 assert(false); // this cannot happen
474 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
479 void Access::addContainerListener(
480 css::uno::Reference
< css::container::XContainerListener
> const & xListener
)
481 throw (css::uno::RuntimeException
)
483 assert(thisIs(IS_ANY
));
485 osl::MutexGuard
g(*lock_
);
486 checkLocalizedPropertyAccess();
487 if (!xListener
.is()) {
488 throw css::uno::RuntimeException(
489 OUString("null listener"),
490 static_cast< cppu::OWeakObject
* >(this));
493 containerListeners_
.insert(xListener
);
498 xListener
->disposing(
499 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
500 } catch (css::lang::DisposedException
&) {}
503 void Access::removeContainerListener(
504 css::uno::Reference
< css::container::XContainerListener
> const & xListener
)
505 throw (css::uno::RuntimeException
)
507 assert(thisIs(IS_ANY
));
508 osl::MutexGuard
g(*lock_
);
509 checkLocalizedPropertyAccess();
510 ContainerListeners::iterator
i(containerListeners_
.find(xListener
));
511 if (i
!= containerListeners_
.end()) {
512 containerListeners_
.erase(i
);
516 OUString
Access::getExactName(OUString
const & aApproximateName
)
517 throw (css::uno::RuntimeException
)
519 assert(thisIs(IS_ANY
));
520 osl::MutexGuard
g(*lock_
);
521 checkLocalizedPropertyAccess();
522 return aApproximateName
;
525 css::uno::Sequence
< css::beans::Property
> Access::getProperties()
526 throw (css::uno::RuntimeException
)
528 assert(thisIs(IS_GROUP
));
529 osl::MutexGuard
g(*lock_
);
530 std::vector
< rtl::Reference
< ChildAccess
> > children(getAllChildren());
531 comphelper::SequenceAsVector
< css::beans::Property
> properties
;
532 for (std::vector
< rtl::Reference
< ChildAccess
> >::iterator
i(
534 i
!= children
.end(); ++i
)
536 properties
.push_back((*i
)->asProperty());
538 return properties
.getAsConstList();
541 css::beans::Property
Access::getPropertyByName(OUString
const & aName
)
542 throw (css::beans::UnknownPropertyException
, css::uno::RuntimeException
)
544 assert(thisIs(IS_GROUP
));
545 osl::MutexGuard
g(*lock_
);
546 rtl::Reference
< ChildAccess
> child(getChild(aName
));
548 throw css::beans::UnknownPropertyException(
549 aName
, static_cast< cppu::OWeakObject
* >(this));
551 return child
->asProperty();
554 sal_Bool
Access::hasPropertyByName(OUString
const & Name
)
555 throw (css::uno::RuntimeException
)
557 assert(thisIs(IS_GROUP
));
558 osl::MutexGuard
g(*lock_
);
559 return getChild(Name
).is();
562 OUString
Access::getHierarchicalName() throw (css::uno::RuntimeException
) {
563 assert(thisIs(IS_ANY
));
564 osl::MutexGuard
g(*lock_
);
565 checkLocalizedPropertyAccess();
566 // For backwards compatibility, return an absolute path representation where
569 rtl::Reference
< RootAccess
> root(getRootAccess());
571 rootPath
= root
->getAbsolutePathRepresentation();
573 OUString
rel(getRelativePathRepresentation());
574 OUStringBuffer
path(rootPath
);
575 if (!rootPath
.isEmpty() && rootPath
!= "/" && !rel
.isEmpty()) {
579 return path
.makeStringAndClear();
582 OUString
Access::composeHierarchicalName(
583 OUString
const & aRelativeName
)
585 css::lang::IllegalArgumentException
, css::lang::NoSupportException
,
586 css::uno::RuntimeException
)
588 assert(thisIs(IS_ANY
));
589 osl::MutexGuard
g(*lock_
);
590 checkLocalizedPropertyAccess();
591 if (aRelativeName
.isEmpty() || aRelativeName
[0] == '/') {
592 throw css::lang::IllegalArgumentException(
593 OUString("configmgr composeHierarchicalName inappropriate relative"
595 static_cast< cppu::OWeakObject
* >(this), -1);
597 OUStringBuffer
path(getRelativePathRepresentation());
598 if (path
.getLength() != 0) {
599 path
.append(sal_Unicode('/'));
601 path
.append(aRelativeName
);
602 return path
.makeStringAndClear();
605 OUString
Access::getName() throw (css::uno::RuntimeException
) {
606 assert(thisIs(IS_ANY
));
607 osl::MutexGuard
g(*lock_
);
608 checkLocalizedPropertyAccess();
609 return getNameInternal();
612 void Access::setName(OUString
const & aName
)
613 throw (css::uno::RuntimeException
)
615 assert(thisIs(IS_ANY
));
618 osl::MutexGuard
g(*lock_
);
619 checkLocalizedPropertyAccess();
621 Modifications localMods
;
622 switch (getNode()->kind()) {
623 case Node::KIND_GROUP
:
626 rtl::Reference
< Access
> parent(getParentAccess());
628 rtl::Reference
< Node
> node(getNode());
629 if (! node
->getTemplateName().isEmpty()) {
630 rtl::Reference
< ChildAccess
> other(
631 parent
->getChild(aName
));
632 if (other
.get() == this) {
635 if (node
->getMandatory() == Data::NO_LAYER
&&
636 !(other
.is() && other
->isFinalized()))
638 rtl::Reference
< RootAccess
> root(getRootAccess());
639 rtl::Reference
< ChildAccess
> childAccess(
640 dynamic_cast< ChildAccess
* >(this));
641 localMods
.add(getRelativePath());
642 // unbind() modifies the parent chain that
643 // markChildAsModified() walks, so order is
645 parent
->markChildAsModified(childAccess
);
646 //TODO: must not throw
647 childAccess
->unbind(); // must not throw
649 other
->unbind(); // must not throw
651 childAccess
->bind(root
, parent
, aName
);
653 parent
->markChildAsModified(childAccess
);
654 //TODO: must not throw
655 localMods
.add(getRelativePath());
662 case Node::KIND_LOCALIZED_PROPERTY
:
663 // renaming a property could only work for an extension property,
664 // but a localized property is never an extension property
665 throw css::uno::RuntimeException(
666 OUString("configmgr setName inappropriate node"),
667 static_cast< cppu::OWeakObject
* >(this));
669 assert(false); // this cannot happen
672 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
677 css::beans::Property
Access::getAsProperty() throw (css::uno::RuntimeException
)
679 assert(thisIs(IS_ANY
));
680 osl::MutexGuard
g(*lock_
);
681 checkLocalizedPropertyAccess();
685 css::uno::Reference
< css::beans::XPropertySetInfo
> Access::getPropertySetInfo()
686 throw (css::uno::RuntimeException
)
688 assert(thisIs(IS_GROUP
));
692 void Access::setPropertyValue(
693 OUString
const & aPropertyName
, css::uno::Any
const & aValue
)
695 css::beans::UnknownPropertyException
, css::beans::PropertyVetoException
,
696 css::lang::IllegalArgumentException
, css::lang::WrappedTargetException
,
697 css::uno::RuntimeException
)
699 assert(thisIs(IS_GROUP
));
702 osl::MutexGuard
g(*lock_
);
703 if (!getRootAccess()->isUpdate()) {
704 throw css::uno::RuntimeException(
705 OUString("configmgr setPropertyValue on non-update access"),
706 static_cast< cppu::OWeakObject
* >(this));
708 Modifications localMods
;
709 if (!setChildProperty(aPropertyName
, aValue
, &localMods
)) {
710 throw css::beans::UnknownPropertyException(
711 aPropertyName
, static_cast< cppu::OWeakObject
* >(this));
713 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
718 css::uno::Any
Access::getPropertyValue(OUString
const & PropertyName
)
720 css::beans::UnknownPropertyException
, css::lang::WrappedTargetException
,
721 css::uno::RuntimeException
)
723 assert(thisIs(IS_GROUP
));
724 osl::MutexGuard
g(*lock_
);
725 rtl::Reference
< ChildAccess
> child(getChild(PropertyName
));
727 throw css::beans::UnknownPropertyException(
728 PropertyName
, static_cast< cppu::OWeakObject
* >(this));
730 return child
->asValue();
733 void Access::addPropertyChangeListener(
734 OUString
const & aPropertyName
,
735 css::uno::Reference
< css::beans::XPropertyChangeListener
> const &
738 css::beans::UnknownPropertyException
, css::lang::WrappedTargetException
,
739 css::uno::RuntimeException
)
741 assert(thisIs(IS_GROUP
));
743 osl::MutexGuard
g(*lock_
);
744 if (!xListener
.is()) {
745 throw css::uno::RuntimeException(
746 OUString("null listener"),
747 static_cast< cppu::OWeakObject
* >(this));
749 checkKnownProperty(aPropertyName
);
751 propertyChangeListeners_
[aPropertyName
].insert(xListener
);
756 xListener
->disposing(
757 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
758 } catch (css::lang::DisposedException
&) {}
761 void Access::removePropertyChangeListener(
762 OUString
const & aPropertyName
,
763 css::uno::Reference
< css::beans::XPropertyChangeListener
> const &
766 css::beans::UnknownPropertyException
, css::lang::WrappedTargetException
,
767 css::uno::RuntimeException
)
769 assert(thisIs(IS_GROUP
));
770 osl::MutexGuard
g(*lock_
);
771 checkKnownProperty(aPropertyName
);
772 PropertyChangeListeners::iterator
i(
773 propertyChangeListeners_
.find(aPropertyName
));
774 if (i
!= propertyChangeListeners_
.end()) {
775 PropertyChangeListenersElement::iterator
j(i
->second
.find(aListener
));
776 if (j
!= i
->second
.end()) {
778 if (i
->second
.empty()) {
779 propertyChangeListeners_
.erase(i
);
785 void Access::addVetoableChangeListener(
786 OUString
const & PropertyName
,
787 css::uno::Reference
< css::beans::XVetoableChangeListener
> const &
790 css::beans::UnknownPropertyException
, css::lang::WrappedTargetException
,
791 css::uno::RuntimeException
)
793 assert(thisIs(IS_GROUP
));
795 osl::MutexGuard
g(*lock_
);
796 if (!aListener
.is()) {
797 throw css::uno::RuntimeException(
798 OUString("null listener"),
799 static_cast< cppu::OWeakObject
* >(this));
801 checkKnownProperty(PropertyName
);
803 vetoableChangeListeners_
[PropertyName
].insert(aListener
);
804 //TODO: actually call vetoableChangeListeners_
809 aListener
->disposing(
810 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
811 } catch (css::lang::DisposedException
&) {}
814 void Access::removeVetoableChangeListener(
815 OUString
const & PropertyName
,
816 css::uno::Reference
< css::beans::XVetoableChangeListener
> const &
819 css::beans::UnknownPropertyException
, css::lang::WrappedTargetException
,
820 css::uno::RuntimeException
)
822 assert(thisIs(IS_GROUP
));
823 osl::MutexGuard
g(*lock_
);
824 checkKnownProperty(PropertyName
);
825 VetoableChangeListeners::iterator
i(
826 vetoableChangeListeners_
.find(PropertyName
));
827 if (i
!= vetoableChangeListeners_
.end()) {
828 VetoableChangeListenersElement::iterator
j(i
->second
.find(aListener
));
829 if (j
!= i
->second
.end()) {
831 if (i
->second
.empty()) {
832 vetoableChangeListeners_
.erase(i
);
838 void Access::setPropertyValues(
839 css::uno::Sequence
< OUString
> const & aPropertyNames
,
840 css::uno::Sequence
< css::uno::Any
> const & aValues
)
842 css::beans::PropertyVetoException
, css::lang::IllegalArgumentException
,
843 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
845 assert(thisIs(IS_GROUP
));
848 osl::MutexGuard
g(*lock_
);
849 if (!getRootAccess()->isUpdate()) {
850 throw css::uno::RuntimeException(
851 OUString("configmgr setPropertyValues on non-update access"),
852 static_cast< cppu::OWeakObject
* >(this));
854 if (aPropertyNames
.getLength() != aValues
.getLength()) {
855 throw css::lang::IllegalArgumentException(
856 OUString("configmgr setPropertyValues: aPropertyNames/aValues of"
857 " different length"),
858 static_cast< cppu::OWeakObject
* >(this), -1);
860 Modifications localMods
;
861 for (sal_Int32 i
= 0; i
< aPropertyNames
.getLength(); ++i
) {
862 if (!setChildProperty(aPropertyNames
[i
], aValues
[i
], &localMods
)) {
863 throw css::lang::IllegalArgumentException(
864 OUString("configmgr setPropertyValues inappropriate property"
866 static_cast< cppu::OWeakObject
* >(this), -1);
869 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
874 css::uno::Sequence
< css::uno::Any
> Access::getPropertyValues(
875 css::uno::Sequence
< OUString
> const & aPropertyNames
)
876 throw (css::uno::RuntimeException
)
878 assert(thisIs(IS_GROUP
));
879 osl::MutexGuard
g(*lock_
);
880 css::uno::Sequence
< css::uno::Any
> vals(aPropertyNames
.getLength());
881 for (sal_Int32 i
= 0; i
< aPropertyNames
.getLength(); ++i
) {
882 rtl::Reference
< ChildAccess
> child(getChild(aPropertyNames
[i
]));
884 throw css::uno::RuntimeException(
885 OUString("configmgr getPropertyValues inappropriate property"
887 static_cast< cppu::OWeakObject
* >(this));
889 vals
[i
] = child
->asValue();
894 void Access::addPropertiesChangeListener(
895 css::uno::Sequence
< OUString
> const &,
896 css::uno::Reference
< css::beans::XPropertiesChangeListener
> const &
898 throw (css::uno::RuntimeException
)
900 assert(thisIs(IS_GROUP
));
902 osl::MutexGuard
g(*lock_
);
903 if (!xListener
.is()) {
904 throw css::uno::RuntimeException(
905 OUString("null listener"),
906 static_cast< cppu::OWeakObject
* >(this));
909 propertiesChangeListeners_
.insert(xListener
);
914 xListener
->disposing(
915 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
916 } catch (css::lang::DisposedException
&) {}
919 void Access::removePropertiesChangeListener(
920 css::uno::Reference
< css::beans::XPropertiesChangeListener
> const &
922 throw (css::uno::RuntimeException
)
924 assert(thisIs(IS_GROUP
));
925 osl::MutexGuard
g(*lock_
);
926 PropertiesChangeListeners::iterator
i(
927 propertiesChangeListeners_
.find(xListener
));
928 if (i
!= propertiesChangeListeners_
.end()) {
929 propertiesChangeListeners_
.erase(i
);
933 void Access::firePropertiesChangeEvent(
934 css::uno::Sequence
< OUString
> const & aPropertyNames
,
935 css::uno::Reference
< css::beans::XPropertiesChangeListener
> const &
937 throw (css::uno::RuntimeException
)
939 assert(thisIs(IS_GROUP
));
940 css::uno::Sequence
< css::beans::PropertyChangeEvent
> events(
941 aPropertyNames
.getLength());
942 for (sal_Int32 i
= 0; i
< events
.getLength(); ++i
) {
943 events
[i
].Source
= static_cast< cppu::OWeakObject
* >(this);
944 events
[i
].PropertyName
= aPropertyNames
[i
];
945 events
[i
].Further
= false;
946 events
[i
].PropertyHandle
= -1;
948 xListener
->propertiesChange(events
);
951 css::uno::Reference
< css::beans::XHierarchicalPropertySetInfo
>
952 Access::getHierarchicalPropertySetInfo() throw (css::uno::RuntimeException
) {
953 assert(thisIs(IS_GROUP
));
957 void Access::setHierarchicalPropertyValue(
958 OUString
const & aHierarchicalPropertyName
,
959 css::uno::Any
const & aValue
)
961 css::beans::UnknownPropertyException
, css::beans::PropertyVetoException
,
962 css::lang::IllegalArgumentException
, css::lang::WrappedTargetException
,
963 css::uno::RuntimeException
)
965 assert(thisIs(IS_GROUP
));
968 osl::MutexGuard
g(*lock_
);
969 if (!getRootAccess()->isUpdate()) {
970 throw css::uno::RuntimeException(
971 OUString("configmgr setHierarchicalPropertyName on non-update"
973 static_cast< cppu::OWeakObject
* >(this));
975 rtl::Reference
< ChildAccess
> child(
976 getSubChild(aHierarchicalPropertyName
));
978 throw css::beans::UnknownPropertyException(
979 aHierarchicalPropertyName
,
980 static_cast< cppu::OWeakObject
* >(this));
982 child
->checkFinalized();
983 Modifications localMods
;
984 child
->setProperty(aValue
, &localMods
);
985 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
990 css::uno::Any
Access::getHierarchicalPropertyValue(
991 OUString
const & aHierarchicalPropertyName
)
993 css::beans::UnknownPropertyException
,
994 css::lang::IllegalArgumentException
, css::lang::WrappedTargetException
,
995 css::uno::RuntimeException
)
997 assert(thisIs(IS_GROUP
));
998 osl::MutexGuard
g(*lock_
);
999 rtl::Reference
< ChildAccess
> child(getSubChild(aHierarchicalPropertyName
));
1001 throw css::beans::UnknownPropertyException(
1002 aHierarchicalPropertyName
,
1003 static_cast< cppu::OWeakObject
* >(this));
1005 return child
->asValue();
1008 void Access::setHierarchicalPropertyValues(
1009 css::uno::Sequence
< OUString
> const & aHierarchicalPropertyNames
,
1010 css::uno::Sequence
< css::uno::Any
> const & Values
)
1012 css::beans::PropertyVetoException
, css::lang::IllegalArgumentException
,
1013 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
1015 assert(thisIs(IS_GROUP
));
1018 osl::MutexGuard
g(*lock_
);
1019 if (!getRootAccess()->isUpdate()) {
1020 throw css::uno::RuntimeException(
1021 OUString("configmgr setPropertyValues on non-update access"),
1022 static_cast< cppu::OWeakObject
* >(this));
1024 if (aHierarchicalPropertyNames
.getLength() != Values
.getLength()) {
1025 throw css::lang::IllegalArgumentException(
1026 OUString("configmgr setHierarchicalPropertyValues:"
1027 " aHierarchicalPropertyNames/Values of different"
1029 static_cast< cppu::OWeakObject
* >(this), -1);
1031 Modifications localMods
;
1032 for (sal_Int32 i
= 0; i
< aHierarchicalPropertyNames
.getLength(); ++i
) {
1033 rtl::Reference
< ChildAccess
> child(
1034 getSubChild(aHierarchicalPropertyNames
[i
]));
1036 throw css::lang::IllegalArgumentException(
1037 OUString("configmgr setHierarchicalPropertyValues"
1038 " inappropriate property name"),
1039 static_cast< cppu::OWeakObject
* >(this), -1);
1041 child
->checkFinalized();
1042 child
->setProperty(Values
[i
], &localMods
);
1044 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
1049 css::uno::Sequence
< css::uno::Any
> Access::getHierarchicalPropertyValues(
1050 css::uno::Sequence
< OUString
> const & aHierarchicalPropertyNames
)
1052 css::lang::IllegalArgumentException
, css::lang::WrappedTargetException
,
1053 css::uno::RuntimeException
)
1055 assert(thisIs(IS_GROUP
));
1056 osl::MutexGuard
g(*lock_
);
1057 css::uno::Sequence
< css::uno::Any
> vals(
1058 aHierarchicalPropertyNames
.getLength());
1059 for (sal_Int32 i
= 0; i
< aHierarchicalPropertyNames
.getLength(); ++i
) {
1060 rtl::Reference
< ChildAccess
> child(
1061 getSubChild(aHierarchicalPropertyNames
[i
]));
1063 throw css::lang::IllegalArgumentException(
1064 OUString("configmgr getHierarchicalPropertyValues inappropriate"
1065 " hierarchical property name"),
1066 static_cast< cppu::OWeakObject
* >(this), -1);
1068 vals
[i
] = child
->asValue();
1073 css::beans::Property
Access::getPropertyByHierarchicalName(
1074 OUString
const & aHierarchicalName
)
1075 throw (css::beans::UnknownPropertyException
, css::uno::RuntimeException
)
1077 assert(thisIs(IS_GROUP
));
1078 osl::MutexGuard
g(*lock_
);
1079 rtl::Reference
< ChildAccess
> child(getSubChild(aHierarchicalName
));
1081 throw css::beans::UnknownPropertyException(
1082 aHierarchicalName
, static_cast< cppu::OWeakObject
* >(this));
1084 return child
->asProperty();
1087 sal_Bool
Access::hasPropertyByHierarchicalName(
1088 OUString
const & aHierarchicalName
)
1089 throw (css::uno::RuntimeException
)
1091 assert(thisIs(IS_GROUP
));
1092 osl::MutexGuard
g(*lock_
);
1093 return getSubChild(aHierarchicalName
).is();
1096 void Access::replaceByName(
1097 OUString
const & aName
, css::uno::Any
const & aElement
)
1099 css::lang::IllegalArgumentException
,
1100 css::container::NoSuchElementException
,
1101 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
1103 assert(thisIs(IS_UPDATE
));
1106 osl::MutexGuard
g(*lock_
);
1107 checkLocalizedPropertyAccess();
1108 rtl::Reference
< ChildAccess
> child(getChild(aName
));
1110 throw css::container::NoSuchElementException(
1111 aName
, static_cast< cppu::OWeakObject
* >(this));
1113 child
->checkFinalized();
1114 Modifications localMods
;
1115 switch (getNode()->kind()) {
1116 case Node::KIND_LOCALIZED_PROPERTY
:
1117 case Node::KIND_GROUP
:
1118 child
->setProperty(aElement
, &localMods
);
1120 case Node::KIND_SET
:
1122 rtl::Reference
< ChildAccess
> freeAcc(
1123 getFreeSetMember(aElement
));
1124 rtl::Reference
< RootAccess
> root(getRootAccess());
1125 localMods
.add(child
->getRelativePath());
1126 child
->unbind(); // must not throw
1127 freeAcc
->bind(root
, this, aName
); // must not throw
1128 markChildAsModified(freeAcc
); //TODO: must not throw
1132 assert(false); // this cannot happen
1135 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
1140 void Access::insertByName(
1141 OUString
const & aName
, css::uno::Any
const & aElement
)
1143 css::lang::IllegalArgumentException
,
1144 css::container::ElementExistException
,
1145 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
1147 assert(thisIs(IS_EXTENSIBLE
|IS_UPDATE
));
1150 osl::MutexGuard
g(*lock_
);
1151 checkLocalizedPropertyAccess();
1153 if (getChild(aName
).is()) {
1154 throw css::container::ElementExistException(
1155 aName
, static_cast< cppu::OWeakObject
* >(this));
1157 Modifications localMods
;
1158 switch (getNode()->kind()) {
1159 case Node::KIND_LOCALIZED_PROPERTY
:
1160 insertLocalizedValueChild(aName
, aElement
, &localMods
);
1162 case Node::KIND_GROUP
:
1164 checkValue(aElement
, TYPE_ANY
, true);
1165 rtl::Reference
< ChildAccess
> child(
1167 components_
, getRootAccess(), this, aName
,
1169 Data::NO_LAYER
, TYPE_ANY
, true, aElement
, true)));
1170 markChildAsModified(child
);
1171 localMods
.add(child
->getRelativePath());
1174 case Node::KIND_SET
:
1176 rtl::Reference
< ChildAccess
> freeAcc(
1177 getFreeSetMember(aElement
));
1178 freeAcc
->bind(getRootAccess(), this, aName
); // must not throw
1179 markChildAsModified(freeAcc
); //TODO: must not throw
1180 localMods
.add(freeAcc
->getRelativePath());
1184 assert(false); // this cannot happen
1187 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
1192 void Access::removeByName(OUString
const & aName
)
1194 css::container::NoSuchElementException
,
1195 css::lang::WrappedTargetException
, css::uno::RuntimeException
)
1197 assert(thisIs(IS_EXTENSIBLE
|IS_UPDATE
));
1200 osl::MutexGuard
g(*lock_
);
1201 checkLocalizedPropertyAccess();
1202 rtl::Reference
< ChildAccess
> child(getChild(aName
));
1203 if (!child
.is() || child
->isFinalized() ||
1204 child
->getNode()->getMandatory() != Data::NO_LAYER
)
1206 throw css::container::NoSuchElementException(
1207 aName
, static_cast< cppu::OWeakObject
* >(this));
1209 if (getNode()->kind() == Node::KIND_GROUP
) {
1210 rtl::Reference
< Node
> p(child
->getNode());
1211 if (p
->kind() != Node::KIND_PROPERTY
||
1212 !dynamic_cast< PropertyNode
* >(p
.get())->isExtension())
1214 throw css::container::NoSuchElementException(
1215 aName
, static_cast< cppu::OWeakObject
* >(this));
1218 Modifications localMods
;
1219 localMods
.add(child
->getRelativePath());
1220 // unbind() modifies the parent chain that markChildAsModified() walks,
1221 // so order is important:
1222 markChildAsModified(child
); //TODO: must not throw
1224 getNotificationRoot()->initBroadcaster(localMods
.getRoot(), &bc
);
1229 css::uno::Reference
< css::uno::XInterface
> Access::createInstance()
1230 throw (css::uno::Exception
, css::uno::RuntimeException
)
1232 assert(thisIs(IS_SET
|IS_UPDATE
));
1234 dynamic_cast< SetNode
* >(getNode().get())->getDefaultTemplateName());
1235 rtl::Reference
< Node
> tmpl(
1236 components_
.getTemplate(Data::NO_LAYER
, tmplName
));
1238 throw css::uno::Exception(
1239 (OUString("unknown template ") +
1241 static_cast< cppu::OWeakObject
* >(this));
1243 rtl::Reference
< Node
> node(tmpl
->clone(true));
1244 node
->setLayer(Data::NO_LAYER
);
1245 return static_cast< cppu::OWeakObject
* >(
1246 new ChildAccess(components_
, getRootAccess(), node
));
1249 css::uno::Reference
< css::uno::XInterface
> Access::createInstanceWithArguments(
1250 css::uno::Sequence
< css::uno::Any
> const & aArguments
)
1251 throw (css::uno::Exception
, css::uno::RuntimeException
)
1253 assert(thisIs(IS_SET
|IS_UPDATE
));
1254 if (aArguments
.getLength() != 0) {
1255 throw css::uno::Exception(
1256 OUString("configuration SimpleSetUpdate createInstanceWithArguments"
1257 " must not specify any arguments"),
1258 static_cast< cppu::OWeakObject
* >(this));
1260 return createInstance();
1263 Access::Access(Components
& components
):
1264 components_(components
), disposed_(false)
1269 Access::~Access() {}
1271 void Access::initDisposeBroadcaster(Broadcaster
* broadcaster
) {
1272 assert(broadcaster
!= 0);
1273 for (DisposeListeners::iterator
i(disposeListeners_
.begin());
1274 i
!= disposeListeners_
.end(); ++i
)
1276 broadcaster
->addDisposeNotification(
1278 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
1280 for (ContainerListeners::iterator
i(containerListeners_
.begin());
1281 i
!= containerListeners_
.end(); ++i
)
1283 broadcaster
->addDisposeNotification(
1285 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
1287 for (PropertyChangeListeners::iterator
i(propertyChangeListeners_
.begin());
1288 i
!= propertyChangeListeners_
.end(); ++i
)
1290 for (PropertyChangeListenersElement::iterator
j(i
->second
.begin());
1291 j
!= i
->second
.end(); ++j
)
1293 broadcaster
->addDisposeNotification(
1295 css::lang::EventObject(
1296 static_cast< cppu::OWeakObject
* >(this)));
1299 for (VetoableChangeListeners::iterator
i(vetoableChangeListeners_
.begin());
1300 i
!= vetoableChangeListeners_
.end(); ++i
)
1302 for (VetoableChangeListenersElement::iterator
j(i
->second
.begin());
1303 j
!= i
->second
.end(); ++j
)
1305 broadcaster
->addDisposeNotification(
1307 css::lang::EventObject(
1308 static_cast< cppu::OWeakObject
* >(this)));
1311 for (PropertiesChangeListeners::iterator
i(
1312 propertiesChangeListeners_
.begin());
1313 i
!= propertiesChangeListeners_
.end(); ++i
)
1315 broadcaster
->addDisposeNotification(
1317 css::lang::EventObject(static_cast< cppu::OWeakObject
* >(this)));
1319 //TODO: iterate over children w/ listeners (incl. unmodified ones):
1320 for (ModifiedChildren::iterator
i(modifiedChildren_
.begin());
1321 i
!= modifiedChildren_
.end(); ++i
)
1323 rtl::Reference
< ChildAccess
> child(getModifiedChild(i
));
1325 child
->initDisposeBroadcaster(broadcaster
);
1330 void Access::clearListeners() throw() {
1331 disposeListeners_
.clear();
1332 containerListeners_
.clear();
1333 propertyChangeListeners_
.clear();
1334 vetoableChangeListeners_
.clear();
1335 propertiesChangeListeners_
.clear();
1336 //TODO: iterate over children w/ listeners (incl. unmodified ones):
1337 for (ModifiedChildren::iterator
i(modifiedChildren_
.begin());
1338 i
!= modifiedChildren_
.end(); ++i
)
1340 rtl::Reference
< ChildAccess
> child(getModifiedChild(i
));
1342 child
->clearListeners();
1347 css::uno::Any
Access::queryInterface(css::uno::Type
const & aType
)
1348 throw (css::uno::RuntimeException
)
1350 css::uno::Any
res(OWeakObject::queryInterface(aType
));
1351 if (res
.hasValue()) {
1354 res
= cppu::queryInterface(
1355 aType
, static_cast< css::lang::XTypeProvider
* >(this),
1356 static_cast< css::lang::XServiceInfo
* >(this),
1357 static_cast< css::lang::XComponent
* >(this),
1358 static_cast< css::container::XHierarchicalNameAccess
* >(this),
1359 static_cast< css::container::XContainer
* >(this),
1360 static_cast< css::beans::XExactName
* >(this),
1361 static_cast< css::container::XHierarchicalName
* >(this),
1362 static_cast< css::container::XNamed
* >(this),
1363 static_cast< css::beans::XProperty
* >(this),
1364 static_cast< css::container::XElementAccess
* >(this),
1365 static_cast< css::container::XNameAccess
* >(this));
1366 if (res
.hasValue()) {
1369 if (getNode()->kind() == Node::KIND_GROUP
) {
1370 res
= cppu::queryInterface(
1371 aType
, static_cast< css::beans::XPropertySetInfo
* >(this),
1372 static_cast< css::beans::XPropertySet
* >(this),
1373 static_cast< css::beans::XMultiPropertySet
* >(this),
1374 static_cast< css::beans::XHierarchicalPropertySet
* >(this),
1375 static_cast< css::beans::XMultiHierarchicalPropertySet
* >(this),
1376 static_cast< css::beans::XHierarchicalPropertySetInfo
* >(this));
1377 if (res
.hasValue()) {
1381 if (getRootAccess()->isUpdate()) {
1382 res
= cppu::queryInterface(
1383 aType
, static_cast< css::container::XNameReplace
* >(this),
1384 static_cast< css::container::XHierarchicalNameReplace
* >(this));
1385 if (res
.hasValue()) {
1388 if (getNode()->kind() != Node::KIND_GROUP
||
1389 dynamic_cast< GroupNode
* >(getNode().get())->isExtensible())
1391 res
= cppu::queryInterface(
1392 aType
, static_cast< css::container::XNameContainer
* >(this));
1393 if (res
.hasValue()) {
1397 if (getNode()->kind() == Node::KIND_SET
) {
1398 res
= cppu::queryInterface(
1399 aType
, static_cast< css::lang::XSingleServiceFactory
* >(this));
1405 Components
& Access::getComponents() const {
1409 void Access::checkLocalizedPropertyAccess() {
1410 if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY
&&
1411 !Components::allLocales(getRootAccess()->getLocale()))
1413 throw css::uno::RuntimeException(
1414 OUString("configmgr Access to specialized LocalizedPropertyNode"),
1415 static_cast< cppu::OWeakObject
* >(this));
1419 rtl::Reference
< Node
> Access::getParentNode() {
1420 rtl::Reference
< Access
> parent(getParentAccess());
1421 return parent
.is() ? parent
->getNode() : rtl::Reference
< Node
>();
1424 rtl::Reference
< ChildAccess
> Access::getChild(OUString
const & name
) {
1425 if (getNode()->kind() == Node::KIND_LOCALIZED_PROPERTY
&& name
.match("*")) {
1426 OUString
locale(name
.copy(1));
1427 if (locale
.match("*")) {
1430 ("access best-matching localized property value via"
1431 " \"*<locale>\" with <locale> \"")
1432 << locale
<< "\" recursively starting with \"*\"");
1433 return getChild(locale
);
1436 locale
.isEmpty(), "configmgr",
1437 ("access best-matching localized property value via \"*<locale>\""
1438 " with empty <locale>; falling back to defaults"));
1439 if (!locale
.isEmpty()) {
1440 // Find best match using an adaption of RFC 4647 lookup matching
1441 // rules, removing "-" or "_" delimited segments from the end:
1443 rtl::Reference
< ChildAccess
> child(getChild(locale
));
1447 sal_Int32 i
= locale
.getLength() - 1;
1448 while (i
> 0 && locale
[i
] != '-' && locale
[i
] != '_') {
1454 locale
= locale
.copy(0, i
);
1456 // As a workaround for broken xcu data that does not use shortest
1457 // xml:lang attributes, look for the first entry with the same first
1458 // segment as the requested language tag before falling back to
1459 // defaults (see fdo#33638):
1461 !locale
.isEmpty() && locale
.indexOf('-') == -1 &&
1462 locale
.indexOf('_') == -1);
1463 std::vector
< rtl::Reference
< ChildAccess
> > children(
1465 for (std::vector
< rtl::Reference
< ChildAccess
> >::iterator
i(
1467 i
!= children
.end(); ++i
)
1469 OUString
name2((*i
)->getNameInternal());
1470 if (name2
.match(locale
) &&
1471 (name2
.getLength() == locale
.getLength() ||
1472 name2
[locale
.getLength()] == '-' ||
1473 name2
[locale
.getLength()] == '_'))
1479 // Defaults are the "en-US" locale, the "en" locale, the empty string
1480 // locale, the first child (if any), or a null ChildAccess, in that
1482 rtl::Reference
< ChildAccess
> child(getChild("en-US"));
1486 child
= getChild("en");
1490 child
= getChild(OUString());
1494 std::vector
< rtl::Reference
< ChildAccess
> > children(getAllChildren());
1495 if (!children
.empty()) {
1496 return children
.front();
1498 return rtl::Reference
< ChildAccess
>();
1500 ModifiedChildren::iterator
i(modifiedChildren_
.find(name
));
1501 return i
== modifiedChildren_
.end()
1502 ? getUnmodifiedChild(name
) : getModifiedChild(i
);
1505 std::vector
< rtl::Reference
< ChildAccess
> > Access::getAllChildren() {
1506 std::vector
< rtl::Reference
< ChildAccess
> > vec
;
1507 NodeMap
const & members
= getNode()->getMembers();
1508 for (NodeMap::const_iterator
i(members
.begin()); i
!= members
.end(); ++i
) {
1509 if (modifiedChildren_
.find(i
->first
) == modifiedChildren_
.end()) {
1510 vec
.push_back(getUnmodifiedChild(i
->first
));
1511 assert(vec
.back().is());
1514 for (ModifiedChildren::iterator
i(modifiedChildren_
.begin());
1515 i
!= modifiedChildren_
.end(); ++i
)
1517 rtl::Reference
< ChildAccess
> child(getModifiedChild(i
));
1519 vec
.push_back(child
);
1525 void Access::checkValue(css::uno::Any
const & value
, Type type
, bool nillable
) {
1530 // fall through (cannot happen)
1535 switch (getDynamicType(value
)) {
1538 // fall through (cannot happen)
1551 ok
= value
.hasValue() ? value
.isExtractableTo(mapType(type
)) : nillable
;
1555 throw css::lang::IllegalArgumentException(
1556 OUString("configmgr inappropriate property value"),
1557 static_cast< cppu::OWeakObject
* >(this), -1);
1561 void Access::insertLocalizedValueChild(
1562 OUString
const & name
, css::uno::Any
const & value
,
1563 Modifications
* localModifications
)
1565 assert(localModifications
!= 0);
1566 LocalizedPropertyNode
* locprop
= dynamic_cast< LocalizedPropertyNode
* >(
1568 checkValue(value
, locprop
->getStaticType(), locprop
->isNillable());
1569 rtl::Reference
< ChildAccess
> child(
1571 components_
, getRootAccess(), this, name
,
1572 new LocalizedValueNode(Data::NO_LAYER
, value
)));
1573 markChildAsModified(child
);
1574 localModifications
->add(child
->getRelativePath());
1577 void Access::reportChildChanges(
1578 std::vector
< css::util::ElementChange
> * changes
)
1580 assert(changes
!= 0);
1581 for (ModifiedChildren::iterator
i(modifiedChildren_
.begin());
1582 i
!= modifiedChildren_
.end(); ++i
)
1584 rtl::Reference
< ChildAccess
> child(getModifiedChild(i
));
1586 child
->reportChildChanges(changes
);
1587 changes
->push_back(css::util::ElementChange());
1588 //TODO: changed value and/or inserted node
1590 changes
->push_back(css::util::ElementChange()); //TODO: removed node
1595 void Access::commitChildChanges(
1596 bool valid
, Modifications
* globalModifications
)
1598 assert(globalModifications
!= 0);
1599 while (!modifiedChildren_
.empty()) {
1600 bool childValid
= valid
;
1601 ModifiedChildren::iterator
i(modifiedChildren_
.begin());
1602 rtl::Reference
< ChildAccess
> child(getModifiedChild(i
));
1604 childValid
= childValid
&& !child
->isFinalized();
1605 child
->commitChanges(childValid
, globalModifications
);
1606 //TODO: currently, this is called here for directly inserted
1607 // children as well as for children whose sub-children were
1608 // modified (and should never be called for directly removed
1609 // children); clarify what exactly should happen here for
1610 // directly inserted children
1612 NodeMap
& members
= getNode()->getMembers();
1613 NodeMap::iterator
j(members
.find(i
->first
));
1616 if (j
!= members
.end()) {
1617 childValid
= childValid
&&
1618 j
->second
->getFinalized() == Data::NO_LAYER
;
1620 child
->getNode()->setMandatory(j
->second
->getMandatory());
1624 members
[i
->first
] = child
->getNode();
1628 childValid
= childValid
&& j
!= members
.end() &&
1629 j
->second
->getFinalized() == Data::NO_LAYER
&&
1630 j
->second
->getMandatory() == Data::NO_LAYER
;
1635 if (childValid
&& i
->second
.directlyModified
) {
1636 Path
path(getAbsolutePath());
1637 path
.push_back(i
->first
);
1638 components_
.addModification(path
);
1639 globalModifications
->add(path
);
1641 i
->second
.child
->committed();
1642 modifiedChildren_
.erase(i
);
1646 void Access::initBroadcasterAndChanges(
1647 Modifications::Node
const & modifications
, Broadcaster
* broadcaster
,
1648 std::vector
< css::util::ElementChange
> * allChanges
)
1650 assert(broadcaster
!= 0);
1651 comphelper::SequenceAsVector
< css::beans::PropertyChangeEvent
> propChanges
;
1652 bool collectPropChanges
= !propertiesChangeListeners_
.empty();
1653 for (Modifications::Node::Children::const_iterator
i(
1654 modifications
.children
.begin());
1655 i
!= modifications
.children
.end(); ++i
)
1657 rtl::Reference
< ChildAccess
> child(getChild(i
->first
));
1659 switch (child
->getNode()->kind()) {
1660 case Node::KIND_LOCALIZED_PROPERTY
:
1661 if (!i
->second
.children
.empty()) {
1662 if (Components::allLocales(getRootAccess()->getLocale())) {
1663 child
->initBroadcasterAndChanges(
1664 i
->second
, broadcaster
, allChanges
);
1665 //TODO: if allChanges==0, recurse only into children
1668 //TODO: filter child mods that are irrelevant for
1670 for (ContainerListeners::iterator
j(
1671 containerListeners_
.begin());
1672 j
!= containerListeners_
.end(); ++j
)
1675 addContainerElementReplacedNotification(
1677 css::container::ContainerEvent(
1678 static_cast< cppu::OWeakObject
* >(
1680 css::uno::makeAny(i
->first
),
1681 css::uno::Any(), css::uno::Any()));
1682 //TODO: non-void Element, ReplacedElement
1684 PropertyChangeListeners::iterator
j(
1685 propertyChangeListeners_
.find(i
->first
));
1686 if (j
!= propertyChangeListeners_
.end()) {
1687 for (PropertyChangeListenersElement::iterator
k(
1689 k
!= j
->second
.end(); ++k
)
1691 broadcaster
->addPropertyChangeNotification(
1693 css::beans::PropertyChangeEvent(
1694 static_cast< cppu::OWeakObject
* >(
1696 i
->first
, false, -1, css::uno::Any(),
1700 j
= propertyChangeListeners_
.find(OUString());
1701 if (j
!= propertyChangeListeners_
.end()) {
1702 for (PropertyChangeListenersElement::iterator
k(
1704 k
!= j
->second
.end(); ++k
)
1706 broadcaster
->addPropertyChangeNotification(
1708 css::beans::PropertyChangeEvent(
1709 static_cast< cppu::OWeakObject
* >(
1711 i
->first
, false, -1, css::uno::Any(),
1715 if (allChanges
!= 0) {
1716 allChanges
->push_back(
1717 css::util::ElementChange(
1719 child
->getRelativePathRepresentation()),
1720 css::uno::Any(), css::uno::Any()));
1721 //TODO: non-void Element, ReplacedElement
1723 if (collectPropChanges
) {
1724 propChanges
.push_back(
1725 css::beans::PropertyChangeEvent(
1726 static_cast< cppu::OWeakObject
* >(this),
1727 i
->first
, false, -1, css::uno::Any(),
1732 // else: spurious Modifications::Node not representing a change
1734 case Node::KIND_LOCALIZED_VALUE
:
1735 assert(Components::allLocales(getRootAccess()->getLocale()));
1736 for (ContainerListeners::iterator
j(
1737 containerListeners_
.begin());
1738 j
!= containerListeners_
.end(); ++j
)
1740 broadcaster
->addContainerElementReplacedNotification(
1742 css::container::ContainerEvent(
1743 static_cast< cppu::OWeakObject
* >(this),
1744 css::uno::makeAny(i
->first
), child
->asValue(),
1746 //TODO: distinguish add/modify; non-void ReplacedElement
1748 if (allChanges
!= 0) {
1749 allChanges
->push_back(
1750 css::util::ElementChange(
1752 child
->getRelativePathRepresentation()),
1753 child
->asValue(), css::uno::Any()));
1754 //TODO: non-void ReplacedElement
1756 assert(!collectPropChanges
);
1758 case Node::KIND_PROPERTY
:
1760 for (ContainerListeners::iterator
j(
1761 containerListeners_
.begin());
1762 j
!= containerListeners_
.end(); ++j
)
1764 broadcaster
->addContainerElementReplacedNotification(
1766 css::container::ContainerEvent(
1767 static_cast< cppu::OWeakObject
* >(this),
1768 css::uno::makeAny(i
->first
), child
->asValue(),
1770 //TODO: distinguish add/remove/modify; non-void
1773 PropertyChangeListeners::iterator
j(
1774 propertyChangeListeners_
.find(i
->first
));
1775 if (j
!= propertyChangeListeners_
.end()) {
1776 for (PropertyChangeListenersElement::iterator
k(
1778 k
!= j
->second
.end(); ++k
)
1780 broadcaster
->addPropertyChangeNotification(
1782 css::beans::PropertyChangeEvent(
1783 static_cast< cppu::OWeakObject
* >(this),
1784 i
->first
, false, -1, css::uno::Any(),
1788 j
= propertyChangeListeners_
.find(OUString());
1789 if (j
!= propertyChangeListeners_
.end()) {
1790 for (PropertyChangeListenersElement::iterator
k(
1792 k
!= j
->second
.end(); ++k
)
1794 broadcaster
->addPropertyChangeNotification(
1796 css::beans::PropertyChangeEvent(
1797 static_cast< cppu::OWeakObject
* >(this),
1798 i
->first
, false, -1, css::uno::Any(),
1802 if (allChanges
!= 0) {
1803 allChanges
->push_back(
1804 css::util::ElementChange(
1806 child
->getRelativePathRepresentation()),
1807 child
->asValue(), css::uno::Any()));
1808 //TODO: non-void ReplacedElement
1810 if (collectPropChanges
) {
1811 propChanges
.push_back(
1812 css::beans::PropertyChangeEvent(
1813 static_cast< cppu::OWeakObject
* >(this),
1814 i
->first
, false, -1, css::uno::Any(),
1819 case Node::KIND_GROUP
:
1820 case Node::KIND_SET
:
1821 if (i
->second
.children
.empty()) {
1822 if (!child
->getNode()->getTemplateName().isEmpty()) {
1823 for (ContainerListeners::iterator
j(
1824 containerListeners_
.begin());
1825 j
!= containerListeners_
.end(); ++j
)
1828 addContainerElementInsertedNotification(
1830 css::container::ContainerEvent(
1831 static_cast< cppu::OWeakObject
* >(
1833 css::uno::makeAny(i
->first
),
1834 child
->asValue(), css::uno::Any()));
1836 if (allChanges
!= 0) {
1837 allChanges
->push_back(
1838 css::util::ElementChange(
1840 child
->getRelativePathRepresentation()),
1841 css::uno::Any(), css::uno::Any()));
1842 //TODO: non-void Element, ReplacedElement
1845 // else: spurious Modifications::Node not representing a
1848 child
->initBroadcasterAndChanges(
1849 i
->second
, broadcaster
, allChanges
);
1850 //TODO: if allChanges==0, recurse only into children w/
1854 case Node::KIND_ROOT
:
1855 assert(false); // this cannot happen
1859 switch (getNode()->kind()) {
1860 case Node::KIND_LOCALIZED_PROPERTY
:
1861 // Removed localized property value:
1862 assert(Components::allLocales(getRootAccess()->getLocale()));
1863 for (ContainerListeners::iterator
j(
1864 containerListeners_
.begin());
1865 j
!= containerListeners_
.end(); ++j
)
1867 broadcaster
->addContainerElementRemovedNotification(
1869 css::container::ContainerEvent(
1870 static_cast< cppu::OWeakObject
* >(this),
1871 css::uno::makeAny(i
->first
), css::uno::Any(),
1873 //TODO: non-void ReplacedElement
1875 if (allChanges
!= 0) {
1876 OUStringBuffer
path(getRelativePathRepresentation());
1877 if (path
.getLength() != 0) {
1878 path
.append(sal_Unicode('/'));
1881 Data::createSegment(
1884 allChanges
->push_back(
1885 css::util::ElementChange(
1886 css::uno::makeAny(path
.makeStringAndClear()),
1887 css::uno::Any(), css::uno::Any()));
1888 //TODO: non-void ReplacedElement
1890 assert(!collectPropChanges
);
1892 case Node::KIND_GROUP
:
1894 // Removed (non-localized) extension property:
1895 for (ContainerListeners::iterator
j(
1896 containerListeners_
.begin());
1897 j
!= containerListeners_
.end(); ++j
)
1899 broadcaster
->addContainerElementRemovedNotification(
1901 css::container::ContainerEvent(
1902 static_cast< cppu::OWeakObject
* >(this),
1903 css::uno::makeAny(i
->first
), css::uno::Any(),
1905 //TODO: non-void ReplacedElement
1907 PropertyChangeListeners::iterator
j(
1908 propertyChangeListeners_
.find(i
->first
));
1909 if (j
!= propertyChangeListeners_
.end()) {
1910 for (PropertyChangeListenersElement::iterator
k(
1912 k
!= j
->second
.end(); ++k
)
1914 broadcaster
->addPropertyChangeNotification(
1916 css::beans::PropertyChangeEvent(
1917 static_cast< cppu::OWeakObject
* >(this),
1918 i
->first
, false, -1, css::uno::Any(),
1922 j
= propertyChangeListeners_
.find(OUString());
1923 if (j
!= propertyChangeListeners_
.end()) {
1924 for (PropertyChangeListenersElement::iterator
k(
1926 k
!= j
->second
.end(); ++k
)
1928 broadcaster
->addPropertyChangeNotification(
1930 css::beans::PropertyChangeEvent(
1931 static_cast< cppu::OWeakObject
* >(this),
1932 i
->first
, false, -1, css::uno::Any(),
1936 if (allChanges
!= 0) {
1937 OUStringBuffer
path(
1938 getRelativePathRepresentation());
1939 if (path
.getLength() != 0) {
1940 path
.append(sal_Unicode('/'));
1942 path
.append(i
->first
);
1943 allChanges
->push_back(
1944 css::util::ElementChange(
1945 css::uno::makeAny(path
.makeStringAndClear()),
1946 css::uno::Any(), css::uno::Any()));
1947 //TODO: non-void ReplacedElement
1949 if (collectPropChanges
) {
1950 propChanges
.push_back(
1951 css::beans::PropertyChangeEvent(
1952 static_cast< cppu::OWeakObject
* >(this),
1953 i
->first
, false, -1, css::uno::Any(),
1958 case Node::KIND_SET
:
1959 // Removed set member:
1960 if (i
->second
.children
.empty()) {
1961 for (ContainerListeners::iterator
j(
1962 containerListeners_
.begin());
1963 j
!= containerListeners_
.end(); ++j
)
1965 broadcaster
->addContainerElementRemovedNotification(
1967 css::container::ContainerEvent(
1968 static_cast< cppu::OWeakObject
* >(this),
1969 css::uno::makeAny(i
->first
),
1970 css::uno::Any(), css::uno::Any()));
1971 //TODO: non-void ReplacedElement
1973 if (allChanges
!= 0) {
1974 OUStringBuffer
path(
1975 getRelativePathRepresentation());
1976 if (path
.getLength() != 0) {
1977 path
.append(sal_Unicode('/'));
1980 Data::createSegment(
1983 allChanges
->push_back(
1984 css::util::ElementChange(
1985 css::uno::makeAny(path
.makeStringAndClear()),
1986 css::uno::Any(), css::uno::Any()));
1987 //TODO: non-void ReplacedElement
1990 // else: spurious Modifications::Node not representing a change
1993 assert(false); // this cannot happen
1998 if (!propChanges
.empty()) {
1999 css::uno::Sequence
< css::beans::PropertyChangeEvent
> seq(
2000 propChanges
.getAsConstList());
2001 for (PropertiesChangeListeners::iterator
i(
2002 propertiesChangeListeners_
.begin());
2003 i
!= propertiesChangeListeners_
.end(); ++i
)
2005 broadcaster
->addPropertiesChangeNotification(*i
, seq
);
2010 bool Access::isDisposed() const {
2014 Access::ModifiedChild::ModifiedChild() {}
2016 Access::ModifiedChild::ModifiedChild(
2017 rtl::Reference
< ChildAccess
> const & theChild
, bool theDirectlyModified
):
2018 child(theChild
), directlyModified(theDirectlyModified
)
2021 rtl::Reference
< ChildAccess
> Access::getModifiedChild(
2022 ModifiedChildren::iterator
const & childIterator
)
2024 return (childIterator
->second
.child
->getParentAccess() == this &&
2025 (childIterator
->second
.child
->getNameInternal() ==
2026 childIterator
->first
))
2027 ? childIterator
->second
.child
: rtl::Reference
< ChildAccess
>();
2030 rtl::Reference
< ChildAccess
> Access::getUnmodifiedChild(
2031 OUString
const & name
)
2033 assert(modifiedChildren_
.find(name
) == modifiedChildren_
.end());
2034 rtl::Reference
< Node
> node(getNode()->getMember(name
));
2036 return rtl::Reference
< ChildAccess
>();
2038 WeakChildMap::iterator
i(cachedChildren_
.find(name
));
2039 if (i
!= cachedChildren_
.end()) {
2040 rtl::Reference
< ChildAccess
> child
;
2041 if (i
->second
->acquireCounting() > 1) {
2042 child
.set(i
->second
); // must not throw
2044 i
->second
->releaseNondeleting();
2046 child
->setNode(node
);
2050 rtl::Reference
< ChildAccess
> child(
2051 new ChildAccess(components_
, getRootAccess(), this, name
, node
));
2052 cachedChildren_
[name
] = child
.get();
2056 rtl::Reference
< ChildAccess
> Access::getSubChild(OUString
const & path
) {
2058 // For backwards compatibility, allow absolute paths where meaningful:
2059 if (!path
.isEmpty() && path
[0] == '/') {
2061 if (!getRootAccess().is()) {
2062 return rtl::Reference
< ChildAccess
>();
2064 Path
abs(getAbsolutePath());
2065 for (Path::iterator
j(abs
.begin()); j
!= abs
.end(); ++j
) {
2068 OUString templateName1
;
2069 i
= Data::parseSegment(
2070 path
, i
, &name1
, &setElement1
, &templateName1
);
2071 if (i
== -1 || (i
!= path
.getLength() && path
[i
] != '/')) {
2072 return rtl::Reference
< ChildAccess
>();
2076 OUString templateName2
;
2077 Data::parseSegment(*j
, 0, &name2
, &setElement2
, &templateName2
);
2078 if (name1
!= name2
|| setElement1
!= setElement2
||
2080 !Data::equalTemplateNames(templateName1
, templateName2
)))
2082 return rtl::Reference
< ChildAccess
>();
2084 if (i
!= path
.getLength()) {
2089 for (rtl::Reference
< Access
> parent(this);;) {
2092 OUString templateName
;
2093 i
= Data::parseSegment(path
, i
, &name
, &setElement
, &templateName
);
2094 if (i
== -1 || (i
!= path
.getLength() && path
[i
] != '/')) {
2095 return rtl::Reference
< ChildAccess
>();
2097 rtl::Reference
< ChildAccess
> child(parent
->getChild(name
));
2099 return rtl::Reference
< ChildAccess
>();
2102 rtl::Reference
< Node
> p(parent
->getNode());
2103 switch (p
->kind()) {
2104 case Node::KIND_LOCALIZED_PROPERTY
:
2105 if (!Components::allLocales(getRootAccess()->getLocale()) ||
2106 !templateName
.isEmpty())
2108 return rtl::Reference
< ChildAccess
>();
2111 case Node::KIND_SET
:
2112 if (!templateName
.isEmpty() &&
2113 !dynamic_cast< SetNode
* >(p
.get())->isValidTemplate(
2116 return rtl::Reference
< ChildAccess
>();
2120 return rtl::Reference
< ChildAccess
>();
2123 // For backwards compatibility, ignore a final slash after non-value
2125 if (child
->isValue()) {
2126 return i
== path
.getLength()
2127 ? child
: rtl::Reference
< ChildAccess
>();
2128 } else if (i
>= path
.getLength() - 1) {
2132 parent
= child
.get();
2136 bool Access::setChildProperty(
2137 OUString
const & name
, css::uno::Any
const & value
,
2138 Modifications
* localModifications
)
2140 assert(localModifications
!= 0);
2141 rtl::Reference
< ChildAccess
> child(getChild(name
));
2145 child
->checkFinalized();
2146 child
->setProperty(value
, localModifications
);
2150 css::beans::Property
Access::asProperty() {
2151 css::uno::Type type
;
2154 rtl::Reference
< Node
> p(getNode());
2155 switch (p
->kind()) {
2156 case Node::KIND_PROPERTY
:
2158 PropertyNode
* prop
= dynamic_cast< PropertyNode
* >(p
.get());
2159 type
= mapType(prop
->getStaticType());
2160 nillable
= prop
->isNillable();
2161 removable
= prop
->isExtension();
2164 case Node::KIND_LOCALIZED_PROPERTY
:
2166 LocalizedPropertyNode
* locprop
=
2167 dynamic_cast< LocalizedPropertyNode
*>(p
.get());
2168 if (Components::allLocales(getRootAccess()->getLocale())) {
2169 type
= cppu::UnoType
< css::uno::XInterface
>::get();
2173 type
= mapType(locprop
->getStaticType());
2174 removable
= false; //TODO ???
2176 nillable
= locprop
->isNillable();
2179 case Node::KIND_LOCALIZED_VALUE
:
2181 LocalizedPropertyNode
* locprop
=
2182 dynamic_cast< LocalizedPropertyNode
* >(getParentNode().get());
2183 type
= mapType(locprop
->getStaticType());
2184 nillable
= locprop
->isNillable();
2185 removable
= false; //TODO ???
2189 type
= cppu::UnoType
< css::uno::XInterface
>::get(); //TODO: correct?
2191 rtl::Reference
< Node
> parent(getParentNode());
2192 removable
= parent
.is() && parent
->kind() == Node::KIND_SET
;
2195 return css::beans::Property(
2196 getNameInternal(), -1, type
,
2197 (css::beans::PropertyAttribute::BOUND
| //TODO: correct for group/set?
2198 css::beans::PropertyAttribute::CONSTRAINED
|
2199 (nillable
? css::beans::PropertyAttribute::MAYBEVOID
: 0) |
2200 (getRootAccess()->isUpdate() && removable
2201 ? css::beans::PropertyAttribute::REMOVABLE
: 0) |
2202 (!getRootAccess()->isUpdate() || p
->getFinalized() != Data::NO_LAYER
2203 ? css::beans::PropertyAttribute::READONLY
: 0))); //TODO: MAYBEDEFAULT
2206 void Access::checkFinalized() {
2207 if (isFinalized()) {
2208 throw css::lang::IllegalArgumentException(
2209 OUString("configmgr modification of finalized item"),
2210 static_cast< cppu::OWeakObject
* >(this), -1);
2214 void Access::checkKnownProperty(OUString
const & descriptor
) {
2215 if (descriptor
.isEmpty()) {
2218 rtl::Reference
< ChildAccess
> child(getChild(descriptor
));
2220 switch (child
->getNode()->kind()) {
2221 case Node::KIND_PROPERTY
:
2223 case Node::KIND_LOCALIZED_PROPERTY
:
2224 if (!Components::allLocales(getRootAccess()->getLocale())) {
2228 case Node::KIND_LOCALIZED_VALUE
:
2229 if (Components::allLocales(getRootAccess()->getLocale())) {
2237 throw css::beans::UnknownPropertyException(
2238 descriptor
, static_cast< cppu::OWeakObject
* >(this));
2241 rtl::Reference
< ChildAccess
> Access::getFreeSetMember(
2242 css::uno::Any
const & value
)
2244 rtl::Reference
< ChildAccess
> freeAcc
;
2245 css::uno::Reference
< css::lang::XUnoTunnel
> tunnel
;
2249 reinterpret_cast< ChildAccess
* >(
2250 tunnel
->getSomething(ChildAccess::getTunnelId())));
2252 if (!freeAcc
.is() || freeAcc
->getParentAccess().is() ||
2253 (freeAcc
->isInTransaction() &&
2254 freeAcc
->getRootAccess() != getRootAccess()))
2256 throw css::lang::IllegalArgumentException(
2257 OUString("configmgr inappropriate set element"),
2258 static_cast< cppu::OWeakObject
* >(this), 1);
2260 assert(dynamic_cast< SetNode
* >(getNode().get()) != 0);
2261 if (!dynamic_cast< SetNode
* >(getNode().get())->isValidTemplate(
2262 freeAcc
->getNode()->getTemplateName()))
2264 throw css::lang::IllegalArgumentException(
2265 OUString("configmgr inappropriate set element"),
2266 static_cast< cppu::OWeakObject
* >(this), 1);
2271 rtl::Reference
< Access
> Access::getNotificationRoot() {
2272 for (rtl::Reference
< Access
> p(this);;) {
2273 rtl::Reference
< Access
> parent(p
->getParentAccess());
2282 bool Access::thisIs(int what
) {
2283 osl::MutexGuard
g(*lock_
);
2284 rtl::Reference
< Node
> p(getNode());
2285 Node::Kind
k(p
->kind());
2286 return (k
!= Node::KIND_PROPERTY
&& k
!= Node::KIND_LOCALIZED_VALUE
&&
2287 ((what
& IS_GROUP
) == 0 || k
== Node::KIND_GROUP
) &&
2288 ((what
& IS_SET
) == 0 || k
== Node::KIND_SET
) &&
2289 ((what
& IS_EXTENSIBLE
) == 0 || k
!= Node::KIND_GROUP
||
2290 dynamic_cast< GroupNode
* >(p
.get())->isExtensible()) &&
2291 ((what
& IS_GROUP_MEMBER
) == 0 ||
2292 getParentNode()->kind() == Node::KIND_GROUP
)) ||
2293 ((what
& IS_SET_MEMBER
) == 0 ||
2294 getParentNode()->kind() == Node::KIND_SET
) ||
2295 ((what
& IS_UPDATE
) == 0 || getRootAccess()->isUpdate());
2301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */