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