LCOV - code coverage report
Current view: top level - configmgr/source - access.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 637 1118 57.0 %
Date: 2015-06-13 12:38:46 Functions: 57 85 67.1 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11