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 /* -----------------------------07.09.00 11:06--------------------------------
352 
353  ---------------------------------------------------------------------------*/
354 struct theConfigManager : public rtl::Static<ConfigManager, theConfigManager> {};
355 
356 ConfigManager* ConfigManager::GetConfigManager()
357 {
358     return &theConfigManager::get();
359 }
360 /* -----------------------------08.09.00 13:22--------------------------------
361 
362  ---------------------------------------------------------------------------*/
363 rtl::OUString ConfigManager::GetConfigBaseURL()
364 {
365 	return C2U(cConfigBaseURL);
366 }
367 /* -----------------------------25.09.00 16:34--------------------------------
368 
369  ---------------------------------------------------------------------------*/
370 Any ConfigManager::GetDirectConfigProperty(ConfigProperty eProp)
371 {
372     switch(eProp)
373     {
374         case INSTALLPATH:
375             OSL_ENSURE( false,
376                         "ConfigManager::GetDirectConfigProperty: "
377                         "INSTALLPATH no longer supported." );
378             return Any();
379         case USERINSTALLURL:
380             OSL_ENSURE( false,
381                         "ConfigManager::GetDirectConfigProperty: "
382                         "USERINSTALLURL no longer supported." );
383             return Any();
384         case OFFICEINSTALL:
385             OSL_ENSURE( false,
386                         "ConfigManager::GetDirectConfigProperty: "
387                         "OFFICEINSTALL no longer supported." );
388             return Any();
389         case OFFICEINSTALLURL:
390             OSL_ENSURE( false,
391                         "ConfigManager::GetDirectConfigProperty: "
392                         "OFFICEINSTALLURL no longer supported." );
393             return Any();
394         default:
395             break;
396     }
397 
398     Any aRet;
399     ::rtl::OUString &rBrandName = BrandName::get();
400     if ( eProp == PRODUCTNAME && rBrandName.getLength() )
401     {
402         aRet <<= rBrandName;
403         return aRet;
404     }
405 
406     rtl::OUString &rProductVersion = ProductVersion::get();
407     if ( eProp == PRODUCTVERSION && rProductVersion.getLength() )
408     {
409         aRet <<= rProductVersion;
410         return aRet;
411     }
412 
413     rtl::OUString &rAboutBoxProductVersion = AboutBoxProductVersion::get();
414     if ( eProp == ABOUTBOXPRODUCTVERSION && rAboutBoxProductVersion.getLength() )
415     {
416         aRet <<= rAboutBoxProductVersion;
417         return aRet;
418     }
419 
420     rtl::OUString &rOOOVendor = OOOVendor::get();
421     if ( eProp == OOOVENDOR && rOOOVendor.getLength() )
422     {
423         aRet <<= rOOOVendor;
424         return aRet;
425     }
426 
427 
428     rtl::OUString &rProductExtension = ProductExtension::get();
429     if ( eProp == PRODUCTEXTENSION && rProductExtension.getLength() )
430     {
431         aRet <<= rProductExtension;
432         return aRet;
433     }
434 
435     rtl::OUString &rXMLFileFormatName = XMLFileFormatName::get();
436     if ( eProp == PRODUCTXMLFILEFORMATNAME && rXMLFileFormatName.getLength() )
437     {
438         aRet <<= rXMLFileFormatName;
439         return aRet;
440     }
441 
442     rtl::OUString &rXMLFileFormatVersion = XMLFileFormatVersion::get();
443     if ( eProp == PRODUCTXMLFILEFORMATVERSION && rXMLFileFormatVersion.getLength() )
444     {
445         aRet <<= rXMLFileFormatVersion;
446         return aRet;
447     }
448 
449     sal_Int32 &rOpenSourceContext = OpenSourceContext::get();
450     if ( eProp == OPENSOURCECONTEXT && ( rOpenSourceContext >= 0 ) )
451     {
452         aRet <<= rOpenSourceContext;
453         return aRet;
454     }
455 
456     rtl::OUString &rWriterCompatibilityVersionOOo11 = WriterCompatibilityVersionOOo11::get();
457     if ( eProp == WRITERCOMPATIBILITYVERSIONOOO11 && rWriterCompatibilityVersionOOo11.getLength() )
458     {
459         aRet <<= rWriterCompatibilityVersionOOo11;
460         return aRet;
461     }
462 
463     if (eProp == PRODUCTEXTENSION) {
464         rtl::OUString name(
465             rtl::OUString(
466                 RTL_CONSTASCII_USTRINGPARAM(
467                     "${BRAND_BASE_DIR}/program/edition/edition.ini")));
468         rtl::Bootstrap::expandMacros(name);
469         if (rtl::Bootstrap(name).getFrom(
470                 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EDITIONNAME")),
471                 rProductExtension))
472         {
473             return com::sun::star::uno::Any(rProductExtension);
474         }
475     }
476 
477 	OUString sPath = C2U(cConfigBaseURL);
478 	switch(eProp)
479 	{
480 		case LOCALE:						sPath += C2U("Setup/L10N"); break;
481 
482         case PRODUCTNAME:
483         case PRODUCTVERSION:
484         case PRODUCTEXTENSION:
485         case PRODUCTXMLFILEFORMATNAME :
486 		case PRODUCTXMLFILEFORMATVERSION:
487         case OPENSOURCECONTEXT:
488         case OOOVENDOR:
489         case ABOUTBOXPRODUCTVERSION:        sPath += C2U("Setup/Product"); break;
490 
491 		case DEFAULTCURRENCY:				sPath += C2U("Setup/L10N"); break;
492 
493 		case WRITERCOMPATIBILITYVERSIONOOO11:
494 			sPath += C2U("Office.Compatibility/WriterCompatibilityVersion"); break;
495         default:
496             break;
497 	}
498 	Sequence< Any > aArgs(1);
499 	aArgs[0] <<= sPath;
500 	Reference< XMultiServiceFactory > xCfgProvider = GetConfigManager()->GetConfigurationProvider();
501 	if(!xCfgProvider.is())
502 		return aRet;
503 	Reference< XInterface > xIFace;
504 	try
505 	{
506 		xIFace = xCfgProvider->createInstanceWithArguments(
507 				C2U(cAccessSrvc),
508 				aArgs);
509 
510 	}
511 	catch(Exception&){}
512 	Reference<XNameAccess> xDirectAccess(xIFace, UNO_QUERY);
513 	if(xDirectAccess.is())
514 	{
515 		OUString sProperty;
516 		switch(eProp)
517 		{
518 			case LOCALE:							sProperty = C2U("ooLocale"); break;
519             case PRODUCTNAME:						sProperty = C2U("ooName"); break;
520             case PRODUCTVERSION:					sProperty = C2U("ooSetupVersion"); break;
521             case ABOUTBOXPRODUCTVERSION: 			sProperty = C2U("ooSetupVersionAboutBox"); break;
522             case OOOVENDOR:                         sProperty = C2U("ooVendor"); break;
523             case PRODUCTEXTENSION:					sProperty = C2U("ooSetupExtension"); break;
524             case PRODUCTXMLFILEFORMATNAME:          sProperty = C2U("ooXMLFileFormatName"); break;
525             case PRODUCTXMLFILEFORMATVERSION:       sProperty = C2U("ooXMLFileFormatVersion"); break;
526             case OPENSOURCECONTEXT:                 sProperty = C2U("ooOpenSourceContext"); break;
527             case DEFAULTCURRENCY:                   sProperty = C2U("ooSetupCurrency"); break;
528 			case WRITERCOMPATIBILITYVERSIONOOO11:	sProperty = C2U("OOo11"); break;
529             default:
530                 break;
531 		}
532 		try
533 		{
534 			aRet = xDirectAccess->getByName(sProperty);
535 		}
536 		catch(Exception&)
537 		{
538             #if OSL_DEBUG_LEVEL > 0
539             rtl::OStringBuffer aBuf(256);
540             aBuf.append( "ConfigManager::GetDirectConfigProperty: could not retrieve the property \"" );
541             aBuf.append( rtl::OUStringToOString( sProperty, RTL_TEXTENCODING_ASCII_US ) );
542             aBuf.append( "\" under \"" );
543             aBuf.append( rtl::OUStringToOString( sPath, RTL_TEXTENCODING_ASCII_US ) );
544             aBuf.append( "\" (caught an exception)!" );
545 			OSL_ENSURE( sal_False, aBuf.getStr() );
546             #endif
547 		}
548 	}
549 
550     if ( eProp == PRODUCTNAME )
551         aRet >>= rBrandName;
552 
553     if ( eProp == PRODUCTXMLFILEFORMATNAME )
554         aRet >>= rXMLFileFormatName;
555 
556     if ( eProp == PRODUCTXMLFILEFORMATVERSION )
557         aRet >>= rXMLFileFormatVersion;
558 
559     if ( eProp == PRODUCTVERSION )
560         aRet >>= rProductVersion;
561 
562     if( eProp == OOOVENDOR )
563         aRet >>= rOOOVendor;
564 
565     if ( eProp == ABOUTBOXPRODUCTVERSION )
566     {
567         aRet >>= rAboutBoxProductVersion;
568         getBasisAboutBoxProductVersion( rAboutBoxProductVersion );
569         aRet <<= rAboutBoxProductVersion;
570     }
571 
572     if ( eProp == PRODUCTEXTENSION )
573         aRet >>= rProductExtension;
574 
575     if ( eProp == WRITERCOMPATIBILITYVERSIONOOO11 )
576         aRet >>= rWriterCompatibilityVersionOOo11;
577 
578     if ( eProp == OPENSOURCECONTEXT )
579         aRet >>= rOpenSourceContext;
580 
581 	return aRet;
582 }
583 
584 /*---------------------------------------------------------------------------*/
585 void ConfigManager::getBasisAboutBoxProductVersion( OUString& rVersion )
586 {
587     rtl::OUString aPackageVersion = UNISTRING( "${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":OOOPackageVersion}" );
588     rtl::Bootstrap::expandMacros( aPackageVersion );
589 
590     if ( aPackageVersion.getLength() )
591     {
592         sal_Int32 nTokIndex = 0;
593         rtl::OUString aVersionMinor = aPackageVersion.getToken( 1, '.', nTokIndex );
594         rtl::OUString aVersionMicro;
595 
596         if ( nTokIndex > 0 )
597             aVersionMicro = aPackageVersion.getToken( 0, '.', nTokIndex );
598 
599         if ( aVersionMinor.getLength() == 0 )
600             aVersionMinor = UNISTRING( "0" );
601         if ( aVersionMicro.getLength() == 0 )
602             aVersionMicro = UNISTRING( "0" );
603 
604         sal_Int32 nIndex = rVersion.indexOf( '.' );
605         if ( nIndex == -1 )
606         {
607             rVersion += UNISTRING( "." );
608             rVersion += aVersionMinor;
609         }
610         else
611         {
612             nIndex = rVersion.indexOf( '.', nIndex+1 );
613         }
614         if ( nIndex == -1 )
615         {
616             rVersion += UNISTRING( "." );
617             rVersion += aVersionMicro;
618         }
619         else
620         {
621             rVersion = rVersion.replaceAt( nIndex+1, rVersion.getLength()-nIndex-1, aVersionMicro );
622         }
623     }
624 }
625 
626 /* -----------------------------12.12.00 17:22--------------------------------
627 
628  ---------------------------------------------------------------------------*/
629 Reference< XHierarchicalNameAccess> ConfigManager::GetHierarchyAccess(const OUString& rFullPath)
630 {
631 	Sequence< Any > aArgs(1);
632 	aArgs[0] <<= rFullPath;
633 	Reference< XMultiServiceFactory > xCfgProvider = GetLocalConfigurationProvider();
634 	Reference< XInterface > xIFace;
635 	if(xCfgProvider.is())
636 	{
637 		try
638 		{
639 			xIFace = xCfgProvider->createInstanceWithArguments(
640 					C2U(cAccessSrvc),
641 					aArgs);
642 		}
643 #ifdef DBG_UTIL
644 		catch(Exception& rEx)
645 		{
646 			OString sMsg("CreateInstance exception: ");
647 			sMsg += OString(rEx.Message.getStr(),
648 						rEx.Message.getLength(),
649 				 		RTL_TEXTENCODING_ASCII_US);
650 			OSL_ENSURE(sal_False, sMsg.getStr());
651 		}
652 #else
653 		catch(Exception&){}
654 #endif
655 	}
656 	return Reference<XHierarchicalNameAccess>(xIFace, UNO_QUERY);
657 }
658 /* -----------------------------12.12.00 17:17--------------------------------
659 
660  ---------------------------------------------------------------------------*/
661 Any ConfigManager::GetLocalProperty(const OUString& rProperty)
662 {
663 	OUString sPath = C2U(cConfigBaseURL);
664 	sPath += rProperty;
665 
666 	OUString sNode, sProperty;
667     OSL_VERIFY( splitLastFromConfigurationPath(sPath, sNode, sProperty) );
668 
669 	Reference< XNameAccess> xAccess( GetHierarchyAccess(sNode), UNO_QUERY );
670 	Any aRet;
671 	try
672 	{
673 		if(xAccess.is())
674 			aRet = xAccess->getByName(sProperty);
675 	}
676 #ifdef DBG_UTIL
677 	catch(Exception& rEx)
678 	{
679 		OString sMsg("GetLocalProperty: ");
680 		sMsg += OString(rEx.Message.getStr(),
681 					rEx.Message.getLength(),
682 				 	RTL_TEXTENCODING_ASCII_US);
683 		OSL_ENSURE(sal_False, sMsg.getStr());
684 	}
685 #else
686 	catch(Exception&){}
687 #endif
688 	return aRet;
689 }
690 /* -----------------------------12.12.00 17:17--------------------------------
691 
692  ---------------------------------------------------------------------------*/
693 void ConfigManager::PutLocalProperty(const OUString& rProperty, const Any& rValue)
694 {
695 	OUString sPath = C2U(cConfigBaseURL);
696 	sPath += rProperty;
697 
698 	OUString sNode, sProperty;
699     OSL_VERIFY( splitLastFromConfigurationPath(sPath, sNode, sProperty) );
700 
701 	Reference<XNameReplace> xNodeReplace(GetHierarchyAccess(sNode), UNO_QUERY);
702 	if(xNodeReplace.is())
703 	{
704 		try
705 		{
706 			xNodeReplace->replaceByName(sProperty, rValue);
707 		}
708 #ifdef DBG_UTIL
709 		catch(Exception& rEx)
710 		{
711 			OString sMsg("PutLocalProperty: ");
712 			sMsg += OString(rEx.Message.getStr(),
713 						rEx.Message.getLength(),
714 				 		RTL_TEXTENCODING_ASCII_US);
715 			OSL_ENSURE(sal_False, sMsg.getStr());
716 		}
717 #else
718 		catch(Exception& ){}
719 #endif
720 	}
721 }
722 /* -----------------------------13.12.00 08:47--------------------------------
723 
724  ---------------------------------------------------------------------------*/
725 sal_Bool	ConfigManager::IsLocalConfigProvider()
726 {
727 	return false;
728 }
729 
730