summaryrefslogtreecommitdiff
path: root/unotools/source/config/configitem.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'unotools/source/config/configitem.cxx')
-rw-r--r--unotools/source/config/configitem.cxx1422
1 files changed, 1422 insertions, 0 deletions
diff --git a/unotools/source/config/configitem.cxx b/unotools/source/config/configitem.cxx
new file mode 100644
index 000000000000..e191f471057a
--- /dev/null
+++ b/unotools/source/config/configitem.cxx
@@ -0,0 +1,1422 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_unotools.hxx"
+#include "unotools/configitem.hxx"
+#include "unotools/configmgr.hxx"
+#include "unotools/configpathes.hxx"
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/beans/XMultiPropertySet.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+#include <com/sun/star/util/XChangesNotifier.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XHierarchicalName.hpp>
+#include <com/sun/star/configuration/XTemplateContainer.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/awt/XRequestCallback.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/util/XStringEscape.hpp>
+#include <com/sun/star/util/XChangesBatch.hpp>
+#include <osl/diagnose.h>
+#include <tools/solarmutex.hxx>
+#include <rtl/ustrbuf.hxx>
+
+using namespace utl;
+using rtl::OUString;
+using rtl::OString;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::container;
+using namespace com::sun::star::configuration;
+
+#define C2U(cChar) OUString::createFromAscii(cChar)
+#include <cppuhelper/implbase1.hxx> // helper for implementations
+
+#ifdef DBG_UTIL
+inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx)
+{
+ OString sMsg(cText);
+ sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, sMsg.getStr());
+}
+#define CATCH_INFO(a) \
+catch(Exception& rEx) \
+{ \
+ lcl_CFG_DBG_EXCEPTION(a, rEx);\
+}
+#else
+ #define lcl_CFG_DBG_EXCEPTION( a, b)
+ #define CATCH_INFO(a) catch(Exception& ){}
+#endif
+
+/*
+ The ConfigChangeListener_Impl receives notifications from the configuration about changes that
+ have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its
+ "CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired
+ before doing so.
+*/
+
+namespace utl{
+ class ConfigChangeListener_Impl : public cppu::WeakImplHelper1
+ <
+ com::sun::star::util::XChangesListener
+ >
+ {
+ public:
+ ConfigItem* pParent;
+ const Sequence< OUString > aPropertyNames;
+ ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames);
+ ~ConfigChangeListener_Impl();
+
+ //XChangesListener
+ virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException);
+
+ //XEventListener
+ virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
+ };
+/* -----------------------------12.02.01 11:38--------------------------------
+
+ ---------------------------------------------------------------------------*/
+struct ConfigItem_Impl
+{
+ utl::ConfigManager* pManager;
+ sal_Int16 nMode;
+ sal_Bool bIsModified;
+ sal_Bool bEnableInternalNotification;
+
+ sal_Int16 nInValueChange;
+ ConfigItem_Impl() :
+ pManager(0),
+ nMode(0),
+ bIsModified(sal_False),
+ bEnableInternalNotification(sal_False),
+ nInValueChange(0)
+ {}
+};
+}
+/* -----------------------------04.12.00 10:25--------------------------------
+
+ ---------------------------------------------------------------------------*/
+class ValueCounter_Impl
+{
+ sal_Int16& rCnt;
+public:
+ ValueCounter_Impl(sal_Int16& rCounter):
+ rCnt(rCounter)
+ {rCnt++;}
+ ~ValueCounter_Impl()
+ {
+ OSL_ENSURE(rCnt>0, "RefCount < 0 ??");
+ rCnt--;
+ }
+};
+/* -----------------------------03.12.02 -------------------------------------
+
+ ---------------------------------------------------------------------------*/
+namespace
+{
+ // helper to achieve exception - safe handling of an Item under construction
+ template <class TYP>
+ class AutoDeleter // : Noncopyable
+ {
+ TYP* m_pItem;
+ public:
+ AutoDeleter(TYP * pItem)
+ : m_pItem(pItem)
+ {
+ }
+
+ ~AutoDeleter()
+ {
+ delete m_pItem;
+ }
+
+ void keep() { m_pItem = 0; }
+ };
+}
+/* -----------------------------29.08.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ConfigChangeListener_Impl::ConfigChangeListener_Impl(
+ ConfigItem& rItem, const Sequence< OUString >& rNames) :
+ pParent(&rItem),
+ aPropertyNames(rNames)
+{
+}
+/* -----------------------------29.08.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ConfigChangeListener_Impl::~ConfigChangeListener_Impl()
+{
+}
+/* -----------------------------29.08.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool lcl_Find(
+ const rtl::OUString& rTemp,
+ const OUString* pCheckPropertyNames,
+ sal_Int32 nLength)
+{
+ //return true if the path is completely correct or if it is longer
+ //i.e ...Print/Content/Graphic and .../Print
+ for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++)
+ if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) )
+ return sal_True;
+ return sal_False;
+}
+//-----------------------------------------------------------------------------
+void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException)
+{
+ const ElementChange* pElementChanges = rEvent.Changes.getConstArray();
+
+ Sequence<OUString> aChangedNames(rEvent.Changes.getLength());
+ OUString* pNames = aChangedNames.getArray();
+
+ const OUString* pCheckPropertyNames = aPropertyNames.getConstArray();
+
+ sal_Int32 nNotify = 0;
+ for(int i = 0; i < aChangedNames.getLength(); i++)
+ {
+ OUString sTemp;
+ pElementChanges[i].Accessor >>= sTemp;
+ if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength()))
+ pNames[nNotify++] = sTemp;
+ }
+ if( nNotify )
+ {
+ if ( ::tools::SolarMutex::Acquire() )
+ {
+ aChangedNames.realloc(nNotify);
+ pParent->CallNotify(aChangedNames);
+ ::tools::SolarMutex::Release();
+ }
+ }
+}
+
+/* -----------------------------29.08.00 16:34--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException)
+{
+ pParent->RemoveChangesListener();
+}
+/* -----------------------------29.08.00 12:50--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ConfigItem::ConfigItem(const OUString rSubTree, sal_Int16 nSetMode ) :
+ sSubTree(rSubTree),
+ pImpl(new ConfigItem_Impl)
+{
+ AutoDeleter<ConfigItem_Impl> aNewImpl(pImpl);
+
+ pImpl->pManager = ConfigManager::GetConfigManager();
+ pImpl->nMode = nSetMode;
+ if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE))
+ pImpl->pManager->AddConfigItem(*this);
+ else
+ m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
+
+ // no more exceptions after c'tor has finished
+ aNewImpl.keep();
+ pImpl->nMode &= ~CONFIG_MODE_PROPAGATE_ERRORS;
+}
+/* -----------------------------17.11.00 13:53--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ConfigItem::ConfigItem(utl::ConfigManager& rManager, const rtl::OUString rSubTree) :
+ sSubTree(rSubTree),
+ pImpl(new ConfigItem_Impl)
+{
+ pImpl->pManager = &rManager;
+ pImpl->nMode = CONFIG_MODE_IMMEDIATE_UPDATE; // does not allow exceptions
+ m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
+}
+//---------------------------------------------------------------------
+//--- 02.08.2002 16:33:23 -----------------------------------------------
+sal_Bool ConfigItem::IsValidConfigMgr() const
+{
+ return ( pImpl->pManager && pImpl->pManager->GetConfigurationProvider().is() );
+}
+
+/* -----------------------------29.08.00 12:52--------------------------------
+
+ ---------------------------------------------------------------------------*/
+ConfigItem::~ConfigItem()
+{
+ if(pImpl->pManager)
+ {
+ RemoveChangesListener();
+ pImpl->pManager->RemoveConfigItem(*this);
+ }
+ delete pImpl;
+}
+/* -----------------------------29.08.00 12:52--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::ReleaseConfigMgr()
+{
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ try
+ {
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ xBatch->commitChanges();
+ }
+ CATCH_INFO("Exception from commitChanges(): ")
+ }
+ RemoveChangesListener();
+ OSL_ENSURE(pImpl->pManager, "ConfigManager already released");
+ pImpl->pManager = 0;
+}
+/* -----------------------------29.08.00 12:52--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames )
+{
+ // the call is forwarded to the virtual Notify() method
+ // it is pure virtual, so all classes deriving from ConfigItem have to decide how they
+ // want to notify listeners
+ if(!IsInValueChange() || pImpl->bEnableInternalNotification)
+ Notify(rPropertyNames);
+}
+
+/* -----------------------------12.12.00 17:09--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool lcl_IsLocalProperty(const OUString& rSubTree, const OUString& rProperty)
+{
+ static const sal_Char* aLocalProperties[] =
+ {
+ "Office.Common/Path/Current/Storage",
+ "Office.Common/Path/Current/Temp"
+ };
+ static const int aLocalPropLen[] =
+ {
+ 34,
+ 31
+ };
+ OUString sProperty(rSubTree);
+ sProperty += C2U("/");
+ sProperty += rProperty;
+
+ if(sProperty.equalsAsciiL( aLocalProperties[0], aLocalPropLen[0]) ||
+ sProperty.equalsAsciiL( aLocalProperties[1], aLocalPropLen[1]))
+ return sal_True;
+
+ return sal_False;
+}
+/* -----------------------------10.04.01 15:00--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& lInNames ,
+ const Sequence< Any >& lInValues ,
+ Sequence< Any >& lOutValues )
+{
+ // Safe impossible cases.
+ // This method should be called for special ConfigItem-mode only!
+ OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" );
+
+ sal_Int32 nSourceCounter ; // used to step during input lists
+ sal_Int32 nSourceSize ; // marks end of loop over input lists
+ sal_Int32 nDestinationCounter ; // actual position in output lists
+ sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue >
+ sal_Int32 nPropertiesSize ; // marks end of inner loop
+ Sequence< OUString > lPropertyNames ; // list of all locales for localized entry
+ Sequence< PropertyValue > lProperties ; // localized values of an configuration entry packed for return
+ Reference< XInterface > xLocalizedNode ; // if cfg entry is localized ... lInValues contains an XInterface!
+
+ // Optimise follow algorithm ... A LITTLE BIT :-)
+ // There exist two different possibilities:
+ // i ) There exist no localized entries ... => size of lOutValues will be the same like lInNames/lInValues!
+ // ii) There exist some (mostly one or two) localized entries ... => size of lOutValues will be the same like lInNames/lInValues!
+ // ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service).
+ // We read all his child nodes and pack it into Sequence< PropertyValue >.
+ // The result list we pack into the return any. We never change size of lists!
+ nSourceSize = lInNames.getLength();
+ lOutValues.realloc( nSourceSize );
+
+ // Algorithm:
+ // Copy all names and values from in to out lists.
+ // Look for special localized entries ... You can detect it as "XInterface" packed into an Any.
+ // Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >.
+ // Add this list to out lists then.
+
+ nDestinationCounter = 0;
+ for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
+ {
+ // If item a special localized one ... convert and pack it ...
+ if( lInValues[nSourceCounter].getValueTypeName() == C2U("com.sun.star.uno.XInterface") )
+ {
+ lInValues[nSourceCounter] >>= xLocalizedNode;
+ Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY );
+ if( xSetAccess.is() == sal_True )
+ {
+ lPropertyNames = xSetAccess->getElementNames() ;
+ nPropertiesSize = lPropertyNames.getLength() ;
+ lProperties.realloc( nPropertiesSize ) ;
+
+ for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
+ {
+ #if OSL_DEBUG_LEVEL > 1
+ // Sometimes it's better to see what's going on :-)
+ OUString sPropName = lInNames[nSourceCounter];
+ OUString sLocaleName = lPropertyNames[nPropertyCounter];
+ #endif
+ lProperties[nPropertyCounter].Name = lPropertyNames[nPropertyCounter] ;
+ OUString sLocaleValue;
+ xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue ;
+ lProperties[nPropertyCounter].Value <<= sLocaleValue;
+ }
+
+ lOutValues[nDestinationCounter] <<= lProperties;
+ }
+ }
+ // ... or copy normal items to return lists directly.
+ else
+ {
+ lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
+ }
+ ++nDestinationCounter;
+ }
+}
+/* -----------------------------10.04.01 15:00--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames ,
+ const Sequence< Any >& lInValues ,
+ Sequence< OUString >& lOutNames ,
+ Sequence< Any >& lOutValues )
+{
+ // Safe impossible cases.
+ // This method should be called for special ConfigItem-mode only!
+ OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" );
+
+ sal_Int32 nSourceCounter ; // used to step during input lists
+ sal_Int32 nSourceSize ; // marks end of loop over input lists
+ sal_Int32 nDestinationCounter ; // actual position in output lists
+ sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue >
+ sal_Int32 nPropertiesSize ; // marks end of inner loop
+ OUString sNodeName ; // base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" )
+ Sequence< PropertyValue > lProperties ; // localized values of an configuration entry getted from lInValues-Any
+
+ // Optimise follow algorithm ... A LITTLE BIT :-)
+ // There exist two different possibilities:
+ // i ) There exist no localized entries ... => size of lOutNames/lOutValues will be the same like lInNames/lInValues!
+ // ii) There exist some (mostly one or two) localized entries ... => size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues.
+ // => I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast.
+ // We should reserve same space for output list like input ones first.
+ // Follow algorithm looks for these borders and change it for ii) only!
+ // It will be faster then a "realloc()" call in every loop ...
+ nSourceSize = lInNames.getLength();
+
+ lOutNames.realloc ( nSourceSize );
+ lOutValues.realloc ( nSourceSize );
+
+ // Algorithm:
+ // Copy all names and values from const to return lists.
+ // Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any.
+ // Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues.
+
+ nDestinationCounter = 0;
+ for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
+ {
+ // If item a special localized one ... split it and insert his parts to output lists ...
+ if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) )
+ {
+ lInValues[nSourceCounter] >>= lProperties ;
+ sNodeName = lInNames[nSourceCounter] ;
+ sNodeName += C2U("/") ;
+ nPropertiesSize = lProperties.getLength() ;
+
+ if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() )
+ {
+ lOutNames.realloc ( nDestinationCounter+nPropertiesSize );
+ lOutValues.realloc ( nDestinationCounter+nPropertiesSize );
+ }
+
+ for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
+ {
+ lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name ;
+ lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value ;
+ ++nDestinationCounter;
+ }
+ }
+ // ... or copy normal items to return lists directly.
+ else
+ {
+ if( (nDestinationCounter+1) > lOutNames.getLength() )
+ {
+ lOutNames.realloc ( nDestinationCounter+1 );
+ lOutValues.realloc ( nDestinationCounter+1 );
+ }
+
+ lOutNames [nDestinationCounter] = lInNames [nSourceCounter];
+ lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
+ ++nDestinationCounter;
+ }
+ }
+}
+/* -----------------------------03.02.2003 14:44------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< rtl::OUString >& rNames)
+{
+ sal_Int32 i;
+
+ // size of return list is fix!
+ // Every item must match to length of incoming name list.
+ sal_Int32 nCount = rNames.getLength();
+ Sequence< sal_Bool > lStates(nCount);
+
+ // We must be shure to return a valid information everytime!
+ // Set default to non readonly ... similar to the configuration handling of this property.
+ for ( i=0; i<nCount; ++i)
+ lStates[i] = sal_False;
+
+ // no access - no informations ...
+ Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree();
+ if (!xHierarchyAccess.is())
+ return lStates;
+
+ for (i=0; i<nCount; ++i)
+ {
+ try
+ {
+ if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, rNames[i]))
+ {
+ OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nlocal mode seams to be used!?\n");
+ continue;
+ }
+
+ OUString sName = rNames[i];
+ OUString sPath;
+ OUString sProperty;
+
+ ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty);
+ if (!sPath.getLength() && !sProperty.getLength())
+ {
+ OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nsplitt failed\n");
+ continue;
+ }
+
+ Reference< XInterface > xNode;
+ Reference< XPropertySet > xSet ;
+ Reference< XPropertySetInfo > xInfo;
+ if (sPath.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(sPath);
+ if (!(aNode >>= xNode) || !xNode.is())
+ {
+ OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno set available\n");
+ continue;
+ }
+ }
+ else
+ {
+ xNode = Reference< XInterface >(xHierarchyAccess, UNO_QUERY);
+ }
+
+ xSet = Reference< XPropertySet >(xNode, UNO_QUERY);
+ if (xSet.is())
+ {
+ xInfo = xSet->getPropertySetInfo();
+ OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n");
+ }
+ else
+ {
+ xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY);
+ OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n");
+ }
+
+ if (!xInfo.is())
+ {
+ OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno prop info available\n");
+ continue;
+ }
+
+ Property aProp = xInfo->getPropertyByName(sProperty);
+ lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY);
+ }
+ catch(Exception&){}
+ }
+
+ return lStates;
+}
+
+/* -----------------------------29.08.00 15:10--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames)
+{
+ Sequence< Any > aRet(rNames.getLength());
+ const OUString* pNames = rNames.getConstArray();
+ Any* pRet = aRet.getArray();
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ for(int i = 0; i < rNames.getLength(); i++)
+ {
+ try
+ {
+ if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
+ {
+ OUString sProperty(sSubTree);
+ sProperty += C2U("/");
+ sProperty += pNames[i];
+ pRet[i] = pImpl->pManager->GetLocalProperty(sProperty);
+ }
+ else
+ pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]);
+ }
+ catch(Exception& rEx)
+ {
+#if OSL_DEBUG_LEVEL > 0
+ OString sMsg("XHierarchicalNameAccess: ");
+ sMsg += OString(rEx.Message.getStr(),
+ rEx.Message.getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ sMsg += OString("\n");
+ sMsg += OString(ConfigManager::GetConfigBaseURL().getStr(),
+ ConfigManager::GetConfigBaseURL().getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ sMsg += OString(sSubTree.getStr(),
+ sSubTree.getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ sMsg += OString("/");
+ sMsg += OString(pNames[i].getStr(),
+ pNames[i].getLength(),
+ RTL_TEXTENCODING_ASCII_US);
+ OSL_ENSURE(sal_False, sMsg.getStr());
+#else
+ (void) rEx; // avoid warning
+#endif
+ }
+ }
+
+ // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >.
+ if((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES)
+ {
+ Sequence< Any > lValues;
+ impl_packLocalizedProperties( rNames, aRet, lValues );
+ aRet = lValues;
+ }
+ }
+ return aRet;
+}
+/* -----------------------------29.08.00 17:28--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::PutProperties( const Sequence< OUString >& rNames,
+ const Sequence< Any>& rValues)
+{
+ ValueCounter_Impl aCounter(pImpl->nInValueChange);
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY);
+ sal_Bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is();
+ if(bRet)
+ {
+ Sequence< OUString > lNames ;
+ Sequence< Any > lValues ;
+ const OUString* pNames = NULL ;
+ const Any* pValues = NULL ;
+ sal_Int32 nNameCount ;
+ if(( pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES )
+ {
+ // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue >
+ // as value of an localized configuration entry!
+ // How we can do that?
+ // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"!
+ impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues );
+ pNames = lNames.getConstArray ();
+ pValues = lValues.getConstArray ();
+ nNameCount = lNames.getLength ();
+ }
+ else
+ {
+ // This is the normal mode ...
+ // Use given input lists directly.
+ pNames = rNames.getConstArray ();
+ pValues = rValues.getConstArray ();
+ nNameCount = rNames.getLength ();
+ }
+ for(int i = 0; i < nNameCount; i++)
+ {
+ if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
+ {
+ OUString sProperty(sSubTree);
+ sProperty += C2U("/");
+ sProperty += pNames[i];
+ pImpl->pManager->PutLocalProperty(sProperty, pValues[i]);
+ }
+ else
+ {
+ try
+ {
+ OUString sNode, sProperty;
+ if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
+
+ Reference<XNameAccess> xNodeAcc;
+ aNode >>= xNodeAcc;
+ Reference<XNameReplace> xNodeReplace(xNodeAcc, UNO_QUERY);
+ Reference<XNameContainer> xNodeCont (xNodeAcc, UNO_QUERY);
+
+ sal_Bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty));
+ if (bExist && xNodeReplace.is())
+ xNodeReplace->replaceByName(sProperty, pValues[i]);
+ else
+ if (!bExist && xNodeCont.is())
+ xNodeCont->insertByName(sProperty, pValues[i]);
+ else
+ bRet = sal_False;
+ }
+ else //direct value
+ {
+ xTopNodeReplace->replaceByName(sProperty, pValues[i]);
+ }
+ }
+ CATCH_INFO("Exception from PutProperties: ");
+ }
+ }
+ try
+ {
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ xBatch->commitChanges();
+ }
+ CATCH_INFO("Exception from commitChanges(): ")
+ }
+
+ return bRet;
+}
+/* -----------------------------08.12.05 15:27--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::DisableNotification()
+{
+ OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" );
+ RemoveChangesListener();
+}
+/* -----------------------------29.08.00 16:19--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::EnableNotification(const Sequence< OUString >& rNames,
+ sal_Bool bEnableInternalNotification )
+
+{
+ OSL_ENSURE(0 == (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible");
+ pImpl->bEnableInternalNotification = bEnableInternalNotification;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY);
+ if(!xChgNot.is())
+ return sal_False;
+
+ OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called");
+ if(xChangeLstnr.is())
+ xChgNot->removeChangesListener( xChangeLstnr );
+ sal_Bool bRet = sal_True;
+
+ try
+ {
+ xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames);
+ xChgNot->addChangesListener( xChangeLstnr );
+ }
+ catch(RuntimeException& )
+ {
+ bRet = sal_False;
+ }
+ return bRet;
+}
+/* -----------------------------29.08.00 16:47--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::RemoveChangesListener()
+{
+ Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY);
+ if(xChgNot.is() && xChangeLstnr.is())
+ {
+ try
+ {
+ xChgNot->removeChangesListener( xChangeLstnr );
+ xChangeLstnr = 0;
+ }
+ catch(Exception & )
+ {
+ }
+ }
+}
+/* -----------------------------10.07.00 --------------------------------
+
+ ---------------------------------------------------------------------------*/
+void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode)
+{
+ switch (_eFormat)
+ {
+ case CONFIG_NAME_LOCAL_NAME:
+ // unaltered - this is our input format
+ break;
+
+ case CONFIG_NAME_FULL_PATH:
+ {
+ Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY);
+ if (xFormatter.is())
+ {
+ OUString * pNames = _rNames.getArray();
+ for(int i = 0; i<_rNames.getLength(); ++i)
+ try
+ {
+ pNames[i] = xFormatter->composeHierarchicalName(pNames[i]);
+ }
+ CATCH_INFO("Exception from composeHierarchicalName(): ")
+ break;
+ }
+ }
+ OSL_ENSURE(false, "Cannot create absolute pathes: missing interface");
+ // make local pathes instaed
+
+ case CONFIG_NAME_LOCAL_PATH:
+ {
+ Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY);
+ if (xTypeContainer.is())
+ {
+ OUString sTypeName = xTypeContainer->getElementTemplateName();
+ sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1);
+
+ OUString * pNames = _rNames.getArray();
+ for(int i = 0; i<_rNames.getLength(); ++i)
+ {
+ pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName);
+ }
+ }
+ else
+ {
+ static const OUString sSetService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.SetAccess"));
+ Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY);
+ if (xSVI.is() && xSVI->supportsService(sSetService))
+ {
+ OUString * pNames = _rNames.getArray();
+ for(int i = 0; i<_rNames.getLength(); ++i)
+ {
+ pNames[i] = wrapConfigurationElementName(pNames[i]);
+ }
+ }
+ }
+ }
+ break;
+
+ case CONFIG_NAME_PLAINTEXT_NAME:
+ {
+ Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY);
+ if (xEscaper.is())
+ {
+ OUString * pNames = _rNames.getArray();
+ for(int i = 0; i<_rNames.getLength(); ++i)
+ try
+ {
+ pNames[i] = xEscaper->unescapeString(pNames[i]);
+ }
+ CATCH_INFO("Exception from unescapeString(): ")
+ }
+ }
+ break;
+
+ }
+}
+/* -----------------------------10.07.00 --------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode)
+{
+ ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT;
+
+ return GetNodeNames(rNode, eDefaultFormat);
+}
+/* -----------------------------15.09.00 12:06--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat)
+{
+ Sequence< OUString > aRet;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ try
+ {
+ Reference<XNameAccess> xCont;
+ if(rNode.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
+ aNode >>= xCont;
+ }
+ else
+ xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY);
+ if(xCont.is())
+ {
+ aRet = xCont->getElementNames();
+ lcl_normalizeLocalNames(aRet,eFormat,xCont);
+ }
+
+ }
+ CATCH_INFO("Exception from GetNodeNames: ");
+ }
+ return aRet;
+}
+/* -----------------------------15.09.00 15:52--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::ClearNodeSet(const OUString& rNode)
+{
+ ValueCounter_Impl aCounter(pImpl->nInValueChange);
+ sal_Bool bRet = sal_False;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ try
+ {
+ Reference<XNameContainer> xCont;
+ if(rNode.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
+ aNode >>= xCont;
+ }
+ else
+ xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
+ if(!xCont.is())
+ return sal_False;
+ Sequence< OUString > aNames = xCont->getElementNames();
+ const OUString* pNames = aNames.getConstArray();
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ for(sal_Int32 i = 0; i < aNames.getLength(); i++)
+ {
+ try
+ {
+ xCont->removeByName(pNames[i]);
+ }
+ CATCH_INFO("Exception from removeByName(): ")
+ }
+ xBatch->commitChanges();
+ bRet = sal_True;
+ }
+ CATCH_INFO("Exception from ClearNodeSet")
+ }
+ return bRet;
+}
+/* -----------------------------24.11.00 10:58--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements)
+{
+ ValueCounter_Impl aCounter(pImpl->nInValueChange);
+ sal_Bool bRet = sal_False;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ const OUString* pElements = rElements.getConstArray();
+ try
+ {
+ Reference<XNameContainer> xCont;
+ if(rNode.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
+ aNode >>= xCont;
+ }
+ else
+ xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
+ if(!xCont.is())
+ return sal_False;
+ try
+ {
+ for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++)
+ {
+ xCont->removeByName(pElements[nElement]);
+ }
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ xBatch->commitChanges();
+ }
+ CATCH_INFO("Exception from commitChanges(): ")
+ bRet = sal_True;
+ }
+ CATCH_INFO("Exception from GetNodeNames: ")
+ }
+ return bRet;
+}
+//----------------------------------------------------------------------------
+static inline
+OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix )
+{
+ OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix);
+ return extractFirstFromConfigurationPath( sSubPath );
+}
+//----------------------------------------------------------------------------
+static
+Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix )
+{
+ const PropertyValue* pProperties = rValues.getConstArray();
+
+ Sequence< OUString > aSubNodeNames(rValues.getLength());
+ OUString* pSubNodeNames = aSubNodeNames.getArray();
+
+ OUString sLastSubNode;
+ sal_Int32 nSubIndex = 0;
+
+ for(sal_Int32 i = 0; i < rValues.getLength(); i++)
+ {
+ OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix);
+ OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath );
+
+ if(sLastSubNode != sSubNode)
+ {
+ pSubNodeNames[nSubIndex++] = sSubNode;
+ }
+
+ sLastSubNode = sSubNode;
+ }
+ aSubNodeNames.realloc(nSubIndex);
+
+ return aSubNodeNames;
+}
+/* -----------------------------15.09.00 15:52--------------------------------
+ add or change properties
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::SetSetProperties(
+ const OUString& rNode, Sequence< PropertyValue > rValues)
+{
+ ValueCounter_Impl aCounter(pImpl->nInValueChange);
+ sal_Bool bRet = sal_True;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ try
+ {
+ Reference<XNameContainer> xCont;
+ if(rNode.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
+ aNode >>= xCont;
+ }
+ else
+ xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
+ if(!xCont.is())
+ return sal_False;
+
+ Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
+
+ if(xFac.is())
+ {
+ const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
+
+ const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
+
+ for(sal_Int32 j = 0; j <nSubNodeCount ; j++)
+ {
+ if(!xCont->hasByName(aSubNodeNames[j]))
+ {
+ Reference<XInterface> xInst = xFac->createInstance();
+ Any aVal; aVal <<= xInst;
+ xCont->insertByName(aSubNodeNames[j], aVal);
+ }
+ //set values
+ }
+ try
+ {
+ xBatch->commitChanges();
+ }
+ CATCH_INFO("Exception from commitChanges(): ")
+
+ const PropertyValue* pProperties = rValues.getConstArray();
+
+ Sequence< OUString > aSetNames(rValues.getLength());
+ OUString* pSetNames = aSetNames.getArray();
+
+ Sequence< Any> aSetValues(rValues.getLength());
+ Any* pSetValues = aSetValues.getArray();
+
+ sal_Bool bEmptyNode = rNode.getLength() == 0;
+ for(sal_Int32 k = 0; k < rValues.getLength(); k++)
+ {
+ pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
+ pSetValues[k] = pProperties[k].Value;
+ }
+ bRet = PutProperties(aSetNames, aSetValues);
+ }
+ else
+ {
+ //if no factory is available then the node contains basic data elements
+ const PropertyValue* pValues = rValues.getConstArray();
+ for(int nValue = 0; nValue < rValues.getLength();nValue++)
+ {
+ try
+ {
+ OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
+
+ if(xCont->hasByName(sSubNode))
+ xCont->replaceByName(sSubNode, pValues[nValue].Value);
+ else
+ xCont->insertByName(sSubNode, pValues[nValue].Value);
+
+ OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name),
+ "Invalid config path" );
+ }
+ CATCH_INFO("Exception form insert/replaceByName(): ")
+ }
+ xBatch->commitChanges();
+ }
+ }
+#ifdef DBG_UTIL
+ catch(Exception& rEx)
+ {
+ lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx);
+#else
+ catch(Exception&)
+ {
+#endif
+ bRet = sal_False;
+ }
+ }
+ return bRet;
+}
+/* -----------------------------15.09.00 15:52--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::ReplaceSetProperties(
+ const OUString& rNode, Sequence< PropertyValue > rValues)
+{
+ ValueCounter_Impl aCounter(pImpl->nInValueChange);
+ sal_Bool bRet = sal_True;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ try
+ {
+ Reference<XNameContainer> xCont;
+ if(rNode.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
+ aNode >>= xCont;
+ }
+ else
+ xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
+ if(!xCont.is())
+ return sal_False;
+
+ // JB: Change: now the same name handling for sets of simple values
+ const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
+ const OUString* pSubNodeNames = aSubNodeNames.getConstArray();
+ const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
+
+ Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
+ const bool isSimpleValueSet = !xFac.is();
+
+ //remove unknown members first
+ {
+ const Sequence<OUString> aContainerSubNodes = xCont->getElementNames();
+ const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray();
+
+ for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++)
+ {
+ sal_Bool bFound = sal_False;
+ for(sal_Int32 j = 0; j < nSubNodeCount; j++)
+ {
+ if(pSubNodeNames[j] == pContainerSubNodes[nContSub])
+ {
+ bFound = sal_True;
+ break;
+ }
+ }
+ if(!bFound)
+ try
+ {
+ xCont->removeByName(pContainerSubNodes[nContSub]);
+ }
+ catch (Exception & )
+ {
+ if (isSimpleValueSet)
+ try
+ {
+ // #i37322#: fallback action: replace with <void/>
+ xCont->replaceByName(pContainerSubNodes[nContSub], Any());
+ // fallback successfull: continue looping
+ continue;
+ }
+ catch (Exception &)
+ {} // propagate original exception, if fallback fails
+
+ throw;
+ }
+ }
+ try { xBatch->commitChanges(); }
+ CATCH_INFO("Exception from commitChanges(): ")
+ }
+
+ if(xFac.is()) // !isSimpleValueSet
+ {
+ for(sal_Int32 j = 0; j < nSubNodeCount; j++)
+ {
+ if(!xCont->hasByName(pSubNodeNames[j]))
+ {
+ //create if not available
+ Reference<XInterface> xInst = xFac->createInstance();
+ Any aVal; aVal <<= xInst;
+ xCont->insertByName(pSubNodeNames[j], aVal);
+ }
+ }
+ try { xBatch->commitChanges(); }
+ CATCH_INFO("Exception from commitChanges(): ")
+
+ const PropertyValue* pProperties = rValues.getConstArray();
+
+ Sequence< OUString > aSetNames(rValues.getLength());
+ OUString* pSetNames = aSetNames.getArray();
+
+ Sequence< Any> aSetValues(rValues.getLength());
+ Any* pSetValues = aSetValues.getArray();
+
+ sal_Bool bEmptyNode = rNode.getLength() == 0;
+ for(sal_Int32 k = 0; k < rValues.getLength(); k++)
+ {
+ pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
+ pSetValues[k] = pProperties[k].Value;
+ }
+ bRet = PutProperties(aSetNames, aSetValues);
+ }
+ else
+ {
+ const PropertyValue* pValues = rValues.getConstArray();
+
+ //if no factory is available then the node contains basic data elements
+ for(int nValue = 0; nValue < rValues.getLength();nValue++)
+ {
+ try
+ {
+ OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
+
+ if(xCont->hasByName(sSubNode))
+ xCont->replaceByName(sSubNode, pValues[nValue].Value);
+ else
+ xCont->insertByName(sSubNode, pValues[nValue].Value);
+ }
+ CATCH_INFO("Exception from insert/replaceByName(): ");
+ }
+ xBatch->commitChanges();
+ }
+ }
+#ifdef DBG_UTIL
+ catch(Exception& rEx)
+ {
+ lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx);
+#else
+ catch(Exception&)
+ {
+#endif
+ bRet = sal_False;
+ }
+ }
+ return bRet;
+}
+/* -----------------------------07.05.01 12:15--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::getUniqueSetElementName( const ::rtl::OUString& _rSetNode, ::rtl::OUString& _rName)
+{
+ ::rtl::OUString sNewElementName;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ sal_Bool bRet = sal_False;
+ if(xHierarchyAccess.is())
+ {
+ try
+ {
+ Reference< XNameAccess > xSetNode;
+ xHierarchyAccess->getByHierarchicalName(_rSetNode) >>= xSetNode;
+ if (xSetNode.is())
+ {
+ const sal_uInt32 nPrime = 65521; // a prime number
+ const sal_uInt32 nPrimeLess2 = nPrime - 2;
+ sal_uInt32 nEngendering = (rand() % nPrimeLess2) + 2; // the engendering of the field
+
+ // the element which will loop through the field
+ sal_uInt32 nFieldElement = nEngendering;
+
+ for (; 1 != nFieldElement; nFieldElement = (nFieldElement * nEngendering) % nPrime)
+ {
+ ::rtl::OUString sThisRoundTrial = _rName;
+ sThisRoundTrial += ::rtl::OUString::valueOf((sal_Int32)nFieldElement);
+
+ if (!xSetNode->hasByName(sThisRoundTrial))
+ {
+ _rName = sThisRoundTrial;
+ bRet = sal_True;
+ break;
+ }
+ }
+ }
+ }
+ CATCH_INFO("Exception from getUniqueSetElementName(): ")
+ }
+ return bRet;
+}
+/* -----------------------------23.01.01 12:49--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::AddNode(const rtl::OUString& rNode, const rtl::OUString& rNewNode)
+{
+ ValueCounter_Impl aCounter(pImpl->nInValueChange);
+ sal_Bool bRet = sal_True;
+ Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
+ if(xHierarchyAccess.is())
+ {
+ Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
+ try
+ {
+ Reference<XNameContainer> xCont;
+ if(rNode.getLength())
+ {
+ Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
+ aNode >>= xCont;
+ }
+ else
+ xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
+ if(!xCont.is())
+ return sal_False;
+
+ Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
+
+ if(xFac.is())
+ {
+ if(!xCont->hasByName(rNewNode))
+ {
+ Reference<XInterface> xInst = xFac->createInstance();
+ Any aVal; aVal <<= xInst;
+ xCont->insertByName(rNewNode, aVal);
+ }
+ try
+ {
+ xBatch->commitChanges();
+ }
+ CATCH_INFO("Exception from commitChanges(): ")
+ }
+ else
+ {
+ //if no factory is available then the node contains basic data elements
+ try
+ {
+ if(!xCont->hasByName(rNewNode))
+ xCont->insertByName(rNewNode, Any());
+ }
+ CATCH_INFO("Exception from AddNode(): ")
+ }
+ xBatch->commitChanges();
+ }
+#ifdef DBG_UTIL
+ catch(Exception& rEx)
+ {
+ lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx);
+#else
+ catch(Exception&)
+ {
+#endif
+ bRet = sal_False;
+ }
+ }
+ return bRet;
+}
+/* -----------------------------12.02.01 11:38--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int16 ConfigItem::GetMode() const
+{
+ return pImpl->nMode;
+}
+/* -----------------------------12.02.01 13:31--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::SetModified()
+{
+ pImpl->bIsModified = sal_True;
+}
+/* -----------------------------05.05.01 14:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::ClearModified()
+{
+ pImpl->bIsModified = sal_False;
+}
+/* -----------------------------12.02.01 13:31--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::IsModified() const
+{
+ return pImpl->bIsModified;
+}
+/* -----------------------------12.02.01 13:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Bool ConfigItem::IsInValueChange() const
+{
+ return pImpl->nInValueChange > 0;
+}
+/* -----------------------------21.06.01 12:26--------------------------------
+
+ ---------------------------------------------------------------------------*/
+Reference< XHierarchicalNameAccess> ConfigItem::GetTree()
+{
+ Reference< XHierarchicalNameAccess> xRet;
+ if(!m_xHierarchyAccess.is())
+ xRet = pImpl->pManager->AcquireTree(*this);
+ else
+ xRet = m_xHierarchyAccess;
+ OSL_ENSURE(xRet.is(), "AcquireTree failed");
+ return xRet;
+}
+/* -----------------------------22.06.01 08:42--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::LockTree()
+{
+ OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call LockTree in CONFIG_MODE_RELEASE_TREE mode, only");
+ m_xHierarchyAccess = GetTree();
+}
+/* -----------------------------22.06.01 08:42--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void ConfigItem::UnlockTree()
+{
+ OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call UnlockTree in CONFIG_MODE_RELEASE_TREE mode, only");
+ if(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE))
+ m_xHierarchyAccess = 0;
+}
+
+