1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_stoc.hxx"
30 #include <osl/mutex.hxx>
31 #ifndef _OSL_DIAGNOSE_HXX_
32 #include <osl/diagnose.h>
33 #endif
34 #include <cppuhelper/queryinterface.hxx>
35 #include <cppuhelper/weak.hxx>
36 #include <cppuhelper/factory.hxx>
37 #include <cppuhelper/implbase1.hxx>
38 #include <cppuhelper/implbase4.hxx>
39 #include <cppuhelper/implbase3.hxx>
40 #ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
41 #include <cppuhelper/implementationentry.hxx>
42 #endif
43 #include <registry/registry.hxx>
44 
45 #include <com/sun/star/registry/XSimpleRegistry.hpp>
46 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
47 #include <com/sun/star/lang/XServiceInfo.hpp>
48 #include <com/sun/star/lang/XTypeProvider.hpp>
49 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
50 #include <com/sun/star/lang/XInitialization.hpp>
51 #include <com/sun/star/container/XEnumerationAccess.hpp>
52 
53 #include <bootstrapservices.hxx>
54 
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::registry;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::container;
59 using namespace cppu;
60 using namespace osl;
61 using namespace rtl;
62 
63 
64 #define SERVICENAME "com.sun.star.registry.NestedRegistry"
65 #define IMPLNAME	   "com.sun.star.comp.stoc.NestedRegistry"
66 
67 extern rtl_StandardModuleCount g_moduleCount;
68 
69 namespace stoc_bootstrap
70 {
71 Sequence< OUString > defreg_getSupportedServiceNames()
72 {
73 	static Sequence < OUString > *pNames = 0;
74 	if( ! pNames )
75 	{
76 		MutexGuard guard( Mutex::getGlobalMutex() );
77 		if( !pNames )
78 		{
79 			static Sequence< OUString > seqNames(1);
80 			seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
81 			pNames = &seqNames;
82 		}
83 	}
84 	return *pNames;
85 }
86 
87 OUString defreg_getImplementationName()
88 {
89 	static OUString *pImplName = 0;
90 	if( ! pImplName )
91 	{
92 		MutexGuard guard( Mutex::getGlobalMutex() );
93 		if( ! pImplName )
94 		{
95 			static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
96 			pImplName = &implName;
97 		}
98 	}
99 	return *pImplName;
100 }
101 }
102 
103 namespace stoc_defreg
104 {
105 //*************************************************************************
106 // NestedRegistryImpl
107 //*************************************************************************
108 class NestedKeyImpl;
109 
110 class NestedRegistryImpl	: public WeakAggImplHelper4 < XSimpleRegistry, XInitialization, XServiceInfo, XEnumerationAccess >
111 {
112 public:
113 	NestedRegistryImpl( );
114 
115 	~NestedRegistryImpl();
116 
117     // XServiceInfo
118     virtual OUString SAL_CALL getImplementationName(  ) throw(RuntimeException);
119     virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
120     virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(  ) throw(RuntimeException);
121 
122 	// XInitialization
123     virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
124 		throw(Exception, RuntimeException);
125 
126 	// XSimpleRegistry
127     virtual OUString SAL_CALL getURL() throw(RuntimeException);
128     virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) throw(InvalidRegistryException, RuntimeException);
129     virtual sal_Bool SAL_CALL isValid(  ) throw(RuntimeException);
130     virtual void SAL_CALL close(  ) throw(InvalidRegistryException, RuntimeException);
131     virtual void SAL_CALL destroy(  ) throw(InvalidRegistryException, RuntimeException);
132     virtual Reference< XRegistryKey > SAL_CALL getRootKey(  ) throw(InvalidRegistryException, RuntimeException);
133     virtual sal_Bool SAL_CALL isReadOnly(  ) throw(InvalidRegistryException, RuntimeException);
134     virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) throw(InvalidRegistryException, MergeConflictException, RuntimeException);
135 
136     // XEnumerationAccess
137     virtual Reference< XEnumeration > SAL_CALL createEnumeration(  ) throw (RuntimeException);
138     virtual Type SAL_CALL getElementType(  ) throw (RuntimeException);
139     virtual sal_Bool SAL_CALL hasElements(  ) throw (RuntimeException);
140 
141 	friend class NestedKeyImpl;
142 protected:
143 	Mutex						m_mutex;
144 	sal_uInt32					m_state;
145 	Reference<XSimpleRegistry>	m_localReg;
146 	Reference<XSimpleRegistry>	m_defaultReg;
147 
148 };
149 
150 //*************************************************************************
151 // class NestedKeyImpl the implenetation of interface XRegistryKey
152 //*************************************************************************
153 class NestedKeyImpl : public WeakImplHelper1< XRegistryKey >
154 {
155 public:
156 	NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
157 				   Reference<XRegistryKey>& localKey,
158 				   Reference<XRegistryKey>& defaultKey);
159 
160 	NestedKeyImpl( const OUString& aKeyName,
161 					NestedKeyImpl* pKey);
162 
163 	~NestedKeyImpl();
164 
165 	// XRegistryKey
166     virtual OUString SAL_CALL getKeyName() throw(RuntimeException);
167     virtual sal_Bool SAL_CALL isReadOnly(  ) throw(InvalidRegistryException, RuntimeException);
168     virtual sal_Bool SAL_CALL isValid(  ) throw(RuntimeException);
169     virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException);
170     virtual RegistryValueType SAL_CALL getValueType(  ) throw(InvalidRegistryException, RuntimeException);
171     virtual sal_Int32 SAL_CALL getLongValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
172     virtual void SAL_CALL setLongValue( sal_Int32 value ) throw(InvalidRegistryException, RuntimeException);
173     virtual Sequence< sal_Int32 > SAL_CALL getLongListValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
174     virtual void SAL_CALL setLongListValue( const ::com::sun::star::uno::Sequence< sal_Int32 >& seqValue ) throw(InvalidRegistryException, RuntimeException);
175     virtual OUString SAL_CALL getAsciiValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
176     virtual void SAL_CALL setAsciiValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException);
177     virtual Sequence< OUString > SAL_CALL getAsciiListValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
178     virtual void SAL_CALL setAsciiListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException);
179     virtual OUString SAL_CALL getStringValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
180     virtual void SAL_CALL setStringValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException);
181     virtual Sequence< OUString > SAL_CALL getStringListValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
182     virtual void SAL_CALL setStringListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException);
183     virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue(  ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
184     virtual void SAL_CALL setBinaryValue( const ::com::sun::star::uno::Sequence< sal_Int8 >& value ) throw(InvalidRegistryException, RuntimeException);
185     virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
186     virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
187     virtual void SAL_CALL closeKey(  ) throw(InvalidRegistryException, RuntimeException);
188     virtual void SAL_CALL deleteKey( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException);
189     virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys(  ) throw(InvalidRegistryException, RuntimeException);
190     virtual Sequence< OUString > SAL_CALL getKeyNames(  ) throw(InvalidRegistryException, RuntimeException);
191     virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) throw(InvalidRegistryException, RuntimeException);
192     virtual void SAL_CALL deleteLink( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException);
193     virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException);
194     virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
195 
196 protected:
197 	void 		computeChanges();
198 	OUString 	computeName(const OUString& name);
199 
200 	OUString 					m_name;
201 	sal_uInt32					m_state;
202 	NestedRegistryImpl*			m_pRegistry;
203 	Reference<XRegistryKey>	  	m_localKey;
204 	Reference<XRegistryKey>	  	m_defaultKey;
205 };
206 
207 
208 //*************************************************************************
209 NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
210 							  Reference<XRegistryKey>& localKey,
211 							  Reference<XRegistryKey>& defaultKey )
212 	: m_pRegistry(pDefaultRegistry)
213 {
214 	m_pRegistry->acquire();
215 
216 	m_localKey = localKey;
217 	m_defaultKey = defaultKey;
218 
219 	if (m_localKey.is())
220 	{
221 		m_name = m_localKey->getKeyName();
222 	} else
223 	if (m_defaultKey.is())
224 	{
225 		m_name = m_defaultKey->getKeyName();
226 	}
227 
228 	m_state = m_pRegistry->m_state;
229 }
230 
231 //*************************************************************************
232 NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName,
233 							  NestedKeyImpl* pKey)
234 	: m_pRegistry(pKey->m_pRegistry)
235 {
236 	m_pRegistry->acquire();
237 
238 	if (pKey->m_localKey.is() && pKey->m_localKey->isValid())
239 	{
240 		m_localKey = pKey->m_localKey->openKey(rKeyName);
241 	}
242 	if (pKey->m_defaultKey.is() && pKey->m_defaultKey->isValid())
243 	{
244 		m_defaultKey = pKey->m_defaultKey->openKey(rKeyName);
245 	}
246 
247 	if (m_localKey.is())
248 	{
249 		m_name = m_localKey->getKeyName();
250 	} else
251 	if (m_defaultKey.is())
252 	{
253 		m_name = m_defaultKey->getKeyName();
254 	}
255 
256 	m_state = m_pRegistry->m_state;
257 }
258 
259 //*************************************************************************
260 NestedKeyImpl::~NestedKeyImpl()
261 {
262 	if ( m_pRegistry )
263 		m_pRegistry->release();
264 }
265 
266 //*************************************************************************
267 void NestedKeyImpl::computeChanges()
268 {
269 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
270 	if ( m_state != m_pRegistry->m_state )
271 	{
272 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
273 
274 		Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name);
275 
276 		if ( tmpKey.is() )
277 		{
278 			m_localKey = rootKey->openKey(m_name);
279 		}
280 
281 		m_state = m_pRegistry->m_state;
282 	}
283 }
284 
285 //*************************************************************************
286 // NestedKey_Impl::computeName()
287 //
288 OUString NestedKeyImpl::computeName(const OUString& name)
289 {
290 	OUString resLocalName, resDefaultName;
291 
292 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
293 	try
294 	{
295 		if ( m_localKey.is() && m_localKey->isValid() )
296 		{
297 			resLocalName = m_localKey->getResolvedName(name);
298 		} else
299 		{
300 			if ( m_defaultKey.is() && m_defaultKey->isValid() )
301 				return m_defaultKey->getResolvedName(name);
302 		}
303 
304 		if ( resLocalName.getLength() > 0 && m_pRegistry->m_defaultReg->isValid() )
305 		{
306 			Reference<XRegistryKey> localRoot(m_pRegistry->m_localReg->getRootKey());
307 			Reference<XRegistryKey> defaultRoot(m_pRegistry->m_defaultReg->getRootKey());
308 
309 			resDefaultName = defaultRoot->getResolvedName(resLocalName);
310 
311 			sal_uInt32 count = 100;
312 
313 			while (resLocalName != resDefaultName && count > 0)
314 			{
315 				count--;
316 
317 				if (resLocalName.getLength() == 0 || resDefaultName.getLength() == 0)
318 					throw InvalidRegistryException();
319 
320 				resLocalName = localRoot->getResolvedName(resDefaultName);
321 				resDefaultName = defaultRoot->getResolvedName(resLocalName);
322 			}
323 		}
324 	}
325 	catch(InvalidRegistryException& )
326 	{
327 	}
328 
329 	return resLocalName;
330 }
331 
332 //*************************************************************************
333 OUString SAL_CALL NestedKeyImpl::getKeyName() throw(RuntimeException)
334 {
335 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
336 	return m_name;
337 }
338 
339 //*************************************************************************
340 sal_Bool SAL_CALL NestedKeyImpl::isReadOnly(  )
341 	throw(InvalidRegistryException, RuntimeException)
342 {
343 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
344 	computeChanges();
345 
346 	if ( m_localKey.is() && m_localKey->isValid() )
347 	   	return m_localKey->isReadOnly();
348 	else
349 		throw InvalidRegistryException();
350 }
351 
352 //*************************************************************************
353 sal_Bool SAL_CALL NestedKeyImpl::isValid(  ) throw(RuntimeException)
354 {
355 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
356 	return ((m_localKey.is() && m_localKey->isValid()) ||
357 		    (m_defaultKey.is() && m_defaultKey->isValid()) );
358 }
359 
360 //*************************************************************************
361 RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName )
362 	throw(InvalidRegistryException, RuntimeException)
363 {
364 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
365 	computeChanges();
366 
367 	if ( m_localKey.is() && m_localKey->isValid() )
368 	{
369 		return m_localKey->getKeyType(rKeyName);
370 	} else
371 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
372 	{
373 		return m_defaultKey->getKeyType(rKeyName);
374 	}
375 
376 	return RegistryKeyType_KEY;
377 }
378 
379 //*************************************************************************
380 RegistryValueType SAL_CALL NestedKeyImpl::getValueType(  )
381 	throw(InvalidRegistryException, RuntimeException)
382 {
383 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
384 	computeChanges();
385 
386 	if ( m_localKey.is() && m_localKey->isValid() )
387 	{
388 		return m_localKey->getValueType();
389 	} else
390 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
391 	{
392 		return m_defaultKey->getValueType();
393 	}
394 
395 	return RegistryValueType_NOT_DEFINED;
396 }
397 
398 //*************************************************************************
399 sal_Int32 SAL_CALL NestedKeyImpl::getLongValue(  )
400 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
401 {
402 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
403 	computeChanges();
404 
405 	if ( m_localKey.is() && m_localKey->isValid() )
406 	{
407 		return m_localKey->getLongValue();
408 	} else
409 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
410 	{
411 		return m_defaultKey->getLongValue();
412 	} else
413 	{
414 		throw InvalidRegistryException();
415 	}
416 }
417 
418 //*************************************************************************
419 void SAL_CALL NestedKeyImpl::setLongValue( sal_Int32 value )
420 	throw(InvalidRegistryException, RuntimeException)
421 {
422 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
423 	computeChanges();
424 
425 	if ( m_localKey.is() && m_localKey->isValid() )
426 	{
427 		m_localKey->setLongValue(value);
428 	} else
429 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
430 	{
431 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
432 		m_localKey = rootKey->createKey(m_name);
433 		m_localKey->setLongValue(value);
434 		m_state = m_pRegistry->m_state++;
435 	} else
436 	{
437 		throw InvalidRegistryException();
438 	}
439 }
440 
441 //*************************************************************************
442 Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue(  )
443 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
444 {
445 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
446 	computeChanges();
447 
448 	if ( m_localKey.is() && m_localKey->isValid() )
449 	{
450 		return m_localKey->getLongListValue();
451 	} else
452 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
453 	{
454 		return m_defaultKey->getLongListValue();
455 	} else
456 	{
457 		throw InvalidRegistryException();
458 	}
459 }
460 
461 //*************************************************************************
462 void SAL_CALL NestedKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue )
463 	throw(InvalidRegistryException, RuntimeException)
464 {
465 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
466 	computeChanges();
467 
468 	if ( m_localKey.is() && m_localKey->isValid() )
469 	{
470 		m_localKey->setLongListValue(seqValue);
471 	} else
472 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
473 	{
474 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
475 		m_localKey = rootKey->createKey(m_name);
476 		m_localKey->setLongListValue(seqValue);
477 		m_state = m_pRegistry->m_state++;
478 	} else
479 	{
480 		throw InvalidRegistryException();
481 	}
482 }
483 
484 //*************************************************************************
485 OUString SAL_CALL NestedKeyImpl::getAsciiValue(  )
486 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
487 {
488 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
489 	computeChanges();
490 
491 	if ( m_localKey.is() && m_localKey->isValid() )
492 	{
493 		return m_localKey->getAsciiValue();
494 	} else
495 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
496 	{
497 		return m_defaultKey->getAsciiValue();
498 	} else
499 	{
500 		throw InvalidRegistryException();
501 	}
502 }
503 
504 //*************************************************************************
505 void SAL_CALL NestedKeyImpl::setAsciiValue( const OUString& value )
506 	throw(InvalidRegistryException, RuntimeException)
507 {
508 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
509 	computeChanges();
510 
511 	if ( m_localKey.is() && m_localKey->isValid() )
512 	{
513 		m_localKey->setAsciiValue(value);
514 	} else
515 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
516 	{
517 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
518 		m_localKey = rootKey->createKey(m_name);
519 		m_localKey->setAsciiValue(value);
520 		m_state = m_pRegistry->m_state++;
521 	} else
522 	{
523 		throw InvalidRegistryException();
524 	}
525 }
526 
527 //*************************************************************************
528 Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue(  )
529 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
530 {
531 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
532 	computeChanges();
533 
534 	if ( m_localKey.is() && m_localKey->isValid() )
535 	{
536 		return m_localKey->getAsciiListValue();
537 	} else
538 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
539 	{
540 		return m_defaultKey->getAsciiListValue();
541 	} else
542 	{
543 		throw InvalidRegistryException();
544 	}
545 }
546 
547 //*************************************************************************
548 void SAL_CALL NestedKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue )
549 	throw(InvalidRegistryException, RuntimeException)
550 {
551 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
552 	computeChanges();
553 
554 	if ( m_localKey.is() && m_localKey->isValid() )
555 	{
556 		m_localKey->setAsciiListValue(seqValue);
557 	} else
558 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
559 	{
560 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
561 		m_localKey = rootKey->createKey(m_name);
562 		m_localKey->setAsciiListValue(seqValue);
563 		m_state = m_pRegistry->m_state++;
564 	} else
565 	{
566 		throw InvalidRegistryException();
567 	}
568 }
569 
570 //*************************************************************************
571 OUString SAL_CALL NestedKeyImpl::getStringValue(  )
572 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
573 {
574 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
575 	computeChanges();
576 
577 	if ( m_localKey.is() && m_localKey->isValid() )
578 	{
579 		return m_localKey->getStringValue();
580 	} else
581 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
582 	{
583 		return m_defaultKey->getStringValue();
584 	} else
585 	{
586 		throw InvalidRegistryException();
587 	}
588 }
589 
590 //*************************************************************************
591 void SAL_CALL NestedKeyImpl::setStringValue( const OUString& value )
592 	throw(InvalidRegistryException, RuntimeException)
593 {
594 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
595 	computeChanges();
596 
597 	if ( m_localKey.is() && m_localKey->isValid() )
598 	{
599 		m_localKey->setStringValue(value);
600 	} else
601 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
602 	{
603 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
604 		m_localKey = rootKey->createKey(m_name);
605 		m_localKey->setStringValue(value);
606 		m_state = m_pRegistry->m_state++;
607 	} else
608 	{
609 		throw InvalidRegistryException();
610 	}
611 }
612 
613 //*************************************************************************
614 Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue(  )
615 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
616 {
617 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
618 	computeChanges();
619 
620 	if ( m_localKey.is() && m_localKey->isValid() )
621 	{
622 		return m_localKey->getStringListValue();
623 	} else
624 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
625 	{
626 		return m_defaultKey->getStringListValue();
627 	} else
628 	{
629 		throw InvalidRegistryException();
630 	}
631 }
632 
633 //*************************************************************************
634 void SAL_CALL NestedKeyImpl::setStringListValue( const Sequence< OUString >& seqValue )
635 	throw(InvalidRegistryException, RuntimeException)
636 {
637 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
638 	computeChanges();
639 
640 	if ( m_localKey.is() && m_localKey->isValid() )
641 	{
642 		m_localKey->setStringListValue(seqValue);
643 	} else
644 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
645 	{
646 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
647 		m_localKey = rootKey->createKey(m_name);
648 		m_localKey->setStringListValue(seqValue);
649 		m_state = m_pRegistry->m_state++;
650 	} else
651 	{
652 		throw InvalidRegistryException();
653 	}
654 }
655 
656 //*************************************************************************
657 Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue(  )
658 	throw(InvalidRegistryException, InvalidValueException, RuntimeException)
659 {
660 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
661 	computeChanges();
662 
663 	if ( m_localKey.is() && m_localKey->isValid() )
664 	{
665 		return m_localKey->getBinaryValue();
666 	} else
667 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
668 	{
669 		return m_defaultKey->getBinaryValue();
670 	} else
671 	{
672 		throw InvalidRegistryException();
673 	}
674 }
675 
676 //*************************************************************************
677 void SAL_CALL NestedKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value )
678 	throw(InvalidRegistryException, RuntimeException)
679 {
680 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
681 	computeChanges();
682 
683 	if ( m_localKey.is() && m_localKey->isValid() )
684 	{
685 		m_localKey->setBinaryValue(value);
686 	} else
687 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
688 	{
689 		Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
690 		m_localKey = rootKey->createKey(m_name);
691 		m_localKey->setBinaryValue(value);
692 		m_state = m_pRegistry->m_state++;
693 	} else
694 	{
695 		throw InvalidRegistryException();
696 	}
697 }
698 
699 //*************************************************************************
700 Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName )
701 	throw(InvalidRegistryException, RuntimeException)
702 {
703 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
704 	if ( !m_localKey.is() && !m_defaultKey.is() )
705 	{
706 		throw InvalidRegistryException();
707 	}
708 
709 	OUString resolvedName = computeName(aKeyName);
710 
711 	if ( resolvedName.getLength() == 0 )
712 		throw InvalidRegistryException();
713 
714 	Reference<XRegistryKey> localKey, defaultKey;
715 
716 	if ( m_localKey.is() && m_localKey->isValid() )
717 	{
718 		localKey = m_pRegistry->m_localReg->getRootKey()->openKey(resolvedName);
719 	}
720 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
721 	{
722 		defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
723 	}
724 
725 	if ( localKey.is() || defaultKey.is() )
726 	{
727 		return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
728 	} else
729 	{
730 		return Reference<XRegistryKey>();
731 	}
732 }
733 
734 //*************************************************************************
735 Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName )
736 	throw(InvalidRegistryException, RuntimeException)
737 {
738 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
739 	if ( (!m_localKey.is() && !m_defaultKey.is()) ||
740 		 (m_localKey.is() && m_localKey->isReadOnly()) )
741 	{
742 		throw InvalidRegistryException();
743 	}
744 
745 	OUString resolvedName = computeName(aKeyName);
746 
747 	if ( resolvedName.getLength() == 0 )
748 		throw InvalidRegistryException();
749 
750 	if ( m_localKey.is() && m_localKey->isValid() )
751 	{
752 		Reference<XRegistryKey> localKey, defaultKey;
753 
754 		localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName);
755 		if ( localKey.is() )
756 		{
757 			if ( m_defaultKey.is() && m_defaultKey->isValid() )
758 			{
759 				defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
760 			}
761 
762 			m_state = m_pRegistry->m_state++;
763 
764 			return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
765 		}
766 	} else
767 	{
768 		Reference<XRegistryKey> localKey, defaultKey;
769 
770 		if ( m_defaultKey.is() && m_defaultKey->isValid() )
771 		{
772 			Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
773 			m_localKey = rootKey->createKey(m_name);
774 
775 			localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName);
776 
777 			if ( localKey.is() )
778 			{
779 				defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
780 
781 				m_state = m_pRegistry->m_state++;
782 
783 				return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
784 			}
785 		}
786 	}
787 
788 	return Reference<XRegistryKey>();
789 }
790 
791 //*************************************************************************
792 void SAL_CALL NestedKeyImpl::closeKey(  )
793 	throw(InvalidRegistryException, RuntimeException)
794 {
795 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
796 	if ( m_localKey.is() && m_localKey->isValid() )
797 	{
798 		m_localKey->closeKey();
799 	}
800 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
801 	{
802 		m_defaultKey->closeKey();
803 	}
804 }
805 
806 //*************************************************************************
807 void SAL_CALL NestedKeyImpl::deleteKey( const OUString& rKeyName )
808 	throw(InvalidRegistryException, RuntimeException)
809 {
810 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
811 	if ( m_localKey.is() && m_localKey->isValid() &&
812 		 !m_localKey->isReadOnly() )
813 	{
814 		OUString resolvedName = computeName(rKeyName);
815 
816 		if ( resolvedName.getLength() == 0 )
817 		{
818 			throw InvalidRegistryException();
819 		}
820 
821 		m_pRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
822 	} else
823 	{
824 		throw InvalidRegistryException();
825 	}
826 }
827 
828 //*************************************************************************
829 Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys(  )
830 	throw(InvalidRegistryException, RuntimeException)
831 {
832 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
833 	if ( !m_localKey.is() && !m_defaultKey.is() )
834 	{
835 		throw InvalidRegistryException();
836 	}
837 
838 	Sequence<OUString> localSeq, defaultSeq;
839 
840 	if ( m_localKey.is() && m_localKey->isValid() )
841 	{
842 		localSeq = m_localKey->getKeyNames();
843 	}
844 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
845 	{
846 		defaultSeq = m_defaultKey->getKeyNames();
847 	}
848 
849 	sal_uInt32 local = localSeq.getLength();
850 	sal_uInt32 def = defaultSeq.getLength();
851 	sal_uInt32 len = 0;
852 
853 	sal_uInt32 i, j;
854 	for (i=0; i < local; i++)
855 	{
856 		for (j=0 ; j < def; j++)
857 		{
858 			if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
859 			{
860 				len++;
861 				break;
862 			}
863 		}
864 	}
865 
866 	Sequence< Reference<XRegistryKey> > retSeq(local + def - len);
867 	sal_Bool 							insert = sal_True;
868 	OUString	 						name;
869 	sal_Int32							lastIndex;
870 
871 	for (i=0; i < local; i++)
872 	{
873 		name = localSeq.getConstArray()[i];
874 		lastIndex = name.lastIndexOf('/');
875 		name = name.copy(lastIndex);
876 		retSeq.getArray()[i] =
877 			(XRegistryKey*)new NestedKeyImpl(name, this);
878 	}
879 
880 	sal_uInt32 k = local;
881 	for (i=0; i < def; i++)
882 	{
883 		insert = sal_True;
884 
885 		for (j=0 ; j < local; j++)
886 		{
887 			if ( retSeq.getConstArray()[j]->getKeyName()
888 					== defaultSeq.getConstArray()[i] )
889 			{
890 				insert = sal_False;
891 				break;
892 			}
893 		}
894 
895 		if ( insert )
896 		{
897 			name = defaultSeq.getConstArray()[i];
898 			lastIndex = name.lastIndexOf('/');
899 			name = name.copy(lastIndex);
900 			retSeq.getArray()[k++] =
901 				(XRegistryKey*)new NestedKeyImpl(name, this);
902 		}
903 	}
904 
905 	return retSeq;
906 }
907 
908 //*************************************************************************
909 Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames(  )
910 	throw(InvalidRegistryException, RuntimeException)
911 {
912 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
913 	if ( !m_localKey.is() && !m_defaultKey.is() )
914 	{
915 		throw InvalidRegistryException();
916 	}
917 
918 	Sequence<OUString> localSeq, defaultSeq;
919 
920 	if ( m_localKey.is() && m_localKey->isValid() )
921 	{
922 		localSeq = m_localKey->getKeyNames();
923 	}
924 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
925 	{
926 		defaultSeq = m_defaultKey->getKeyNames();
927 	}
928 
929 	sal_uInt32 local = localSeq.getLength();
930 	sal_uInt32 def = defaultSeq.getLength();
931 	sal_uInt32 len = 0;
932 
933 	sal_uInt32 i, j;
934 	for (i=0; i < local; i++)
935 	{
936 		for (j=0 ; j < def; j++)
937 		{
938 			if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
939 			{
940 				len++;
941 				break;
942 			}
943 		}
944 	}
945 
946 	Sequence<OUString> 	retSeq(local + def - len);
947 	sal_Bool 			insert = sal_True;
948 
949 	for (i=0; i < local; i++)
950 	{
951 		retSeq.getArray()[i] = localSeq.getConstArray()[i];
952 	}
953 
954 	sal_uInt32 k = local;
955 	for (i=0; i < def; i++)
956 	{
957 		insert = sal_True;
958 
959 		for (j=0 ; j < local; j++)
960 		{
961 			if ( retSeq.getConstArray()[j] == defaultSeq.getConstArray()[i] )
962 			{
963 				insert = sal_False;
964 				break;
965 			}
966 		}
967 
968 		if ( insert )
969 			retSeq.getArray()[k++] = defaultSeq.getConstArray()[i];
970 	}
971 
972 	return retSeq;
973 }
974 
975 //*************************************************************************
976 sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
977 	throw(InvalidRegistryException, RuntimeException)
978 {
979 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
980 
981 	sal_Bool isCreated = sal_False;
982 	if ( !m_localKey.is() && !m_defaultKey.is() )
983 	{
984 		throw InvalidRegistryException();
985 	}
986 
987 	OUString 	linkName;
988 	OUString 	resolvedName;
989 	sal_Int32 	lastIndex = aLinkName.lastIndexOf('/');
990 
991 	if ( lastIndex > 0 )
992 	{
993 		linkName = aLinkName.copy(0, lastIndex);
994 
995 		resolvedName = computeName(linkName);
996 
997 		if ( resolvedName.getLength() == 0 )
998 		{
999 			throw InvalidRegistryException();
1000 		}
1001 
1002 		resolvedName = resolvedName + aLinkName.copy(lastIndex);
1003 	} else
1004 	{
1005 		if ( lastIndex == 0 )
1006 			resolvedName = m_name + aLinkName;
1007 		else
1008 			resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + aLinkName;
1009 	}
1010 
1011 	if ( m_localKey.is() && m_localKey->isValid() )
1012 	{
1013 		isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
1014 	} else
1015 	{
1016 		if ( m_defaultKey.is() && m_defaultKey->isValid() )
1017 		{
1018 			Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
1019 			m_localKey = rootKey->createKey(m_name);
1020 
1021 			isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
1022 		}
1023 	}
1024 
1025 	if ( isCreated )
1026 		m_state = m_pRegistry->m_state++;
1027 
1028 	return isCreated;
1029 }
1030 
1031 //*************************************************************************
1032 void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
1033 	throw(InvalidRegistryException, RuntimeException)
1034 {
1035 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
1036 	if ( !m_localKey.is() && !m_defaultKey.is() )
1037 	{
1038 		throw InvalidRegistryException();
1039 	}
1040 
1041 	OUString 	linkName;
1042 	OUString 	resolvedName;
1043 	sal_Int32 	lastIndex = rLinkName.lastIndexOf('/');
1044 
1045 	if ( lastIndex > 0 )
1046 	{
1047 		linkName = rLinkName.copy(0, lastIndex);
1048 
1049 		resolvedName = computeName(linkName);
1050 
1051 		if ( resolvedName.getLength() == 0 )
1052 		{
1053 			throw InvalidRegistryException();
1054 		}
1055 
1056 		resolvedName = resolvedName + rLinkName.copy(lastIndex);
1057 	} else
1058 	{
1059 		if ( lastIndex == 0 )
1060 			resolvedName = m_name + rLinkName;
1061 		else
1062 			resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName;
1063 	}
1064 
1065 	if ( m_localKey.is() && m_localKey->isValid() &&
1066 		 !m_localKey->isReadOnly() )
1067 	{
1068 		m_pRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
1069 	} else
1070 	{
1071 		throw InvalidRegistryException();
1072 	}
1073 }
1074 
1075 //*************************************************************************
1076 OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
1077 	throw(InvalidRegistryException, RuntimeException)
1078 {
1079 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
1080 	if ( !m_localKey.is() && !m_defaultKey.is() )
1081 	{
1082 		throw InvalidRegistryException();
1083 	}
1084 
1085 	OUString 	linkName;
1086 	OUString 	resolvedName;
1087 	sal_Int32 	lastIndex = rLinkName.lastIndexOf('/');
1088 
1089 	if ( lastIndex > 0 )
1090 	{
1091 		linkName = rLinkName.copy(0, lastIndex);
1092 
1093 		resolvedName = computeName(linkName);
1094 
1095 		if ( resolvedName.getLength() == 0 )
1096 		{
1097 			throw InvalidRegistryException();
1098 		}
1099 
1100 		resolvedName = resolvedName + rLinkName.copy(lastIndex);
1101 	} else
1102 	{
1103 		if ( lastIndex == 0 )
1104 			resolvedName = m_name + rLinkName;
1105 		else
1106 			resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName;
1107 	}
1108 
1109 	OUString linkTarget;
1110 	if ( m_localKey.is() && m_localKey->isValid() )
1111 	{
1112 		try
1113 		{
1114 			linkTarget = m_pRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
1115 			return linkTarget;
1116 		}
1117 		catch(InvalidRegistryException& )
1118 		{
1119 		}
1120 	}
1121 
1122 	if ( m_defaultKey.is() && m_defaultKey->isValid() )
1123 		linkTarget = m_pRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
1124 
1125 	return linkTarget;
1126 }
1127 
1128 //*************************************************************************
1129 OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
1130 	throw(InvalidRegistryException, RuntimeException)
1131 {
1132 	Guard< Mutex > aGuard( m_pRegistry->m_mutex );
1133 	if ( !m_localKey.is() && !m_defaultKey.is() )
1134 	{
1135 		throw InvalidRegistryException();
1136 	}
1137 
1138 	OUString resolvedName = computeName(aKeyName);
1139 
1140 	if ( resolvedName.getLength() == 0 )
1141 	{
1142 		throw InvalidRegistryException();
1143 	}
1144 
1145 	return resolvedName;
1146 }
1147 
1148 //*************************************************************************
1149 //
1150 // DefaultRegistry Implementation
1151 //
1152 //*************************************************************************
1153 NestedRegistryImpl::NestedRegistryImpl( )
1154 	: m_state(0)
1155 {
1156 	g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
1157 }
1158 
1159 //*************************************************************************
1160 NestedRegistryImpl::~NestedRegistryImpl()
1161 {
1162 	g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
1163 }
1164 
1165 
1166 class RegistryEnumueration : public WeakImplHelper1< XEnumeration >
1167 {
1168 public:
1169     RegistryEnumueration(
1170         const Reference< XSimpleRegistry > &r1,
1171         const Reference< XSimpleRegistry > &r2 )
1172         : m_xReg1( r1 ) , m_xReg2( r2 )
1173         {}
1174 public:
1175     virtual sal_Bool SAL_CALL hasMoreElements(  ) throw (RuntimeException);
1176     virtual Any SAL_CALL nextElement(  ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
1177 
1178 private:
1179     Reference< XSimpleRegistry > m_xReg1;
1180     Reference< XSimpleRegistry > m_xReg2;
1181 };
1182 
1183 sal_Bool RegistryEnumueration::hasMoreElements(  ) throw (RuntimeException)
1184 {
1185     return m_xReg1.is() || m_xReg2.is();
1186 }
1187 
1188 Any RegistryEnumueration::nextElement(  )
1189     throw (NoSuchElementException, WrappedTargetException, RuntimeException)
1190 {
1191     Any a;
1192     if( m_xReg1.is() )
1193     {
1194         a <<= m_xReg1;
1195         m_xReg1.clear();
1196     }
1197     else if( m_xReg2.is() )
1198     {
1199         a <<= m_xReg2;
1200         m_xReg2.clear();
1201     }
1202     else
1203     {
1204         throw NoSuchElementException( OUString( RTL_CONSTASCII_USTRINGPARAM(
1205             "NestedRegistry: no nextElement() !" ) ),Reference< XInterface > () );
1206     }
1207     return a;
1208 }
1209 
1210 
1211 Reference< XEnumeration > NestedRegistryImpl::createEnumeration(  ) throw (RuntimeException)
1212 {
1213     MutexGuard guard( m_mutex );
1214     return new RegistryEnumueration( m_localReg, m_defaultReg );
1215 }
1216 
1217 Type NestedRegistryImpl::getElementType(  ) throw (RuntimeException)
1218 {
1219     return getCppuType( &m_localReg );
1220 }
1221 
1222 sal_Bool SAL_CALL NestedRegistryImpl::hasElements(  ) throw (RuntimeException)
1223 {
1224     MutexGuard guard( m_mutex );
1225     return m_localReg.is() || m_defaultReg.is();
1226 }
1227 
1228 
1229 
1230 //*************************************************************************
1231 OUString SAL_CALL NestedRegistryImpl::getImplementationName(  )
1232 	throw(RuntimeException)
1233 {
1234 	return stoc_bootstrap::defreg_getImplementationName();
1235 }
1236 
1237 //*************************************************************************
1238 sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
1239 	throw(RuntimeException)
1240 {
1241 	Guard< Mutex > aGuard( m_mutex );
1242 	Sequence< OUString > aSNL = getSupportedServiceNames();
1243 	const OUString * pArray = aSNL.getArray();
1244 	for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
1245 		if( pArray[i] == ServiceName )
1246 			return sal_True;
1247 	return sal_False;
1248 }
1249 
1250 //*************************************************************************
1251 Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames(  )
1252 	throw(RuntimeException)
1253 {
1254 	return stoc_bootstrap::defreg_getSupportedServiceNames();
1255 }
1256 
1257 //*************************************************************************
1258 void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
1259 	throw( Exception, RuntimeException )
1260 {
1261 	Guard< Mutex > aGuard( m_mutex );
1262 	if ( (aArguments.getLength() == 2) &&
1263 		 (aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) &&
1264 		 (aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) )
1265 	{
1266 		aArguments[0] >>= m_localReg;
1267 		aArguments[1] >>= m_defaultReg;
1268 		if ( m_localReg == m_defaultReg )
1269 			m_defaultReg = Reference< XSimpleRegistry >();
1270 	}
1271 }
1272 
1273 //*************************************************************************
1274 OUString SAL_CALL NestedRegistryImpl::getURL() throw(RuntimeException)
1275 {
1276 	Guard< Mutex > aGuard( m_mutex );
1277 	try
1278 	{
1279 		if ( m_localReg.is() && m_localReg->isValid() )
1280 			return m_localReg->getURL();
1281 	}
1282 	catch(InvalidRegistryException& )
1283 	{
1284 	}
1285 
1286 	return OUString();
1287 }
1288 
1289 //*************************************************************************
1290 void SAL_CALL NestedRegistryImpl::open( const OUString&, sal_Bool, sal_Bool )
1291 	throw(InvalidRegistryException, RuntimeException)
1292 {
1293 	throw InvalidRegistryException(
1294     		OUString::createFromAscii("the 'open' method is not specified for a nested registry"),
1295     		Reference< XInterface >() );
1296 }
1297 
1298 //*************************************************************************
1299 sal_Bool SAL_CALL NestedRegistryImpl::isValid(  ) throw(RuntimeException)
1300 {
1301 	Guard< Mutex > aGuard( m_mutex );
1302 	try
1303 	{
1304 		if ( (m_localReg.is() && m_localReg->isValid()) ||
1305 			 (m_defaultReg.is() && m_defaultReg->isValid()) )
1306 			return sal_True;
1307 	}
1308 	catch(InvalidRegistryException& )
1309 	{
1310 	}
1311 
1312 	return sal_False;
1313 }
1314 
1315 //*************************************************************************
1316 void SAL_CALL NestedRegistryImpl::close(  )
1317 	throw(InvalidRegistryException, RuntimeException)
1318 {
1319 	Guard< Mutex > aGuard( m_mutex );
1320 	if ( m_localReg.is() && m_localReg->isValid() )
1321 	{
1322 		m_localReg->close();
1323 	}
1324 	if ( m_defaultReg.is() && m_defaultReg->isValid() )
1325 	{
1326 		m_defaultReg->close();
1327 	}
1328 /*
1329 	throw InvalidRegistryException(
1330     		OUString::createFromAscii("the 'close' method is not specified for a nested registry"),
1331     		Reference< XInterface >() );
1332 */
1333 }
1334 
1335 //*************************************************************************
1336 void SAL_CALL NestedRegistryImpl::destroy(  )
1337 	throw(InvalidRegistryException, RuntimeException)
1338 {
1339 	throw InvalidRegistryException(
1340     		OUString::createFromAscii("the 'destroy' method is not specified for a nested registry"),
1341     		Reference< XInterface >() );
1342 }
1343 
1344 //*************************************************************************
1345 Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey(  )
1346 	throw(InvalidRegistryException, RuntimeException)
1347 {
1348 	Reference<XRegistryKey> tmpKey;
1349 
1350 	Guard< Mutex > aGuard( m_mutex );
1351 	if ( m_localReg.is() && m_localReg->isValid() )
1352 	{
1353 		Reference<XRegistryKey> localKey, defaultKey;
1354 
1355 		localKey = m_localReg->getRootKey();
1356 
1357 		if ( localKey.is() )
1358 		{
1359 			if ( m_defaultReg.is() && m_defaultReg->isValid() )
1360 			{
1361 				defaultKey = m_defaultReg->getRootKey();
1362 			}
1363 
1364 			return ((XRegistryKey*)new NestedKeyImpl(this, localKey, defaultKey));
1365 		}
1366 	} else
1367 	{
1368 		throw InvalidRegistryException();
1369 	}
1370 
1371 	return Reference<XRegistryKey>();
1372 }
1373 
1374 //*************************************************************************
1375 sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly(  )
1376 	throw(InvalidRegistryException, RuntimeException)
1377 {
1378 	Guard< Mutex > aGuard( m_mutex );
1379 	try
1380 	{
1381 		if ( m_localReg.is() && m_localReg->isValid() )
1382 			return m_localReg->isReadOnly();
1383 	}
1384 	catch(InvalidRegistryException& )
1385 	{
1386 	}
1387 
1388 	return sal_False;
1389 }
1390 
1391 //*************************************************************************
1392 void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl )
1393 	throw(InvalidRegistryException, MergeConflictException, RuntimeException)
1394 {
1395 	Guard< Mutex > aGuard( m_mutex );
1396 	if ( m_localReg.is() && m_localReg->isValid() )
1397 	{
1398 		m_localReg->mergeKey(aKeyName, aUrl);
1399 
1400 		m_state++;
1401 	}
1402 }
1403 } // namespace stco_defreg
1404 
1405 namespace stoc_bootstrap
1406 {
1407 //*************************************************************************
1408 Reference<XInterface> SAL_CALL NestedRegistry_CreateInstance( const Reference<XComponentContext>& )
1409 	throw(Exception)
1410 {
1411 	Reference<XInterface>	xRet;
1412 	XSimpleRegistry *pRegistry = (XSimpleRegistry*) new stoc_defreg::NestedRegistryImpl;
1413 
1414 	if (pRegistry)
1415 	{
1416 		xRet = Reference<XInterface>::query(pRegistry);
1417 	}
1418 
1419 	return xRet;
1420 }
1421 
1422 }
1423 
1424