1*b5088357SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*b5088357SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*b5088357SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*b5088357SAndrew Rist  * distributed with this work for additional information
6*b5088357SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*b5088357SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*b5088357SAndrew Rist  * "License"); you may not use this file except in compliance
9*b5088357SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*b5088357SAndrew Rist  *
11*b5088357SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*b5088357SAndrew Rist  *
13*b5088357SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*b5088357SAndrew Rist  * software distributed under the License is distributed on an
15*b5088357SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b5088357SAndrew Rist  * KIND, either express or implied.  See the License for the
17*b5088357SAndrew Rist  * specific language governing permissions and limitations
18*b5088357SAndrew Rist  * under the License.
19*b5088357SAndrew Rist  *
20*b5088357SAndrew Rist  *************************************************************/
21*b5088357SAndrew Rist 
22*b5088357SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_unotools.hxx"
26cdf0e10cSrcweir #include "unotools/configitem.hxx"
27cdf0e10cSrcweir #include "unotools/configmgr.hxx"
28cdf0e10cSrcweir #include "unotools/configpathes.hxx"
29cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
30cdf0e10cSrcweir #include <com/sun/star/beans/XMultiPropertySet.hpp>
31cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
32cdf0e10cSrcweir #include <com/sun/star/util/XChangesListener.hpp>
33cdf0e10cSrcweir #include <com/sun/star/util/XChangesNotifier.hpp>
34cdf0e10cSrcweir #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
35cdf0e10cSrcweir #include <com/sun/star/container/XHierarchicalName.hpp>
36cdf0e10cSrcweir #include <com/sun/star/configuration/XTemplateContainer.hpp>
37cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XSingleServiceFactory.hpp>
39cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp>
40cdf0e10cSrcweir #include <com/sun/star/awt/XRequestCallback.hpp>
41cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
42cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
43cdf0e10cSrcweir #include <com/sun/star/util/XStringEscape.hpp>
44cdf0e10cSrcweir #include <com/sun/star/util/XChangesBatch.hpp>
45cdf0e10cSrcweir #include <osl/diagnose.h>
46cdf0e10cSrcweir #include <tools/solarmutex.hxx>
47cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir using namespace utl;
50cdf0e10cSrcweir using rtl::OUString;
51cdf0e10cSrcweir using rtl::OString;
52cdf0e10cSrcweir using namespace com::sun::star::uno;
53cdf0e10cSrcweir using namespace com::sun::star::util;
54cdf0e10cSrcweir using namespace com::sun::star::lang;
55cdf0e10cSrcweir using namespace com::sun::star::beans;
56cdf0e10cSrcweir using namespace com::sun::star::container;
57cdf0e10cSrcweir using namespace com::sun::star::configuration;
58cdf0e10cSrcweir 
59cdf0e10cSrcweir #define C2U(cChar) OUString::createFromAscii(cChar)
60cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> // helper for implementations
61cdf0e10cSrcweir 
62cdf0e10cSrcweir #ifdef DBG_UTIL
63cdf0e10cSrcweir inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx)
64cdf0e10cSrcweir {
65cdf0e10cSrcweir 	OString sMsg(cText);
66cdf0e10cSrcweir 	sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US);
67cdf0e10cSrcweir 	OSL_ENSURE(sal_False, sMsg.getStr());
68cdf0e10cSrcweir }
69cdf0e10cSrcweir #define CATCH_INFO(a) \
70cdf0e10cSrcweir catch(Exception& rEx)   \
71cdf0e10cSrcweir {                       \
72cdf0e10cSrcweir     lcl_CFG_DBG_EXCEPTION(a, rEx);\
73cdf0e10cSrcweir }
74cdf0e10cSrcweir #else
75cdf0e10cSrcweir 	#define lcl_CFG_DBG_EXCEPTION( a, b)
76cdf0e10cSrcweir     #define CATCH_INFO(a) catch(Exception& ){}
77cdf0e10cSrcweir #endif
78cdf0e10cSrcweir 
79cdf0e10cSrcweir /*
80cdf0e10cSrcweir 	The ConfigChangeListener_Impl receives notifications from the configuration about changes that
81cdf0e10cSrcweir 	have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its
82cdf0e10cSrcweir 	"CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired
83cdf0e10cSrcweir 	before doing so.
84cdf0e10cSrcweir */
85cdf0e10cSrcweir 
86cdf0e10cSrcweir namespace utl{
87cdf0e10cSrcweir     class ConfigChangeListener_Impl : public cppu::WeakImplHelper1
88cdf0e10cSrcweir 	<
89cdf0e10cSrcweir         com::sun::star::util::XChangesListener
90cdf0e10cSrcweir 	>
91cdf0e10cSrcweir 	{
92cdf0e10cSrcweir 		public:
93cdf0e10cSrcweir 			ConfigItem* 				pParent;
94cdf0e10cSrcweir 			const Sequence< OUString > 	aPropertyNames;
95cdf0e10cSrcweir 			ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames);
96cdf0e10cSrcweir 			~ConfigChangeListener_Impl();
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 		//XChangesListener
99cdf0e10cSrcweir     	virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException);
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 		//XEventListener
102cdf0e10cSrcweir     	virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
103cdf0e10cSrcweir 	};
104cdf0e10cSrcweir /* -----------------------------12.02.01 11:38--------------------------------
105cdf0e10cSrcweir 
106cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
107cdf0e10cSrcweir struct ConfigItem_Impl
108cdf0e10cSrcweir {
109cdf0e10cSrcweir 	utl::ConfigManager* 		pManager;
110cdf0e10cSrcweir    	sal_Int16 					nMode;
111cdf0e10cSrcweir 	sal_Bool					bIsModified;
112cdf0e10cSrcweir     sal_Bool                    bEnableInternalNotification;
113cdf0e10cSrcweir 
114cdf0e10cSrcweir 	sal_Int16					nInValueChange;
115cdf0e10cSrcweir 	ConfigItem_Impl() :
116cdf0e10cSrcweir 		pManager(0),
117cdf0e10cSrcweir 		nMode(0),
118cdf0e10cSrcweir 		bIsModified(sal_False),
119cdf0e10cSrcweir         bEnableInternalNotification(sal_False),
120cdf0e10cSrcweir 		nInValueChange(0)
121cdf0e10cSrcweir     {}
122cdf0e10cSrcweir };
123cdf0e10cSrcweir }
124cdf0e10cSrcweir /* -----------------------------04.12.00 10:25--------------------------------
125cdf0e10cSrcweir 
126cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
127cdf0e10cSrcweir class ValueCounter_Impl
128cdf0e10cSrcweir {
129cdf0e10cSrcweir 	sal_Int16& rCnt;
130cdf0e10cSrcweir public:
131cdf0e10cSrcweir 	ValueCounter_Impl(sal_Int16& rCounter):
132cdf0e10cSrcweir 		rCnt(rCounter)
133cdf0e10cSrcweir 			{rCnt++;}
134cdf0e10cSrcweir 	~ValueCounter_Impl()
135cdf0e10cSrcweir 			{
136cdf0e10cSrcweir 				OSL_ENSURE(rCnt>0, "RefCount < 0 ??");
137cdf0e10cSrcweir 				rCnt--;
138cdf0e10cSrcweir 			}
139cdf0e10cSrcweir };
140cdf0e10cSrcweir /* -----------------------------03.12.02 -------------------------------------
141cdf0e10cSrcweir 
142cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
143cdf0e10cSrcweir namespace
144cdf0e10cSrcweir {
145cdf0e10cSrcweir     // helper to achieve exception - safe handling of an Item under construction
146cdf0e10cSrcweir     template <class TYP>
147cdf0e10cSrcweir     class AutoDeleter // : Noncopyable
148cdf0e10cSrcweir     {
149cdf0e10cSrcweir         TYP* m_pItem;
150cdf0e10cSrcweir     public:
151cdf0e10cSrcweir         AutoDeleter(TYP * pItem)
152cdf0e10cSrcweir         : m_pItem(pItem)
153cdf0e10cSrcweir         {
154cdf0e10cSrcweir         }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir         ~AutoDeleter()
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             delete m_pItem;
159cdf0e10cSrcweir         }
160cdf0e10cSrcweir 
161cdf0e10cSrcweir         void keep() { m_pItem = 0; }
162cdf0e10cSrcweir     };
163cdf0e10cSrcweir }
164cdf0e10cSrcweir /* -----------------------------29.08.00 16:34--------------------------------
165cdf0e10cSrcweir 
166cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
167cdf0e10cSrcweir ConfigChangeListener_Impl::ConfigChangeListener_Impl(
168cdf0e10cSrcweir 			 ConfigItem& rItem, const Sequence< OUString >& rNames) :
169cdf0e10cSrcweir 	pParent(&rItem),
170cdf0e10cSrcweir 	aPropertyNames(rNames)
171cdf0e10cSrcweir {
172cdf0e10cSrcweir }
173cdf0e10cSrcweir /* -----------------------------29.08.00 16:34--------------------------------
174cdf0e10cSrcweir 
175cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
176cdf0e10cSrcweir ConfigChangeListener_Impl::~ConfigChangeListener_Impl()
177cdf0e10cSrcweir {
178cdf0e10cSrcweir }
179cdf0e10cSrcweir /* -----------------------------29.08.00 16:34--------------------------------
180cdf0e10cSrcweir 
181cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
182cdf0e10cSrcweir sal_Bool lcl_Find(
183cdf0e10cSrcweir 		const rtl::OUString& rTemp,
184cdf0e10cSrcweir 		const OUString* pCheckPropertyNames,
185cdf0e10cSrcweir 		sal_Int32 nLength)
186cdf0e10cSrcweir {
187cdf0e10cSrcweir 	//return true if the path is completely correct or if it is longer
188cdf0e10cSrcweir 	//i.e ...Print/Content/Graphic and .../Print
189cdf0e10cSrcweir 	for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++)
190cdf0e10cSrcweir 		if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) )
191cdf0e10cSrcweir 			return sal_True;
192cdf0e10cSrcweir 	return sal_False;
193cdf0e10cSrcweir }
194cdf0e10cSrcweir //-----------------------------------------------------------------------------
195cdf0e10cSrcweir void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException)
196cdf0e10cSrcweir {
197cdf0e10cSrcweir 	const ElementChange* pElementChanges = rEvent.Changes.getConstArray();
198cdf0e10cSrcweir 
199cdf0e10cSrcweir 	Sequence<OUString>	aChangedNames(rEvent.Changes.getLength());
200cdf0e10cSrcweir 	OUString* pNames = aChangedNames.getArray();
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	const OUString* pCheckPropertyNames = aPropertyNames.getConstArray();
203cdf0e10cSrcweir 
204cdf0e10cSrcweir 	sal_Int32 nNotify = 0;
205cdf0e10cSrcweir 	for(int i = 0; i < aChangedNames.getLength(); i++)
206cdf0e10cSrcweir 	{
207cdf0e10cSrcweir 		OUString sTemp;
208cdf0e10cSrcweir 		pElementChanges[i].Accessor >>= sTemp;
209cdf0e10cSrcweir 		if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength()))
210cdf0e10cSrcweir 			pNames[nNotify++] = sTemp;
211cdf0e10cSrcweir 	}
212cdf0e10cSrcweir 	if( nNotify )
213cdf0e10cSrcweir 	{
214cdf0e10cSrcweir 		if ( ::tools::SolarMutex::Acquire() )
215cdf0e10cSrcweir 		{
216cdf0e10cSrcweir 			aChangedNames.realloc(nNotify);
217cdf0e10cSrcweir 			pParent->CallNotify(aChangedNames);
218cdf0e10cSrcweir 			::tools::SolarMutex::Release();
219cdf0e10cSrcweir 		}
220cdf0e10cSrcweir 	}
221cdf0e10cSrcweir }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir /* -----------------------------29.08.00 16:34--------------------------------
224cdf0e10cSrcweir 
225cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
226cdf0e10cSrcweir void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException)
227cdf0e10cSrcweir {
228cdf0e10cSrcweir 	pParent->RemoveChangesListener();
229cdf0e10cSrcweir }
230cdf0e10cSrcweir /* -----------------------------29.08.00 12:50--------------------------------
231cdf0e10cSrcweir 
232cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
233cdf0e10cSrcweir ConfigItem::ConfigItem(const OUString rSubTree, sal_Int16 nSetMode ) :
234cdf0e10cSrcweir 	sSubTree(rSubTree),
235cdf0e10cSrcweir 	pImpl(new ConfigItem_Impl)
236cdf0e10cSrcweir {
237cdf0e10cSrcweir     AutoDeleter<ConfigItem_Impl> aNewImpl(pImpl);
238cdf0e10cSrcweir 
239cdf0e10cSrcweir 	pImpl->pManager = ConfigManager::GetConfigManager();
240cdf0e10cSrcweir 	pImpl->nMode = nSetMode;
241cdf0e10cSrcweir     if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE))
242cdf0e10cSrcweir         pImpl->pManager->AddConfigItem(*this);
243cdf0e10cSrcweir     else
244cdf0e10cSrcweir         m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
245cdf0e10cSrcweir 
246cdf0e10cSrcweir     // no more exceptions after c'tor has finished
247cdf0e10cSrcweir     aNewImpl.keep();
248cdf0e10cSrcweir 	pImpl->nMode &= ~CONFIG_MODE_PROPAGATE_ERRORS;
249cdf0e10cSrcweir }
250cdf0e10cSrcweir /* -----------------------------17.11.00 13:53--------------------------------
251cdf0e10cSrcweir 
252cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
253cdf0e10cSrcweir ConfigItem::ConfigItem(utl::ConfigManager& 	rManager, const rtl::OUString rSubTree) :
254cdf0e10cSrcweir 	sSubTree(rSubTree),
255cdf0e10cSrcweir 	pImpl(new ConfigItem_Impl)
256cdf0e10cSrcweir {
257cdf0e10cSrcweir 	pImpl->pManager = &rManager;
258cdf0e10cSrcweir 	pImpl->nMode = CONFIG_MODE_IMMEDIATE_UPDATE; // does not allow exceptions
259cdf0e10cSrcweir     m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
260cdf0e10cSrcweir }
261cdf0e10cSrcweir //---------------------------------------------------------------------
262cdf0e10cSrcweir //--- 02.08.2002 16:33:23 -----------------------------------------------
263cdf0e10cSrcweir sal_Bool ConfigItem::IsValidConfigMgr() const
264cdf0e10cSrcweir {
265cdf0e10cSrcweir 	return ( pImpl->pManager && pImpl->pManager->GetConfigurationProvider().is() );
266cdf0e10cSrcweir }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir /* -----------------------------29.08.00 12:52--------------------------------
269cdf0e10cSrcweir 
270cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
271cdf0e10cSrcweir ConfigItem::~ConfigItem()
272cdf0e10cSrcweir {
273cdf0e10cSrcweir 	if(pImpl->pManager)
274cdf0e10cSrcweir 	{
275cdf0e10cSrcweir         RemoveChangesListener();
276cdf0e10cSrcweir 		pImpl->pManager->RemoveConfigItem(*this);
277cdf0e10cSrcweir 	}
278cdf0e10cSrcweir 	delete pImpl;
279cdf0e10cSrcweir }
280cdf0e10cSrcweir /* -----------------------------29.08.00 12:52--------------------------------
281cdf0e10cSrcweir 
282cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
283cdf0e10cSrcweir void	ConfigItem::ReleaseConfigMgr()
284cdf0e10cSrcweir {
285cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
286cdf0e10cSrcweir     if(xHierarchyAccess.is())
287cdf0e10cSrcweir 	{
288cdf0e10cSrcweir 		try
289cdf0e10cSrcweir 		{
290cdf0e10cSrcweir 			Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
291cdf0e10cSrcweir 			xBatch->commitChanges();
292cdf0e10cSrcweir 		}
293cdf0e10cSrcweir         CATCH_INFO("Exception from commitChanges(): ")
294cdf0e10cSrcweir 	}
295cdf0e10cSrcweir 	RemoveChangesListener();
296cdf0e10cSrcweir 	OSL_ENSURE(pImpl->pManager, "ConfigManager already released");
297cdf0e10cSrcweir 	pImpl->pManager = 0;
298cdf0e10cSrcweir }
299cdf0e10cSrcweir /* -----------------------------29.08.00 12:52--------------------------------
300cdf0e10cSrcweir 
301cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
302cdf0e10cSrcweir void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames )
303cdf0e10cSrcweir {
304cdf0e10cSrcweir 	// the call is forwarded to the virtual Notify() method
305cdf0e10cSrcweir 	// it is pure virtual, so all classes deriving from ConfigItem have to decide how they
306cdf0e10cSrcweir 	// want to notify listeners
307cdf0e10cSrcweir     if(!IsInValueChange() || pImpl->bEnableInternalNotification)
308cdf0e10cSrcweir 		Notify(rPropertyNames);
309cdf0e10cSrcweir }
310cdf0e10cSrcweir 
311cdf0e10cSrcweir /* -----------------------------12.12.00 17:09--------------------------------
312cdf0e10cSrcweir 
313cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
314cdf0e10cSrcweir sal_Bool lcl_IsLocalProperty(const OUString& rSubTree, const OUString& rProperty)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir 	static const sal_Char* aLocalProperties[] =
317cdf0e10cSrcweir 	{
318cdf0e10cSrcweir 		"Office.Common/Path/Current/Storage",
319cdf0e10cSrcweir         "Office.Common/Path/Current/Temp"
320cdf0e10cSrcweir 	};
321cdf0e10cSrcweir 	static const int aLocalPropLen[] =
322cdf0e10cSrcweir 	{
323cdf0e10cSrcweir 		34,
324cdf0e10cSrcweir         31
325cdf0e10cSrcweir 	};
326cdf0e10cSrcweir 	OUString sProperty(rSubTree);
327cdf0e10cSrcweir 	sProperty += C2U("/");
328cdf0e10cSrcweir 	sProperty += rProperty;
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 	if(sProperty.equalsAsciiL( aLocalProperties[0], aLocalPropLen[0]) ||
331cdf0e10cSrcweir         sProperty.equalsAsciiL( aLocalProperties[1], aLocalPropLen[1]))
332cdf0e10cSrcweir 		return sal_True;
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 	return sal_False;
335cdf0e10cSrcweir }
336cdf0e10cSrcweir /* -----------------------------10.04.01 15:00--------------------------------
337cdf0e10cSrcweir 
338cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
339cdf0e10cSrcweir void ConfigItem::impl_packLocalizedProperties(	const	Sequence< OUString >&	lInNames	,
340cdf0e10cSrcweir 												const	Sequence< Any >&		lInValues	,
341cdf0e10cSrcweir 														Sequence< Any >&		lOutValues	)
342cdf0e10cSrcweir {
343cdf0e10cSrcweir 	// Safe impossible cases.
344cdf0e10cSrcweir 	// This method should be called for special ConfigItem-mode only!
345cdf0e10cSrcweir     OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" );
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 	sal_Int32					nSourceCounter		;	// used to step during input lists
348cdf0e10cSrcweir 	sal_Int32					nSourceSize			;	// marks end of loop over input lists
349cdf0e10cSrcweir 	sal_Int32					nDestinationCounter	;	// actual position in output lists
350cdf0e10cSrcweir 	sal_Int32					nPropertyCounter	;	// counter of inner loop for Sequence< PropertyValue >
351cdf0e10cSrcweir 	sal_Int32					nPropertiesSize		;	// marks end of inner loop
352cdf0e10cSrcweir 	Sequence< OUString >		lPropertyNames		;	// list of all locales for localized entry
353cdf0e10cSrcweir 	Sequence< PropertyValue >	lProperties			;	// localized values of an configuration entry packed for return
354cdf0e10cSrcweir 	Reference< XInterface >		xLocalizedNode		;	// if cfg entry is localized ... lInValues contains an XInterface!
355cdf0e10cSrcweir 
356cdf0e10cSrcweir 	// Optimise follow algorithm ... A LITTLE BIT :-)
357cdf0e10cSrcweir 	// There exist two different possibilities:
358cdf0e10cSrcweir 	//	i )	There exist no localized entries ...						=>	size of lOutValues will be the same like lInNames/lInValues!
359cdf0e10cSrcweir 	//	ii)	There exist some (mostly one or two) localized entries ...	=>	size of lOutValues will be the same like lInNames/lInValues!
360cdf0e10cSrcweir 	//	... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service).
361cdf0e10cSrcweir 	//		We read all his child nodes and pack it into Sequence< PropertyValue >.
362cdf0e10cSrcweir 	//		The result list we pack into the return any. We never change size of lists!
363cdf0e10cSrcweir 	nSourceSize = lInNames.getLength();
364cdf0e10cSrcweir 	lOutValues.realloc( nSourceSize );
365cdf0e10cSrcweir 
366cdf0e10cSrcweir 	// Algorithm:
367cdf0e10cSrcweir 	// Copy all names and values from in to out lists.
368cdf0e10cSrcweir 	// Look for special localized entries ... You can detect it as "XInterface" packed into an Any.
369cdf0e10cSrcweir 	// Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >.
370cdf0e10cSrcweir 	// Add this list to out lists then.
371cdf0e10cSrcweir 
372cdf0e10cSrcweir 	nDestinationCounter = 0;
373cdf0e10cSrcweir 	for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
374cdf0e10cSrcweir 	{
375cdf0e10cSrcweir 		// If item a special localized one ... convert and pack it ...
376cdf0e10cSrcweir 		if( lInValues[nSourceCounter].getValueTypeName() == C2U("com.sun.star.uno.XInterface") )
377cdf0e10cSrcweir 		{
378cdf0e10cSrcweir 			lInValues[nSourceCounter] >>= xLocalizedNode;
379cdf0e10cSrcweir 			Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY );
380cdf0e10cSrcweir 			if( xSetAccess.is() == sal_True )
381cdf0e10cSrcweir 			{
382cdf0e10cSrcweir 				lPropertyNames	=	xSetAccess->getElementNames()	;
383cdf0e10cSrcweir 				nPropertiesSize	=	lPropertyNames.getLength()		;
384cdf0e10cSrcweir 				lProperties.realloc( nPropertiesSize )				;
385cdf0e10cSrcweir 
386cdf0e10cSrcweir 				for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
387cdf0e10cSrcweir 				{
388cdf0e10cSrcweir                     #if OSL_DEBUG_LEVEL > 1
389cdf0e10cSrcweir 					// Sometimes it's better to see what's going on :-)
390cdf0e10cSrcweir                     OUString sPropName   = lInNames[nSourceCounter];
391cdf0e10cSrcweir                     OUString sLocaleName = lPropertyNames[nPropertyCounter];
392cdf0e10cSrcweir 					#endif
393cdf0e10cSrcweir 					lProperties[nPropertyCounter].Name	=	lPropertyNames[nPropertyCounter]							;
394cdf0e10cSrcweir 					OUString sLocaleValue;
395cdf0e10cSrcweir 					xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue	;
396cdf0e10cSrcweir 					lProperties[nPropertyCounter].Value	<<=	sLocaleValue;
397cdf0e10cSrcweir 				}
398cdf0e10cSrcweir 
399cdf0e10cSrcweir 				lOutValues[nDestinationCounter] <<= lProperties;
400cdf0e10cSrcweir 			}
401cdf0e10cSrcweir 		}
402cdf0e10cSrcweir 		// ... or copy normal items to return lists directly.
403cdf0e10cSrcweir 		else
404cdf0e10cSrcweir 		{
405cdf0e10cSrcweir 			lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
406cdf0e10cSrcweir 		}
407cdf0e10cSrcweir 		++nDestinationCounter;
408cdf0e10cSrcweir 	}
409cdf0e10cSrcweir }
410cdf0e10cSrcweir /* -----------------------------10.04.01 15:00--------------------------------
411cdf0e10cSrcweir 
412cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
413cdf0e10cSrcweir void ConfigItem::impl_unpackLocalizedProperties(	const	Sequence< OUString >&	lInNames	,
414cdf0e10cSrcweir 													const	Sequence< Any >&		lInValues	,
415cdf0e10cSrcweir 															Sequence< OUString >&	lOutNames	,
416cdf0e10cSrcweir 															Sequence< Any >&		lOutValues	)
417cdf0e10cSrcweir {
418cdf0e10cSrcweir 	// Safe impossible cases.
419cdf0e10cSrcweir 	// This method should be called for special ConfigItem-mode only!
420cdf0e10cSrcweir     OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" );
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 	sal_Int32					nSourceCounter		;	// used to step during input lists
423cdf0e10cSrcweir 	sal_Int32					nSourceSize			;	// marks end of loop over input lists
424cdf0e10cSrcweir 	sal_Int32					nDestinationCounter	;	// actual position in output lists
425cdf0e10cSrcweir 	sal_Int32					nPropertyCounter	;	// counter of inner loop for Sequence< PropertyValue >
426cdf0e10cSrcweir 	sal_Int32					nPropertiesSize		;	// marks end of inner loop
427cdf0e10cSrcweir 	OUString					sNodeName			;	// base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" )
428cdf0e10cSrcweir 	Sequence< PropertyValue >	lProperties			;	// localized values of an configuration entry getted from lInValues-Any
429cdf0e10cSrcweir 
430cdf0e10cSrcweir 	// Optimise follow algorithm ... A LITTLE BIT :-)
431cdf0e10cSrcweir 	// There exist two different possibilities:
432cdf0e10cSrcweir 	//	i )	There exist no localized entries ...						=>	size of lOutNames/lOutValues will be the same like lInNames/lInValues!
433cdf0e10cSrcweir 	//	ii)	There exist some (mostly one or two) localized entries ...	=>	size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues.
434cdf0e10cSrcweir 	//	=>	I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast.
435cdf0e10cSrcweir 	//		We should reserve same space for output list like input ones first.
436cdf0e10cSrcweir 	//		Follow algorithm looks for these borders and change it for ii) only!
437cdf0e10cSrcweir 	//		It will be faster then a "realloc()" call in every loop ...
438cdf0e10cSrcweir 	nSourceSize = lInNames.getLength();
439cdf0e10cSrcweir 
440cdf0e10cSrcweir 	lOutNames.realloc	( nSourceSize );
441cdf0e10cSrcweir 	lOutValues.realloc	( nSourceSize );
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 	// Algorithm:
444cdf0e10cSrcweir 	// Copy all names and values from const to return lists.
445cdf0e10cSrcweir 	// Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any.
446cdf0e10cSrcweir 	// Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues.
447cdf0e10cSrcweir 
448cdf0e10cSrcweir 	nDestinationCounter = 0;
449cdf0e10cSrcweir 	for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
450cdf0e10cSrcweir 	{
451cdf0e10cSrcweir 		// If item a special localized one ... split it and insert his parts to output lists ...
452cdf0e10cSrcweir 		if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) )
453cdf0e10cSrcweir 		{
454cdf0e10cSrcweir 			lInValues[nSourceCounter]	>>=	lProperties				;
455cdf0e10cSrcweir 			sNodeName				=	lInNames[nSourceCounter] 	;
456cdf0e10cSrcweir 			sNodeName				+=	C2U("/")					;
457cdf0e10cSrcweir 			nPropertiesSize			=	lProperties.getLength()		;
458cdf0e10cSrcweir 
459cdf0e10cSrcweir 			if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() )
460cdf0e10cSrcweir 			{
461cdf0e10cSrcweir 				lOutNames.realloc	( nDestinationCounter+nPropertiesSize );
462cdf0e10cSrcweir 				lOutValues.realloc	( nDestinationCounter+nPropertiesSize );
463cdf0e10cSrcweir 			}
464cdf0e10cSrcweir 
465cdf0e10cSrcweir 			for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
466cdf0e10cSrcweir 			{
467cdf0e10cSrcweir  				lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name	;
468cdf0e10cSrcweir 				lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value				;
469cdf0e10cSrcweir 				++nDestinationCounter;
470cdf0e10cSrcweir 			}
471cdf0e10cSrcweir 		}
472cdf0e10cSrcweir 		// ... or copy normal items to return lists directly.
473cdf0e10cSrcweir 		else
474cdf0e10cSrcweir 		{
475cdf0e10cSrcweir 			if( (nDestinationCounter+1) > lOutNames.getLength() )
476cdf0e10cSrcweir 			{
477cdf0e10cSrcweir 				lOutNames.realloc	( nDestinationCounter+1 );
478cdf0e10cSrcweir 				lOutValues.realloc	( nDestinationCounter+1 );
479cdf0e10cSrcweir 			}
480cdf0e10cSrcweir 
481cdf0e10cSrcweir 			lOutNames [nDestinationCounter] = lInNames [nSourceCounter];
482cdf0e10cSrcweir 			lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
483cdf0e10cSrcweir 			++nDestinationCounter;
484cdf0e10cSrcweir 		}
485cdf0e10cSrcweir 	}
486cdf0e10cSrcweir }
487cdf0e10cSrcweir /* -----------------------------03.02.2003 14:44------------------------------
488cdf0e10cSrcweir 
489cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
490cdf0e10cSrcweir Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< rtl::OUString >& rNames)
491cdf0e10cSrcweir {
492cdf0e10cSrcweir     sal_Int32 i;
493cdf0e10cSrcweir 
494cdf0e10cSrcweir     // size of return list is fix!
495cdf0e10cSrcweir     // Every item must match to length of incoming name list.
496cdf0e10cSrcweir     sal_Int32 nCount = rNames.getLength();
497cdf0e10cSrcweir     Sequence< sal_Bool > lStates(nCount);
498cdf0e10cSrcweir 
499cdf0e10cSrcweir     // We must be shure to return a valid information everytime!
500cdf0e10cSrcweir     // Set default to non readonly ... similar to the configuration handling of this property.
501cdf0e10cSrcweir     for ( i=0; i<nCount; ++i)
502cdf0e10cSrcweir         lStates[i] = sal_False;
503cdf0e10cSrcweir 
504cdf0e10cSrcweir     // no access - no informations ...
505cdf0e10cSrcweir     Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree();
506cdf0e10cSrcweir     if (!xHierarchyAccess.is())
507cdf0e10cSrcweir         return lStates;
508cdf0e10cSrcweir 
509cdf0e10cSrcweir     for (i=0; i<nCount; ++i)
510cdf0e10cSrcweir     {
511cdf0e10cSrcweir         try
512cdf0e10cSrcweir         {
513cdf0e10cSrcweir             if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, rNames[i]))
514cdf0e10cSrcweir             {
515cdf0e10cSrcweir                 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nlocal mode seams to be used!?\n");
516cdf0e10cSrcweir                 continue;
517cdf0e10cSrcweir             }
518cdf0e10cSrcweir 
519cdf0e10cSrcweir             OUString sName = rNames[i];
520cdf0e10cSrcweir             OUString sPath;
521cdf0e10cSrcweir             OUString sProperty;
522cdf0e10cSrcweir 
523cdf0e10cSrcweir             ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty);
524cdf0e10cSrcweir             if (!sPath.getLength() && !sProperty.getLength())
525cdf0e10cSrcweir             {
526cdf0e10cSrcweir                 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nsplitt failed\n");
527cdf0e10cSrcweir                 continue;
528cdf0e10cSrcweir             }
529cdf0e10cSrcweir 
530cdf0e10cSrcweir             Reference< XInterface >       xNode;
531cdf0e10cSrcweir             Reference< XPropertySet >     xSet ;
532cdf0e10cSrcweir             Reference< XPropertySetInfo > xInfo;
533cdf0e10cSrcweir             if (sPath.getLength())
534cdf0e10cSrcweir             {
535cdf0e10cSrcweir                 Any aNode = xHierarchyAccess->getByHierarchicalName(sPath);
536cdf0e10cSrcweir                 if (!(aNode >>= xNode) || !xNode.is())
537cdf0e10cSrcweir                 {
538cdf0e10cSrcweir                     OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno set available\n");
539cdf0e10cSrcweir                     continue;
540cdf0e10cSrcweir                 }
541cdf0e10cSrcweir             }
542cdf0e10cSrcweir             else
543cdf0e10cSrcweir             {
544cdf0e10cSrcweir                 xNode = Reference< XInterface >(xHierarchyAccess, UNO_QUERY);
545cdf0e10cSrcweir             }
546cdf0e10cSrcweir 
547cdf0e10cSrcweir 	    xSet = Reference< XPropertySet >(xNode, UNO_QUERY);
548cdf0e10cSrcweir             if (xSet.is())
549cdf0e10cSrcweir 	    {
550cdf0e10cSrcweir 	        xInfo = xSet->getPropertySetInfo();
551cdf0e10cSrcweir                 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n");
552cdf0e10cSrcweir 	    }
553cdf0e10cSrcweir             else
554cdf0e10cSrcweir 	    {
555cdf0e10cSrcweir 	       	xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY);
556cdf0e10cSrcweir                 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n");
557cdf0e10cSrcweir 	    }
558cdf0e10cSrcweir 
559cdf0e10cSrcweir             if (!xInfo.is())
560cdf0e10cSrcweir             {
561cdf0e10cSrcweir                 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno prop info available\n");
562cdf0e10cSrcweir                 continue;
563cdf0e10cSrcweir             }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir             Property aProp = xInfo->getPropertyByName(sProperty);
566cdf0e10cSrcweir             lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY);
567cdf0e10cSrcweir         }
568cdf0e10cSrcweir         catch(Exception&){}
569cdf0e10cSrcweir     }
570cdf0e10cSrcweir 
571cdf0e10cSrcweir     return lStates;
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir /* -----------------------------29.08.00 15:10--------------------------------
575cdf0e10cSrcweir 
576cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
577cdf0e10cSrcweir Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames)
578cdf0e10cSrcweir {
579cdf0e10cSrcweir 	Sequence< Any > aRet(rNames.getLength());
580cdf0e10cSrcweir 	const OUString* pNames = rNames.getConstArray();
581cdf0e10cSrcweir 	Any* pRet = aRet.getArray();
582cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
583cdf0e10cSrcweir     if(xHierarchyAccess.is())
584cdf0e10cSrcweir 	{
585cdf0e10cSrcweir 		for(int i = 0; i < rNames.getLength(); i++)
586cdf0e10cSrcweir 		{
587cdf0e10cSrcweir 			try
588cdf0e10cSrcweir 			{
589cdf0e10cSrcweir 				if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
590cdf0e10cSrcweir 				{
591cdf0e10cSrcweir 					OUString sProperty(sSubTree);
592cdf0e10cSrcweir 					sProperty += C2U("/");
593cdf0e10cSrcweir 					sProperty += pNames[i];
594cdf0e10cSrcweir 					pRet[i] = pImpl->pManager->GetLocalProperty(sProperty);
595cdf0e10cSrcweir 				}
596cdf0e10cSrcweir 				else
597cdf0e10cSrcweir 					pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]);
598cdf0e10cSrcweir 			}
599cdf0e10cSrcweir 			catch(Exception& rEx)
600cdf0e10cSrcweir 			{
601cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
602cdf0e10cSrcweir 				OString sMsg("XHierarchicalNameAccess: ");
603cdf0e10cSrcweir 				sMsg += OString(rEx.Message.getStr(),
604cdf0e10cSrcweir 					rEx.Message.getLength(),
605cdf0e10cSrcweir 				 	RTL_TEXTENCODING_ASCII_US);
606cdf0e10cSrcweir 				sMsg += OString("\n");
607cdf0e10cSrcweir 				sMsg += OString(ConfigManager::GetConfigBaseURL().getStr(),
608cdf0e10cSrcweir 					ConfigManager::GetConfigBaseURL().getLength(),
609cdf0e10cSrcweir 				 	RTL_TEXTENCODING_ASCII_US);
610cdf0e10cSrcweir 				sMsg += OString(sSubTree.getStr(),
611cdf0e10cSrcweir 					sSubTree.getLength(),
612cdf0e10cSrcweir 				 	RTL_TEXTENCODING_ASCII_US);
613cdf0e10cSrcweir 				sMsg += OString("/");
614cdf0e10cSrcweir 				sMsg += OString(pNames[i].getStr(),
615cdf0e10cSrcweir 					pNames[i].getLength(),
616cdf0e10cSrcweir 				 	RTL_TEXTENCODING_ASCII_US);
617cdf0e10cSrcweir 				OSL_ENSURE(sal_False, sMsg.getStr());
618cdf0e10cSrcweir #else
619cdf0e10cSrcweir                 (void) rEx; // avoid warning
620cdf0e10cSrcweir #endif
621cdf0e10cSrcweir 			}
622cdf0e10cSrcweir 		}
623cdf0e10cSrcweir 
624cdf0e10cSrcweir 		// In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >.
625cdf0e10cSrcweir         if((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES)
626cdf0e10cSrcweir 		{
627cdf0e10cSrcweir 			Sequence< Any > lValues;
628cdf0e10cSrcweir 			impl_packLocalizedProperties( rNames, aRet, lValues );
629cdf0e10cSrcweir 			aRet = lValues;
630cdf0e10cSrcweir 		}
631cdf0e10cSrcweir 	}
632cdf0e10cSrcweir 	return aRet;
633cdf0e10cSrcweir }
634cdf0e10cSrcweir /* -----------------------------29.08.00 17:28--------------------------------
635cdf0e10cSrcweir 
636cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
637cdf0e10cSrcweir sal_Bool ConfigItem::PutProperties( const Sequence< OUString >& rNames,
638cdf0e10cSrcweir 												const Sequence< Any>& rValues)
639cdf0e10cSrcweir {
640cdf0e10cSrcweir 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
641cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
642cdf0e10cSrcweir     Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY);
643cdf0e10cSrcweir 	sal_Bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is();
644cdf0e10cSrcweir 	if(bRet)
645cdf0e10cSrcweir 	{
646cdf0e10cSrcweir 		Sequence< OUString >	lNames			;
647cdf0e10cSrcweir 		Sequence< Any >			lValues			;
648cdf0e10cSrcweir 		const OUString*			pNames	= NULL	;
649cdf0e10cSrcweir 		const Any*				pValues	= NULL	;
650cdf0e10cSrcweir 		sal_Int32				nNameCount		;
651cdf0e10cSrcweir         if(( pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES )
652cdf0e10cSrcweir 		{
653cdf0e10cSrcweir 			// If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue >
654cdf0e10cSrcweir 			// as value of an localized configuration entry!
655cdf0e10cSrcweir 			// How we can do that?
656cdf0e10cSrcweir 			// We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"!
657cdf0e10cSrcweir 			impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues );
658cdf0e10cSrcweir 			pNames		= lNames.getConstArray	();
659cdf0e10cSrcweir 			pValues		= lValues.getConstArray	();
660cdf0e10cSrcweir 			nNameCount	= lNames.getLength		();
661cdf0e10cSrcweir 		}
662cdf0e10cSrcweir 		else
663cdf0e10cSrcweir 		{
664cdf0e10cSrcweir 			// This is the normal mode ...
665cdf0e10cSrcweir 			// Use given input lists directly.
666cdf0e10cSrcweir 			pNames		= rNames.getConstArray	();
667cdf0e10cSrcweir 			pValues		= rValues.getConstArray	();
668cdf0e10cSrcweir 			nNameCount	= rNames.getLength		();
669cdf0e10cSrcweir 		}
670cdf0e10cSrcweir 		for(int i = 0; i < nNameCount; i++)
671cdf0e10cSrcweir 		{
672cdf0e10cSrcweir 			if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
673cdf0e10cSrcweir 			{
674cdf0e10cSrcweir 				OUString sProperty(sSubTree);
675cdf0e10cSrcweir 				sProperty += C2U("/");
676cdf0e10cSrcweir 				sProperty += pNames[i];
677cdf0e10cSrcweir 				pImpl->pManager->PutLocalProperty(sProperty, pValues[i]);
678cdf0e10cSrcweir 			}
679cdf0e10cSrcweir 			else
680cdf0e10cSrcweir 			{
681cdf0e10cSrcweir 				try
682cdf0e10cSrcweir 				{
683cdf0e10cSrcweir                     OUString sNode, sProperty;
684cdf0e10cSrcweir                     if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
685cdf0e10cSrcweir                     {
686cdf0e10cSrcweir 						Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
687cdf0e10cSrcweir 
688cdf0e10cSrcweir                         Reference<XNameAccess> xNodeAcc;
689cdf0e10cSrcweir 						aNode >>= xNodeAcc;
690cdf0e10cSrcweir 						Reference<XNameReplace>   xNodeReplace(xNodeAcc, UNO_QUERY);
691cdf0e10cSrcweir 						Reference<XNameContainer> xNodeCont   (xNodeAcc, UNO_QUERY);
692cdf0e10cSrcweir 
693cdf0e10cSrcweir                         sal_Bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty));
694cdf0e10cSrcweir                         if (bExist && xNodeReplace.is())
695cdf0e10cSrcweir 						    xNodeReplace->replaceByName(sProperty, pValues[i]);
696cdf0e10cSrcweir                         else
697cdf0e10cSrcweir 						if (!bExist && xNodeCont.is())
698cdf0e10cSrcweir 						    xNodeCont->insertByName(sProperty, pValues[i]);
699cdf0e10cSrcweir 						else
700cdf0e10cSrcweir 							bRet = sal_False;
701cdf0e10cSrcweir 					}
702cdf0e10cSrcweir 					else //direct value
703cdf0e10cSrcweir 					{
704cdf0e10cSrcweir 						xTopNodeReplace->replaceByName(sProperty, pValues[i]);
705cdf0e10cSrcweir 					}
706cdf0e10cSrcweir 				}
707cdf0e10cSrcweir                 CATCH_INFO("Exception from PutProperties: ");
708cdf0e10cSrcweir 			}
709cdf0e10cSrcweir 		}
710cdf0e10cSrcweir 		try
711cdf0e10cSrcweir 		{
712cdf0e10cSrcweir 			Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
713cdf0e10cSrcweir 			xBatch->commitChanges();
714cdf0e10cSrcweir 		}
715cdf0e10cSrcweir         CATCH_INFO("Exception from commitChanges(): ")
716cdf0e10cSrcweir 	}
717cdf0e10cSrcweir 
718cdf0e10cSrcweir 	return bRet;
719cdf0e10cSrcweir }
720cdf0e10cSrcweir /* -----------------------------08.12.05 15:27--------------------------------
721cdf0e10cSrcweir 
722cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
723cdf0e10cSrcweir void ConfigItem::DisableNotification()
724cdf0e10cSrcweir {
725cdf0e10cSrcweir     OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" );
726cdf0e10cSrcweir     RemoveChangesListener();
727cdf0e10cSrcweir }
728cdf0e10cSrcweir /* -----------------------------29.08.00 16:19--------------------------------
729cdf0e10cSrcweir 
730cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
731cdf0e10cSrcweir sal_Bool    ConfigItem::EnableNotification(const Sequence< OUString >& rNames,
732cdf0e10cSrcweir                 sal_Bool bEnableInternalNotification )
733cdf0e10cSrcweir 
734cdf0e10cSrcweir {
735cdf0e10cSrcweir     OSL_ENSURE(0 == (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible");
736cdf0e10cSrcweir     pImpl->bEnableInternalNotification = bEnableInternalNotification;
737cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
738cdf0e10cSrcweir     Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY);
739cdf0e10cSrcweir 	if(!xChgNot.is())
740cdf0e10cSrcweir 		return sal_False;
741cdf0e10cSrcweir 
742cdf0e10cSrcweir 	OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called");
743cdf0e10cSrcweir 	if(xChangeLstnr.is())
744cdf0e10cSrcweir 		xChgNot->removeChangesListener( xChangeLstnr );
745cdf0e10cSrcweir 	sal_Bool bRet = sal_True;
746cdf0e10cSrcweir 
747cdf0e10cSrcweir 	try
748cdf0e10cSrcweir 	{
749cdf0e10cSrcweir 		xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames);
750cdf0e10cSrcweir 		xChgNot->addChangesListener( xChangeLstnr );
751cdf0e10cSrcweir 	}
752cdf0e10cSrcweir 	catch(RuntimeException& )
753cdf0e10cSrcweir 	{
754cdf0e10cSrcweir 		bRet = sal_False;
755cdf0e10cSrcweir 	}
756cdf0e10cSrcweir 	return bRet;
757cdf0e10cSrcweir }
758cdf0e10cSrcweir /* -----------------------------29.08.00 16:47--------------------------------
759cdf0e10cSrcweir 
760cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
761cdf0e10cSrcweir void ConfigItem::RemoveChangesListener()
762cdf0e10cSrcweir {
763cdf0e10cSrcweir     Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY);
764cdf0e10cSrcweir 	if(xChgNot.is() && xChangeLstnr.is())
765cdf0e10cSrcweir 	{
766cdf0e10cSrcweir 		try
767cdf0e10cSrcweir 		{
768cdf0e10cSrcweir 			xChgNot->removeChangesListener( xChangeLstnr );
769cdf0e10cSrcweir             xChangeLstnr = 0;
770cdf0e10cSrcweir 		}
771cdf0e10cSrcweir 		catch(Exception & )
772cdf0e10cSrcweir 		{
773cdf0e10cSrcweir 		}
774cdf0e10cSrcweir 	}
775cdf0e10cSrcweir }
776cdf0e10cSrcweir /* -----------------------------10.07.00      --------------------------------
777cdf0e10cSrcweir 
778cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
779cdf0e10cSrcweir void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode)
780cdf0e10cSrcweir {
781cdf0e10cSrcweir     switch (_eFormat)
782cdf0e10cSrcweir     {
783cdf0e10cSrcweir     case CONFIG_NAME_LOCAL_NAME:
784cdf0e10cSrcweir         // unaltered - this is our input format
785cdf0e10cSrcweir         break;
786cdf0e10cSrcweir 
787cdf0e10cSrcweir     case CONFIG_NAME_FULL_PATH:
788cdf0e10cSrcweir         {
789cdf0e10cSrcweir             Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY);
790cdf0e10cSrcweir             if (xFormatter.is())
791cdf0e10cSrcweir             {
792cdf0e10cSrcweir                 OUString * pNames = _rNames.getArray();
793cdf0e10cSrcweir                 for(int i = 0; i<_rNames.getLength(); ++i)
794cdf0e10cSrcweir                 try
795cdf0e10cSrcweir                 {
796cdf0e10cSrcweir                     pNames[i] = xFormatter->composeHierarchicalName(pNames[i]);
797cdf0e10cSrcweir                 }
798cdf0e10cSrcweir                 CATCH_INFO("Exception from composeHierarchicalName(): ")
799cdf0e10cSrcweir                 break;
800cdf0e10cSrcweir             }
801cdf0e10cSrcweir         }
802cdf0e10cSrcweir         OSL_ENSURE(false, "Cannot create absolute pathes: missing interface");
803cdf0e10cSrcweir         // make local pathes instaed
804cdf0e10cSrcweir 
805cdf0e10cSrcweir     case CONFIG_NAME_LOCAL_PATH:
806cdf0e10cSrcweir         {
807cdf0e10cSrcweir             Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY);
808cdf0e10cSrcweir             if (xTypeContainer.is())
809cdf0e10cSrcweir             {
810cdf0e10cSrcweir                 OUString sTypeName = xTypeContainer->getElementTemplateName();
811cdf0e10cSrcweir                 sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1);
812cdf0e10cSrcweir 
813cdf0e10cSrcweir                 OUString * pNames = _rNames.getArray();
814cdf0e10cSrcweir                 for(int i = 0; i<_rNames.getLength(); ++i)
815cdf0e10cSrcweir                 {
816cdf0e10cSrcweir                     pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName);
817cdf0e10cSrcweir                 }
818cdf0e10cSrcweir             }
819cdf0e10cSrcweir             else
820cdf0e10cSrcweir             {
821cdf0e10cSrcweir                 static const OUString sSetService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.SetAccess"));
822cdf0e10cSrcweir                 Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY);
823cdf0e10cSrcweir                 if (xSVI.is() && xSVI->supportsService(sSetService))
824cdf0e10cSrcweir                 {
825cdf0e10cSrcweir                     OUString * pNames = _rNames.getArray();
826cdf0e10cSrcweir                     for(int i = 0; i<_rNames.getLength(); ++i)
827cdf0e10cSrcweir                     {
828cdf0e10cSrcweir                         pNames[i] = wrapConfigurationElementName(pNames[i]);
829cdf0e10cSrcweir                     }
830cdf0e10cSrcweir                 }
831cdf0e10cSrcweir             }
832cdf0e10cSrcweir         }
833cdf0e10cSrcweir         break;
834cdf0e10cSrcweir 
835cdf0e10cSrcweir     case CONFIG_NAME_PLAINTEXT_NAME:
836cdf0e10cSrcweir         {
837cdf0e10cSrcweir             Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY);
838cdf0e10cSrcweir             if (xEscaper.is())
839cdf0e10cSrcweir             {
840cdf0e10cSrcweir                 OUString * pNames = _rNames.getArray();
841cdf0e10cSrcweir                 for(int i = 0; i<_rNames.getLength(); ++i)
842cdf0e10cSrcweir                 try
843cdf0e10cSrcweir                 {
844cdf0e10cSrcweir                     pNames[i] = xEscaper->unescapeString(pNames[i]);
845cdf0e10cSrcweir                 }
846cdf0e10cSrcweir                 CATCH_INFO("Exception from unescapeString(): ")
847cdf0e10cSrcweir             }
848cdf0e10cSrcweir         }
849cdf0e10cSrcweir         break;
850cdf0e10cSrcweir 
851cdf0e10cSrcweir     }
852cdf0e10cSrcweir }
853cdf0e10cSrcweir /* -----------------------------10.07.00      --------------------------------
854cdf0e10cSrcweir 
855cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
856cdf0e10cSrcweir Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode)
857cdf0e10cSrcweir {
858cdf0e10cSrcweir     ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT;
859cdf0e10cSrcweir 
860cdf0e10cSrcweir     return GetNodeNames(rNode, eDefaultFormat);
861cdf0e10cSrcweir }
862cdf0e10cSrcweir /* -----------------------------15.09.00 12:06--------------------------------
863cdf0e10cSrcweir 
864cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
865cdf0e10cSrcweir Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat)
866cdf0e10cSrcweir {
867cdf0e10cSrcweir 	Sequence< OUString > aRet;
868cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
869cdf0e10cSrcweir     if(xHierarchyAccess.is())
870cdf0e10cSrcweir 	{
871cdf0e10cSrcweir 		try
872cdf0e10cSrcweir 		{
873cdf0e10cSrcweir 			Reference<XNameAccess> xCont;
874cdf0e10cSrcweir 			if(rNode.getLength())
875cdf0e10cSrcweir 			{
876cdf0e10cSrcweir 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
877cdf0e10cSrcweir 				aNode >>= xCont;
878cdf0e10cSrcweir 			}
879cdf0e10cSrcweir 			else
880cdf0e10cSrcweir 				xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY);
881cdf0e10cSrcweir 			if(xCont.is())
882cdf0e10cSrcweir 			{
883cdf0e10cSrcweir 				aRet = xCont->getElementNames();
884cdf0e10cSrcweir                 lcl_normalizeLocalNames(aRet,eFormat,xCont);
885cdf0e10cSrcweir             }
886cdf0e10cSrcweir 
887cdf0e10cSrcweir 		}
888cdf0e10cSrcweir         CATCH_INFO("Exception from GetNodeNames: ");
889cdf0e10cSrcweir 	}
890cdf0e10cSrcweir 	return aRet;
891cdf0e10cSrcweir }
892cdf0e10cSrcweir /* -----------------------------15.09.00 15:52--------------------------------
893cdf0e10cSrcweir 
894cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
895cdf0e10cSrcweir sal_Bool ConfigItem::ClearNodeSet(const OUString& rNode)
896cdf0e10cSrcweir {
897cdf0e10cSrcweir 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
898cdf0e10cSrcweir     sal_Bool bRet = sal_False;
899cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
900cdf0e10cSrcweir     if(xHierarchyAccess.is())
901cdf0e10cSrcweir 	{
902cdf0e10cSrcweir 		try
903cdf0e10cSrcweir 		{
904cdf0e10cSrcweir 			Reference<XNameContainer> xCont;
905cdf0e10cSrcweir 			if(rNode.getLength())
906cdf0e10cSrcweir 			{
907cdf0e10cSrcweir 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
908cdf0e10cSrcweir 				aNode >>= xCont;
909cdf0e10cSrcweir 			}
910cdf0e10cSrcweir 			else
911cdf0e10cSrcweir 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
912cdf0e10cSrcweir 			if(!xCont.is())
913cdf0e10cSrcweir 				return sal_False;
914cdf0e10cSrcweir 			Sequence< OUString > aNames = xCont->getElementNames();
915cdf0e10cSrcweir 			const OUString* pNames = aNames.getConstArray();
916cdf0e10cSrcweir 			Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
917cdf0e10cSrcweir 			for(sal_Int32 i = 0; i < aNames.getLength(); i++)
918cdf0e10cSrcweir 			{
919cdf0e10cSrcweir 				try
920cdf0e10cSrcweir 				{
921cdf0e10cSrcweir 					xCont->removeByName(pNames[i]);
922cdf0e10cSrcweir 				}
923cdf0e10cSrcweir                 CATCH_INFO("Exception from removeByName(): ")
924cdf0e10cSrcweir 			}
925cdf0e10cSrcweir 			xBatch->commitChanges();
926cdf0e10cSrcweir             bRet = sal_True;
927cdf0e10cSrcweir 		}
928cdf0e10cSrcweir         CATCH_INFO("Exception from ClearNodeSet")
929cdf0e10cSrcweir 	}
930cdf0e10cSrcweir 	return bRet;
931cdf0e10cSrcweir }
932cdf0e10cSrcweir /* -----------------------------24.11.00 10:58--------------------------------
933cdf0e10cSrcweir 
934cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
935cdf0e10cSrcweir sal_Bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements)
936cdf0e10cSrcweir {
937cdf0e10cSrcweir 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
938cdf0e10cSrcweir     sal_Bool bRet = sal_False;
939cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
940cdf0e10cSrcweir     if(xHierarchyAccess.is())
941cdf0e10cSrcweir 	{
942cdf0e10cSrcweir 		const OUString* pElements = rElements.getConstArray();
943cdf0e10cSrcweir 		try
944cdf0e10cSrcweir 		{
945cdf0e10cSrcweir 			Reference<XNameContainer> xCont;
946cdf0e10cSrcweir 			if(rNode.getLength())
947cdf0e10cSrcweir 			{
948cdf0e10cSrcweir 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
949cdf0e10cSrcweir 				aNode >>= xCont;
950cdf0e10cSrcweir 			}
951cdf0e10cSrcweir 			else
952cdf0e10cSrcweir 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
953cdf0e10cSrcweir 			if(!xCont.is())
954cdf0e10cSrcweir 				return sal_False;
955cdf0e10cSrcweir 			try
956cdf0e10cSrcweir 			{
957cdf0e10cSrcweir 				for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++)
958cdf0e10cSrcweir 				{
959cdf0e10cSrcweir 					xCont->removeByName(pElements[nElement]);
960cdf0e10cSrcweir 				}
961cdf0e10cSrcweir 				Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
962cdf0e10cSrcweir 				xBatch->commitChanges();
963cdf0e10cSrcweir 			}
964cdf0e10cSrcweir             CATCH_INFO("Exception from commitChanges(): ")
965cdf0e10cSrcweir             bRet = sal_True;
966cdf0e10cSrcweir         }
967cdf0e10cSrcweir         CATCH_INFO("Exception from GetNodeNames: ")
968cdf0e10cSrcweir 	}
969cdf0e10cSrcweir 	return bRet;
970cdf0e10cSrcweir }
971cdf0e10cSrcweir //----------------------------------------------------------------------------
972cdf0e10cSrcweir static inline
973cdf0e10cSrcweir OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix )
974cdf0e10cSrcweir {
975cdf0e10cSrcweir     OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix);
976cdf0e10cSrcweir     return extractFirstFromConfigurationPath( sSubPath );
977cdf0e10cSrcweir }
978cdf0e10cSrcweir //----------------------------------------------------------------------------
979cdf0e10cSrcweir static
980cdf0e10cSrcweir Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix )
981cdf0e10cSrcweir {
982cdf0e10cSrcweir     const PropertyValue* pProperties = rValues.getConstArray();
983cdf0e10cSrcweir 
984cdf0e10cSrcweir     Sequence< OUString > aSubNodeNames(rValues.getLength());
985cdf0e10cSrcweir     OUString* pSubNodeNames = aSubNodeNames.getArray();
986cdf0e10cSrcweir 
987cdf0e10cSrcweir     OUString sLastSubNode;
988cdf0e10cSrcweir     sal_Int32 nSubIndex = 0;
989cdf0e10cSrcweir 
990cdf0e10cSrcweir     for(sal_Int32 i = 0; i < rValues.getLength(); i++)
991cdf0e10cSrcweir     {
992cdf0e10cSrcweir         OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix);
993cdf0e10cSrcweir         OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath );
994cdf0e10cSrcweir 
995cdf0e10cSrcweir         if(sLastSubNode != sSubNode)
996cdf0e10cSrcweir 	    {
997cdf0e10cSrcweir 		    pSubNodeNames[nSubIndex++] = sSubNode;
998cdf0e10cSrcweir 	    }
999cdf0e10cSrcweir 
1000cdf0e10cSrcweir 	    sLastSubNode = sSubNode;
1001cdf0e10cSrcweir     }
1002cdf0e10cSrcweir     aSubNodeNames.realloc(nSubIndex);
1003cdf0e10cSrcweir 
1004cdf0e10cSrcweir     return aSubNodeNames;
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir /* -----------------------------15.09.00 15:52--------------------------------
1007cdf0e10cSrcweir 	add or change properties
1008cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1009cdf0e10cSrcweir sal_Bool ConfigItem::SetSetProperties(
1010cdf0e10cSrcweir 	const OUString& rNode, Sequence< PropertyValue > rValues)
1011cdf0e10cSrcweir {
1012cdf0e10cSrcweir 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
1013cdf0e10cSrcweir     sal_Bool bRet = sal_True;
1014cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1015cdf0e10cSrcweir     if(xHierarchyAccess.is())
1016cdf0e10cSrcweir 	{
1017cdf0e10cSrcweir 		Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1018cdf0e10cSrcweir 		try
1019cdf0e10cSrcweir 		{
1020cdf0e10cSrcweir 			Reference<XNameContainer> xCont;
1021cdf0e10cSrcweir 			if(rNode.getLength())
1022cdf0e10cSrcweir 			{
1023cdf0e10cSrcweir 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1024cdf0e10cSrcweir 				aNode >>= xCont;
1025cdf0e10cSrcweir 			}
1026cdf0e10cSrcweir 			else
1027cdf0e10cSrcweir 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1028cdf0e10cSrcweir 			if(!xCont.is())
1029cdf0e10cSrcweir 				return sal_False;
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir 			Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir             if(xFac.is())
1034cdf0e10cSrcweir 			{
1035cdf0e10cSrcweir 				const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir                 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir 				for(sal_Int32 j = 0; j <nSubNodeCount ; j++)
1040cdf0e10cSrcweir 				{
1041cdf0e10cSrcweir 					if(!xCont->hasByName(aSubNodeNames[j]))
1042cdf0e10cSrcweir 					{
1043cdf0e10cSrcweir 						Reference<XInterface> xInst = xFac->createInstance();
1044cdf0e10cSrcweir 						Any aVal; aVal <<= xInst;
1045cdf0e10cSrcweir 						xCont->insertByName(aSubNodeNames[j], aVal);
1046cdf0e10cSrcweir 					}
1047cdf0e10cSrcweir 					//set values
1048cdf0e10cSrcweir 				}
1049cdf0e10cSrcweir 				try
1050cdf0e10cSrcweir 				{
1051cdf0e10cSrcweir 					xBatch->commitChanges();
1052cdf0e10cSrcweir 				}
1053cdf0e10cSrcweir                 CATCH_INFO("Exception from commitChanges(): ")
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir 				const PropertyValue* pProperties = rValues.getConstArray();
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir 				Sequence< OUString > aSetNames(rValues.getLength());
1058cdf0e10cSrcweir 				OUString* pSetNames = aSetNames.getArray();
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir 				Sequence< Any> aSetValues(rValues.getLength());
1061cdf0e10cSrcweir 				Any* pSetValues = aSetValues.getArray();
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir 				sal_Bool bEmptyNode = rNode.getLength() == 0;
1064cdf0e10cSrcweir 				for(sal_Int32 k = 0; k < rValues.getLength(); k++)
1065cdf0e10cSrcweir 				{
1066cdf0e10cSrcweir 					pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
1067cdf0e10cSrcweir 					pSetValues[k] = pProperties[k].Value;
1068cdf0e10cSrcweir 				}
1069cdf0e10cSrcweir 				bRet = PutProperties(aSetNames, aSetValues);
1070cdf0e10cSrcweir 			}
1071cdf0e10cSrcweir 			else
1072cdf0e10cSrcweir 			{
1073cdf0e10cSrcweir 				//if no factory is available then the node contains basic data elements
1074cdf0e10cSrcweir 				const PropertyValue* pValues = rValues.getConstArray();
1075cdf0e10cSrcweir 				for(int nValue = 0; nValue < rValues.getLength();nValue++)
1076cdf0e10cSrcweir 				{
1077cdf0e10cSrcweir 					try
1078cdf0e10cSrcweir 					{
1079cdf0e10cSrcweir 						OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir                         if(xCont->hasByName(sSubNode))
1082cdf0e10cSrcweir 							xCont->replaceByName(sSubNode, pValues[nValue].Value);
1083cdf0e10cSrcweir 						else
1084cdf0e10cSrcweir 							xCont->insertByName(sSubNode, pValues[nValue].Value);
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir 						OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name),
1087cdf0e10cSrcweir 							"Invalid config path" );
1088cdf0e10cSrcweir 					}
1089cdf0e10cSrcweir                     CATCH_INFO("Exception form insert/replaceByName(): ")
1090cdf0e10cSrcweir 				}
1091cdf0e10cSrcweir 				xBatch->commitChanges();
1092cdf0e10cSrcweir 			}
1093cdf0e10cSrcweir 		}
1094cdf0e10cSrcweir #ifdef DBG_UTIL
1095cdf0e10cSrcweir         catch(Exception& rEx)
1096cdf0e10cSrcweir 		{
1097cdf0e10cSrcweir             lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx);
1098cdf0e10cSrcweir #else
1099cdf0e10cSrcweir         catch(Exception&)
1100cdf0e10cSrcweir 		{
1101cdf0e10cSrcweir #endif
1102cdf0e10cSrcweir 			bRet = sal_False;
1103cdf0e10cSrcweir 		}
1104cdf0e10cSrcweir     }
1105cdf0e10cSrcweir 	return bRet;
1106cdf0e10cSrcweir }
1107cdf0e10cSrcweir /* -----------------------------15.09.00 15:52--------------------------------
1108cdf0e10cSrcweir 
1109cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1110cdf0e10cSrcweir sal_Bool ConfigItem::ReplaceSetProperties(
1111cdf0e10cSrcweir 	const OUString& rNode, Sequence< PropertyValue > rValues)
1112cdf0e10cSrcweir {
1113cdf0e10cSrcweir 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
1114cdf0e10cSrcweir     sal_Bool bRet = sal_True;
1115cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1116cdf0e10cSrcweir     if(xHierarchyAccess.is())
1117cdf0e10cSrcweir 	{
1118cdf0e10cSrcweir 		Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1119cdf0e10cSrcweir 		try
1120cdf0e10cSrcweir 		{
1121cdf0e10cSrcweir 			Reference<XNameContainer> xCont;
1122cdf0e10cSrcweir 			if(rNode.getLength())
1123cdf0e10cSrcweir 			{
1124cdf0e10cSrcweir 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1125cdf0e10cSrcweir 				aNode >>= xCont;
1126cdf0e10cSrcweir 			}
1127cdf0e10cSrcweir 			else
1128cdf0e10cSrcweir 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1129cdf0e10cSrcweir 			if(!xCont.is())
1130cdf0e10cSrcweir 				return sal_False;
1131cdf0e10cSrcweir 
1132cdf0e10cSrcweir             // JB: Change: now the same name handling for sets of simple values
1133cdf0e10cSrcweir 			const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
1134cdf0e10cSrcweir 			const OUString* pSubNodeNames = aSubNodeNames.getConstArray();
1135cdf0e10cSrcweir             const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir 			Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1138cdf0e10cSrcweir             const bool isSimpleValueSet = !xFac.is();
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir 		    //remove unknown members first
1141cdf0e10cSrcweir             {
1142cdf0e10cSrcweir 				const Sequence<OUString> aContainerSubNodes = xCont->getElementNames();
1143cdf0e10cSrcweir 				const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray();
1144cdf0e10cSrcweir 
1145cdf0e10cSrcweir 				for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++)
1146cdf0e10cSrcweir 				{
1147cdf0e10cSrcweir 					sal_Bool bFound = sal_False;
1148cdf0e10cSrcweir 					for(sal_Int32 j = 0; j < nSubNodeCount; j++)
1149cdf0e10cSrcweir                     {
1150cdf0e10cSrcweir 						if(pSubNodeNames[j] == pContainerSubNodes[nContSub])
1151cdf0e10cSrcweir 						{
1152cdf0e10cSrcweir 							bFound = sal_True;
1153cdf0e10cSrcweir 							break;
1154cdf0e10cSrcweir 						}
1155cdf0e10cSrcweir                     }
1156cdf0e10cSrcweir 					if(!bFound)
1157cdf0e10cSrcweir                     try
1158cdf0e10cSrcweir 					{
1159cdf0e10cSrcweir 						xCont->removeByName(pContainerSubNodes[nContSub]);
1160cdf0e10cSrcweir 					}
1161cdf0e10cSrcweir                     catch (Exception & )
1162cdf0e10cSrcweir                     {
1163cdf0e10cSrcweir                         if (isSimpleValueSet)
1164cdf0e10cSrcweir                         try
1165cdf0e10cSrcweir                         {
1166cdf0e10cSrcweir                             // #i37322#: fallback action: replace with <void/>
1167cdf0e10cSrcweir                             xCont->replaceByName(pContainerSubNodes[nContSub], Any());
1168cdf0e10cSrcweir                             // fallback successfull: continue looping
1169cdf0e10cSrcweir                             continue;
1170cdf0e10cSrcweir                         }
1171cdf0e10cSrcweir                         catch (Exception &)
1172cdf0e10cSrcweir                         {} // propagate original exception, if fallback fails
1173cdf0e10cSrcweir 
1174cdf0e10cSrcweir                         throw;
1175cdf0e10cSrcweir                     }
1176cdf0e10cSrcweir 				}
1177cdf0e10cSrcweir 				try { xBatch->commitChanges(); }
1178cdf0e10cSrcweir                 CATCH_INFO("Exception from commitChanges(): ")
1179cdf0e10cSrcweir             }
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir 			if(xFac.is()) // !isSimpleValueSet
1182cdf0e10cSrcweir 			{
1183cdf0e10cSrcweir 				for(sal_Int32 j = 0; j < nSubNodeCount; j++)
1184cdf0e10cSrcweir 				{
1185cdf0e10cSrcweir 					if(!xCont->hasByName(pSubNodeNames[j]))
1186cdf0e10cSrcweir 					{
1187cdf0e10cSrcweir 						//create if not available
1188cdf0e10cSrcweir 						Reference<XInterface> xInst = xFac->createInstance();
1189cdf0e10cSrcweir 						Any aVal; aVal <<= xInst;
1190cdf0e10cSrcweir 						xCont->insertByName(pSubNodeNames[j], aVal);
1191cdf0e10cSrcweir 					}
1192cdf0e10cSrcweir 				}
1193cdf0e10cSrcweir 				try	{ xBatch->commitChanges(); }
1194cdf0e10cSrcweir                 CATCH_INFO("Exception from commitChanges(): ")
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir 				const PropertyValue* pProperties = rValues.getConstArray();
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir 				Sequence< OUString > aSetNames(rValues.getLength());
1199cdf0e10cSrcweir 				OUString* pSetNames = aSetNames.getArray();
1200cdf0e10cSrcweir 
1201cdf0e10cSrcweir 				Sequence< Any> aSetValues(rValues.getLength());
1202cdf0e10cSrcweir 				Any* pSetValues = aSetValues.getArray();
1203cdf0e10cSrcweir 
1204cdf0e10cSrcweir                 sal_Bool bEmptyNode = rNode.getLength() == 0;
1205cdf0e10cSrcweir                 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
1206cdf0e10cSrcweir 				{
1207cdf0e10cSrcweir                     pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
1208cdf0e10cSrcweir 					pSetValues[k] = pProperties[k].Value;
1209cdf0e10cSrcweir 				}
1210cdf0e10cSrcweir 				bRet = PutProperties(aSetNames, aSetValues);
1211cdf0e10cSrcweir 			}
1212cdf0e10cSrcweir 			else
1213cdf0e10cSrcweir 			{
1214cdf0e10cSrcweir 				const PropertyValue* pValues = rValues.getConstArray();
1215cdf0e10cSrcweir 
1216cdf0e10cSrcweir 				//if no factory is available then the node contains basic data elements
1217cdf0e10cSrcweir 				for(int nValue = 0; nValue < rValues.getLength();nValue++)
1218cdf0e10cSrcweir 				{
1219cdf0e10cSrcweir 					try
1220cdf0e10cSrcweir 					{
1221cdf0e10cSrcweir 						OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
1222cdf0e10cSrcweir 
1223cdf0e10cSrcweir                         if(xCont->hasByName(sSubNode))
1224cdf0e10cSrcweir 							xCont->replaceByName(sSubNode, pValues[nValue].Value);
1225cdf0e10cSrcweir 						else
1226cdf0e10cSrcweir 							xCont->insertByName(sSubNode, pValues[nValue].Value);
1227cdf0e10cSrcweir 					}
1228cdf0e10cSrcweir                     CATCH_INFO("Exception from insert/replaceByName(): ");
1229cdf0e10cSrcweir                 }
1230cdf0e10cSrcweir 				xBatch->commitChanges();
1231cdf0e10cSrcweir 			}
1232cdf0e10cSrcweir 		}
1233cdf0e10cSrcweir #ifdef DBG_UTIL
1234cdf0e10cSrcweir         catch(Exception& rEx)
1235cdf0e10cSrcweir 		{
1236cdf0e10cSrcweir             lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx);
1237cdf0e10cSrcweir #else
1238cdf0e10cSrcweir         catch(Exception&)
1239cdf0e10cSrcweir 		{
1240cdf0e10cSrcweir #endif
1241cdf0e10cSrcweir 			bRet = sal_False;
1242cdf0e10cSrcweir 		}
1243cdf0e10cSrcweir     }
1244cdf0e10cSrcweir 	return bRet;
1245cdf0e10cSrcweir }
1246cdf0e10cSrcweir /* -----------------------------07.05.01 12:15--------------------------------
1247cdf0e10cSrcweir 
1248cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1249cdf0e10cSrcweir sal_Bool ConfigItem::getUniqueSetElementName( const ::rtl::OUString& _rSetNode, ::rtl::OUString& _rName)
1250cdf0e10cSrcweir {
1251cdf0e10cSrcweir 	::rtl::OUString sNewElementName;
1252cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1253cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1254cdf0e10cSrcweir     if(xHierarchyAccess.is())
1255cdf0e10cSrcweir     {
1256cdf0e10cSrcweir         try
1257cdf0e10cSrcweir         {
1258cdf0e10cSrcweir             Reference< XNameAccess > xSetNode;
1259cdf0e10cSrcweir             xHierarchyAccess->getByHierarchicalName(_rSetNode) >>= xSetNode;
1260cdf0e10cSrcweir             if (xSetNode.is())
1261cdf0e10cSrcweir             {
1262cdf0e10cSrcweir                 const sal_uInt32 nPrime = 65521;                            // a prime number
1263cdf0e10cSrcweir                 const sal_uInt32 nPrimeLess2 = nPrime - 2;
1264cdf0e10cSrcweir                 sal_uInt32 nEngendering     = (rand() % nPrimeLess2) + 2;   // the engendering of the field
1265cdf0e10cSrcweir 
1266cdf0e10cSrcweir                 // the element which will loop through the field
1267cdf0e10cSrcweir                 sal_uInt32 nFieldElement = nEngendering;
1268cdf0e10cSrcweir 
1269cdf0e10cSrcweir                 for (; 1 != nFieldElement; nFieldElement = (nFieldElement * nEngendering) % nPrime)
1270cdf0e10cSrcweir                 {
1271cdf0e10cSrcweir                     ::rtl::OUString sThisRoundTrial = _rName;
1272cdf0e10cSrcweir                     sThisRoundTrial += ::rtl::OUString::valueOf((sal_Int32)nFieldElement);
1273cdf0e10cSrcweir 
1274cdf0e10cSrcweir                     if (!xSetNode->hasByName(sThisRoundTrial))
1275cdf0e10cSrcweir                     {
1276cdf0e10cSrcweir                         _rName = sThisRoundTrial;
1277cdf0e10cSrcweir                         bRet =  sal_True;
1278cdf0e10cSrcweir 						break;
1279cdf0e10cSrcweir                     }
1280cdf0e10cSrcweir                 }
1281cdf0e10cSrcweir             }
1282cdf0e10cSrcweir         }
1283cdf0e10cSrcweir         CATCH_INFO("Exception from getUniqueSetElementName(): ")
1284cdf0e10cSrcweir     }
1285cdf0e10cSrcweir     return bRet;
1286cdf0e10cSrcweir }
1287cdf0e10cSrcweir /* -----------------------------23.01.01 12:49--------------------------------
1288cdf0e10cSrcweir 
1289cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1290cdf0e10cSrcweir sal_Bool ConfigItem::AddNode(const rtl::OUString& rNode, const rtl::OUString& rNewNode)
1291cdf0e10cSrcweir {
1292cdf0e10cSrcweir 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
1293cdf0e10cSrcweir     sal_Bool bRet = sal_True;
1294cdf0e10cSrcweir     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1295cdf0e10cSrcweir     if(xHierarchyAccess.is())
1296cdf0e10cSrcweir 	{
1297cdf0e10cSrcweir 		Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1298cdf0e10cSrcweir 		try
1299cdf0e10cSrcweir 		{
1300cdf0e10cSrcweir 			Reference<XNameContainer> xCont;
1301cdf0e10cSrcweir 			if(rNode.getLength())
1302cdf0e10cSrcweir 			{
1303cdf0e10cSrcweir 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1304cdf0e10cSrcweir 				aNode >>= xCont;
1305cdf0e10cSrcweir 			}
1306cdf0e10cSrcweir 			else
1307cdf0e10cSrcweir 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1308cdf0e10cSrcweir 			if(!xCont.is())
1309cdf0e10cSrcweir 				return sal_False;
1310cdf0e10cSrcweir 
1311cdf0e10cSrcweir 			Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1312cdf0e10cSrcweir 
1313cdf0e10cSrcweir             if(xFac.is())
1314cdf0e10cSrcweir 			{
1315cdf0e10cSrcweir 				if(!xCont->hasByName(rNewNode))
1316cdf0e10cSrcweir 				{
1317cdf0e10cSrcweir 					Reference<XInterface> xInst = xFac->createInstance();
1318cdf0e10cSrcweir 					Any aVal; aVal <<= xInst;
1319cdf0e10cSrcweir 					xCont->insertByName(rNewNode, aVal);
1320cdf0e10cSrcweir 				}
1321cdf0e10cSrcweir 				try
1322cdf0e10cSrcweir 				{
1323cdf0e10cSrcweir 					xBatch->commitChanges();
1324cdf0e10cSrcweir 				}
1325cdf0e10cSrcweir                 CATCH_INFO("Exception from commitChanges(): ")
1326cdf0e10cSrcweir 			}
1327cdf0e10cSrcweir 			else
1328cdf0e10cSrcweir 			{
1329cdf0e10cSrcweir 				//if no factory is available then the node contains basic data elements
1330cdf0e10cSrcweir 				try
1331cdf0e10cSrcweir 				{
1332cdf0e10cSrcweir 					if(!xCont->hasByName(rNewNode))
1333cdf0e10cSrcweir 						xCont->insertByName(rNewNode, Any());
1334cdf0e10cSrcweir 				}
1335cdf0e10cSrcweir                 CATCH_INFO("Exception from AddNode(): ")
1336cdf0e10cSrcweir 			}
1337cdf0e10cSrcweir 			xBatch->commitChanges();
1338cdf0e10cSrcweir 		}
1339cdf0e10cSrcweir #ifdef DBG_UTIL
1340cdf0e10cSrcweir         catch(Exception& rEx)
1341cdf0e10cSrcweir 		{
1342cdf0e10cSrcweir             lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx);
1343cdf0e10cSrcweir #else
1344cdf0e10cSrcweir         catch(Exception&)
1345cdf0e10cSrcweir 		{
1346cdf0e10cSrcweir #endif
1347cdf0e10cSrcweir 			bRet = sal_False;
1348cdf0e10cSrcweir 		}
1349cdf0e10cSrcweir 	}
1350cdf0e10cSrcweir 	return bRet;
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir /* -----------------------------12.02.01 11:38--------------------------------
1353cdf0e10cSrcweir 
1354cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1355cdf0e10cSrcweir sal_Int16 	ConfigItem::GetMode() const
1356cdf0e10cSrcweir {
1357cdf0e10cSrcweir 	return pImpl->nMode;
1358cdf0e10cSrcweir }
1359cdf0e10cSrcweir /* -----------------------------12.02.01 13:31--------------------------------
1360cdf0e10cSrcweir 
1361cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1362cdf0e10cSrcweir void 	ConfigItem::SetModified()
1363cdf0e10cSrcweir {
1364cdf0e10cSrcweir 	pImpl->bIsModified = sal_True;
1365cdf0e10cSrcweir }
1366cdf0e10cSrcweir /* -----------------------------05.05.01 14:07--------------------------------
1367cdf0e10cSrcweir 
1368cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1369cdf0e10cSrcweir void    ConfigItem::ClearModified()
1370cdf0e10cSrcweir {
1371cdf0e10cSrcweir     pImpl->bIsModified = sal_False;
1372cdf0e10cSrcweir }
1373cdf0e10cSrcweir /* -----------------------------12.02.01 13:31--------------------------------
1374cdf0e10cSrcweir 
1375cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1376cdf0e10cSrcweir sal_Bool ConfigItem::IsModified() const
1377cdf0e10cSrcweir {
1378cdf0e10cSrcweir 	return pImpl->bIsModified;
1379cdf0e10cSrcweir }
1380cdf0e10cSrcweir /* -----------------------------12.02.01 13:33--------------------------------
1381cdf0e10cSrcweir 
1382cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1383cdf0e10cSrcweir sal_Bool ConfigItem::IsInValueChange() const
1384cdf0e10cSrcweir {
1385cdf0e10cSrcweir 	return pImpl->nInValueChange > 0;
1386cdf0e10cSrcweir }
1387cdf0e10cSrcweir /* -----------------------------21.06.01 12:26--------------------------------
1388cdf0e10cSrcweir 
1389cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1390cdf0e10cSrcweir Reference< XHierarchicalNameAccess> ConfigItem::GetTree()
1391cdf0e10cSrcweir {
1392cdf0e10cSrcweir     Reference< XHierarchicalNameAccess> xRet;
1393cdf0e10cSrcweir     if(!m_xHierarchyAccess.is())
1394cdf0e10cSrcweir         xRet = pImpl->pManager->AcquireTree(*this);
1395cdf0e10cSrcweir     else
1396cdf0e10cSrcweir         xRet = m_xHierarchyAccess;
1397cdf0e10cSrcweir     OSL_ENSURE(xRet.is(), "AcquireTree failed");
1398cdf0e10cSrcweir     return xRet;
1399cdf0e10cSrcweir }
1400cdf0e10cSrcweir /* -----------------------------22.06.01 08:42--------------------------------
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1403cdf0e10cSrcweir void ConfigItem::LockTree()
1404cdf0e10cSrcweir {
1405cdf0e10cSrcweir     OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call LockTree in CONFIG_MODE_RELEASE_TREE mode, only");
1406cdf0e10cSrcweir     m_xHierarchyAccess = GetTree();
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir /* -----------------------------22.06.01 08:42--------------------------------
1409cdf0e10cSrcweir 
1410cdf0e10cSrcweir  ---------------------------------------------------------------------------*/
1411cdf0e10cSrcweir void ConfigItem::UnlockTree()
1412cdf0e10cSrcweir {
1413cdf0e10cSrcweir     OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call UnlockTree in CONFIG_MODE_RELEASE_TREE mode, only");
1414cdf0e10cSrcweir     if(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE))
1415cdf0e10cSrcweir         m_xHierarchyAccess = 0;
1416cdf0e10cSrcweir }
1417cdf0e10cSrcweir 
1418cdf0e10cSrcweir 
1419