LCOV - code coverage report
Current view: top level - unotools/source/config - configitem.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 315 495 63.6 %
Date: 2014-04-11 Functions: 31 36 86.1 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "unotools/configitem.hxx"
      21             : #include "unotools/configmgr.hxx"
      22             : #include "unotools/configpaths.hxx"
      23             : #include <comphelper/processfactory.hxx>
      24             : #include <com/sun/star/beans/XMultiPropertySet.hpp>
      25             : #include <com/sun/star/beans/XPropertySet.hpp>
      26             : #include <com/sun/star/util/XChangesListener.hpp>
      27             : #include <com/sun/star/util/XChangesNotifier.hpp>
      28             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      29             : #include <com/sun/star/container/XHierarchicalName.hpp>
      30             : #include <com/sun/star/configuration/XTemplateContainer.hpp>
      31             : #include <com/sun/star/container/XNameContainer.hpp>
      32             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      33             : #include <com/sun/star/lang/XServiceInfo.hpp>
      34             : #include <com/sun/star/awt/XRequestCallback.hpp>
      35             : #include <com/sun/star/beans/PropertyValue.hpp>
      36             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      37             : #include <com/sun/star/util/XStringEscape.hpp>
      38             : #include <com/sun/star/util/XChangesBatch.hpp>
      39             : #include <osl/diagnose.h>
      40             : #include <tools/solarmutex.hxx>
      41             : #include <rtl/ustrbuf.hxx>
      42             : 
      43             : using namespace utl;
      44             : using namespace com::sun::star::uno;
      45             : using namespace com::sun::star::util;
      46             : using namespace com::sun::star::lang;
      47             : using namespace com::sun::star::beans;
      48             : using namespace com::sun::star::container;
      49             : using namespace com::sun::star::configuration;
      50             : 
      51             : #include <cppuhelper/implbase1.hxx>
      52             : 
      53             : #ifdef DBG_UTIL
      54             : static inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx)
      55             : {
      56             :     OString sMsg(cText);
      57             :     sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US);
      58             :     OSL_FAIL(sMsg.getStr());
      59             : }
      60             : #define CATCH_INFO(a) \
      61             : catch(const Exception& rEx)   \
      62             : {                       \
      63             :     lcl_CFG_DBG_EXCEPTION(a, rEx);\
      64             : }
      65             : #else
      66             :     #define CATCH_INFO(a) catch(const Exception&){}
      67             : #endif
      68             : 
      69             : /*
      70             :     The ConfigChangeListener_Impl receives notifications from the configuration about changes that
      71             :     have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its
      72             :     "CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired
      73             :     before doing so.
      74             : */
      75             : 
      76             : namespace utl{
      77             :     class ConfigChangeListener_Impl : public cppu::WeakImplHelper1
      78             :     <
      79             :         com::sun::star::util::XChangesListener
      80             :     >
      81             :     {
      82             :         public:
      83             :             ConfigItem*                 pParent;
      84             :             const Sequence< OUString >  aPropertyNames;
      85             :             ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames);
      86             :             virtual ~ConfigChangeListener_Impl();
      87             : 
      88             :         //XChangesListener
      89             :         virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
      90             : 
      91             :         //XEventListener
      92             :         virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
      93             :     };
      94             : }
      95             : 
      96             : class ValueCounter_Impl
      97             : {
      98             :     sal_Int16& rCnt;
      99             : public:
     100        1766 :     ValueCounter_Impl(sal_Int16& rCounter):
     101        1766 :         rCnt(rCounter)
     102        1766 :             {rCnt++;}
     103        1766 :     ~ValueCounter_Impl()
     104             :             {
     105             :                 OSL_ENSURE(rCnt>0, "RefCount < 0 ??");
     106        1766 :                 rCnt--;
     107        1766 :             }
     108             : };
     109             : 
     110        8230 : ConfigChangeListener_Impl::ConfigChangeListener_Impl(
     111             :              ConfigItem& rItem, const Sequence< OUString >& rNames) :
     112             :     pParent(&rItem),
     113        8230 :     aPropertyNames(rNames)
     114             : {
     115        8230 : }
     116             : 
     117       14964 : ConfigChangeListener_Impl::~ConfigChangeListener_Impl()
     118             : {
     119       14964 : }
     120             : 
     121       14584 : static bool lcl_Find(
     122             :         const OUString& rTemp,
     123             :         const OUString* pCheckPropertyNames,
     124             :         sal_Int32 nLength)
     125             : {
     126             :     //return true if the path is completely correct or if it is longer
     127             :     //i.e ...Print/Content/Graphic and .../Print
     128      121121 :     for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++)
     129      116646 :         if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) )
     130       10109 :             return true;
     131        4475 :     return false;
     132             : }
     133             : 
     134       12384 : void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException, std::exception)
     135             : {
     136       12384 :     const ElementChange* pElementChanges = rEvent.Changes.getConstArray();
     137             : 
     138       12384 :     Sequence<OUString>  aChangedNames(rEvent.Changes.getLength());
     139       12384 :     OUString* pNames = aChangedNames.getArray();
     140             : 
     141       12384 :     const OUString* pCheckPropertyNames = aPropertyNames.getConstArray();
     142             : 
     143       12384 :     sal_Int32 nNotify = 0;
     144       26968 :     for(int i = 0; i < aChangedNames.getLength(); i++)
     145             :     {
     146       14584 :         OUString sTemp;
     147       14584 :         pElementChanges[i].Accessor >>= sTemp;
     148       14584 :         if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength()))
     149       10109 :             pNames[nNotify++] = sTemp;
     150       14584 :     }
     151       12384 :     if( nNotify )
     152             :     {
     153        8975 :         if ( ::tools::SolarMutex::Acquire() )
     154             :         {
     155        8975 :             aChangedNames.realloc(nNotify);
     156        8975 :             pParent->CallNotify(aChangedNames);
     157        8975 :             ::tools::SolarMutex::Release();
     158             :         }
     159       12384 :     }
     160       12384 : }
     161             : 
     162           0 : void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException, std::exception)
     163             : {
     164           0 :     pParent->RemoveChangesListener();
     165           0 : }
     166             : 
     167       15494 : ConfigItem::ConfigItem(const OUString &rSubTree, sal_Int16 nSetMode ) :
     168             :     sSubTree(rSubTree),
     169             :     m_nMode(nSetMode),
     170             :     m_bIsModified(false),
     171             :     m_bEnableInternalNotification(false),
     172       15494 :     m_nInValueChange(0)
     173             : {
     174       15494 :     if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE))
     175         610 :         ConfigManager::getConfigManager().addConfigItem(*this);
     176             :     else
     177       14884 :         m_xHierarchyAccess = ConfigManager::getConfigManager().addConfigItem(*this);
     178       15494 : }
     179             : 
     180       28732 : ConfigItem::~ConfigItem()
     181             : {
     182       14366 :     RemoveChangesListener();
     183       14366 :     ConfigManager::getConfigManager().removeConfigItem(*this);
     184       14366 : }
     185             : 
     186        8975 : void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames )
     187             : {
     188             :     // the call is forwarded to the virtual Notify() method
     189             :     // it is pure virtual, so all classes deriving from ConfigItem have to decide how they
     190             :     // want to notify listeners
     191        8975 :     if(!IsInValueChange() || m_bEnableInternalNotification)
     192          66 :         Notify(rPropertyNames);
     193        8975 : }
     194             : 
     195           0 : void ConfigItem::impl_packLocalizedProperties(  const   Sequence< OUString >&   lInNames    ,
     196             :                                                 const   Sequence< Any >&        lInValues   ,
     197             :                                                         Sequence< Any >&        lOutValues  )
     198             : {
     199             :     // Safe impossible cases.
     200             :     // This method should be called for special ConfigItem-mode only!
     201             :     OSL_ENSURE( ((m_nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" );
     202             : 
     203             :     sal_Int32                   nSourceCounter;      // used to step during input lists
     204             :     sal_Int32                   nSourceSize;         // marks end of loop over input lists
     205             :     sal_Int32                   nDestinationCounter; // actual position in output lists
     206             :     sal_Int32                   nPropertyCounter;    // counter of inner loop for Sequence< PropertyValue >
     207             :     sal_Int32                   nPropertiesSize;     // marks end of inner loop
     208           0 :     Sequence< OUString >        lPropertyNames;      // list of all locales for localized entry
     209           0 :     Sequence< PropertyValue >   lProperties;         // localized values of an configuration entry packed for return
     210           0 :     Reference< XInterface >     xLocalizedNode;      // if cfg entry is localized ... lInValues contains an XInterface!
     211             : 
     212             :     // Optimise follow algorithm ... A LITTLE BIT :-)
     213             :     // There exist two different possibilities:
     214             :     //  i ) There exist no localized entries ...                        =>  size of lOutValues will be the same like lInNames/lInValues!
     215             :     //  ii) There exist some (mostly one or two) localized entries ...  =>  size of lOutValues will be the same like lInNames/lInValues!
     216             :     //  ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service).
     217             :     //      We read all his child nodes and pack it into Sequence< PropertyValue >.
     218             :     //      The result list we pack into the return any. We never change size of lists!
     219           0 :     nSourceSize = lInNames.getLength();
     220           0 :     lOutValues.realloc( nSourceSize );
     221             : 
     222             :     // Algorithm:
     223             :     // Copy all names and values from in to out lists.
     224             :     // Look for special localized entries ... You can detect it as "XInterface" packed into an Any.
     225             :     // Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >.
     226             :     // Add this list to out lists then.
     227             : 
     228           0 :     nDestinationCounter = 0;
     229           0 :     for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
     230             :     {
     231             :         // If item a special localized one ... convert and pack it ...
     232           0 :         if( lInValues[nSourceCounter].getValueTypeName() == "com.sun.star.uno.XInterface" )
     233             :         {
     234           0 :             lInValues[nSourceCounter] >>= xLocalizedNode;
     235           0 :             Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY );
     236           0 :             if( xSetAccess.is() )
     237             :             {
     238           0 :                 lPropertyNames  =   xSetAccess->getElementNames();
     239           0 :                 nPropertiesSize =   lPropertyNames.getLength();
     240           0 :                 lProperties.realloc( nPropertiesSize );
     241             : 
     242           0 :                 for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
     243             :                 {
     244             :                     #if OSL_DEBUG_LEVEL > 1
     245             :                     // Sometimes it's better to see what's going on :-)
     246             :                     OUString sPropName   = lInNames[nSourceCounter];
     247             :                     OUString sLocaleName = lPropertyNames[nPropertyCounter];
     248             :                     #endif
     249           0 :                     lProperties[nPropertyCounter].Name  =   lPropertyNames[nPropertyCounter];
     250           0 :                     OUString sLocaleValue;
     251           0 :                     xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue;
     252           0 :                     lProperties[nPropertyCounter].Value <<= sLocaleValue;
     253           0 :                 }
     254             : 
     255           0 :                 lOutValues[nDestinationCounter] <<= lProperties;
     256           0 :             }
     257             :         }
     258             :         // ... or copy normal items to return lists directly.
     259             :         else
     260             :         {
     261           0 :             lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
     262             :         }
     263           0 :         ++nDestinationCounter;
     264           0 :     }
     265           0 : }
     266             : 
     267           0 : void ConfigItem::impl_unpackLocalizedProperties(    const   Sequence< OUString >&   lInNames    ,
     268             :                                                     const   Sequence< Any >&        lInValues   ,
     269             :                                                             Sequence< OUString >&   lOutNames   ,
     270             :                                                             Sequence< Any >&        lOutValues  )
     271             : {
     272             :     // Safe impossible cases.
     273             :     // This method should be called for special ConfigItem-mode only!
     274             :     OSL_ENSURE( ((m_nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" );
     275             : 
     276             :     sal_Int32                   nSourceCounter;      // used to step during input lists
     277             :     sal_Int32                   nSourceSize;         // marks end of loop over input lists
     278             :     sal_Int32                   nDestinationCounter; // actual position in output lists
     279             :     sal_Int32                   nPropertyCounter;    // counter of inner loop for Sequence< PropertyValue >
     280             :     sal_Int32                   nPropertiesSize;     // marks end of inner loop
     281           0 :     OUString                    sNodeName;           // base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" )
     282           0 :     Sequence< PropertyValue >   lProperties;         // localized values of an configuration entry getted from lInValues-Any
     283             : 
     284             :     // Optimise follow algorithm ... A LITTLE BIT :-)
     285             :     // There exist two different possibilities:
     286             :     //  i ) There exist no localized entries ...                        =>  size of lOutNames/lOutValues will be the same like lInNames/lInValues!
     287             :     //  ii) There exist some (mostly one or two) localized entries ...  =>  size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues.
     288             :     //  =>  I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast.
     289             :     //      We should reserve same space for output list like input ones first.
     290             :     //      Follow algorithm looks for these borders and change it for ii) only!
     291             :     //      It will be faster then a "realloc()" call in every loop ...
     292           0 :     nSourceSize = lInNames.getLength();
     293             : 
     294           0 :     lOutNames.realloc   ( nSourceSize );
     295           0 :     lOutValues.realloc  ( nSourceSize );
     296             : 
     297             :     // Algorithm:
     298             :     // Copy all names and values from const to return lists.
     299             :     // Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any.
     300             :     // Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues.
     301             : 
     302           0 :     nDestinationCounter = 0;
     303           0 :     for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
     304             :     {
     305             :         // If item a special localized one ... split it and insert his parts to output lists ...
     306           0 :         if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) )
     307             :         {
     308           0 :             lInValues[nSourceCounter] >>= lProperties;
     309           0 :             nPropertiesSize = lProperties.getLength();
     310             : 
     311           0 :             sNodeName = lInNames[nSourceCounter] + "/";
     312             : 
     313           0 :             if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() )
     314             :             {
     315           0 :                 lOutNames.realloc   ( nDestinationCounter+nPropertiesSize );
     316           0 :                 lOutValues.realloc  ( nDestinationCounter+nPropertiesSize );
     317             :             }
     318             : 
     319           0 :             for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
     320             :             {
     321           0 :                  lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name;
     322           0 :                 lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value;
     323           0 :                 ++nDestinationCounter;
     324             :             }
     325             :         }
     326             :         // ... or copy normal items to return lists directly.
     327             :         else
     328             :         {
     329           0 :             if( (nDestinationCounter+1) > lOutNames.getLength() )
     330             :             {
     331           0 :                 lOutNames.realloc   ( nDestinationCounter+1 );
     332           0 :                 lOutValues.realloc  ( nDestinationCounter+1 );
     333             :             }
     334             : 
     335           0 :             lOutNames [nDestinationCounter] = lInNames [nSourceCounter];
     336           0 :             lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
     337           0 :             ++nDestinationCounter;
     338             :         }
     339           0 :     }
     340           0 : }
     341             : 
     342         738 : Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< OUString >& rNames)
     343             : {
     344             :     sal_Int32 i;
     345             : 
     346             :     // size of return list is fix!
     347             :     // Every item must match to length of incoming name list.
     348         738 :     sal_Int32 nCount = rNames.getLength();
     349         738 :     Sequence< sal_Bool > lStates(nCount);
     350             : 
     351             :     // We must be shure to return a valid information everytime!
     352             :     // Set default to non readonly ... similar to the configuration handling of this property.
     353        9470 :     for ( i=0; i<nCount; ++i)
     354        8732 :         lStates[i] = sal_False;
     355             : 
     356             :     // no access - no information ...
     357        1476 :     Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree();
     358         738 :     if (!xHierarchyAccess.is())
     359           0 :         return lStates;
     360             : 
     361        9470 :     for (i=0; i<nCount; ++i)
     362             :     {
     363             :         try
     364             :         {
     365        8732 :             OUString sName = rNames[i];
     366       17464 :             OUString sPath;
     367       17464 :             OUString sProperty;
     368             : 
     369        8732 :             ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty);
     370        8732 :             if (sPath.isEmpty() && sProperty.isEmpty())
     371             :             {
     372             :                 OSL_FAIL("ConfigItem::IsReadonly()\nsplitt failed\n");
     373           0 :                 continue;
     374             :             }
     375             : 
     376       17464 :             Reference< XInterface >       xNode;
     377       17464 :             Reference< XPropertySet >     xSet;
     378       17464 :             Reference< XPropertySetInfo > xInfo;
     379        8732 :             if (!sPath.isEmpty())
     380             :             {
     381        3275 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(sPath);
     382        3275 :                 if (!(aNode >>= xNode) || !xNode.is())
     383             :                 {
     384             :                     OSL_FAIL("ConfigItem::IsReadonly()\nno set available\n");
     385           0 :                     continue;
     386        3275 :                 }
     387             :             }
     388             :             else
     389             :             {
     390        5457 :                 xNode = xHierarchyAccess;
     391             :             }
     392             : 
     393        8732 :         xSet = Reference< XPropertySet >(xNode, UNO_QUERY);
     394        8732 :             if (xSet.is())
     395             :         {
     396        8732 :             xInfo = xSet->getPropertySetInfo();
     397             :                 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n");
     398             :         }
     399             :             else
     400             :         {
     401           0 :                xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY);
     402             :                 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n");
     403             :         }
     404             : 
     405        8732 :             if (!xInfo.is())
     406             :             {
     407             :                 OSL_FAIL("ConfigItem::IsReadonly()\nno prop info available\n");
     408           0 :                 continue;
     409             :             }
     410             : 
     411       17464 :             Property aProp = xInfo->getPropertyByName(sProperty);
     412       17464 :             lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY);
     413             :         }
     414           0 :         catch (const Exception&)
     415             :         {
     416             :         }
     417             :     }
     418             : 
     419         738 :     return lStates;
     420             : }
     421             : 
     422       68937 : Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames)
     423             : {
     424       68937 :     Sequence< Any > aRet(rNames.getLength());
     425       68937 :     const OUString* pNames = rNames.getConstArray();
     426       68937 :     Any* pRet = aRet.getArray();
     427      137874 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     428       68937 :     if(xHierarchyAccess.is())
     429             :     {
     430      518110 :         for(int i = 0; i < rNames.getLength(); i++)
     431             :         {
     432             :             try
     433             :             {
     434      449173 :                 pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]);
     435             :             }
     436          11 :             catch (const Exception& rEx)
     437             :             {
     438             :                 SAL_WARN(
     439             :                     "unotools.config",
     440             :                     "ignoring XHierarchicalNameAccess to /org.openoffice."
     441             :                         << sSubTree << "/" << pNames[i] << " Exception: "
     442             :                         << rEx.Message);
     443             :             }
     444             :         }
     445             : 
     446             :         // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >.
     447       68937 :         if((m_nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES)
     448             :         {
     449           0 :             Sequence< Any > lValues;
     450           0 :             impl_packLocalizedProperties( rNames, aRet, lValues );
     451           0 :             aRet = lValues;
     452             :         }
     453             :     }
     454      137874 :     return aRet;
     455             : }
     456             : 
     457        1348 : bool ConfigItem::PutProperties( const Sequence< OUString >& rNames,
     458             :                                                 const Sequence< Any>& rValues)
     459             : {
     460        1348 :     ValueCounter_Impl aCounter(m_nInValueChange);
     461        2696 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     462        2696 :     Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY);
     463        1348 :     bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is();
     464        1348 :     if(bRet)
     465             :     {
     466        1348 :         Sequence< OUString >    lNames;
     467        2696 :         Sequence< Any >         lValues;
     468        1348 :         const OUString*         pNames  = NULL;
     469        1348 :         const Any*              pValues = NULL;
     470             :         sal_Int32               nNameCount;
     471        1348 :         if(( m_nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES )
     472             :         {
     473             :             // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue >
     474             :             // as value of an localized configuration entry!
     475             :             // How we can do that?
     476             :             // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"!
     477           0 :             impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues );
     478           0 :             pNames      = lNames.getConstArray  ();
     479           0 :             pValues     = lValues.getConstArray ();
     480           0 :             nNameCount  = lNames.getLength      ();
     481             :         }
     482             :         else
     483             :         {
     484             :             // This is the normal mode ...
     485             :             // Use given input lists directly.
     486        1348 :             pNames      = rNames.getConstArray  ();
     487        1348 :             pValues     = rValues.getConstArray ();
     488        1348 :             nNameCount  = rNames.getLength      ();
     489             :         }
     490       10700 :         for(int i = 0; i < nNameCount; i++)
     491             :         {
     492             :             try
     493             :             {
     494       18704 :                 OUString sNode, sProperty;
     495        9352 :                 if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
     496             :                 {
     497        1152 :                     Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
     498             : 
     499        2304 :                     Reference<XNameAccess> xNodeAcc;
     500        1152 :                     aNode >>= xNodeAcc;
     501        2304 :                     Reference<XNameReplace>   xNodeReplace(xNodeAcc, UNO_QUERY);
     502        2304 :                     Reference<XNameContainer> xNodeCont   (xNodeAcc, UNO_QUERY);
     503             : 
     504        1152 :                     bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty));
     505        1152 :                     if (bExist && xNodeReplace.is())
     506        1152 :                         xNodeReplace->replaceByName(sProperty, pValues[i]);
     507             :                     else
     508           0 :                         if (!bExist && xNodeCont.is())
     509           0 :                             xNodeCont->insertByName(sProperty, pValues[i]);
     510             :                         else
     511        1152 :                             bRet = false;
     512             :                 }
     513             :                 else //direct value
     514             :                 {
     515        8200 :                     xTopNodeReplace->replaceByName(sProperty, pValues[i]);
     516        9352 :                 }
     517             :             }
     518           0 :             CATCH_INFO("Exception from PutProperties: ");
     519             :         }
     520             :         try
     521             :         {
     522        1348 :             Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     523        1348 :             xBatch->commitChanges();
     524             :         }
     525        1348 :         CATCH_INFO("Exception from commitChanges(): ")
     526             :     }
     527             : 
     528        2696 :     return bRet;
     529             : }
     530             : 
     531        2012 : void ConfigItem::DisableNotification()
     532             : {
     533             :     OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" );
     534        2012 :     RemoveChangesListener();
     535        2012 : }
     536             : 
     537        8230 : bool    ConfigItem::EnableNotification(const Sequence< OUString >& rNames,
     538             :                 bool bEnableInternalNotification )
     539             : 
     540             : {
     541             :     OSL_ENSURE(0 == (m_nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible");
     542        8230 :     m_bEnableInternalNotification = bEnableInternalNotification;
     543        8230 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     544       16460 :     Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY);
     545        8230 :     if(!xChgNot.is())
     546           0 :         return false;
     547             : 
     548             :     OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called");
     549        8230 :     if(xChangeLstnr.is())
     550           0 :         xChgNot->removeChangesListener( xChangeLstnr );
     551        8230 :     bool bRet = true;
     552             : 
     553             :     try
     554             :     {
     555        8230 :         xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames);
     556        8230 :         xChgNot->addChangesListener( xChangeLstnr );
     557             :     }
     558           0 :     catch (const RuntimeException&)
     559             :     {
     560           0 :         bRet = false;
     561             :     }
     562       16460 :     return bRet;
     563             : }
     564             : 
     565       16378 : void ConfigItem::RemoveChangesListener()
     566             : {
     567       16378 :     Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY);
     568       16378 :     if(xChgNot.is() && xChangeLstnr.is())
     569             :     {
     570             :         try
     571             :         {
     572        7482 :             xChgNot->removeChangesListener( xChangeLstnr );
     573        7482 :             xChangeLstnr = 0;
     574             :         }
     575           0 :         catch (const Exception&)
     576             :         {
     577             :         }
     578       16378 :     }
     579       16378 : }
     580             : 
     581       20021 : static void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode)
     582             : {
     583       20021 :     switch (_eFormat)
     584             :     {
     585             :     case CONFIG_NAME_LOCAL_NAME:
     586             :         // unaltered - this is our input format
     587       19494 :         break;
     588             : 
     589             :     case CONFIG_NAME_FULL_PATH:
     590             :         {
     591           0 :             Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY);
     592           0 :             if (xFormatter.is())
     593             :             {
     594           0 :                 OUString * pNames = _rNames.getArray();
     595           0 :                 for(int i = 0; i<_rNames.getLength(); ++i)
     596             :                 {
     597             :                     try
     598             :                     {
     599           0 :                         pNames[i] = xFormatter->composeHierarchicalName(pNames[i]);
     600             :                     }
     601           0 :                     CATCH_INFO("Exception from composeHierarchicalName(): ")
     602             :                 }
     603           0 :                 break;
     604           0 :             }
     605             :         }
     606             :         OSL_FAIL("Cannot create absolute paths: missing interface");
     607             :         // make local paths instaed
     608             : 
     609             :     case CONFIG_NAME_LOCAL_PATH:
     610             :         {
     611         527 :             Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY);
     612         527 :             if (xTypeContainer.is())
     613             :             {
     614           0 :                 OUString sTypeName = xTypeContainer->getElementTemplateName();
     615           0 :                 sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1);
     616             : 
     617           0 :                 OUString * pNames = _rNames.getArray();
     618           0 :                 for(int i = 0; i<_rNames.getLength(); ++i)
     619             :                 {
     620           0 :                     pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName);
     621           0 :                 }
     622             :             }
     623             :             else
     624             :             {
     625         527 :                 Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY);
     626         527 :                 if (xSVI.is() && xSVI->supportsService("com.sun.star.configuration.SetAccess"))
     627             :                 {
     628         527 :                     OUString * pNames = _rNames.getArray();
     629        1987 :                     for(int i = 0; i<_rNames.getLength(); ++i)
     630             :                     {
     631        1460 :                         pNames[i] = wrapConfigurationElementName(pNames[i]);
     632             :                     }
     633         527 :                 }
     634         527 :             }
     635             :         }
     636         527 :         break;
     637             : 
     638             :     case CONFIG_NAME_PLAINTEXT_NAME:
     639             :         {
     640           0 :             Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY);
     641           0 :             if (xEscaper.is())
     642             :             {
     643           0 :                 OUString * pNames = _rNames.getArray();
     644           0 :                 for(int i = 0; i<_rNames.getLength(); ++i)
     645             :                 try
     646             :                 {
     647           0 :                     pNames[i] = xEscaper->unescapeString(pNames[i]);
     648             :                 }
     649           0 :                 CATCH_INFO("Exception from unescapeString(): ")
     650           0 :             }
     651             :         }
     652           0 :         break;
     653             : 
     654             :     }
     655       20021 : }
     656             : 
     657       19494 : Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode)
     658             : {
     659       19494 :     ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT;
     660             : 
     661       19494 :     return GetNodeNames(rNode, eDefaultFormat);
     662             : }
     663             : 
     664       20021 : Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat)
     665             : {
     666       20021 :     Sequence< OUString > aRet;
     667       40042 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     668       20021 :     if(xHierarchyAccess.is())
     669             :     {
     670             :         try
     671             :         {
     672       20021 :             Reference<XNameAccess> xCont;
     673       20021 :             if(!rNode.isEmpty())
     674             :             {
     675       19804 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     676       19804 :                 aNode >>= xCont;
     677             :             }
     678             :             else
     679         217 :                 xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY);
     680       20021 :             if(xCont.is())
     681             :             {
     682       20021 :                 aRet = xCont->getElementNames();
     683       20021 :                 lcl_normalizeLocalNames(aRet,eFormat,xCont);
     684       20021 :             }
     685             : 
     686             :         }
     687           0 :         CATCH_INFO("Exception from GetNodeNames: ");
     688             :     }
     689       40042 :     return aRet;
     690             : }
     691             : 
     692           4 : bool ConfigItem::ClearNodeSet(const OUString& rNode)
     693             : {
     694           4 :     ValueCounter_Impl aCounter(m_nInValueChange);
     695           4 :     bool bRet = false;
     696           8 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     697           4 :     if(xHierarchyAccess.is())
     698             :     {
     699             :         try
     700             :         {
     701           4 :             Reference<XNameContainer> xCont;
     702           4 :             if(!rNode.isEmpty())
     703             :             {
     704           4 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     705           4 :                 aNode >>= xCont;
     706             :             }
     707             :             else
     708           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     709           4 :             if(!xCont.is())
     710           0 :                 return false;
     711           8 :             Sequence< OUString > aNames = xCont->getElementNames();
     712           4 :             const OUString* pNames = aNames.getConstArray();
     713           8 :             Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     714          19 :             for(sal_Int32 i = 0; i < aNames.getLength(); i++)
     715             :             {
     716             :                 try
     717             :                 {
     718          15 :                     xCont->removeByName(pNames[i]);
     719             :                 }
     720           0 :                 CATCH_INFO("Exception from removeByName(): ")
     721             :             }
     722           4 :             xBatch->commitChanges();
     723           8 :             bRet = true;
     724             :         }
     725           0 :         CATCH_INFO("Exception from ClearNodeSet")
     726             :     }
     727           8 :     return bRet;
     728             : }
     729             : 
     730          25 : bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements)
     731             : {
     732          25 :     ValueCounter_Impl aCounter(m_nInValueChange);
     733          25 :     bool bRet = false;
     734          50 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     735          25 :     if(xHierarchyAccess.is())
     736             :     {
     737          25 :         const OUString* pElements = rElements.getConstArray();
     738             :         try
     739             :         {
     740          25 :             Reference<XNameContainer> xCont;
     741          25 :             if(!rNode.isEmpty())
     742             :             {
     743          25 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     744          25 :                 aNode >>= xCont;
     745             :             }
     746             :             else
     747           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     748          25 :             if(!xCont.is())
     749           0 :                 return false;
     750             :             try
     751             :             {
     752          35 :                 for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++)
     753             :                 {
     754          25 :                     xCont->removeByName(pElements[nElement]);
     755             :                 }
     756          10 :                 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     757          10 :                 xBatch->commitChanges();
     758             :             }
     759          15 :             CATCH_INFO("Exception from commitChanges(): ")
     760          25 :             bRet = true;
     761             :         }
     762           0 :         CATCH_INFO("Exception from GetNodeNames: ")
     763             :     }
     764          50 :     return bRet;
     765             : }
     766             : 
     767             : static inline
     768        1008 : OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix )
     769             : {
     770        1008 :     OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix);
     771        1008 :     return extractFirstFromConfigurationPath( sSubPath );
     772             : }
     773             : 
     774             : static
     775         389 : Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix )
     776             : {
     777         389 :     const PropertyValue* pProperties = rValues.getConstArray();
     778             : 
     779         389 :     Sequence< OUString > aSubNodeNames(rValues.getLength());
     780         389 :     OUString* pSubNodeNames = aSubNodeNames.getArray();
     781             : 
     782         778 :     OUString sLastSubNode;
     783         389 :     sal_Int32 nSubIndex = 0;
     784             : 
     785        2106 :     for(sal_Int32 i = 0; i < rValues.getLength(); i++)
     786             :     {
     787        1717 :         OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix);
     788        3434 :         OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath );
     789             : 
     790        1717 :         if(sLastSubNode != sSubNode)
     791             :         {
     792        1045 :             pSubNodeNames[nSubIndex++] = sSubNode;
     793             :         }
     794             : 
     795        1717 :         sLastSubNode = sSubNode;
     796        1717 :     }
     797         389 :     aSubNodeNames.realloc(nSubIndex);
     798             : 
     799         778 :     return aSubNodeNames;
     800             : }
     801             : 
     802             : // Add or change properties
     803          37 : bool ConfigItem::SetSetProperties(
     804             :     const OUString& rNode, Sequence< PropertyValue > rValues)
     805             : {
     806          37 :     ValueCounter_Impl aCounter(m_nInValueChange);
     807          37 :     bool bRet = true;
     808          74 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     809          37 :     if(xHierarchyAccess.is())
     810             :     {
     811          37 :         Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     812             :         try
     813             :         {
     814          37 :             Reference<XNameContainer> xCont;
     815          37 :             if(!rNode.isEmpty())
     816             :             {
     817          37 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     818          37 :                 aNode >>= xCont;
     819             :             }
     820             :             else
     821           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     822          37 :             if(!xCont.is())
     823           0 :                 return false;
     824             : 
     825          74 :             Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
     826             : 
     827          37 :             if(xFac.is())
     828             :             {
     829          37 :                 const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
     830             : 
     831          37 :                 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
     832             : 
     833          74 :                 for(sal_Int32 j = 0; j <nSubNodeCount; j++)
     834             :                 {
     835          37 :                     if(!xCont->hasByName(aSubNodeNames[j]))
     836             :                     {
     837          25 :                         Reference<XInterface> xInst = xFac->createInstance();
     838          50 :                         Any aVal; aVal <<= xInst;
     839          50 :                         xCont->insertByName(aSubNodeNames[j], aVal);
     840             :                     }
     841             :                     //set values
     842             :                 }
     843             :                 try
     844             :                 {
     845          37 :                     xBatch->commitChanges();
     846             :                 }
     847           0 :                 CATCH_INFO("Exception from commitChanges(): ")
     848             : 
     849          37 :                 const PropertyValue* pProperties = rValues.getConstArray();
     850             : 
     851          74 :                 Sequence< OUString > aSetNames(rValues.getLength());
     852          37 :                 OUString* pSetNames = aSetNames.getArray();
     853             : 
     854          74 :                 Sequence< Any> aSetValues(rValues.getLength());
     855          37 :                 Any* pSetValues = aSetValues.getArray();
     856             : 
     857          37 :                 bool bEmptyNode = rNode.isEmpty();
     858         746 :                 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
     859             :                 {
     860         709 :                     pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
     861         709 :                     pSetValues[k] = pProperties[k].Value;
     862             :                 }
     863          74 :                 bRet = PutProperties(aSetNames, aSetValues);
     864             :             }
     865             :             else
     866             :             {
     867             :                 //if no factory is available then the node contains basic data elements
     868           0 :                 const PropertyValue* pValues = rValues.getConstArray();
     869           0 :                 for(int nValue = 0; nValue < rValues.getLength();nValue++)
     870             :                 {
     871             :                     try
     872             :                     {
     873           0 :                         OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
     874             : 
     875           0 :                         if(xCont->hasByName(sSubNode))
     876           0 :                             xCont->replaceByName(sSubNode, pValues[nValue].Value);
     877             :                         else
     878           0 :                             xCont->insertByName(sSubNode, pValues[nValue].Value);
     879             : 
     880             :                         OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name),
     881           0 :                             "Invalid config path" );
     882             :                     }
     883           0 :                     CATCH_INFO("Exception form insert/replaceByName(): ")
     884             :                 }
     885           0 :                 xBatch->commitChanges();
     886          37 :             }
     887             :         }
     888             : #ifdef DBG_UTIL
     889             :         catch (const Exception& rEx)
     890             :         {
     891             :             lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx);
     892             : #else
     893           0 :         catch (const Exception&)
     894             :         {
     895             : #endif
     896           0 :             bRet = false;
     897          37 :         }
     898             :     }
     899          74 :     return bRet;
     900             : }
     901             : 
     902         352 : bool ConfigItem::ReplaceSetProperties(
     903             :     const OUString& rNode, Sequence< PropertyValue > rValues)
     904             : {
     905         352 :     ValueCounter_Impl aCounter(m_nInValueChange);
     906         352 :     bool bRet = true;
     907         704 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     908         352 :     if(xHierarchyAccess.is())
     909             :     {
     910         352 :         Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     911             :         try
     912             :         {
     913         352 :             Reference<XNameContainer> xCont;
     914         352 :             if(!rNode.isEmpty())
     915             :             {
     916         352 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     917         352 :                 aNode >>= xCont;
     918             :             }
     919             :             else
     920           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     921         352 :             if(!xCont.is())
     922           0 :                 return false;
     923             : 
     924             :             // JB: Change: now the same name handling for sets of simple values
     925         704 :             const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
     926         352 :             const OUString* pSubNodeNames = aSubNodeNames.getConstArray();
     927         352 :             const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
     928             : 
     929         704 :             Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
     930         352 :             const bool isSimpleValueSet = !xFac.is();
     931             : 
     932             :             //remove unknown members first
     933             :             {
     934         352 :                 const Sequence<OUString> aContainerSubNodes = xCont->getElementNames();
     935         352 :                 const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray();
     936             : 
     937         592 :                 for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++)
     938             :                 {
     939         240 :                     bool bFound = false;
     940        2770 :                     for(sal_Int32 j = 0; j < nSubNodeCount; j++)
     941             :                     {
     942        2770 :                         if(pSubNodeNames[j] == pContainerSubNodes[nContSub])
     943             :                         {
     944         240 :                             bFound = true;
     945         240 :                             break;
     946             :                         }
     947             :                     }
     948         240 :                     if(!bFound)
     949             :                     try
     950             :                     {
     951           0 :                         xCont->removeByName(pContainerSubNodes[nContSub]);
     952             :                     }
     953           0 :                     catch (const Exception&)
     954             :                     {
     955           0 :                         if (isSimpleValueSet)
     956             :                         {
     957             :                             try
     958             :                             {
     959             :                                 // #i37322#: fallback action: replace with <void/>
     960           0 :                                 xCont->replaceByName(pContainerSubNodes[nContSub], Any());
     961             :                                 // fallback successful: continue looping
     962           0 :                                 continue;
     963             :                             }
     964           0 :                             catch (Exception &)
     965             :                             {} // propagate original exception, if fallback fails
     966             :                         }
     967           0 :                         throw;
     968             :                     }
     969             :                 }
     970         352 :                 try { xBatch->commitChanges(); }
     971         352 :                 CATCH_INFO("Exception from commitChanges(): ")
     972             :             }
     973             : 
     974         352 :             if(xFac.is()) // !isSimpleValueSet
     975             :             {
     976           0 :                 for(sal_Int32 j = 0; j < nSubNodeCount; j++)
     977             :                 {
     978           0 :                     if(!xCont->hasByName(pSubNodeNames[j]))
     979             :                     {
     980             :                         //create if not available
     981           0 :                         Reference<XInterface> xInst = xFac->createInstance();
     982           0 :                         Any aVal; aVal <<= xInst;
     983           0 :                         xCont->insertByName(pSubNodeNames[j], aVal);
     984             :                     }
     985             :                 }
     986           0 :                 try { xBatch->commitChanges(); }
     987           0 :                 CATCH_INFO("Exception from commitChanges(): ")
     988             : 
     989           0 :                 const PropertyValue* pProperties = rValues.getConstArray();
     990             : 
     991           0 :                 Sequence< OUString > aSetNames(rValues.getLength());
     992           0 :                 OUString* pSetNames = aSetNames.getArray();
     993             : 
     994           0 :                 Sequence< Any> aSetValues(rValues.getLength());
     995           0 :                 Any* pSetValues = aSetValues.getArray();
     996             : 
     997           0 :                 bool bEmptyNode = rNode.isEmpty();
     998           0 :                 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
     999             :                 {
    1000           0 :                     pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
    1001           0 :                     pSetValues[k] = pProperties[k].Value;
    1002             :                 }
    1003           0 :                 bRet = PutProperties(aSetNames, aSetValues);
    1004             :             }
    1005             :             else
    1006             :             {
    1007         352 :                 const PropertyValue* pValues = rValues.getConstArray();
    1008             : 
    1009             :                 //if no factory is available then the node contains basic data elements
    1010        1360 :                 for(int nValue = 0; nValue < rValues.getLength();nValue++)
    1011             :                 {
    1012             :                     try
    1013             :                     {
    1014        1008 :                         OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
    1015             : 
    1016        1008 :                         if(xCont->hasByName(sSubNode))
    1017         240 :                             xCont->replaceByName(sSubNode, pValues[nValue].Value);
    1018             :                         else
    1019         768 :                             xCont->insertByName(sSubNode, pValues[nValue].Value);
    1020             :                     }
    1021           0 :                     CATCH_INFO("Exception from insert/replaceByName(): ");
    1022             :                 }
    1023         352 :                 xBatch->commitChanges();
    1024         352 :             }
    1025             :         }
    1026             : #ifdef DBG_UTIL
    1027             :         catch (const Exception& rEx)
    1028             :         {
    1029             :             lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx);
    1030             : #else
    1031           0 :         catch (const Exception&)
    1032             :         {
    1033             : #endif
    1034           0 :             bRet = false;
    1035         352 :         }
    1036             :     }
    1037         704 :     return bRet;
    1038             : }
    1039             : 
    1040           0 : bool ConfigItem::AddNode(const OUString& rNode, const OUString& rNewNode)
    1041             : {
    1042           0 :     ValueCounter_Impl aCounter(m_nInValueChange);
    1043           0 :     bool bRet = true;
    1044           0 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
    1045           0 :     if(xHierarchyAccess.is())
    1046             :     {
    1047           0 :         Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
    1048             :         try
    1049             :         {
    1050           0 :             Reference<XNameContainer> xCont;
    1051           0 :             if(!rNode.isEmpty())
    1052             :             {
    1053           0 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
    1054           0 :                 aNode >>= xCont;
    1055             :             }
    1056             :             else
    1057           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
    1058           0 :             if(!xCont.is())
    1059           0 :                 return false;
    1060             : 
    1061           0 :             Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
    1062             : 
    1063           0 :             if(xFac.is())
    1064             :             {
    1065           0 :                 if(!xCont->hasByName(rNewNode))
    1066             :                 {
    1067           0 :                     Reference<XInterface> xInst = xFac->createInstance();
    1068           0 :                     Any aVal; aVal <<= xInst;
    1069           0 :                     xCont->insertByName(rNewNode, aVal);
    1070             :                 }
    1071             :                 try
    1072             :                 {
    1073           0 :                     xBatch->commitChanges();
    1074             :                 }
    1075           0 :                 CATCH_INFO("Exception from commitChanges(): ")
    1076             :             }
    1077             :             else
    1078             :             {
    1079             :                 //if no factory is available then the node contains basic data elements
    1080             :                 try
    1081             :                 {
    1082           0 :                     if(!xCont->hasByName(rNewNode))
    1083           0 :                         xCont->insertByName(rNewNode, Any());
    1084             :                 }
    1085           0 :                 CATCH_INFO("Exception from AddNode(): ")
    1086             :             }
    1087           0 :             xBatch->commitChanges();
    1088             :         }
    1089             : #ifdef DBG_UTIL
    1090             :         catch (const Exception& rEx)
    1091             :         {
    1092             :             lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx);
    1093             : #else
    1094           0 :         catch (const Exception&)
    1095             :         {
    1096             : #endif
    1097           0 :             bRet = false;
    1098           0 :         }
    1099             :     }
    1100           0 :     return bRet;
    1101             : }
    1102             : 
    1103       16125 : sal_Int16   ConfigItem::GetMode() const
    1104             : {
    1105       16125 :     return m_nMode;
    1106             : }
    1107             : 
    1108        2079 : void    ConfigItem::SetModified()
    1109             : {
    1110        2079 :     m_bIsModified = true;
    1111        2079 : }
    1112             : 
    1113         297 : void    ConfigItem::ClearModified()
    1114             : {
    1115         297 :     m_bIsModified = false;
    1116         297 : }
    1117             : 
    1118       55275 : bool ConfigItem::IsModified() const
    1119             : {
    1120       55275 :     return m_bIsModified;
    1121             : }
    1122             : 
    1123        8975 : bool ConfigItem::IsInValueChange() const
    1124             : {
    1125        8975 :     return m_nInValueChange > 0;
    1126             : }
    1127             : 
    1128       99692 : Reference< XHierarchicalNameAccess> ConfigItem::GetTree()
    1129             : {
    1130       99692 :     Reference< XHierarchicalNameAccess> xRet;
    1131       99692 :     if(!m_xHierarchyAccess.is())
    1132         631 :         xRet = ConfigManager::acquireTree(*this);
    1133             :     else
    1134       99061 :         xRet = m_xHierarchyAccess;
    1135       99692 :     return xRet;
    1136             : }
    1137             : 
    1138             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10