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