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