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

Generated by: LCOV version 1.10