1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20 #include <osl/mutex.hxx>
21 #include <comphelper/sequence.hxx>
22 #include <cppuhelper/weak.hxx>
23 #include <cppuhelper/implbase.hxx>
24 #include <cppuhelper/implbase4.hxx>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <rtl/ref.hxx>
27
28 #include <com/sun/star/registry/XSimpleRegistry.hpp>
29 #include <com/sun/star/lang/XServiceInfo.hpp>
30 #include <com/sun/star/lang/XInitialization.hpp>
31 #include <com/sun/star/container/XEnumerationAccess.hpp>
32
33 namespace com::sun::star::uno { class XComponentContext; }
34
35 using namespace css::uno;
36 using namespace css::registry;
37 using namespace css::lang;
38 using namespace css::container;
39 using namespace cppu;
40 using namespace osl;
41
42 namespace {
43
44 class NestedRegistryImpl : public WeakAggImplHelper4 < XSimpleRegistry, XInitialization, XServiceInfo, XEnumerationAccess >
45 {
46 public:
47 NestedRegistryImpl( );
48
49 // XServiceInfo
50 virtual OUString SAL_CALL getImplementationName( ) override;
51 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
52 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
53
54 // XInitialization
55 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
56
57 // XSimpleRegistry
58 virtual OUString SAL_CALL getURL() override;
59 virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) override;
60 virtual sal_Bool SAL_CALL isValid( ) override;
61 virtual void SAL_CALL close( ) override;
62 virtual void SAL_CALL destroy( ) override;
63 virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) override;
64 virtual sal_Bool SAL_CALL isReadOnly( ) override;
65 virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) override;
66
67 // XEnumerationAccess
68 virtual Reference< XEnumeration > SAL_CALL createEnumeration( ) override;
69 virtual Type SAL_CALL getElementType( ) override;
70 virtual sal_Bool SAL_CALL hasElements( ) override;
71
72 friend class NestedKeyImpl;
73 protected:
74 Mutex m_mutex;
75 sal_uInt32 m_state;
76 Reference<XSimpleRegistry> m_localReg;
77 Reference<XSimpleRegistry> m_defaultReg;
78
79 };
80
81
82 // class NestedKeyImpl the implementation of interface XRegistryKey
83
84 class NestedKeyImpl : public WeakImplHelper< XRegistryKey >
85 {
86 public:
87 NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
88 Reference<XRegistryKey>& localKey,
89 Reference<XRegistryKey>& defaultKey);
90
91 NestedKeyImpl( const OUString& aKeyName,
92 NestedKeyImpl* pKey);
93
94 // XRegistryKey
95 virtual OUString SAL_CALL getKeyName() override;
96 virtual sal_Bool SAL_CALL isReadOnly( ) override;
97 virtual sal_Bool SAL_CALL isValid( ) override;
98 virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) override;
99 virtual RegistryValueType SAL_CALL getValueType( ) override;
100 virtual sal_Int32 SAL_CALL getLongValue( ) override;
101 virtual void SAL_CALL setLongValue( sal_Int32 value ) override;
102 virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) override;
103 virtual void SAL_CALL setLongListValue( const css::uno::Sequence< sal_Int32 >& seqValue ) override;
104 virtual OUString SAL_CALL getAsciiValue( ) override;
105 virtual void SAL_CALL setAsciiValue( const OUString& value ) override;
106 virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) override;
107 virtual void SAL_CALL setAsciiListValue( const css::uno::Sequence< OUString >& seqValue ) override;
108 virtual OUString SAL_CALL getStringValue( ) override;
109 virtual void SAL_CALL setStringValue( const OUString& value ) override;
110 virtual Sequence< OUString > SAL_CALL getStringListValue( ) override;
111 virtual void SAL_CALL setStringListValue( const css::uno::Sequence< OUString >& seqValue ) override;
112 virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) override;
113 virtual void SAL_CALL setBinaryValue( const css::uno::Sequence< sal_Int8 >& value ) override;
114 virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) override;
115 virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) override;
116 virtual void SAL_CALL closeKey( ) override;
117 virtual void SAL_CALL deleteKey( const OUString& rKeyName ) override;
118 virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) override;
119 virtual Sequence< OUString > SAL_CALL getKeyNames( ) override;
120 virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) override;
121 virtual void SAL_CALL deleteLink( const OUString& rLinkName ) override;
122 virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) override;
123 virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) override;
124
125 protected:
126 void computeChanges();
127 OUString computeName(const OUString& name);
128
129 OUString m_name;
130 sal_uInt32 m_state;
131 rtl::Reference<NestedRegistryImpl> m_xRegistry;
132 Reference<XRegistryKey> m_localKey;
133 Reference<XRegistryKey> m_defaultKey;
134 };
135
136
NestedKeyImpl(NestedRegistryImpl * pDefaultRegistry,Reference<XRegistryKey> & localKey,Reference<XRegistryKey> & defaultKey)137 NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
138 Reference<XRegistryKey>& localKey,
139 Reference<XRegistryKey>& defaultKey )
140 : m_xRegistry(pDefaultRegistry)
141 {
142 m_localKey = localKey;
143 m_defaultKey = defaultKey;
144
145 if (m_localKey.is())
146 {
147 m_name = m_localKey->getKeyName();
148 }
149 else if (m_defaultKey.is())
150 {
151 m_name = m_defaultKey->getKeyName();
152 }
153
154 m_state = m_xRegistry->m_state;
155 }
156
157
NestedKeyImpl(const OUString & rKeyName,NestedKeyImpl * pKey)158 NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName,
159 NestedKeyImpl* pKey)
160 : m_xRegistry(pKey->m_xRegistry)
161 {
162 if (pKey->m_localKey.is() && pKey->m_localKey->isValid())
163 {
164 m_localKey = pKey->m_localKey->openKey(rKeyName);
165 }
166 if (pKey->m_defaultKey.is() && pKey->m_defaultKey->isValid())
167 {
168 m_defaultKey = pKey->m_defaultKey->openKey(rKeyName);
169 }
170
171 if (m_localKey.is())
172 {
173 m_name = m_localKey->getKeyName();
174 }
175 else if (m_defaultKey.is())
176 {
177 m_name = m_defaultKey->getKeyName();
178 }
179
180 m_state = m_xRegistry->m_state;
181 }
182
computeChanges()183 void NestedKeyImpl::computeChanges()
184 {
185 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
186 if ( m_state == m_xRegistry->m_state )
187 return;
188
189 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
190
191 Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name);
192
193 if ( tmpKey.is() )
194 {
195 m_localKey = rootKey->openKey(m_name);
196 }
197
198 m_state = m_xRegistry->m_state;
199 }
200
201
202 // NestedKey_Impl::computeName()
203
computeName(const OUString & name)204 OUString NestedKeyImpl::computeName(const OUString& name)
205 {
206 OUString resLocalName, resDefaultName;
207
208 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
209 try
210 {
211 if ( m_localKey.is() && m_localKey->isValid() )
212 {
213 resLocalName = m_localKey->getResolvedName(name);
214 }
215 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
216 {
217 return m_defaultKey->getResolvedName(name);
218 }
219
220 if ( !resLocalName.isEmpty() && m_xRegistry->m_defaultReg->isValid() )
221 {
222 Reference<XRegistryKey> localRoot(m_xRegistry->m_localReg->getRootKey());
223 Reference<XRegistryKey> defaultRoot(m_xRegistry->m_defaultReg->getRootKey());
224
225 resDefaultName = defaultRoot->getResolvedName(resLocalName);
226
227 sal_uInt32 count = 100;
228
229 while (resLocalName != resDefaultName && count > 0)
230 {
231 count--;
232
233 if (resLocalName.isEmpty() || resDefaultName.isEmpty())
234 throw InvalidRegistryException();
235
236 resLocalName = localRoot->getResolvedName(resDefaultName);
237 resDefaultName = defaultRoot->getResolvedName(resLocalName);
238 }
239 }
240 }
241 catch(InvalidRegistryException& )
242 {
243 }
244
245 return resLocalName;
246 }
247
248
getKeyName()249 OUString SAL_CALL NestedKeyImpl::getKeyName()
250 {
251 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
252 return m_name;
253 }
254
255
isReadOnly()256 sal_Bool SAL_CALL NestedKeyImpl::isReadOnly( )
257 {
258 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
259 computeChanges();
260
261 if ( !m_localKey.is() || !m_localKey->isValid() )
262 throw InvalidRegistryException();
263
264 return m_localKey->isReadOnly();
265 }
266
267
isValid()268 sal_Bool SAL_CALL NestedKeyImpl::isValid( )
269 {
270 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
271 return ((m_localKey.is() && m_localKey->isValid()) ||
272 (m_defaultKey.is() && m_defaultKey->isValid()) );
273 }
274
275
getKeyType(const OUString & rKeyName)276 RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName )
277 {
278 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
279 computeChanges();
280
281 if ( m_localKey.is() && m_localKey->isValid() )
282 {
283 return m_localKey->getKeyType(rKeyName);
284 }
285 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
286 {
287 return m_defaultKey->getKeyType(rKeyName);
288 }
289
290 return RegistryKeyType_KEY;
291 }
292
293
getValueType()294 RegistryValueType SAL_CALL NestedKeyImpl::getValueType( )
295 {
296 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
297 computeChanges();
298
299 if ( m_localKey.is() && m_localKey->isValid() )
300 {
301 return m_localKey->getValueType();
302 }
303 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
304 {
305 return m_defaultKey->getValueType();
306 }
307
308 return RegistryValueType_NOT_DEFINED;
309 }
310
311
getLongValue()312 sal_Int32 SAL_CALL NestedKeyImpl::getLongValue( )
313 {
314 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
315 computeChanges();
316
317 if ( m_localKey.is() && m_localKey->isValid() )
318 {
319 return m_localKey->getLongValue();
320 }
321 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
322 {
323 return m_defaultKey->getLongValue();
324 }
325 else
326 {
327 throw InvalidRegistryException();
328 }
329 }
330
331
setLongValue(sal_Int32 value)332 void SAL_CALL NestedKeyImpl::setLongValue( sal_Int32 value )
333 {
334 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
335 computeChanges();
336
337 if ( m_localKey.is() && m_localKey->isValid() )
338 {
339 m_localKey->setLongValue(value);
340 }
341 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
342 {
343 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
344 m_localKey = rootKey->createKey(m_name);
345 m_localKey->setLongValue(value);
346 m_state = m_xRegistry->m_state++;
347 }
348 else
349 {
350 throw InvalidRegistryException();
351 }
352 }
353
354
getLongListValue()355 Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue( )
356 {
357 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
358 computeChanges();
359
360 if ( m_localKey.is() && m_localKey->isValid() )
361 {
362 return m_localKey->getLongListValue();
363 }
364 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
365 {
366 return m_defaultKey->getLongListValue();
367 }
368 else
369 {
370 throw InvalidRegistryException();
371 }
372 }
373
374
setLongListValue(const Sequence<sal_Int32> & seqValue)375 void SAL_CALL NestedKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue )
376 {
377 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
378 computeChanges();
379
380 if ( m_localKey.is() && m_localKey->isValid() )
381 {
382 m_localKey->setLongListValue(seqValue);
383 }
384 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
385 {
386 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
387 m_localKey = rootKey->createKey(m_name);
388 m_localKey->setLongListValue(seqValue);
389 m_state = m_xRegistry->m_state++;
390 }
391 else
392 {
393 throw InvalidRegistryException();
394 }
395 }
396
397
getAsciiValue()398 OUString SAL_CALL NestedKeyImpl::getAsciiValue( )
399 {
400 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
401 computeChanges();
402
403 if ( m_localKey.is() && m_localKey->isValid() )
404 {
405 return m_localKey->getAsciiValue();
406 }
407 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
408 {
409 return m_defaultKey->getAsciiValue();
410 }
411 else
412 {
413 throw InvalidRegistryException();
414 }
415 }
416
417
setAsciiValue(const OUString & value)418 void SAL_CALL NestedKeyImpl::setAsciiValue( const OUString& value )
419 {
420 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
421 computeChanges();
422
423 if ( m_localKey.is() && m_localKey->isValid() )
424 {
425 m_localKey->setAsciiValue(value);
426 }
427 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
428 {
429 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
430 m_localKey = rootKey->createKey(m_name);
431 m_localKey->setAsciiValue(value);
432 m_state = m_xRegistry->m_state++;
433 }
434 else
435 {
436 throw InvalidRegistryException();
437 }
438 }
439
440
getAsciiListValue()441 Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue( )
442 {
443 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
444 computeChanges();
445
446 if ( m_localKey.is() && m_localKey->isValid() )
447 {
448 return m_localKey->getAsciiListValue();
449 }
450 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
451 {
452 return m_defaultKey->getAsciiListValue();
453 }
454 else
455 {
456 throw InvalidRegistryException();
457 }
458 }
459
460
setAsciiListValue(const Sequence<OUString> & seqValue)461 void SAL_CALL NestedKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue )
462 {
463 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
464 computeChanges();
465
466 if ( m_localKey.is() && m_localKey->isValid() )
467 {
468 m_localKey->setAsciiListValue(seqValue);
469 }
470 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
471 {
472 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
473 m_localKey = rootKey->createKey(m_name);
474 m_localKey->setAsciiListValue(seqValue);
475 m_state = m_xRegistry->m_state++;
476 }
477 else
478 {
479 throw InvalidRegistryException();
480 }
481 }
482
483
getStringValue()484 OUString SAL_CALL NestedKeyImpl::getStringValue( )
485 {
486 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
487 computeChanges();
488
489 if ( m_localKey.is() && m_localKey->isValid() )
490 {
491 return m_localKey->getStringValue();
492 }
493 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
494 {
495 return m_defaultKey->getStringValue();
496 }
497 else
498 {
499 throw InvalidRegistryException();
500 }
501 }
502
503
setStringValue(const OUString & value)504 void SAL_CALL NestedKeyImpl::setStringValue( const OUString& value )
505 {
506 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
507 computeChanges();
508
509 if ( m_localKey.is() && m_localKey->isValid() )
510 {
511 m_localKey->setStringValue(value);
512 }
513 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
514 {
515 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
516 m_localKey = rootKey->createKey(m_name);
517 m_localKey->setStringValue(value);
518 m_state = m_xRegistry->m_state++;
519 }
520 else
521 {
522 throw InvalidRegistryException();
523 }
524 }
525
526
getStringListValue()527 Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue( )
528 {
529 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
530 computeChanges();
531
532 if ( m_localKey.is() && m_localKey->isValid() )
533 {
534 return m_localKey->getStringListValue();
535 }
536 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
537 {
538 return m_defaultKey->getStringListValue();
539 }
540 else
541 {
542 throw InvalidRegistryException();
543 }
544 }
545
546
setStringListValue(const Sequence<OUString> & seqValue)547 void SAL_CALL NestedKeyImpl::setStringListValue( const Sequence< OUString >& seqValue )
548 {
549 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
550 computeChanges();
551
552 if ( m_localKey.is() && m_localKey->isValid() )
553 {
554 m_localKey->setStringListValue(seqValue);
555 }
556 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
557 {
558 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
559 m_localKey = rootKey->createKey(m_name);
560 m_localKey->setStringListValue(seqValue);
561 m_state = m_xRegistry->m_state++;
562 }
563 else
564 {
565 throw InvalidRegistryException();
566 }
567 }
568
569
getBinaryValue()570 Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue( )
571 {
572 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
573 computeChanges();
574
575 if ( m_localKey.is() && m_localKey->isValid() )
576 {
577 return m_localKey->getBinaryValue();
578 }
579 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
580 {
581 return m_defaultKey->getBinaryValue();
582 }
583 else
584 {
585 throw InvalidRegistryException();
586 }
587 }
588
589
setBinaryValue(const Sequence<sal_Int8> & value)590 void SAL_CALL NestedKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value )
591 {
592 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
593 computeChanges();
594
595 if ( m_localKey.is() && m_localKey->isValid() )
596 {
597 m_localKey->setBinaryValue(value);
598 }
599 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
600 {
601 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
602 m_localKey = rootKey->createKey(m_name);
603 m_localKey->setBinaryValue(value);
604 m_state = m_xRegistry->m_state++;
605 }
606 else
607 {
608 throw InvalidRegistryException();
609 }
610 }
611
612
openKey(const OUString & aKeyName)613 Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName )
614 {
615 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
616 if ( !m_localKey.is() && !m_defaultKey.is() )
617 {
618 throw InvalidRegistryException();
619 }
620
621 OUString resolvedName = computeName(aKeyName);
622
623 if ( resolvedName.isEmpty() )
624 throw InvalidRegistryException();
625
626 Reference<XRegistryKey> localKey, defaultKey;
627
628 if ( m_localKey.is() && m_localKey->isValid() )
629 {
630 localKey = m_xRegistry->m_localReg->getRootKey()->openKey(resolvedName);
631 }
632 if ( m_defaultKey.is() && m_defaultKey->isValid() )
633 {
634 defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
635 }
636
637 if ( localKey.is() || defaultKey.is() )
638 {
639 return new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey);
640 }
641 else
642 {
643 return Reference<XRegistryKey>();
644 }
645 }
646
647
createKey(const OUString & aKeyName)648 Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName )
649 {
650 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
651 if ( (!m_localKey.is() && !m_defaultKey.is()) ||
652 (m_localKey.is() && m_localKey->isReadOnly()) )
653 {
654 throw InvalidRegistryException();
655 }
656
657 OUString resolvedName = computeName(aKeyName);
658
659 if ( resolvedName.isEmpty() )
660 throw InvalidRegistryException();
661
662 if ( m_localKey.is() && m_localKey->isValid() )
663 {
664 Reference<XRegistryKey> localKey, defaultKey;
665
666 localKey = m_xRegistry->m_localReg->getRootKey()->createKey(resolvedName);
667 if ( localKey.is() )
668 {
669 if ( m_defaultKey.is() && m_defaultKey->isValid() )
670 {
671 defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
672 }
673
674 m_state = m_xRegistry->m_state++;
675
676 return new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey);
677 }
678 }
679 else
680 {
681 Reference<XRegistryKey> localKey, defaultKey;
682
683 if ( m_defaultKey.is() && m_defaultKey->isValid() )
684 {
685 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
686 m_localKey = rootKey->createKey(m_name);
687
688 localKey = m_xRegistry->m_localReg->getRootKey()->createKey(resolvedName);
689
690 if ( localKey.is() )
691 {
692 defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
693
694 m_state = m_xRegistry->m_state++;
695
696 return new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey);
697 }
698 }
699 }
700
701 return Reference<XRegistryKey>();
702 }
703
704
closeKey()705 void SAL_CALL NestedKeyImpl::closeKey( )
706 {
707 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
708 if ( m_localKey.is() && m_localKey->isValid() )
709 {
710 m_localKey->closeKey();
711 }
712 if ( m_defaultKey.is() && m_defaultKey->isValid() )
713 {
714 m_defaultKey->closeKey();
715 }
716 }
717
718
deleteKey(const OUString & rKeyName)719 void SAL_CALL NestedKeyImpl::deleteKey( const OUString& rKeyName )
720 {
721 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
722 if ( !m_localKey.is() || !m_localKey->isValid() ||
723 m_localKey->isReadOnly() )
724 {
725 throw InvalidRegistryException();
726 }
727
728 OUString resolvedName = computeName(rKeyName);
729
730 if ( resolvedName.isEmpty() )
731 {
732 throw InvalidRegistryException();
733 }
734
735 m_xRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
736 }
737
738
openKeys()739 Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( )
740 {
741 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
742 if ( !m_localKey.is() && !m_defaultKey.is() )
743 {
744 throw InvalidRegistryException();
745 }
746
747 Sequence<OUString> localSeq, defaultSeq;
748
749 if ( m_localKey.is() && m_localKey->isValid() )
750 {
751 localSeq = m_localKey->getKeyNames();
752 }
753 if ( m_defaultKey.is() && m_defaultKey->isValid() )
754 {
755 defaultSeq = m_defaultKey->getKeyNames();
756 }
757
758 std::vector< Reference<XRegistryKey> > retVec;
759 retVec.reserve(localSeq.getLength() + defaultSeq.getLength());
760
761 auto lKeyNameToRegKey = [this](const OUString& rName) -> Reference<XRegistryKey> {
762 sal_Int32 lastIndex = rName.lastIndexOf('/');
763 OUString name = rName.copy(lastIndex);
764 return new NestedKeyImpl(name, this);
765 };
766
767 for (const auto& rKeyName : std::as_const(localSeq))
768 retVec.push_back(lKeyNameToRegKey(rKeyName));
769
770 for (const auto& rKeyName : std::as_const(defaultSeq))
771 {
772 if ( comphelper::findValue(localSeq, rKeyName) == -1 )
773 {
774 retVec.push_back(lKeyNameToRegKey(rKeyName));
775 }
776 }
777
778 return comphelper::containerToSequence(retVec);
779 }
780
781
getKeyNames()782 Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( )
783 {
784 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
785 if ( !m_localKey.is() && !m_defaultKey.is() )
786 {
787 throw InvalidRegistryException();
788 }
789
790 Sequence<OUString> localSeq, defaultSeq;
791
792 if ( m_localKey.is() && m_localKey->isValid() )
793 {
794 localSeq = m_localKey->getKeyNames();
795 }
796 if ( m_defaultKey.is() && m_defaultKey->isValid() )
797 {
798 defaultSeq = m_defaultKey->getKeyNames();
799 }
800
801 return comphelper::combineSequences(localSeq, defaultSeq);
802 }
803
804
createLink(const OUString & aLinkName,const OUString & aLinkTarget)805 sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
806 {
807 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
808
809 bool isCreated = false;
810 if ( !m_localKey.is() && !m_defaultKey.is() )
811 {
812 throw InvalidRegistryException();
813 }
814
815 OUString linkName;
816 OUString resolvedName;
817 sal_Int32 lastIndex = aLinkName.lastIndexOf('/');
818
819 if ( lastIndex > 0 )
820 {
821 linkName = aLinkName.copy(0, lastIndex);
822
823 resolvedName = computeName(linkName);
824
825 if ( resolvedName.isEmpty() )
826 {
827 throw InvalidRegistryException();
828 }
829
830 resolvedName += aLinkName.copy(lastIndex);
831 }
832 else
833 {
834 if ( lastIndex == 0 )
835 resolvedName = m_name + aLinkName;
836 else
837 resolvedName = m_name + "/" + aLinkName;
838 }
839
840 if ( m_localKey.is() && m_localKey->isValid() )
841 {
842 isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
843 }
844 else
845 {
846 if ( m_defaultKey.is() && m_defaultKey->isValid() )
847 {
848 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
849 m_localKey = rootKey->createKey(m_name);
850
851 isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
852 }
853 }
854
855 if ( isCreated )
856 m_state = m_xRegistry->m_state++;
857
858 return isCreated;
859 }
860
861
deleteLink(const OUString & rLinkName)862 void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
863 {
864 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
865 if ( !m_localKey.is() && !m_defaultKey.is() )
866 {
867 throw InvalidRegistryException();
868 }
869
870 OUString linkName;
871 OUString resolvedName;
872 sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
873
874 if ( lastIndex > 0 )
875 {
876 linkName = rLinkName.copy(0, lastIndex);
877
878 resolvedName = computeName(linkName);
879
880 if ( resolvedName.isEmpty() )
881 {
882 throw InvalidRegistryException();
883 }
884
885 resolvedName += rLinkName.copy(lastIndex);
886 }
887 else
888 {
889 if ( lastIndex == 0 )
890 resolvedName = m_name + rLinkName;
891 else
892 resolvedName = m_name + "/" + rLinkName;
893 }
894
895 if ( !m_localKey.is() || !m_localKey->isValid() ||
896 m_localKey->isReadOnly() )
897 {
898 throw InvalidRegistryException();
899 }
900
901 m_xRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
902 }
903
904
getLinkTarget(const OUString & rLinkName)905 OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
906 {
907 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
908 if ( !m_localKey.is() && !m_defaultKey.is() )
909 {
910 throw InvalidRegistryException();
911 }
912
913 OUString linkName;
914 OUString resolvedName;
915 sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
916
917 if ( lastIndex > 0 )
918 {
919 linkName = rLinkName.copy(0, lastIndex);
920
921 resolvedName = computeName(linkName);
922
923 if ( resolvedName.isEmpty() )
924 {
925 throw InvalidRegistryException();
926 }
927
928 resolvedName += rLinkName.copy(lastIndex);
929 }
930 else
931 {
932 if ( lastIndex == 0 )
933 resolvedName = m_name + rLinkName;
934 else
935 resolvedName = m_name + "/" + rLinkName;
936 }
937
938 OUString linkTarget;
939 if ( m_localKey.is() && m_localKey->isValid() )
940 {
941 try
942 {
943 linkTarget = m_xRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
944 return linkTarget;
945 }
946 catch(InvalidRegistryException& )
947 {
948 }
949 }
950
951 if ( m_defaultKey.is() && m_defaultKey->isValid() )
952 linkTarget = m_xRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
953
954 return linkTarget;
955 }
956
957
getResolvedName(const OUString & aKeyName)958 OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
959 {
960 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
961 if ( !m_localKey.is() && !m_defaultKey.is() )
962 {
963 throw InvalidRegistryException();
964 }
965
966 OUString resolvedName = computeName(aKeyName);
967
968 if ( resolvedName.isEmpty() )
969 {
970 throw InvalidRegistryException();
971 }
972
973 return resolvedName;
974 }
975
976
977 // DefaultRegistry Implementation
978
979
NestedRegistryImpl()980 NestedRegistryImpl::NestedRegistryImpl( )
981 : m_state(0)
982 {}
983
984 class RegistryEnumueration : public WeakImplHelper< XEnumeration >
985 {
986 public:
RegistryEnumueration(const Reference<XSimpleRegistry> & r1,const Reference<XSimpleRegistry> & r2)987 RegistryEnumueration(
988 const Reference< XSimpleRegistry > &r1,
989 const Reference< XSimpleRegistry > &r2 )
990 : m_xReg1( r1 ) , m_xReg2( r2 )
991 {}
992 public:
993 virtual sal_Bool SAL_CALL hasMoreElements( ) override;
994 virtual Any SAL_CALL nextElement( ) override;
995
996 private:
997 Reference< XSimpleRegistry > m_xReg1;
998 Reference< XSimpleRegistry > m_xReg2;
999 };
1000
hasMoreElements()1001 sal_Bool RegistryEnumueration::hasMoreElements( )
1002 {
1003 return m_xReg1.is() || m_xReg2.is();
1004 }
1005
nextElement()1006 Any RegistryEnumueration::nextElement( )
1007 {
1008 Any a;
1009 if( m_xReg1.is() )
1010 {
1011 a <<= m_xReg1;
1012 m_xReg1.clear();
1013 }
1014 else if( m_xReg2.is() )
1015 {
1016 a <<= m_xReg2;
1017 m_xReg2.clear();
1018 }
1019 else
1020 {
1021 throw NoSuchElementException( "NestedRegistry: no nextElement() !" );
1022 }
1023 return a;
1024 }
1025
1026
createEnumeration()1027 Reference< XEnumeration > NestedRegistryImpl::createEnumeration( )
1028 {
1029 MutexGuard guard( m_mutex );
1030 return new RegistryEnumueration( m_localReg, m_defaultReg );
1031 }
1032
getElementType()1033 Type NestedRegistryImpl::getElementType( )
1034 {
1035 return cppu::UnoType<decltype(m_localReg)>::get();
1036 }
1037
hasElements()1038 sal_Bool SAL_CALL NestedRegistryImpl::hasElements( )
1039 {
1040 MutexGuard guard( m_mutex );
1041 return m_localReg.is() || m_defaultReg.is();
1042 }
1043
1044
getImplementationName()1045 OUString SAL_CALL NestedRegistryImpl::getImplementationName( )
1046 {
1047 return "com.sun.star.comp.stoc.NestedRegistry";
1048 }
1049
supportsService(const OUString & ServiceName)1050 sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
1051 {
1052 return cppu::supportsService(this, ServiceName);
1053 }
1054
getSupportedServiceNames()1055 Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( )
1056 {
1057 Sequence< OUString > seqNames { "com.sun.star.registry.NestedRegistry" };
1058 return seqNames;
1059 }
1060
1061
initialize(const Sequence<Any> & aArguments)1062 void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
1063 {
1064 Guard< Mutex > aGuard( m_mutex );
1065 if ( (aArguments.getLength() == 2) &&
1066 (aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) &&
1067 (aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) )
1068 {
1069 aArguments[0] >>= m_localReg;
1070 aArguments[1] >>= m_defaultReg;
1071 if ( m_localReg == m_defaultReg )
1072 m_defaultReg.clear();
1073 }
1074 }
1075
1076
getURL()1077 OUString SAL_CALL NestedRegistryImpl::getURL()
1078 {
1079 Guard< Mutex > aGuard( m_mutex );
1080 try
1081 {
1082 if ( m_localReg.is() && m_localReg->isValid() )
1083 return m_localReg->getURL();
1084 }
1085 catch(InvalidRegistryException& )
1086 {
1087 }
1088
1089 return OUString();
1090 }
1091
1092
open(const OUString &,sal_Bool,sal_Bool)1093 void SAL_CALL NestedRegistryImpl::open( const OUString&, sal_Bool, sal_Bool )
1094 {
1095 throw InvalidRegistryException(
1096 "the 'open' method is not specified for a nested registry" );
1097 }
1098
1099
isValid()1100 sal_Bool SAL_CALL NestedRegistryImpl::isValid( )
1101 {
1102 Guard< Mutex > aGuard( m_mutex );
1103 try
1104 {
1105 if ( (m_localReg.is() && m_localReg->isValid()) ||
1106 (m_defaultReg.is() && m_defaultReg->isValid()) )
1107 return true;
1108 }
1109 catch(InvalidRegistryException& )
1110 {
1111 }
1112
1113 return false;
1114 }
1115
1116
close()1117 void SAL_CALL NestedRegistryImpl::close( )
1118 {
1119 Guard< Mutex > aGuard( m_mutex );
1120 if ( m_localReg.is() && m_localReg->isValid() )
1121 {
1122 m_localReg->close();
1123 }
1124 if ( m_defaultReg.is() && m_defaultReg->isValid() )
1125 {
1126 m_defaultReg->close();
1127 }
1128 }
1129
1130
destroy()1131 void SAL_CALL NestedRegistryImpl::destroy( )
1132 {
1133 throw InvalidRegistryException(
1134 "the 'destroy' method is not specified for a nested registry" );
1135 }
1136
1137
getRootKey()1138 Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( )
1139 {
1140 Guard< Mutex > aGuard( m_mutex );
1141 if ( !m_localReg.is() || !m_localReg->isValid() )
1142 {
1143 throw InvalidRegistryException();
1144 }
1145
1146 Reference<XRegistryKey> localKey, defaultKey;
1147
1148 localKey = m_localReg->getRootKey();
1149
1150 if ( localKey.is() )
1151 {
1152 if ( m_defaultReg.is() && m_defaultReg->isValid() )
1153 {
1154 defaultKey = m_defaultReg->getRootKey();
1155 }
1156
1157 return new NestedKeyImpl(this, localKey, defaultKey);
1158 }
1159
1160 return Reference<XRegistryKey>();
1161 }
1162
1163
isReadOnly()1164 sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( )
1165 {
1166 Guard< Mutex > aGuard( m_mutex );
1167 try
1168 {
1169 if ( m_localReg.is() && m_localReg->isValid() )
1170 return m_localReg->isReadOnly();
1171 }
1172 catch(InvalidRegistryException& )
1173 {
1174 }
1175
1176 return false;
1177 }
1178
1179
mergeKey(const OUString & aKeyName,const OUString & aUrl)1180 void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl )
1181 {
1182 Guard< Mutex > aGuard( m_mutex );
1183 if ( m_localReg.is() && m_localReg->isValid() )
1184 {
1185 m_localReg->mergeKey(aKeyName, aUrl);
1186
1187 m_state++;
1188 }
1189 }
1190
1191 } // namespace
1192
1193 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
com_sun_star_comp_stoc_NestedRegistry_get_implementation(SAL_UNUSED_PARAMETER css::uno::XComponentContext *,css::uno::Sequence<css::uno::Any> const &)1194 com_sun_star_comp_stoc_NestedRegistry_get_implementation(
1195 SAL_UNUSED_PARAMETER css::uno::XComponentContext *,
1196 css::uno::Sequence<css::uno::Any> const &)
1197 {
1198 return cppu::acquire(new NestedRegistryImpl);
1199 }
1200
1201 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
1202