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