LCOV - code coverage report
Current view: top level - unotools/source/config - configitem.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 315 494 63.8 %
Date: 2015-06-13 12:38:46 Functions: 29 34 85.3 %
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 <sal/log.hxx>
      23             : #include <unotools/configitem.hxx>
      24             : #include <unotools/configmgr.hxx>
      25             : #include <unotools/configpaths.hxx>
      26             : #include <comphelper/processfactory.hxx>
      27             : #include <com/sun/star/beans/XMultiPropertySet.hpp>
      28             : #include <com/sun/star/beans/XPropertySet.hpp>
      29             : #include <com/sun/star/util/XChangesListener.hpp>
      30             : #include <com/sun/star/util/XChangesNotifier.hpp>
      31             : #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
      32             : #include <com/sun/star/container/XHierarchicalName.hpp>
      33             : #include <com/sun/star/configuration/XTemplateContainer.hpp>
      34             : #include <com/sun/star/container/XNameContainer.hpp>
      35             : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
      36             : #include <com/sun/star/lang/XServiceInfo.hpp>
      37             : #include <com/sun/star/awt/XRequestCallback.hpp>
      38             : #include <com/sun/star/beans/PropertyValue.hpp>
      39             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      40             : #include <com/sun/star/util/XStringEscape.hpp>
      41             : #include <com/sun/star/util/XChangesBatch.hpp>
      42             : #include <osl/diagnose.h>
      43             : #include <tools/solarmutex.hxx>
      44             : #include <rtl/ustrbuf.hxx>
      45             : 
      46             : using namespace utl;
      47             : using namespace com::sun::star::uno;
      48             : using namespace com::sun::star::util;
      49             : using namespace com::sun::star::lang;
      50             : using namespace com::sun::star::beans;
      51             : using namespace com::sun::star::container;
      52             : using namespace com::sun::star::configuration;
      53             : 
      54             : #include <cppuhelper/implbase1.hxx>
      55             : 
      56             : #ifdef DBG_UTIL
      57             : static inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx)
      58             : {
      59             :     OString sMsg(cText);
      60             :     sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US);
      61             :     OSL_FAIL(sMsg.getStr());
      62             : }
      63             : #define CATCH_INFO(a) \
      64             : catch(const Exception& rEx)   \
      65             : {                       \
      66             :     lcl_CFG_DBG_EXCEPTION(a, rEx);\
      67             : }
      68             : #else
      69             :     #define CATCH_INFO(a) catch(const Exception&){}
      70             : #endif
      71             : 
      72             : /*
      73             :     The ConfigChangeListener_Impl receives notifications from the configuration about changes that
      74             :     have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its
      75             :     "CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired
      76             :     before doing so.
      77             : */
      78             : 
      79             : namespace utl{
      80             :     class ConfigChangeListener_Impl : public cppu::WeakImplHelper1
      81             :     <
      82             :         com::sun::star::util::XChangesListener
      83             :     >
      84             :     {
      85             :         public:
      86             :             ConfigItem*                 pParent;
      87             :             const Sequence< OUString >  aPropertyNames;
      88             :             ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames);
      89             :             virtual ~ConfigChangeListener_Impl();
      90             : 
      91             :         //XChangesListener
      92             :         virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
      93             : 
      94             :         //XEventListener
      95             :         virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
      96             :     };
      97             : }
      98             : 
      99             : class ValueCounter_Impl
     100             : {
     101             :     sal_Int16& rCnt;
     102             : public:
     103        1053 :     explicit ValueCounter_Impl(sal_Int16& rCounter)
     104        1053 :         : rCnt(rCounter)
     105             :     {
     106        1053 :         rCnt++;
     107        1053 :     }
     108        1053 :     ~ValueCounter_Impl()
     109             :     {
     110             :         OSL_ENSURE(rCnt>0, "RefCount < 0 ??");
     111        1053 :         rCnt--;
     112        1053 :     }
     113             : };
     114             : 
     115       12987 : ConfigChangeListener_Impl::ConfigChangeListener_Impl(
     116             :              ConfigItem& rItem, const Sequence< OUString >& rNames) :
     117             :     pParent(&rItem),
     118       12987 :     aPropertyNames(rNames)
     119             : {
     120       12987 : }
     121             : 
     122       23802 : ConfigChangeListener_Impl::~ConfigChangeListener_Impl()
     123             : {
     124       23802 : }
     125             : 
     126       10202 : static bool lcl_Find(
     127             :         const OUString& rTemp,
     128             :         const OUString* pCheckPropertyNames,
     129             :         sal_Int32 nLength)
     130             : {
     131             :     //return true if the path is completely correct or if it is longer
     132             :     //i.e ...Print/Content/Graphic and .../Print
     133      119507 :     for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++)
     134      113718 :         if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) )
     135        4413 :             return true;
     136        5789 :     return false;
     137             : }
     138             : 
     139        8058 : void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException, std::exception)
     140             : {
     141        8058 :     const ElementChange* pElementChanges = rEvent.Changes.getConstArray();
     142             : 
     143        8058 :     Sequence<OUString>  aChangedNames(rEvent.Changes.getLength());
     144        8058 :     OUString* pNames = aChangedNames.getArray();
     145             : 
     146        8058 :     const OUString* pCheckPropertyNames = aPropertyNames.getConstArray();
     147             : 
     148        8058 :     sal_Int32 nNotify = 0;
     149       18260 :     for(int i = 0; i < aChangedNames.getLength(); i++)
     150             :     {
     151       10202 :         OUString sTemp;
     152       10202 :         pElementChanges[i].Accessor >>= sTemp;
     153       10202 :         if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength()))
     154        4413 :             pNames[nNotify++] = sTemp;
     155       10202 :     }
     156        8058 :     if( nNotify )
     157             :     {
     158        3483 :         if ( ::tools::SolarMutex::Acquire() )
     159             :         {
     160        3483 :             aChangedNames.realloc(nNotify);
     161        3483 :             pParent->CallNotify(aChangedNames);
     162        3483 :             ::tools::SolarMutex::Release();
     163             :         }
     164        8058 :     }
     165        8058 : }
     166             : 
     167           0 : void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException, std::exception)
     168             : {
     169           0 :     pParent->RemoveChangesListener();
     170           0 : }
     171             : 
     172       24815 : ConfigItem::ConfigItem(const OUString &rSubTree, ConfigItemMode nSetMode ) :
     173             :     sSubTree(rSubTree),
     174             :     m_nMode(nSetMode),
     175             :     m_bIsModified(false),
     176             :     m_bEnableInternalNotification(false),
     177       24815 :     m_nInValueChange(0)
     178             : {
     179       24815 :     if(nSetMode & ConfigItemMode::ReleaseTree)
     180        1083 :         ConfigManager::getConfigManager().addConfigItem(*this);
     181             :     else
     182       23732 :         m_xHierarchyAccess = ConfigManager::getConfigManager().addConfigItem(*this);
     183       24815 : }
     184             : 
     185       46270 : ConfigItem::~ConfigItem()
     186             : {
     187       23135 :     RemoveChangesListener();
     188       23135 :     ConfigManager::getConfigManager().removeConfigItem(*this);
     189       23135 : }
     190             : 
     191        3483 : void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames )
     192             : {
     193             :     // the call is forwarded to the virtual Notify() method
     194             :     // it is pure virtual, so all classes deriving from ConfigItem have to decide how they
     195             :     // want to notify listeners
     196        3483 :     if(!IsInValueChange() || m_bEnableInternalNotification)
     197         111 :         Notify(rPropertyNames);
     198        3483 : }
     199             : 
     200           0 : void ConfigItem::impl_packLocalizedProperties(  const   Sequence< OUString >&   lInNames    ,
     201             :                                                 const   Sequence< Any >&        lInValues   ,
     202             :                                                         Sequence< Any >&        lOutValues  )
     203             : {
     204             :     // Safe impossible cases.
     205             :     // This method should be called for special ConfigItem-mode only!
     206             :     OSL_ENSURE( ((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" );
     207             : 
     208             :     sal_Int32                   nSourceCounter;      // used to step during input lists
     209             :     sal_Int32                   nSourceSize;         // marks end of loop over input lists
     210             :     sal_Int32                   nDestinationCounter; // actual position in output lists
     211             :     sal_Int32                   nPropertyCounter;    // counter of inner loop for Sequence< PropertyValue >
     212             :     sal_Int32                   nPropertiesSize;     // marks end of inner loop
     213           0 :     Sequence< OUString >        lPropertyNames;      // list of all locales for localized entry
     214           0 :     Sequence< PropertyValue >   lProperties;         // localized values of an configuration entry packed for return
     215           0 :     Reference< XInterface >     xLocalizedNode;      // if cfg entry is localized ... lInValues contains an XInterface!
     216             : 
     217             :     // Optimise follow algorithm ... A LITTLE BIT :-)
     218             :     // There exist two different possibilities:
     219             :     //  i ) There exist no localized entries ...                        =>  size of lOutValues will be the same like lInNames/lInValues!
     220             :     //  ii) There exist some (mostly one or two) localized entries ...  =>  size of lOutValues will be the same like lInNames/lInValues!
     221             :     //  ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service).
     222             :     //      We read all his child nodes and pack it into Sequence< PropertyValue >.
     223             :     //      The result list we pack into the return any. We never change size of lists!
     224           0 :     nSourceSize = lInNames.getLength();
     225           0 :     lOutValues.realloc( nSourceSize );
     226             : 
     227             :     // Algorithm:
     228             :     // Copy all names and values from in to out lists.
     229             :     // Look for special localized entries ... You can detect it as "XInterface" packed into an Any.
     230             :     // Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >.
     231             :     // Add this list to out lists then.
     232             : 
     233           0 :     nDestinationCounter = 0;
     234           0 :     for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
     235             :     {
     236             :         // If item a special localized one ... convert and pack it ...
     237           0 :         if( lInValues[nSourceCounter].getValueTypeName() == "com.sun.star.uno.XInterface" )
     238             :         {
     239           0 :             lInValues[nSourceCounter] >>= xLocalizedNode;
     240           0 :             Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY );
     241           0 :             if( xSetAccess.is() )
     242             :             {
     243           0 :                 lPropertyNames  =   xSetAccess->getElementNames();
     244           0 :                 nPropertiesSize =   lPropertyNames.getLength();
     245           0 :                 lProperties.realloc( nPropertiesSize );
     246             : 
     247           0 :                 for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
     248             :                 {
     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 & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales), "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() == cppu::UnoType<Sequence<PropertyValue>>::get() )
     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        1102 : 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        1102 :     sal_Int32 nCount = rNames.getLength();
     349        1102 :     Sequence< sal_Bool > lStates(nCount);
     350             : 
     351             :     // We must be sure to return a valid information every time!
     352             :     // Set default to non readonly... similar to the configuration handling of this property.
     353       14260 :     for ( i=0; i<nCount; ++i)
     354       13158 :         lStates[i] = sal_False;
     355             : 
     356             :     // no access - no information...
     357        2204 :     Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree();
     358        1102 :     if (!xHierarchyAccess.is())
     359           0 :         return lStates;
     360             : 
     361       14260 :     for (i=0; i<nCount; ++i)
     362             :     {
     363             :         try
     364             :         {
     365       13158 :             OUString sName = rNames[i];
     366       26316 :             OUString sPath;
     367       26316 :             OUString sProperty;
     368             : 
     369       13158 :             (void)::utl::splitLastFromConfigurationPath(sName,sPath,sProperty);
     370       13158 :             if (sPath.isEmpty() && sProperty.isEmpty())
     371             :             {
     372             :                 OSL_FAIL("ConfigItem::IsReadonly()\nsplitt failed\n");
     373           0 :                 continue;
     374             :             }
     375             : 
     376       26316 :             Reference< XInterface >       xNode;
     377       26316 :             Reference< XPropertySet >     xSet;
     378       26316 :             Reference< XPropertySetInfo > xInfo;
     379       13158 :             if (!sPath.isEmpty())
     380             :             {
     381        5098 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(sPath);
     382        5098 :                 if (!(aNode >>= xNode) || !xNode.is())
     383             :                 {
     384             :                     OSL_FAIL("ConfigItem::IsReadonly()\nno set available\n");
     385           0 :                     continue;
     386        5098 :                 }
     387             :             }
     388             :             else
     389             :             {
     390        8060 :                 xNode = Reference<XInterface>( xHierarchyAccess, UNO_QUERY );
     391             :             }
     392             : 
     393       13158 :         xSet = Reference< XPropertySet >(xNode, UNO_QUERY);
     394       13158 :             if (xSet.is())
     395             :         {
     396       13158 :             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       13158 :             if (!xInfo.is())
     406             :             {
     407             :                 OSL_FAIL("ConfigItem::IsReadonly()\nno prop info available\n");
     408           0 :                 continue;
     409             :             }
     410             : 
     411       26316 :             Property aProp = xInfo->getPropertyByName(sProperty);
     412       26316 :             lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY);
     413             :         }
     414           0 :         catch (const Exception&)
     415             :         {
     416             :         }
     417             :     }
     418             : 
     419        1102 :     return lStates;
     420             : }
     421             : 
     422      109805 : Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames)
     423             : {
     424      109805 :     Sequence< Any > aRet(rNames.getLength());
     425      109805 :     const OUString* pNames = rNames.getConstArray();
     426      109805 :     Any* pRet = aRet.getArray();
     427      219610 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     428      109805 :     if(xHierarchyAccess.is())
     429             :     {
     430      833685 :         for(int i = 0; i < rNames.getLength(); i++)
     431             :         {
     432             :             try
     433             :             {
     434      723880 :                 pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]);
     435             :             }
     436           2 :             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      109805 :         if((m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales)
     448             :         {
     449           0 :             Sequence< Any > lValues;
     450           0 :             impl_packLocalizedProperties( rNames, aRet, lValues );
     451           0 :             aRet = lValues;
     452             :         }
     453             :     }
     454      219610 :     return aRet;
     455             : }
     456             : 
     457         371 : bool ConfigItem::PutProperties( const Sequence< OUString >& rNames,
     458             :                                                 const Sequence< Any>& rValues)
     459             : {
     460         371 :     ValueCounter_Impl aCounter(m_nInValueChange);
     461         742 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     462         742 :     Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY);
     463         371 :     bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is();
     464         371 :     if(bRet)
     465             :     {
     466         371 :         Sequence< OUString >    lNames;
     467         742 :         Sequence< Any >         lValues;
     468         371 :         const OUString*         pNames  = NULL;
     469         371 :         const Any*              pValues = NULL;
     470             :         sal_Int32               nNameCount;
     471         371 :         if(( m_nMode & ConfigItemMode::AllLocales ) == ConfigItemMode::AllLocales )
     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         371 :             pNames      = rNames.getConstArray  ();
     487         371 :             pValues     = rValues.getConstArray ();
     488         371 :             nNameCount  = rNames.getLength      ();
     489             :         }
     490        4996 :         for(int i = 0; i < nNameCount; i++)
     491             :         {
     492             :             try
     493             :             {
     494        9250 :                 OUString sNode, sProperty;
     495        4625 :                 if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
     496             :                 {
     497        1985 :                     Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
     498             : 
     499        3970 :                     Reference<XNameAccess> xNodeAcc;
     500        1985 :                     aNode >>= xNodeAcc;
     501        3970 :                     Reference<XNameReplace>   xNodeReplace(xNodeAcc, UNO_QUERY);
     502        3970 :                     Reference<XNameContainer> xNodeCont   (xNodeAcc, UNO_QUERY);
     503             : 
     504        1985 :                     bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty));
     505        1985 :                     if (bExist && xNodeReplace.is())
     506        1985 :                         xNodeReplace->replaceByName(sProperty, pValues[i]);
     507             :                     else
     508           0 :                         if (!bExist && xNodeCont.is())
     509           0 :                             xNodeCont->insertByName(sProperty, pValues[i]);
     510             :                         else
     511        1985 :                             bRet = false;
     512             :                 }
     513             :                 else //direct value
     514             :                 {
     515        2640 :                     xTopNodeReplace->replaceByName(sProperty, pValues[i]);
     516        4625 :                 }
     517             :             }
     518           3 :             CATCH_INFO("Exception from PutProperties: ");
     519             :         }
     520             :         try
     521             :         {
     522         371 :             Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     523         371 :             xBatch->commitChanges();
     524             :         }
     525         371 :         CATCH_INFO("Exception from commitChanges(): ")
     526             :     }
     527             : 
     528         742 :     return bRet;
     529             : }
     530             : 
     531        3228 : void ConfigItem::DisableNotification()
     532             : {
     533             :     OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" );
     534        3228 :     RemoveChangesListener();
     535        3228 : }
     536             : 
     537       12987 : bool ConfigItem::EnableNotification(const Sequence< OUString >& rNames,
     538             :                                     bool bEnableInternalNotification )
     539             : {
     540             :     OSL_ENSURE(!(m_nMode & ConfigItemMode::ReleaseTree), "notification in ConfigItemMode::ReleaseTree mode not possible");
     541       12987 :     m_bEnableInternalNotification = bEnableInternalNotification;
     542       12987 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     543       25974 :     Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY);
     544       12987 :     if(!xChgNot.is())
     545           0 :         return false;
     546             : 
     547             :     OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called");
     548       12987 :     if(xChangeLstnr.is())
     549           0 :         xChgNot->removeChangesListener( xChangeLstnr );
     550       12987 :     bool bRet = true;
     551             : 
     552             :     try
     553             :     {
     554       12987 :         xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames);
     555       12987 :         xChgNot->addChangesListener( xChangeLstnr );
     556             :     }
     557           0 :     catch (const RuntimeException&)
     558             :     {
     559           0 :         bRet = false;
     560             :     }
     561       25974 :     return bRet;
     562             : }
     563             : 
     564       26363 : void ConfigItem::RemoveChangesListener()
     565             : {
     566       26363 :     Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY);
     567       26363 :     if(xChgNot.is() && xChangeLstnr.is())
     568             :     {
     569             :         try
     570             :         {
     571       11901 :             xChgNot->removeChangesListener( xChangeLstnr );
     572       11901 :             xChangeLstnr = 0;
     573             :         }
     574           0 :         catch (const Exception&)
     575             :         {
     576             :         }
     577       26363 :     }
     578       26363 : }
     579             : 
     580       31554 : static void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode)
     581             : {
     582       31554 :     switch (_eFormat)
     583             :     {
     584             :     case CONFIG_NAME_LOCAL_NAME:
     585             :         // unaltered - this is our input format
     586       30752 :         break;
     587             : 
     588             :     case CONFIG_NAME_FULL_PATH:
     589             :         {
     590           0 :             Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY);
     591           0 :             if (xFormatter.is())
     592             :             {
     593           0 :                 OUString * pNames = _rNames.getArray();
     594           0 :                 for(int i = 0; i<_rNames.getLength(); ++i)
     595             :                 {
     596             :                     try
     597             :                     {
     598           0 :                         pNames[i] = xFormatter->composeHierarchicalName(pNames[i]);
     599             :                     }
     600           0 :                     CATCH_INFO("Exception from composeHierarchicalName(): ")
     601             :                 }
     602           0 :                 break;
     603           0 :             }
     604             :         }
     605             :         OSL_FAIL("Cannot create absolute paths: missing interface");
     606             :         // make local paths instaed
     607             : 
     608             :     case CONFIG_NAME_LOCAL_PATH:
     609             :         {
     610         802 :             Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY);
     611         802 :             if (xTypeContainer.is())
     612             :             {
     613           0 :                 OUString sTypeName = xTypeContainer->getElementTemplateName();
     614           0 :                 sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1);
     615             : 
     616           0 :                 OUString * pNames = _rNames.getArray();
     617           0 :                 for(int i = 0; i<_rNames.getLength(); ++i)
     618             :                 {
     619           0 :                     pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName);
     620           0 :                 }
     621             :             }
     622             :             else
     623             :             {
     624         802 :                 Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY);
     625         802 :                 if (xSVI.is() && xSVI->supportsService("com.sun.star.configuration.SetAccess"))
     626             :                 {
     627         802 :                     OUString * pNames = _rNames.getArray();
     628        2912 :                     for(int i = 0; i<_rNames.getLength(); ++i)
     629             :                     {
     630        2110 :                         pNames[i] = wrapConfigurationElementName(pNames[i]);
     631             :                     }
     632         802 :                 }
     633         802 :             }
     634             :         }
     635         802 :         break;
     636             : 
     637             :     case CONFIG_NAME_PLAINTEXT_NAME:
     638             :         {
     639           0 :             Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY);
     640           0 :             if (xEscaper.is())
     641             :             {
     642           0 :                 OUString * pNames = _rNames.getArray();
     643           0 :                 for(int i = 0; i<_rNames.getLength(); ++i)
     644             :                 try
     645             :                 {
     646           0 :                     pNames[i] = xEscaper->unescapeString(pNames[i]);
     647             :                 }
     648           0 :                 CATCH_INFO("Exception from unescapeString(): ")
     649           0 :             }
     650             :         }
     651           0 :         break;
     652             : 
     653             :     }
     654       31554 : }
     655             : 
     656       30752 : Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode)
     657             : {
     658       30752 :     ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT;
     659             : 
     660       30752 :     return GetNodeNames(rNode, eDefaultFormat);
     661             : }
     662             : 
     663       31554 : Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat)
     664             : {
     665       31554 :     Sequence< OUString > aRet;
     666       63108 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     667       31554 :     if(xHierarchyAccess.is())
     668             :     {
     669             :         try
     670             :         {
     671       31554 :             Reference<XNameAccess> xCont;
     672       31554 :             if(!rNode.isEmpty())
     673             :             {
     674       31217 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     675       31217 :                 aNode >>= xCont;
     676             :             }
     677             :             else
     678         337 :                 xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY);
     679       31554 :             if(xCont.is())
     680             :             {
     681       31554 :                 aRet = xCont->getElementNames();
     682       31554 :                 lcl_normalizeLocalNames(aRet,eFormat,xCont);
     683       31554 :             }
     684             : 
     685             :         }
     686           0 :         CATCH_INFO("Exception from GetNodeNames: ");
     687             :     }
     688       63108 :     return aRet;
     689             : }
     690             : 
     691           4 : bool ConfigItem::ClearNodeSet(const OUString& rNode)
     692             : {
     693           4 :     ValueCounter_Impl aCounter(m_nInValueChange);
     694           4 :     bool bRet = false;
     695           8 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     696           4 :     if(xHierarchyAccess.is())
     697             :     {
     698             :         try
     699             :         {
     700           4 :             Reference<XNameContainer> xCont;
     701           4 :             if(!rNode.isEmpty())
     702             :             {
     703           4 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     704           4 :                 aNode >>= xCont;
     705             :             }
     706             :             else
     707           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     708           4 :             if(!xCont.is())
     709           0 :                 return false;
     710           8 :             Sequence< OUString > aNames = xCont->getElementNames();
     711           4 :             const OUString* pNames = aNames.getConstArray();
     712           8 :             Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     713          19 :             for(sal_Int32 i = 0; i < aNames.getLength(); i++)
     714             :             {
     715             :                 try
     716             :                 {
     717          15 :                     xCont->removeByName(pNames[i]);
     718             :                 }
     719           0 :                 CATCH_INFO("Exception from removeByName(): ")
     720             :             }
     721           4 :             xBatch->commitChanges();
     722           8 :             bRet = true;
     723             :         }
     724           0 :         CATCH_INFO("Exception from ClearNodeSet")
     725             :     }
     726           8 :     return bRet;
     727             : }
     728             : 
     729          25 : bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements)
     730             : {
     731          25 :     ValueCounter_Impl aCounter(m_nInValueChange);
     732          25 :     bool bRet = false;
     733          50 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     734          25 :     if(xHierarchyAccess.is())
     735             :     {
     736          25 :         const OUString* pElements = rElements.getConstArray();
     737             :         try
     738             :         {
     739          25 :             Reference<XNameContainer> xCont;
     740          25 :             if(!rNode.isEmpty())
     741             :             {
     742          25 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     743          25 :                 aNode >>= xCont;
     744             :             }
     745             :             else
     746           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     747          25 :             if(!xCont.is())
     748           0 :                 return false;
     749             :             try
     750             :             {
     751          35 :                 for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++)
     752             :                 {
     753          25 :                     xCont->removeByName(pElements[nElement]);
     754             :                 }
     755          10 :                 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     756          10 :                 xBatch->commitChanges();
     757             :             }
     758          15 :             CATCH_INFO("Exception from commitChanges(): ")
     759          25 :             bRet = true;
     760             :         }
     761           0 :         CATCH_INFO("Exception from GetNodeNames: ")
     762             :     }
     763          50 :     return bRet;
     764             : }
     765             : 
     766             : static inline
     767         688 : OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix )
     768             : {
     769         688 :     OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix);
     770         688 :     return extractFirstFromConfigurationPath( sSubPath );
     771             : }
     772             : 
     773             : static
     774         653 : Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix )
     775             : {
     776         653 :     const PropertyValue* pProperties = rValues.getConstArray();
     777             : 
     778         653 :     Sequence< OUString > aSubNodeNames(rValues.getLength());
     779         653 :     OUString* pSubNodeNames = aSubNodeNames.getArray();
     780             : 
     781        1306 :     OUString sLastSubNode;
     782         653 :     sal_Int32 nSubIndex = 0;
     783             : 
     784        2050 :     for(sal_Int32 i = 0; i < rValues.getLength(); i++)
     785             :     {
     786        1397 :         OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix);
     787        2794 :         OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath );
     788             : 
     789        1397 :         if(sLastSubNode != sSubNode)
     790             :         {
     791         725 :             pSubNodeNames[nSubIndex++] = sSubNode;
     792             :         }
     793             : 
     794        1397 :         sLastSubNode = sSubNode;
     795        1397 :     }
     796         653 :     aSubNodeNames.realloc(nSubIndex);
     797             : 
     798        1306 :     return aSubNodeNames;
     799             : }
     800             : 
     801             : // Add or change properties
     802          37 : bool ConfigItem::SetSetProperties(
     803             :     const OUString& rNode, const Sequence< PropertyValue >& rValues)
     804             : {
     805          37 :     ValueCounter_Impl aCounter(m_nInValueChange);
     806          37 :     bool bRet = true;
     807          74 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     808          37 :     if(xHierarchyAccess.is())
     809             :     {
     810          37 :         Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     811             :         try
     812             :         {
     813          37 :             Reference<XNameContainer> xCont;
     814          37 :             if(!rNode.isEmpty())
     815             :             {
     816          37 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     817          37 :                 aNode >>= xCont;
     818             :             }
     819             :             else
     820           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     821          37 :             if(!xCont.is())
     822           0 :                 return false;
     823             : 
     824          74 :             Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
     825             : 
     826          37 :             if(xFac.is())
     827             :             {
     828          37 :                 const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
     829             : 
     830          37 :                 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
     831             : 
     832          74 :                 for(sal_Int32 j = 0; j <nSubNodeCount; j++)
     833             :                 {
     834          37 :                     if(!xCont->hasByName(aSubNodeNames[j]))
     835             :                     {
     836          25 :                         Reference<XInterface> xInst = xFac->createInstance();
     837          50 :                         Any aVal; aVal <<= xInst;
     838          50 :                         xCont->insertByName(aSubNodeNames[j], aVal);
     839             :                     }
     840             :                     //set values
     841             :                 }
     842             :                 try
     843             :                 {
     844          37 :                     xBatch->commitChanges();
     845             :                 }
     846           0 :                 CATCH_INFO("Exception from commitChanges(): ")
     847             : 
     848          37 :                 const PropertyValue* pProperties = rValues.getConstArray();
     849             : 
     850          74 :                 Sequence< OUString > aSetNames(rValues.getLength());
     851          37 :                 OUString* pSetNames = aSetNames.getArray();
     852             : 
     853          74 :                 Sequence< Any> aSetValues(rValues.getLength());
     854          37 :                 Any* pSetValues = aSetValues.getArray();
     855             : 
     856          37 :                 bool bEmptyNode = rNode.isEmpty();
     857         746 :                 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
     858             :                 {
     859         709 :                     pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
     860         709 :                     pSetValues[k] = pProperties[k].Value;
     861             :                 }
     862          74 :                 bRet = PutProperties(aSetNames, aSetValues);
     863             :             }
     864             :             else
     865             :             {
     866             :                 //if no factory is available then the node contains basic data elements
     867           0 :                 const PropertyValue* pValues = rValues.getConstArray();
     868           0 :                 for(int nValue = 0; nValue < rValues.getLength();nValue++)
     869             :                 {
     870             :                     try
     871             :                     {
     872           0 :                         OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
     873             : 
     874           0 :                         if(xCont->hasByName(sSubNode))
     875           0 :                             xCont->replaceByName(sSubNode, pValues[nValue].Value);
     876             :                         else
     877           0 :                             xCont->insertByName(sSubNode, pValues[nValue].Value);
     878             : 
     879             :                         OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name),
     880           0 :                             "Invalid config path" );
     881             :                     }
     882           0 :                     CATCH_INFO("Exception form insert/replaceByName(): ")
     883             :                 }
     884           0 :                 xBatch->commitChanges();
     885          37 :             }
     886             :         }
     887             : #ifdef DBG_UTIL
     888             :         catch (const Exception& rEx)
     889             :         {
     890             :             lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx);
     891             : #else
     892           0 :         catch (const Exception&)
     893             :         {
     894             : #endif
     895           0 :             bRet = false;
     896          37 :         }
     897             :     }
     898          74 :     return bRet;
     899             : }
     900             : 
     901         616 : bool ConfigItem::ReplaceSetProperties(
     902             :     const OUString& rNode, const Sequence< PropertyValue >& rValues)
     903             : {
     904         616 :     ValueCounter_Impl aCounter(m_nInValueChange);
     905         616 :     bool bRet = true;
     906        1232 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
     907         616 :     if(xHierarchyAccess.is())
     908             :     {
     909         616 :         Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
     910             :         try
     911             :         {
     912         616 :             Reference<XNameContainer> xCont;
     913         616 :             if(!rNode.isEmpty())
     914             :             {
     915         616 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
     916         616 :                 aNode >>= xCont;
     917             :             }
     918             :             else
     919           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
     920         616 :             if(!xCont.is())
     921           0 :                 return false;
     922             : 
     923             :             // JB: Change: now the same name handling for sets of simple values
     924        1232 :             const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
     925         616 :             const OUString* pSubNodeNames = aSubNodeNames.getConstArray();
     926         616 :             const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
     927             : 
     928        1232 :             Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
     929         616 :             const bool isSimpleValueSet = !xFac.is();
     930             : 
     931             :             //remove unknown members first
     932             :             {
     933         616 :                 const Sequence<OUString> aContainerSubNodes = xCont->getElementNames();
     934         616 :                 const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray();
     935             : 
     936         696 :                 for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++)
     937             :                 {
     938          80 :                     bool bFound = false;
     939         290 :                     for(sal_Int32 j = 0; j < nSubNodeCount; j++)
     940             :                     {
     941         290 :                         if(pSubNodeNames[j] == pContainerSubNodes[nContSub])
     942             :                         {
     943          80 :                             bFound = true;
     944          80 :                             break;
     945             :                         }
     946             :                     }
     947          80 :                     if(!bFound)
     948             :                     try
     949             :                     {
     950           0 :                         xCont->removeByName(pContainerSubNodes[nContSub]);
     951             :                     }
     952           0 :                     catch (const Exception&)
     953             :                     {
     954           0 :                         if (isSimpleValueSet)
     955             :                         {
     956             :                             try
     957             :                             {
     958             :                                 // #i37322#: fallback action: replace with <void/>
     959           0 :                                 xCont->replaceByName(pContainerSubNodes[nContSub], Any());
     960             :                                 // fallback successful: continue looping
     961           0 :                                 continue;
     962             :                             }
     963           0 :                             catch (Exception &)
     964             :                             {} // propagate original exception, if fallback fails
     965             :                         }
     966           0 :                         throw;
     967             :                     }
     968             :                 }
     969         616 :                 try { xBatch->commitChanges(); }
     970         616 :                 CATCH_INFO("Exception from commitChanges(): ")
     971             :             }
     972             : 
     973         616 :             if(xFac.is()) // !isSimpleValueSet
     974             :             {
     975           0 :                 for(sal_Int32 j = 0; j < nSubNodeCount; j++)
     976             :                 {
     977           0 :                     if(!xCont->hasByName(pSubNodeNames[j]))
     978             :                     {
     979             :                         //create if not available
     980           0 :                         Reference<XInterface> xInst = xFac->createInstance();
     981           0 :                         Any aVal; aVal <<= xInst;
     982           0 :                         xCont->insertByName(pSubNodeNames[j], aVal);
     983             :                     }
     984             :                 }
     985           0 :                 try { xBatch->commitChanges(); }
     986           0 :                 CATCH_INFO("Exception from commitChanges(): ")
     987             : 
     988           0 :                 const PropertyValue* pProperties = rValues.getConstArray();
     989             : 
     990           0 :                 Sequence< OUString > aSetNames(rValues.getLength());
     991           0 :                 OUString* pSetNames = aSetNames.getArray();
     992             : 
     993           0 :                 Sequence< Any> aSetValues(rValues.getLength());
     994           0 :                 Any* pSetValues = aSetValues.getArray();
     995             : 
     996           0 :                 bool bEmptyNode = rNode.isEmpty();
     997           0 :                 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
     998             :                 {
     999           0 :                     pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
    1000           0 :                     pSetValues[k] = pProperties[k].Value;
    1001             :                 }
    1002           0 :                 bRet = PutProperties(aSetNames, aSetValues);
    1003             :             }
    1004             :             else
    1005             :             {
    1006         616 :                 const PropertyValue* pValues = rValues.getConstArray();
    1007             : 
    1008             :                 //if no factory is available then the node contains basic data elements
    1009        1304 :                 for(int nValue = 0; nValue < rValues.getLength();nValue++)
    1010             :                 {
    1011             :                     try
    1012             :                     {
    1013         688 :                         OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
    1014             : 
    1015         688 :                         if(xCont->hasByName(sSubNode))
    1016          80 :                             xCont->replaceByName(sSubNode, pValues[nValue].Value);
    1017             :                         else
    1018         608 :                             xCont->insertByName(sSubNode, pValues[nValue].Value);
    1019             :                     }
    1020           0 :                     CATCH_INFO("Exception from insert/replaceByName(): ");
    1021             :                 }
    1022         616 :                 xBatch->commitChanges();
    1023         616 :             }
    1024             :         }
    1025             : #ifdef DBG_UTIL
    1026             :         catch (const Exception& rEx)
    1027             :         {
    1028             :             lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx);
    1029             : #else
    1030           0 :         catch (const Exception&)
    1031             :         {
    1032             : #endif
    1033           0 :             bRet = false;
    1034         616 :         }
    1035             :     }
    1036        1232 :     return bRet;
    1037             : }
    1038             : 
    1039           0 : bool ConfigItem::AddNode(const OUString& rNode, const OUString& rNewNode)
    1040             : {
    1041           0 :     ValueCounter_Impl aCounter(m_nInValueChange);
    1042           0 :     bool bRet = true;
    1043           0 :     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
    1044           0 :     if(xHierarchyAccess.is())
    1045             :     {
    1046           0 :         Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
    1047             :         try
    1048             :         {
    1049           0 :             Reference<XNameContainer> xCont;
    1050           0 :             if(!rNode.isEmpty())
    1051             :             {
    1052           0 :                 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
    1053           0 :                 aNode >>= xCont;
    1054             :             }
    1055             :             else
    1056           0 :                 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
    1057           0 :             if(!xCont.is())
    1058           0 :                 return false;
    1059             : 
    1060           0 :             Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
    1061             : 
    1062           0 :             if(xFac.is())
    1063             :             {
    1064           0 :                 if(!xCont->hasByName(rNewNode))
    1065             :                 {
    1066           0 :                     Reference<XInterface> xInst = xFac->createInstance();
    1067           0 :                     Any aVal; aVal <<= xInst;
    1068           0 :                     xCont->insertByName(rNewNode, aVal);
    1069             :                 }
    1070             :                 try
    1071             :                 {
    1072           0 :                     xBatch->commitChanges();
    1073             :                 }
    1074           0 :                 CATCH_INFO("Exception from commitChanges(): ")
    1075             :             }
    1076             :             else
    1077             :             {
    1078             :                 //if no factory is available then the node contains basic data elements
    1079             :                 try
    1080             :                 {
    1081           0 :                     if(!xCont->hasByName(rNewNode))
    1082           0 :                         xCont->insertByName(rNewNode, Any());
    1083             :                 }
    1084           0 :                 CATCH_INFO("Exception from AddNode(): ")
    1085             :             }
    1086           0 :             xBatch->commitChanges();
    1087             :         }
    1088             : #ifdef DBG_UTIL
    1089             :         catch (const Exception& rEx)
    1090             :         {
    1091             :             lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx);
    1092             : #else
    1093           0 :         catch (const Exception&)
    1094             :         {
    1095             : #endif
    1096           0 :             bRet = false;
    1097           0 :         }
    1098             :     }
    1099           0 :     return bRet;
    1100             : }
    1101             : 
    1102             : 
    1103        3614 : void    ConfigItem::SetModified()
    1104             : {
    1105        3614 :     m_bIsModified = true;
    1106        3614 : }
    1107             : 
    1108         771 : void    ConfigItem::ClearModified()
    1109             : {
    1110         771 :     m_bIsModified = false;
    1111         771 : }
    1112             : 
    1113             : 
    1114             : 
    1115      156501 : Reference< XHierarchicalNameAccess> ConfigItem::GetTree()
    1116             : {
    1117      156501 :     Reference< XHierarchicalNameAccess> xRet;
    1118      156501 :     if(!m_xHierarchyAccess.is())
    1119        1149 :         xRet = ConfigManager::acquireTree(*this);
    1120             :     else
    1121      155352 :         xRet = m_xHierarchyAccess;
    1122      156501 :     return xRet;
    1123             : }
    1124             : 
    1125         327 : void ConfigItem::Commit()
    1126             : {
    1127         327 :     ImplCommit();
    1128         327 :     ClearModified();
    1129         327 : }
    1130             : 
    1131             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11