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 #include "unotools/configmgr.hxx"
31 #include "unotools/configitem.hxx"
32 #include "unotools/configpathes.hxx"
33 #include <unotools/processfactory.hxx>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
37 #include <com/sun/star/container/XNameContainer.hpp>
38 #include <com/sun/star/beans/PropertyValue.hpp>
39 #include <osl/diagnose.h>
40 #include <rtl/bootstrap.hxx>
41 #include <rtl/instance.hxx>
42 #if OSL_DEBUG_LEVEL > 0
43 #include <rtl/strbuf.hxx>
44 #endif
45 
46 #include <list>
47 
48 //-----------------------------------------------------------------------------
49 
50 using namespace utl;
51 using namespace rtl;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::lang;
54 using namespace com::sun::star::beans;
55 using namespace com::sun::star::container;
56 
57 #define C2U(cChar) OUString::createFromAscii(cChar)
58 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
59 
60 //-----------------------------------------------------------------------------
61 const char* cConfigBaseURL = "/org.openoffice.";
62 //const char* cConfigBaseURL = "/com.sun.star.";
63 const char* cAccessSrvc = "com.sun.star.configuration.ConfigurationUpdateAccess";
64 
65 namespace
66 {
67     struct BrandName
68         : public rtl::Static< ::rtl::OUString, BrandName > {};
69     struct ProductVersion
70         : public rtl::Static< ::rtl::OUString, ProductVersion > {};
71     struct AboutBoxProductVersion
72         : public rtl::Static< ::rtl::OUString, AboutBoxProductVersion > {};
73     struct OOOVendor
74         : public rtl::Static< ::rtl::OUString, OOOVendor > {};
75     struct ProductExtension
76         : public rtl::Static< ::rtl::OUString, ProductExtension > {};
77     struct XMLFileFormatName
78         : public rtl::Static< ::rtl::OUString, XMLFileFormatName > {};
79     struct XMLFileFormatVersion
80         : public rtl::Static< ::rtl::OUString, XMLFileFormatVersion > {};
81     struct WriterCompatibilityVersionOOo11
82         : public rtl::Static< ::rtl::OUString, WriterCompatibilityVersionOOo11 > {};
83     struct OpenSourceContext : public rtl::StaticWithInit< sal_Int32, OpenSourceContext >
84     {
85         sal_Int32 operator() () { return sal_Int32( -1 ); }
86     };
87 
88 }
89 
90 //-----------------------------------------------------------------------------
91 struct ConfigItemListEntry_Impl
92 {
93 	ConfigItem* 				pConfigItem;
94 
95 	ConfigItemListEntry_Impl(ConfigItem* 	pItem ) :
96 		pConfigItem(pItem){}
97 };
98 typedef std::list<ConfigItemListEntry_Impl> ConfigItemList;
99 struct utl::ConfigMgr_Impl
100 {
101 	ConfigItemList 							aItemList;
102 };
103 
104 /* -----------------------------28.08.00 15:35--------------------------------
105 
106  ---------------------------------------------------------------------------*/
107 ConfigManager::ConfigManager() :
108 	pMgrImpl(new utl::ConfigMgr_Impl)
109 {
110 	GetConfigurationProvider(); // attempt to create the provider early
111 }
112 /* -----------------------------17.11.00 13:51--------------------------------
113 
114  ---------------------------------------------------------------------------*/
115 ConfigManager::ConfigManager(Reference< XMultiServiceFactory > xConfigProv) :
116 	xConfigurationProvider(xConfigProv),
117 	pMgrImpl(new utl::ConfigMgr_Impl)
118 {
119 }
120 /* -----------------------------28.08.00 15:35--------------------------------
121 
122  ---------------------------------------------------------------------------*/
123 ConfigManager::~ConfigManager()
124 {
125 	//check list content -> should be empty!
126 	OSL_ENSURE(pMgrImpl->aItemList.empty(), "some ConfigItems are still alive");
127 	if(!pMgrImpl->aItemList.empty())
128 	{
129 		ConfigItemList::iterator aListIter;
130 		for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter)
131 		{
132 			ConfigItemListEntry_Impl& rEntry = *aListIter;
133 			rEntry.pConfigItem->ReleaseConfigMgr();
134 		}
135 		pMgrImpl->aItemList.erase(pMgrImpl->aItemList.begin(), pMgrImpl->aItemList.end());
136 	}
137 	delete pMgrImpl;
138 
139 }
140 /* -----------------------------28.08.00 16:17--------------------------------
141 
142  ---------------------------------------------------------------------------*/
143 Reference< XMultiServiceFactory > ConfigManager::GetConfigurationProvider()
144 {
145 	if(!xConfigurationProvider.is())
146 	{
147 		Reference< XMultiServiceFactory > xMSF = ::utl::getProcessServiceFactory();
148 		if ( xMSF.is() )
149 		{
150 			try
151 			{
152 				xConfigurationProvider = Reference< XMultiServiceFactory >
153 					(xMSF->createInstance(
154 						C2U("com.sun.star.configuration.ConfigurationProvider")),
155 					 UNO_QUERY);
156 			}
157 #ifdef DBG_UTIL
158 	catch(Exception& rEx)
159 	{
160         static sal_Bool bMessage = sal_True;
161         if(bMessage)
162         {
163             bMessage = sal_False;
164             OString sMsg("CreateInstance with arguments exception: ");
165             sMsg += OString(rEx.Message.getStr(),
166                         rEx.Message.getLength(),
167                         RTL_TEXTENCODING_ASCII_US);
168             OSL_ENSURE(sal_False, sMsg.getStr());
169         }
170 	}
171 #else
172 	catch(Exception&){}
173 #endif
174 		}
175 	}
176 	return xConfigurationProvider;
177 }
178 /* -----------------------------03.12.02 -------------------------------------
179 
180  ---------------------------------------------------------------------------*/
181 namespace
182 {
183     // helper to achieve exception - safe registration of a ConfigItem under construction
184     class RegisterConfigItemHelper // : Noncopyable
185     {
186         utl::ConfigManager & rCfgMgr;
187         utl::ConfigItem* pCfgItem;
188     public:
189         RegisterConfigItemHelper(utl::ConfigManager & rMgr, utl::ConfigItem& rCfgItem)
190         : rCfgMgr(rMgr)
191         , pCfgItem(&rCfgItem)
192         {
193             rCfgMgr.RegisterConfigItem(rCfgItem);
194         }
195 
196         ~RegisterConfigItemHelper()
197         {
198             if (pCfgItem) rCfgMgr.RemoveConfigItem(*pCfgItem);
199         }
200 
201         void keep() { pCfgItem = 0; }
202     };
203 }
204 /* -----------------------------12.12.00 17:19--------------------------------
205 
206  ---------------------------------------------------------------------------*/
207 Reference< XMultiServiceFactory > ConfigManager::GetLocalConfigurationProvider()
208 {
209 	return GetConfigurationProvider();
210 }
211 /* -----------------------------29.08.00 12:35--------------------------------
212 
213  ---------------------------------------------------------------------------*/
214 Reference< XHierarchicalNameAccess > ConfigManager::AddConfigItem(utl::ConfigItem& rCfgItem)
215 {
216     RegisterConfigItemHelper registeredItem(*this,rCfgItem);
217     Reference< XHierarchicalNameAccess > xTree = AcquireTree(rCfgItem);
218     registeredItem.keep();
219     return xTree;
220 }
221 /* -----------------------------21.06.01 12:20--------------------------------
222 
223  ---------------------------------------------------------------------------*/
224 void    ConfigManager::RegisterConfigItem(utl::ConfigItem& rCfgItem)
225 {
226     ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin();
227 #ifdef DBG_UTIL
228 	for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter)
229 	{
230 		ConfigItemListEntry_Impl& rEntry = *aListIter;
231 		if(rEntry.pConfigItem == &rCfgItem)
232             OSL_ENSURE(sal_False, "RegisterConfigItem: already inserted!");
233 	}
234 #endif
235     pMgrImpl->aItemList.insert(aListIter, ConfigItemListEntry_Impl(&rCfgItem));
236 }
237 /* -----------------------------21.06.01 12:20--------------------------------
238 
239  ---------------------------------------------------------------------------*/
240 Reference< XHierarchicalNameAccess> ConfigManager::AcquireTree(utl::ConfigItem& rCfgItem)
241 {
242     ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin();
243 #ifdef DBG_UTIL
244     sal_Bool bFound = sal_False;
245     for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter)
246 	{
247 		ConfigItemListEntry_Impl& rEntry = *aListIter;
248 		if(rEntry.pConfigItem == &rCfgItem)
249         {
250             bFound = sal_True;
251             break;
252         }
253     }
254     OSL_ENSURE(bFound, "AcquireTree: ConfigItem unknown!");
255 #endif
256 	OUString sPath = C2U(cConfigBaseURL);
257 	sPath += rCfgItem.GetSubTreeName();
258     Sequence< Any > aArgs(2);
259     Any* pArgs = aArgs.getArray();
260 	PropertyValue aPath;
261 	aPath.Name = C2U("nodepath");
262 	aPath.Value <<= sPath;
263     pArgs[0] <<= aPath;
264     sal_Bool bLazy = 0 != (rCfgItem.GetMode()&CONFIG_MODE_DELAYED_UPDATE);
265     PropertyValue aUpdate;
266     aUpdate.Name = C2U("lazywrite");
267     aUpdate.Value.setValue(&bLazy, ::getBooleanCppuType());
268     pArgs[1] <<= aUpdate;
269 
270     // Initialize item with support for reading/writing more then one locales at same time!
271 	// It's neccessary for creation of a complete configuration entry without changing office locale
272 	// at runtime.
273     if((rCfgItem.GetMode() & CONFIG_MODE_ALL_LOCALES) == CONFIG_MODE_ALL_LOCALES)
274 	{
275         sal_Int32 nCount = aArgs.getLength();
276         aArgs.realloc(nCount+1);
277 
278         PropertyValue aAllLocale;
279         aAllLocale.Name  =   C2U("locale");
280         aAllLocale.Value <<= C2U("*"     );
281         aArgs[nCount]    <<= aAllLocale;
282 	}
283 
284 	Reference< XMultiServiceFactory > xCfgProvider = GetConfigurationProvider();
285 	Reference< XInterface > xIFace;
286 	if(xCfgProvider.is())
287 	{
288 		try
289 		{
290 			xIFace = xCfgProvider->createInstanceWithArguments(
291 					C2U(cAccessSrvc),
292 					aArgs);
293 		}
294 		catch(Exception& rEx)
295 		{
296             if (CONFIG_MODE_PROPAGATE_ERRORS & rCfgItem.GetMode())
297             {
298                 OSL_TRACE("ConfigItem: Propagating creation error: %s\n",
299                             OUStringToOString(rEx.Message,RTL_TEXTENCODING_ASCII_US).getStr());
300 
301                 throw;
302             }
303 #ifdef DBG_UTIL
304             if(0 == (CONFIG_MODE_IGNORE_ERRORS & rCfgItem.GetMode()))
305             {
306                 OString sMsg("CreateInstance exception: ");
307                 sMsg += OString(rEx.Message.getStr(),
308                             rEx.Message.getLength(),
309                             RTL_TEXTENCODING_ASCII_US);
310                 OSL_ENSURE(sal_False, sMsg.getStr());
311             }
312 #endif
313 		}
314     }
315 	return Reference<XHierarchicalNameAccess>(xIFace, UNO_QUERY);
316 }
317 /* -----------------------------29.08.00 12:35--------------------------------
318 
319  ---------------------------------------------------------------------------*/
320 void ConfigManager::RemoveConfigItem(utl::ConfigItem& rCfgItem)
321 {
322 	if( !pMgrImpl->aItemList.empty() )
323 	{
324 		ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin();
325 		for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter)
326 		{
327 			ConfigItemListEntry_Impl& rEntry = *aListIter;
328 			if(rEntry.pConfigItem == &rCfgItem)
329 			{
330 				pMgrImpl->aItemList.erase(aListIter);
331 				break;
332 			}
333 		}
334 	}
335 }
336 /* -----------------------------30.08.00 15:04--------------------------------
337 
338  ---------------------------------------------------------------------------*/
339 void ConfigManager::StoreConfigItems()
340 {
341 	if(!pMgrImpl->aItemList.empty())
342 	{
343 		ConfigItemList::iterator aListIter = pMgrImpl->aItemList.begin();
344 		for(aListIter = pMgrImpl->aItemList.begin(); aListIter != pMgrImpl->aItemList.end(); ++aListIter)
345 		{
346 			ConfigItemListEntry_Impl& rEntry = *aListIter;
347 			if(rEntry.pConfigItem->IsModified())
348             {
349 				rEntry.pConfigItem->Commit();
350                 rEntry.pConfigItem->ClearModified();
351             }
352 		}
353 	}
354 }
355 ConfigManager*	 ConfigManager::pConfigManager = 0;
356 /* -----------------------------07.09.00 11:06--------------------------------
357 
358  ---------------------------------------------------------------------------*/
359 ConfigManager*	ConfigManager::GetConfigManager()
360 {
361 	if(!pConfigManager)
362 	{
363 		pConfigManager = new ConfigManager();
364 	}
365 	return pConfigManager;
366 }
367 /* -----------------------------07.09.00 11:06--------------------------------
368 
369  ---------------------------------------------------------------------------*/
370 void	ConfigManager::RemoveConfigManager()
371 {
372 	if(pConfigManager)
373 	{
374 		delete pConfigManager;
375 		pConfigManager = 0;
376 	}
377 }
378 /* -----------------------------08.09.00 13:22--------------------------------
379 
380  ---------------------------------------------------------------------------*/
381 rtl::OUString ConfigManager::GetConfigBaseURL()
382 {
383 	return C2U(cConfigBaseURL);
384 }
385 /* -----------------------------25.09.00 16:34--------------------------------
386 
387  ---------------------------------------------------------------------------*/
388 Any ConfigManager::GetDirectConfigProperty(ConfigProperty eProp)
389 {
390     switch(eProp)
391     {
392         case INSTALLPATH:
393             OSL_ENSURE( false,
394                         "ConfigManager::GetDirectConfigProperty: "
395                         "INSTALLPATH no longer supported." );
396             return Any();
397         case USERINSTALLURL:
398             OSL_ENSURE( false,
399                         "ConfigManager::GetDirectConfigProperty: "
400                         "USERINSTALLURL no longer supported." );
401             return Any();
402         case OFFICEINSTALL:
403             OSL_ENSURE( false,
404                         "ConfigManager::GetDirectConfigProperty: "
405                         "OFFICEINSTALL no longer supported." );
406             return Any();
407         case OFFICEINSTALLURL:
408             OSL_ENSURE( false,
409                         "ConfigManager::GetDirectConfigProperty: "
410                         "OFFICEINSTALLURL no longer supported." );
411             return Any();
412         default:
413             break;
414     }
415 
416     Any aRet;
417     ::rtl::OUString &rBrandName = BrandName::get();
418     if ( eProp == PRODUCTNAME && rBrandName.getLength() )
419     {
420         aRet <<= rBrandName;
421         return aRet;
422     }
423 
424     rtl::OUString &rProductVersion = ProductVersion::get();
425     if ( eProp == PRODUCTVERSION && rProductVersion.getLength() )
426     {
427         aRet <<= rProductVersion;
428         return aRet;
429     }
430 
431     rtl::OUString &rAboutBoxProductVersion = AboutBoxProductVersion::get();
432     if ( eProp == ABOUTBOXPRODUCTVERSION && rAboutBoxProductVersion.getLength() )
433     {
434         aRet <<= rAboutBoxProductVersion;
435         return aRet;
436     }
437 
438     rtl::OUString &rOOOVendor = OOOVendor::get();
439     if ( eProp == OOOVENDOR && rOOOVendor.getLength() )
440     {
441         aRet <<= rOOOVendor;
442         return aRet;
443     }
444 
445 
446     rtl::OUString &rProductExtension = ProductExtension::get();
447     if ( eProp == PRODUCTEXTENSION && rProductExtension.getLength() )
448     {
449         aRet <<= rProductExtension;
450         return aRet;
451     }
452 
453     rtl::OUString &rXMLFileFormatName = XMLFileFormatName::get();
454     if ( eProp == PRODUCTXMLFILEFORMATNAME && rXMLFileFormatName.getLength() )
455     {
456         aRet <<= rXMLFileFormatName;
457         return aRet;
458     }
459 
460     rtl::OUString &rXMLFileFormatVersion = XMLFileFormatVersion::get();
461     if ( eProp == PRODUCTXMLFILEFORMATVERSION && rXMLFileFormatVersion.getLength() )
462     {
463         aRet <<= rXMLFileFormatVersion;
464         return aRet;
465     }
466 
467     sal_Int32 &rOpenSourceContext = OpenSourceContext::get();
468     if ( eProp == OPENSOURCECONTEXT && ( rOpenSourceContext >= 0 ) )
469     {
470         aRet <<= rOpenSourceContext;
471         return aRet;
472     }
473 
474     rtl::OUString &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
475     if ( eProp == WRITERCOMPATIBILITYVERSIONOOO11 && rWriterCompatibilityVersionOOo11.getLength() )
476     {
477         aRet <<= rWriterCompatibilityVersionOOo11;
478         return aRet;
479     }
480 
481     if (eProp == PRODUCTEXTENSION) {
482         rtl::OUString name(
483             rtl::OUString(
484                 RTL_CONSTASCII_USTRINGPARAM(
485                     "${BRAND_BASE_DIR}/program/edition/edition.ini")));
486         rtl::Bootstrap::expandMacros(name);
487         if (rtl::Bootstrap(name).getFrom(
488                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EDITIONNAME")),
489                 rProductExtension))
490         {
491             return com::sun::star::uno::Any(rProductExtension);
492         }
493     }
494 
495 	OUString sPath = C2U(cConfigBaseURL);
496 	switch(eProp)
497 	{
498 		case LOCALE:						sPath += C2U("Setup/L10N"); break;
499 
500         case PRODUCTNAME:
501         case PRODUCTVERSION:
502         case PRODUCTEXTENSION:
503         case PRODUCTXMLFILEFORMATNAME :
504 		case PRODUCTXMLFILEFORMATVERSION:
505         case OPENSOURCECONTEXT:
506         case OOOVENDOR:
507         case ABOUTBOXPRODUCTVERSION:        sPath += C2U("Setup/Product"); break;
508 
509 		case DEFAULTCURRENCY:				sPath += C2U("Setup/L10N"); break;
510 
511 		case WRITERCOMPATIBILITYVERSIONOOO11:
512 			sPath += C2U("Office.Compatibility/WriterCompatibilityVersion"); break;
513         default:
514             break;
515 	}
516 	Sequence< Any > aArgs(1);
517 	aArgs[0] <<= sPath;
518 	Reference< XMultiServiceFactory > xCfgProvider = GetConfigManager()->GetConfigurationProvider();
519 	if(!xCfgProvider.is())
520 		return aRet;
521 	Reference< XInterface > xIFace;
522 	try
523 	{
524 		xIFace = xCfgProvider->createInstanceWithArguments(
525 				C2U(cAccessSrvc),
526 				aArgs);
527 
528 	}
529 	catch(Exception&){}
530 	Reference<XNameAccess> xDirectAccess(xIFace, UNO_QUERY);
531 	if(xDirectAccess.is())
532 	{
533 		OUString sProperty;
534 		switch(eProp)
535 		{
536 			case LOCALE:							sProperty = C2U("ooLocale"); break;
537             case PRODUCTNAME:						sProperty = C2U("ooName"); break;
538             case PRODUCTVERSION:					sProperty = C2U("ooSetupVersion"); break;
539             case ABOUTBOXPRODUCTVERSION: 			sProperty = C2U("ooSetupVersionAboutBox"); break;
540             case OOOVENDOR:                         sProperty = C2U("ooVendor"); break;
541             case PRODUCTEXTENSION:					sProperty = C2U("ooSetupExtension"); break;
542             case PRODUCTXMLFILEFORMATNAME:          sProperty = C2U("ooXMLFileFormatName"); break;
543             case PRODUCTXMLFILEFORMATVERSION:       sProperty = C2U("ooXMLFileFormatVersion"); break;
544             case OPENSOURCECONTEXT:                 sProperty = C2U("ooOpenSourceContext"); break;
545             case DEFAULTCURRENCY:                   sProperty = C2U("ooSetupCurrency"); break;
546 			case WRITERCOMPATIBILITYVERSIONOOO11:	sProperty = C2U("OOo11"); break;
547             default:
548                 break;
549 		}
550 		try
551 		{
552 			aRet = xDirectAccess->getByName(sProperty);
553 		}
554 		catch(Exception&)
555 		{
556             #if OSL_DEBUG_LEVEL > 0
557             rtl::OStringBuffer aBuf(256);
558             aBuf.append( "ConfigManager::GetDirectConfigProperty: could not retrieve the property \"" );
559             aBuf.append( rtl::OUStringToOString( sProperty, RTL_TEXTENCODING_ASCII_US ) );
560             aBuf.append( "\" under \"" );
561             aBuf.append( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_ASCII_US ) );
562             aBuf.append( "\" (caught an exception)!" );
563 			OSL_ENSURE( sal_False, aBuf.getStr() );
564             #endif
565 		}
566 	}
567 
568     if ( eProp == PRODUCTNAME )
569         aRet >>= rBrandName;
570 
571     if ( eProp == PRODUCTXMLFILEFORMATNAME )
572         aRet >>= rXMLFileFormatName;
573 
574     if ( eProp == PRODUCTXMLFILEFORMATVERSION )
575         aRet >>= rXMLFileFormatVersion;
576 
577     if ( eProp == PRODUCTVERSION )
578         aRet >>= rProductVersion;
579 
580     if( eProp == OOOVENDOR )
581         aRet >>= rOOOVendor;
582 
583     if ( eProp == ABOUTBOXPRODUCTVERSION )
584     {
585         aRet >>= rAboutBoxProductVersion;
586         getBasisAboutBoxProductVersion( rAboutBoxProductVersion );
587         aRet <<= rAboutBoxProductVersion;
588     }
589 
590     if ( eProp == PRODUCTEXTENSION )
591         aRet >>= rProductExtension;
592 
593     if ( eProp == WRITERCOMPATIBILITYVERSIONOOO11 )
594         aRet >>= rWriterCompatibilityVersionOOo11;
595 
596     if ( eProp == OPENSOURCECONTEXT )
597         aRet >>= rOpenSourceContext;
598 
599 	return aRet;
600 }
601 
602 /*---------------------------------------------------------------------------*/
603 void ConfigManager::getBasisAboutBoxProductVersion( OUString& rVersion )
604 {
605     rtl::OUString aPackageVersion = UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":OOOPackageVersion}" );
606     rtl::Bootstrap::expandMacros( aPackageVersion );
607 
608     if ( aPackageVersion.getLength() )
609     {
610         sal_Int32 nTokIndex = 0;
611         rtl::OUString aVersionMinor = aPackageVersion.getToken( 1, '.', nTokIndex );
612         rtl::OUString aVersionMicro;
613 
614         if ( nTokIndex > 0 )
615             aVersionMicro = aPackageVersion.getToken( 0, '.', nTokIndex );
616 
617         if ( aVersionMinor.getLength() == 0 )
618             aVersionMinor = UNISTRING( "0" );
619         if ( aVersionMicro.getLength() == 0 )
620             aVersionMicro = UNISTRING( "0" );
621 
622         sal_Int32 nIndex = rVersion.indexOf( '.' );
623         if ( nIndex == -1 )
624         {
625             rVersion += UNISTRING( "." );
626             rVersion += aVersionMinor;
627         }
628         else
629         {
630             nIndex = rVersion.indexOf( '.', nIndex+1 );
631         }
632         if ( nIndex == -1 )
633         {
634             rVersion += UNISTRING( "." );
635             rVersion += aVersionMicro;
636         }
637         else
638         {
639             rVersion = rVersion.replaceAt( nIndex+1, rVersion.getLength()-nIndex-1, aVersionMicro );
640         }
641     }
642 }
643 
644 /* -----------------------------12.12.00 17:22--------------------------------
645 
646  ---------------------------------------------------------------------------*/
647 Reference< XHierarchicalNameAccess> ConfigManager::GetHierarchyAccess(const OUString& rFullPath)
648 {
649 	Sequence< Any > aArgs(1);
650 	aArgs[0] <<= rFullPath;
651 	Reference< XMultiServiceFactory > xCfgProvider = GetLocalConfigurationProvider();
652 	Reference< XInterface > xIFace;
653 	if(xCfgProvider.is())
654 	{
655 		try
656 		{
657 			xIFace = xCfgProvider->createInstanceWithArguments(
658 					C2U(cAccessSrvc),
659 					aArgs);
660 		}
661 #ifdef DBG_UTIL
662 		catch(Exception& rEx)
663 		{
664 			OString sMsg("CreateInstance exception: ");
665 			sMsg += OString(rEx.Message.getStr(),
666 						rEx.Message.getLength(),
667 				 		RTL_TEXTENCODING_ASCII_US);
668 			OSL_ENSURE(sal_False, sMsg.getStr());
669 		}
670 #else
671 		catch(Exception&){}
672 #endif
673 	}
674 	return Reference<XHierarchicalNameAccess>(xIFace, UNO_QUERY);
675 }
676 /* -----------------------------12.12.00 17:17--------------------------------
677 
678  ---------------------------------------------------------------------------*/
679 Any ConfigManager::GetLocalProperty(const OUString& rProperty)
680 {
681 	OUString sPath = C2U(cConfigBaseURL);
682 	sPath += rProperty;
683 
684 	OUString sNode, sProperty;
685     OSL_VERIFY( splitLastFromConfigurationPath(sPath, sNode, sProperty) );
686 
687 	Reference< XNameAccess> xAccess( GetHierarchyAccess(sNode), UNO_QUERY );
688 	Any aRet;
689 	try
690 	{
691 		if(xAccess.is())
692 			aRet = xAccess->getByName(sProperty);
693 	}
694 #ifdef DBG_UTIL
695 	catch(Exception& rEx)
696 	{
697 		OString sMsg("GetLocalProperty: ");
698 		sMsg += OString(rEx.Message.getStr(),
699 					rEx.Message.getLength(),
700 				 	RTL_TEXTENCODING_ASCII_US);
701 		OSL_ENSURE(sal_False, sMsg.getStr());
702 	}
703 #else
704 	catch(Exception&){}
705 #endif
706 	return aRet;
707 }
708 /* -----------------------------12.12.00 17:17--------------------------------
709 
710  ---------------------------------------------------------------------------*/
711 void ConfigManager::PutLocalProperty(const OUString& rProperty, const Any& rValue)
712 {
713 	OUString sPath = C2U(cConfigBaseURL);
714 	sPath += rProperty;
715 
716 	OUString sNode, sProperty;
717     OSL_VERIFY( splitLastFromConfigurationPath(sPath, sNode, sProperty) );
718 
719 	Reference<XNameReplace> xNodeReplace(GetHierarchyAccess(sNode), UNO_QUERY);
720 	if(xNodeReplace.is())
721 	{
722 		try
723 		{
724 			xNodeReplace->replaceByName(sProperty, rValue);
725 		}
726 #ifdef DBG_UTIL
727 		catch(Exception& rEx)
728 		{
729 			OString sMsg("PutLocalProperty: ");
730 			sMsg += OString(rEx.Message.getStr(),
731 						rEx.Message.getLength(),
732 				 		RTL_TEXTENCODING_ASCII_US);
733 			OSL_ENSURE(sal_False, sMsg.getStr());
734 		}
735 #else
736 		catch(Exception& ){}
737 #endif
738 	}
739 }
740 /* -----------------------------13.12.00 08:47--------------------------------
741 
742  ---------------------------------------------------------------------------*/
743 sal_Bool	ConfigManager::IsLocalConfigProvider()
744 {
745 	return false;
746 }
747 
748