xref: /trunk/main/unotools/source/config/configmgr.cxx (revision 2d7884914f8f9b4a298efe36f7357992ec4c096c)
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