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