xref: /trunk/main/stoc/source/defaultregistry/defaultregistry.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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