xref: /AOO41X/main/unotools/source/config/confignode.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_unotools.hxx"
30 
31 #include <unotools/confignode.hxx>
32 #include <unotools/configpathes.hxx>
33 #include <tools/diagnose_ex.h>
34 #include <osl/diagnose.h>
35 #include <com/sun/star/container/XHierarchicalName.hpp>
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/lang/XComponent.hpp>
39 #include <com/sun/star/util/XStringEscape.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/container/XNamed.hpp>
42 #include <comphelper/extract.hxx>
43 #include <comphelper/componentcontext.hxx>
44 #include <comphelper/namedvaluecollection.hxx>
45 #include <rtl/string.hxx>
46 #if OSL_DEBUG_LEVEL > 0
47 #include <rtl/strbuf.hxx>
48 #endif
49 
50 //........................................................................
51 namespace utl
52 {
53 //........................................................................
54 
55 	using namespace ::com::sun::star::uno;
56 	using namespace ::com::sun::star::lang;
57 	using namespace ::com::sun::star::util;
58 	using namespace ::com::sun::star::beans;
59 	using namespace ::com::sun::star::container;
60 
61 	//========================================================================
62 	//= OConfigurationNode
63 	//========================================================================
64 	//------------------------------------------------------------------------
65 	OConfigurationNode::OConfigurationNode(const Reference< XInterface >& _rxNode )
66 		:m_bEscapeNames(sal_False)
67 	{
68 		OSL_ENSURE(_rxNode.is(), "OConfigurationNode::OConfigurationNode: invalid node interface!");
69 		if (_rxNode.is())
70 		{
71 			// collect all interfaces necessary
72 			m_xHierarchyAccess = Reference< XHierarchicalNameAccess >(_rxNode, UNO_QUERY);
73 			m_xDirectAccess = Reference< XNameAccess >(_rxNode, UNO_QUERY);
74 
75 			// reset _all_ interfaces if _one_ of them is not supported
76 			if (!m_xHierarchyAccess.is() || !m_xDirectAccess.is())
77 			{
78 				m_xHierarchyAccess = NULL;
79 				m_xDirectAccess = NULL;
80 			}
81 
82 			// now for the non-critical interfaces
83 			m_xReplaceAccess = Reference< XNameReplace >(_rxNode, UNO_QUERY);
84 			m_xContainerAccess = Reference< XNameContainer >(_rxNode, UNO_QUERY);
85 		}
86 
87 		Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY);
88 		if (xConfigNodeComp.is())
89 			startComponentListening(xConfigNodeComp);
90 
91 		if (isValid())
92 			setEscape(isSetNode());
93 	}
94 
95 	//------------------------------------------------------------------------
96 	OConfigurationNode::OConfigurationNode(const OConfigurationNode& _rSource)
97 		:OEventListenerAdapter()
98 		,m_xHierarchyAccess(_rSource.m_xHierarchyAccess)
99 		,m_xDirectAccess(_rSource.m_xDirectAccess)
100 		,m_xReplaceAccess(_rSource.m_xReplaceAccess)
101 		,m_xContainerAccess(_rSource.m_xContainerAccess)
102 		,m_bEscapeNames(_rSource.m_bEscapeNames)
103 		,m_sCompletePath(_rSource.m_sCompletePath)
104 	{
105 		Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY);
106 		if (xConfigNodeComp.is())
107 			startComponentListening(xConfigNodeComp);
108 	}
109 
110 	//------------------------------------------------------------------------
111 	const OConfigurationNode& OConfigurationNode::operator=(const OConfigurationNode& _rSource)
112 	{
113 		stopAllComponentListening();
114 
115 		m_xHierarchyAccess = _rSource.m_xHierarchyAccess;
116 		m_xDirectAccess = _rSource.m_xDirectAccess;
117 		m_xContainerAccess = _rSource.m_xContainerAccess;
118 		m_xReplaceAccess = _rSource.m_xReplaceAccess;
119 		m_bEscapeNames = _rSource.m_bEscapeNames;
120 		m_sCompletePath = _rSource.m_sCompletePath;
121 
122 		Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY);
123 		if (xConfigNodeComp.is())
124 			startComponentListening(xConfigNodeComp);
125 
126 		return *this;
127 	}
128 
129 	//------------------------------------------------------------------------
130 	void OConfigurationNode::_disposing( const EventObject& _rSource )
131 	{
132 		Reference< XComponent > xDisposingSource(_rSource.Source, UNO_QUERY);
133 		Reference< XComponent > xConfigNodeComp(m_xDirectAccess, UNO_QUERY);
134 		if (xDisposingSource.get() == xConfigNodeComp.get())
135 			clear();
136 	}
137 
138 	//------------------------------------------------------------------------
139     ::rtl::OUString OConfigurationNode::getLocalName() const
140     {
141         ::rtl::OUString sLocalName;
142         try
143         {
144             Reference< XNamed > xNamed( m_xDirectAccess, UNO_QUERY_THROW );
145             sLocalName = xNamed->getName();
146         }
147         catch( const Exception& )
148         {
149         	DBG_UNHANDLED_EXCEPTION();
150         }
151         return sLocalName;
152     }
153 
154 	//------------------------------------------------------------------------
155     ::rtl::OUString OConfigurationNode::getNodePath() const
156     {
157         ::rtl::OUString sNodePath;
158         try
159         {
160             Reference< XHierarchicalName > xNamed( m_xDirectAccess, UNO_QUERY_THROW );
161             sNodePath = xNamed->getHierarchicalName();
162         }
163         catch( const Exception& )
164         {
165         	DBG_UNHANDLED_EXCEPTION();
166         }
167         return sNodePath;
168     }
169 
170 	//------------------------------------------------------------------------
171 	::rtl::OUString OConfigurationNode::normalizeName(const ::rtl::OUString& _rName, NAMEORIGIN _eOrigin) const
172 	{
173 		::rtl::OUString sName(_rName);
174 		if (getEscape())
175 		{
176 			Reference< XStringEscape > xEscaper(m_xDirectAccess, UNO_QUERY);
177 			if (xEscaper.is() && sName.getLength())
178 			{
179 				try
180 				{
181 					if (NO_CALLER == _eOrigin)
182 						sName = xEscaper->escapeString(sName);
183 					else
184 						sName = xEscaper->unescapeString(sName);
185 				}
186 				catch(Exception&)
187 				{
188 					DBG_UNHANDLED_EXCEPTION();
189 				}
190 			}
191 		}
192 		return sName;
193 	}
194 
195 	//------------------------------------------------------------------------
196 	Sequence< ::rtl::OUString > OConfigurationNode::getNodeNames() const throw()
197 	{
198 		OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::getNodeNames: object is invalid!");
199 		Sequence< ::rtl::OUString > aReturn;
200 		if (m_xDirectAccess.is())
201 		{
202 			try
203 			{
204 				aReturn = m_xDirectAccess->getElementNames();
205 				// normalize the names
206 				::rtl::OUString* pNames = aReturn.getArray();
207 				for (sal_Int32 i=0; i<aReturn.getLength(); ++i, ++pNames)
208 					*pNames = normalizeName(*pNames, NO_CONFIGURATION);
209 			}
210 			catch(Exception&)
211 			{
212 				OSL_ENSURE(sal_False, "OConfigurationNode::getNodeNames: caught a generic exception!");
213 			}
214 		}
215 
216 		return aReturn;
217 	}
218 
219 	//------------------------------------------------------------------------
220 	sal_Bool OConfigurationNode::removeNode(const ::rtl::OUString& _rName) const throw()
221 	{
222 		OSL_ENSURE(m_xContainerAccess.is(), "OConfigurationNode::removeNode: object is invalid!");
223 		if (m_xContainerAccess.is())
224 		{
225 			try
226 			{
227 				::rtl::OUString sName = normalizeName(_rName, NO_CALLER);
228 				m_xContainerAccess->removeByName(sName);
229 				return sal_True;
230 			}
231 			catch (NoSuchElementException&)
232 			{
233                 #if OSL_DEBUG_LEVEL > 0
234                 rtl::OStringBuffer aBuf( 256 );
235                 aBuf.append("OConfigurationNode::removeNode: there is no element named!");
236                 aBuf.append( rtl::OUStringToOString( _rName, RTL_TEXTENCODING_ASCII_US ) );
237                 aBuf.append( "!" );
238 				OSL_ENSURE(sal_False, aBuf.getStr());
239                 #endif
240 			}
241 			catch (WrappedTargetException&)
242 			{
243 				OSL_ENSURE(sal_False, "OConfigurationNode::removeNode: caught a WrappedTargetException!");
244 			}
245 			catch(Exception&)
246 			{
247 				OSL_ENSURE(sal_False, "OConfigurationNode::removeNode: caught a generic exception!");
248 			}
249 		}
250 		return sal_False;
251 	}
252 	//------------------------------------------------------------------------
253 	OConfigurationNode OConfigurationNode::insertNode(const ::rtl::OUString& _rName,const Reference< XInterface >& _xNode) const throw()
254 	{
255 		if(_xNode.is())
256 		{
257 			try
258 			{
259 				::rtl::OUString sName = normalizeName(_rName, NO_CALLER);
260 				m_xContainerAccess->insertByName(sName, makeAny(_xNode));
261 				// if we're here, all was ok ...
262 				return OConfigurationNode( _xNode );
263 			}
264 			catch(const Exception&)
265 			{
266                 DBG_UNHANDLED_EXCEPTION();
267 			}
268 
269 			// dispose the child if it has already been created, but could not be inserted
270 			Reference< XComponent > xChildComp(_xNode, UNO_QUERY);
271 			if (xChildComp.is())
272 				try { xChildComp->dispose(); } catch(Exception&) { }
273 		}
274 
275 		return OConfigurationNode();
276 	}
277 	//------------------------------------------------------------------------
278 	OConfigurationNode OConfigurationNode::createNode(const ::rtl::OUString& _rName) const throw()
279 	{
280 		Reference< XSingleServiceFactory > xChildFactory(m_xContainerAccess, UNO_QUERY);
281 		OSL_ENSURE(xChildFactory.is(), "OConfigurationNode::createNode: object is invalid or read-only!");
282 
283 		if (xChildFactory.is())	// implies m_xContainerAccess.is()
284 		{
285 			Reference< XInterface > xNewChild;
286 			try
287 			{
288 				xNewChild = xChildFactory->createInstance();
289 			}
290 			catch(const Exception&)
291 			{
292                 DBG_UNHANDLED_EXCEPTION();
293 			}
294 			return insertNode(_rName,xNewChild);
295 		}
296 
297 		return OConfigurationNode();
298 	}
299 
300 	//------------------------------------------------------------------------
301 	OConfigurationNode OConfigurationNode::appendNode(const ::rtl::OUString& _rName,const OConfigurationNode& _aNewNode) const throw()
302 	{
303 		return insertNode(_rName,_aNewNode.m_xDirectAccess);
304 	}
305 	//------------------------------------------------------------------------
306 	OConfigurationNode OConfigurationNode::openNode(const ::rtl::OUString& _rPath) const throw()
307 	{
308 		OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::openNode: object is invalid!");
309 		OSL_ENSURE(m_xHierarchyAccess.is(), "OConfigurationNode::openNode: object is invalid!");
310 		try
311 		{
312 			::rtl::OUString sNormalized = normalizeName(_rPath, NO_CALLER);
313 
314 			Reference< XInterface > xNode;
315 			if (m_xDirectAccess.is() && m_xDirectAccess->hasByName(sNormalized))
316 			{
317 				if (!::cppu::extractInterface(xNode, m_xDirectAccess->getByName(sNormalized)))
318 				    OSL_ENSURE(sal_False, "OConfigurationNode::openNode: could not open the node!");
319 			}
320 			else if (m_xHierarchyAccess.is())
321 			{
322 				if (!::cppu::extractInterface(xNode, m_xHierarchyAccess->getByHierarchicalName(_rPath)))
323 				    OSL_ENSURE(sal_False, "OConfigurationNode::openNode: could not open the node!");
324 			}
325             if (xNode.is())
326 			    return OConfigurationNode( xNode );
327 		}
328 		catch(NoSuchElementException& e)
329 		{
330             (void)e;
331             #if OSL_DEBUG_LEVEL > 0
332             rtl::OStringBuffer aBuf( 256 );
333             aBuf.append("OConfigurationNode::openNode: there is no element named ");
334             aBuf.append( rtl::OUStringToOString( _rPath, RTL_TEXTENCODING_ASCII_US ) );
335             aBuf.append("!");
336 			OSL_ENSURE(sal_False, aBuf.getStr());
337             #endif
338 		}
339 		catch(Exception&)
340 		{
341 			OSL_ENSURE(sal_False, "OConfigurationNode::openNode: caught an exception while retrieving the node!");
342 		}
343 		return OConfigurationNode();
344 	}
345 
346 	//------------------------------------------------------------------------
347 	void OConfigurationNode::setEscape(sal_Bool _bEnable)
348 	{
349         m_bEscapeNames = _bEnable && Reference< XStringEscape >::query(m_xDirectAccess).is();
350 	}
351 
352 	//------------------------------------------------------------------------
353 	sal_Bool OConfigurationNode::isSetNode() const
354 	{
355 		sal_Bool bIsSet = sal_False;
356 		Reference< XServiceInfo > xSI(m_xHierarchyAccess, UNO_QUERY);
357 		if (xSI.is())
358 		{
359 			try { bIsSet = xSI->supportsService(::rtl::OUString::createFromAscii("com.sun.star.configuration.SetAccess")); }
360 			catch(Exception&) { }
361 		}
362 		return bIsSet;
363 	}
364 
365 	//---------------------------------------------------------------------
366 	//--- 20.08.01 19:03:20 -----------------------------------------------
367 
368 	sal_Bool OConfigurationNode::hasByHierarchicalName( const ::rtl::OUString& _rName ) const throw()
369 	{
370 		OSL_ENSURE( m_xHierarchyAccess.is(), "OConfigurationNode::hasByHierarchicalName: no hierarchy access!" );
371 		try
372 		{
373 			if ( m_xHierarchyAccess.is() )
374 			{
375 				::rtl::OUString sName = normalizeName( _rName, NO_CALLER );
376 				return m_xHierarchyAccess->hasByHierarchicalName( sName );
377 			}
378 		}
379 		catch(Exception&)
380 		{
381 		}
382 		return sal_False;
383 	}
384 
385 	//------------------------------------------------------------------------
386 	sal_Bool OConfigurationNode::hasByName(const ::rtl::OUString& _rName) const throw()
387 	{
388 		OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::hasByName: object is invalid!");
389 		try
390 		{
391 			::rtl::OUString sName = normalizeName(_rName, NO_CALLER);
392 			if (m_xDirectAccess.is())
393 				return m_xDirectAccess->hasByName(sName);
394 		}
395 		catch(Exception&)
396 		{
397 		}
398 		return sal_False;
399 	}
400 
401 	//------------------------------------------------------------------------
402 	sal_Bool OConfigurationNode::setNodeValue(const ::rtl::OUString& _rPath, const Any& _rValue) const throw()
403 	{
404         sal_Bool bResult = false;
405 
406 		OSL_ENSURE(m_xReplaceAccess.is(), "OConfigurationNode::setNodeValue: object is invalid!");
407 		if (m_xReplaceAccess.is())
408 		{
409 			try
410 			{
411 			    // check if _rPath is a level-1 path
412 			    ::rtl::OUString sNormalizedName = normalizeName(_rPath, NO_CALLER);
413                 if (m_xReplaceAccess->hasByName(sNormalizedName))
414                 {
415 				    m_xReplaceAccess->replaceByName(sNormalizedName, _rValue);
416 				    bResult = true;
417                 }
418 
419 		    	// check if the name refers to a indirect descendant
420                 else if (m_xHierarchyAccess.is() && m_xHierarchyAccess->hasByHierarchicalName(_rPath))
421                 {
422                     OSL_ASSERT(_rPath.getLength());
423 
424                     ::rtl::OUString sParentPath, sLocalName;
425 
426                     if ( splitLastFromConfigurationPath(_rPath, sParentPath, sLocalName) )
427 			        {
428 				        OConfigurationNode aParentAccess = openNode(sParentPath);
429 				        if (aParentAccess.isValid())
430 					        bResult = aParentAccess.setNodeValue(sLocalName, _rValue);
431 			        }
432                     else
433                     {
434 				        m_xReplaceAccess->replaceByName(sLocalName, _rValue);
435                         bResult = true;
436                     }
437                 }
438 
439 			}
440 			catch(IllegalArgumentException&)
441 			{
442 				OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught an IllegalArgumentException!");
443 			}
444 			catch(NoSuchElementException&)
445 			{
446 				OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught a NoSuchElementException!");
447 			}
448 			catch(WrappedTargetException&)
449 			{
450 				OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught a WrappedTargetException!");
451 			}
452 			catch(Exception&)
453 			{
454 				OSL_ENSURE(sal_False, "OConfigurationNode::setNodeValue: could not replace the value: caught a generic Exception!");
455 			}
456 
457 
458 		}
459 		return bResult;
460 	}
461 
462 	//------------------------------------------------------------------------
463 	Any OConfigurationNode::getNodeValue(const ::rtl::OUString& _rPath) const throw()
464 	{
465 		OSL_ENSURE(m_xDirectAccess.is(), "OConfigurationNode::hasByName: object is invalid!");
466 		OSL_ENSURE(m_xHierarchyAccess.is(), "OConfigurationNode::hasByName: object is invalid!");
467 		Any aReturn;
468 		try
469 		{
470 			::rtl::OUString sNormalizedPath = normalizeName(_rPath, NO_CALLER);
471 		    if (m_xDirectAccess.is() && m_xDirectAccess->hasByName(sNormalizedPath) )
472 		    {
473 				aReturn = m_xDirectAccess->getByName(sNormalizedPath);
474             }
475 		    else if (m_xHierarchyAccess.is())
476 		    {
477 				aReturn = m_xHierarchyAccess->getByHierarchicalName(_rPath);
478 		    }
479 		}
480 		catch(const NoSuchElementException&)
481 		{
482             DBG_UNHANDLED_EXCEPTION();
483 		}
484 		return aReturn;
485 	}
486 
487 	//------------------------------------------------------------------------
488 	void OConfigurationNode::clear() throw()
489 	{
490 		m_xHierarchyAccess.clear();
491 		m_xDirectAccess.clear();
492 		m_xReplaceAccess.clear();
493 		m_xContainerAccess.clear();
494 	}
495 
496 	//========================================================================
497 	//= helper
498 	//========================================================================
499     namespace
500     {
501 	    //--------------------------------------------------------------------
502 		static const ::rtl::OUString& lcl_getProviderServiceName( )
503 		{
504 			static ::rtl::OUString s_sProviderServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.configuration.ConfigurationProvider" ) );
505 			return s_sProviderServiceName;
506 		}
507 
508 	    //--------------------------------------------------------------------
509         Reference< XMultiServiceFactory > lcl_getConfigProvider( const ::comphelper::ComponentContext& i_rContext )
510         {
511 		    try
512 		    {
513 			    Reference< XMultiServiceFactory > xProvider( i_rContext.createComponent( lcl_getProviderServiceName() ), UNO_QUERY_THROW );
514                 return xProvider;
515 		    }
516 		    catch ( const Exception& )
517 		    {
518                 DBG_UNHANDLED_EXCEPTION();
519 		    }
520             return NULL;
521         }
522 
523 	    //--------------------------------------------------------------------
524         Reference< XInterface > lcl_createConfigurationRoot( const Reference< XMultiServiceFactory >& i_rxConfigProvider,
525             const ::rtl::OUString& i_rNodePath, const bool i_bUpdatable, const sal_Int32 i_nDepth, const bool i_bLazyWrite )
526         {
527             ENSURE_OR_RETURN( i_rxConfigProvider.is(), "invalid provider", NULL );
528 			try
529 			{
530                 ::comphelper::NamedValueCollection aArgs;
531                 aArgs.put( "nodepath", i_rNodePath );
532                 aArgs.put( "lazywrite", i_bLazyWrite );
533                 aArgs.put( "depth", i_nDepth );
534 
535 				::rtl::OUString sAccessService = ::rtl::OUString::createFromAscii(
536                         i_bUpdatable
537 					? "com.sun.star.configuration.ConfigurationUpdateAccess"
538 					: "com.sun.star.configuration.ConfigurationAccess" );
539 
540 				Reference< XInterface > xRoot(
541                     i_rxConfigProvider->createInstanceWithArguments( sAccessService, aArgs.getWrappedPropertyValues() ),
542                     UNO_SET_THROW
543                 );
544 				return xRoot;
545 			}
546 			catch ( const Exception& )
547 			{
548                 DBG_UNHANDLED_EXCEPTION();
549 			}
550             return NULL;
551         }
552     }
553 	//========================================================================
554 	//= OConfigurationTreeRoot
555 	//========================================================================
556 	//------------------------------------------------------------------------
557 	OConfigurationTreeRoot::OConfigurationTreeRoot( const Reference< XChangesBatch >& _rxRootNode )
558 		:OConfigurationNode( _rxRootNode.get() )
559 		,m_xCommitter(_rxRootNode)
560 	{
561 	}
562 
563 	//------------------------------------------------------------------------
564 	OConfigurationTreeRoot::OConfigurationTreeRoot( const Reference< XInterface >& _rxRootNode )
565 		:OConfigurationNode( _rxRootNode )
566         ,m_xCommitter( _rxRootNode, UNO_QUERY )
567 	{
568 	}
569 
570 	//------------------------------------------------------------------------
571     OConfigurationTreeRoot::OConfigurationTreeRoot( const ::comphelper::ComponentContext& i_rContext, const sal_Char* i_pAsciiNodePath, const bool i_bUpdatable )
572         :OConfigurationNode( lcl_createConfigurationRoot( lcl_getConfigProvider( i_rContext.getLegacyServiceFactory() ),
573             ::rtl::OUString::createFromAscii( i_pAsciiNodePath ), i_bUpdatable, -1, false ).get() )
574         ,m_xCommitter()
575     {
576         if ( i_bUpdatable )
577         {
578             m_xCommitter.set( getUNONode(), UNO_QUERY );
579             OSL_ENSURE( m_xCommitter.is(), "OConfigurationTreeRoot::OConfigurationTreeRoot: could not create an updatable node!" );
580         }
581     }
582 
583 	//------------------------------------------------------------------------
584     OConfigurationTreeRoot::OConfigurationTreeRoot( const ::comphelper::ComponentContext& i_rContext, const ::rtl::OUString& i_rNodePath, const bool i_bUpdatable )
585         :OConfigurationNode( lcl_createConfigurationRoot( lcl_getConfigProvider( i_rContext.getLegacyServiceFactory() ),
586             i_rNodePath, i_bUpdatable, -1, false ).get() )
587         ,m_xCommitter()
588     {
589         if ( i_bUpdatable )
590         {
591             m_xCommitter.set( getUNONode(), UNO_QUERY );
592             OSL_ENSURE( m_xCommitter.is(), "OConfigurationTreeRoot::OConfigurationTreeRoot: could not create an updatable node!" );
593         }
594     }
595 
596 	//------------------------------------------------------------------------
597 	void OConfigurationTreeRoot::clear() throw()
598 	{
599 		OConfigurationNode::clear();
600 		m_xCommitter.clear();
601 	}
602 
603 	//------------------------------------------------------------------------
604 	sal_Bool OConfigurationTreeRoot::commit() const throw()
605 	{
606 		OSL_ENSURE(isValid(), "OConfigurationTreeRoot::commit: object is invalid!");
607 		if (!isValid())
608 			return sal_False;
609 		OSL_ENSURE(m_xCommitter.is(), "OConfigurationTreeRoot::commit: I'm a readonly node!");
610 		if (!m_xCommitter.is())
611 			return sal_False;
612 
613 		try
614 		{
615 			m_xCommitter->commitChanges();
616 			return sal_True;
617 		}
618 		catch(const Exception&)
619 		{
620             DBG_UNHANDLED_EXCEPTION();
621 		}
622 		return sal_False;
623 	}
624 
625 	//------------------------------------------------------------------------
626 	OConfigurationTreeRoot OConfigurationTreeRoot::createWithProvider(const Reference< XMultiServiceFactory >& _rxConfProvider, const ::rtl::OUString& _rPath, sal_Int32 _nDepth, CREATION_MODE _eMode, sal_Bool _bLazyWrite)
627 	{
628         Reference< XInterface > xRoot( lcl_createConfigurationRoot(
629             _rxConfProvider, _rPath, _eMode != CM_READONLY, _nDepth, _bLazyWrite ) );
630         if ( xRoot.is() )
631             return OConfigurationTreeRoot( xRoot );
632         return OConfigurationTreeRoot();
633 	}
634 
635 	//------------------------------------------------------------------------
636 	OConfigurationTreeRoot OConfigurationTreeRoot::createWithServiceFactory( const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rPath, sal_Int32 _nDepth, CREATION_MODE _eMode, sal_Bool _bLazyWrite )
637 	{
638         return createWithProvider( lcl_getConfigProvider( _rxORB ), _rPath, _nDepth, _eMode, _bLazyWrite );
639 	}
640 
641 	//------------------------------------------------------------------------
642 	OConfigurationTreeRoot OConfigurationTreeRoot::tryCreateWithServiceFactory( const Reference< XMultiServiceFactory >& _rxORB,
643 		const ::rtl::OUString& _rPath, sal_Int32 _nDepth , CREATION_MODE _eMode , sal_Bool _bLazyWrite )
644 	{
645 		OSL_ENSURE( _rxORB.is(), "OConfigurationTreeRoot::tryCreateWithServiceFactory: invalid service factory!" );
646 		if ( _rxORB.is() )
647 		{
648 			try
649 			{
650 				Reference< XMultiServiceFactory > xConfigFactory( _rxORB->createInstance( lcl_getProviderServiceName( ) ), UNO_QUERY );
651 				if ( xConfigFactory.is() )
652 					return createWithProvider( xConfigFactory, _rPath, _nDepth, _eMode, _bLazyWrite );
653 			}
654 			catch(const Exception&)
655 			{
656 				// silence this, 'cause the contract of this method states "no assertions"
657 			}
658 		}
659 		return OConfigurationTreeRoot();
660 	}
661 
662 //........................................................................
663 }	// namespace utl
664 //........................................................................
665 
666