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