1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
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>
33 namespace com::sun::star::uno
{ class XComponentContext
; }
35 using namespace css::uno
;
36 using namespace css::registry
;
37 using namespace css::lang
;
38 using namespace css::container
;
44 class NestedRegistryImpl
: public WeakAggImplHelper4
< XSimpleRegistry
, XInitialization
, XServiceInfo
, XEnumerationAccess
>
47 NestedRegistryImpl( );
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
;
55 virtual void SAL_CALL
initialize( const Sequence
< Any
>& aArguments
) override
;
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
;
68 virtual Reference
< XEnumeration
> SAL_CALL
createEnumeration( ) override
;
69 virtual Type SAL_CALL
getElementType( ) override
;
70 virtual sal_Bool SAL_CALL
hasElements( ) override
;
72 friend class NestedKeyImpl
;
76 Reference
<XSimpleRegistry
> m_localReg
;
77 Reference
<XSimpleRegistry
> m_defaultReg
;
82 // class NestedKeyImpl the implementation of interface XRegistryKey
84 class NestedKeyImpl
: public WeakImplHelper
< XRegistryKey
>
87 NestedKeyImpl( NestedRegistryImpl
* pDefaultRegistry
,
88 Reference
<XRegistryKey
>& localKey
,
89 Reference
<XRegistryKey
>& defaultKey
);
91 NestedKeyImpl( const OUString
& aKeyName
,
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
;
126 void computeChanges();
127 OUString
computeName(const OUString
& name
);
131 rtl::Reference
<NestedRegistryImpl
> m_xRegistry
;
132 Reference
<XRegistryKey
> m_localKey
;
133 Reference
<XRegistryKey
> m_defaultKey
;
137 NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl
* pDefaultRegistry
,
138 Reference
<XRegistryKey
>& localKey
,
139 Reference
<XRegistryKey
>& defaultKey
)
140 : m_state(pDefaultRegistry
->m_state
), m_xRegistry(pDefaultRegistry
), m_localKey(localKey
), m_defaultKey(defaultKey
)
144 m_name
= m_localKey
->getKeyName();
146 else if (m_defaultKey
.is())
148 m_name
= m_defaultKey
->getKeyName();
153 NestedKeyImpl::NestedKeyImpl( const OUString
& rKeyName
,
155 : m_xRegistry(pKey
->m_xRegistry
)
157 if (pKey
->m_localKey
.is() && pKey
->m_localKey
->isValid())
159 m_localKey
= pKey
->m_localKey
->openKey(rKeyName
);
161 if (pKey
->m_defaultKey
.is() && pKey
->m_defaultKey
->isValid())
163 m_defaultKey
= pKey
->m_defaultKey
->openKey(rKeyName
);
168 m_name
= m_localKey
->getKeyName();
170 else if (m_defaultKey
.is())
172 m_name
= m_defaultKey
->getKeyName();
175 m_state
= m_xRegistry
->m_state
;
178 void NestedKeyImpl::computeChanges()
180 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
181 if ( m_state
== m_xRegistry
->m_state
)
184 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
186 Reference
<XRegistryKey
> tmpKey
= rootKey
->openKey(m_name
);
190 m_localKey
= rootKey
->openKey(m_name
);
193 m_state
= m_xRegistry
->m_state
;
197 // NestedKey_Impl::computeName()
199 OUString
NestedKeyImpl::computeName(const OUString
& name
)
201 OUString resLocalName
, resDefaultName
;
203 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
206 if ( m_localKey
.is() && m_localKey
->isValid() )
208 resLocalName
= m_localKey
->getResolvedName(name
);
210 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
212 return m_defaultKey
->getResolvedName(name
);
215 if ( !resLocalName
.isEmpty() && m_xRegistry
->m_defaultReg
->isValid() )
217 Reference
<XRegistryKey
> localRoot(m_xRegistry
->m_localReg
->getRootKey());
218 Reference
<XRegistryKey
> defaultRoot(m_xRegistry
->m_defaultReg
->getRootKey());
220 resDefaultName
= defaultRoot
->getResolvedName(resLocalName
);
222 sal_uInt32 count
= 100;
224 while (resLocalName
!= resDefaultName
&& count
> 0)
228 if (resLocalName
.isEmpty() || resDefaultName
.isEmpty())
229 throw InvalidRegistryException();
231 resLocalName
= localRoot
->getResolvedName(resDefaultName
);
232 resDefaultName
= defaultRoot
->getResolvedName(resLocalName
);
236 catch(InvalidRegistryException
& )
244 OUString SAL_CALL
NestedKeyImpl::getKeyName()
246 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
251 sal_Bool SAL_CALL
NestedKeyImpl::isReadOnly( )
253 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
256 if ( !m_localKey
.is() || !m_localKey
->isValid() )
257 throw InvalidRegistryException();
259 return m_localKey
->isReadOnly();
263 sal_Bool SAL_CALL
NestedKeyImpl::isValid( )
265 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
266 return ((m_localKey
.is() && m_localKey
->isValid()) ||
267 (m_defaultKey
.is() && m_defaultKey
->isValid()) );
271 RegistryKeyType SAL_CALL
NestedKeyImpl::getKeyType( const OUString
& rKeyName
)
273 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
276 if ( m_localKey
.is() && m_localKey
->isValid() )
278 return m_localKey
->getKeyType(rKeyName
);
280 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
282 return m_defaultKey
->getKeyType(rKeyName
);
285 return RegistryKeyType_KEY
;
289 RegistryValueType SAL_CALL
NestedKeyImpl::getValueType( )
291 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
294 if ( m_localKey
.is() && m_localKey
->isValid() )
296 return m_localKey
->getValueType();
298 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
300 return m_defaultKey
->getValueType();
303 return RegistryValueType_NOT_DEFINED
;
307 sal_Int32 SAL_CALL
NestedKeyImpl::getLongValue( )
309 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
312 if ( m_localKey
.is() && m_localKey
->isValid() )
314 return m_localKey
->getLongValue();
316 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
318 return m_defaultKey
->getLongValue();
322 throw InvalidRegistryException();
327 void SAL_CALL
NestedKeyImpl::setLongValue( sal_Int32 value
)
329 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
332 if ( m_localKey
.is() && m_localKey
->isValid() )
334 m_localKey
->setLongValue(value
);
336 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
338 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
339 m_localKey
= rootKey
->createKey(m_name
);
340 m_localKey
->setLongValue(value
);
341 m_state
= m_xRegistry
->m_state
++;
345 throw InvalidRegistryException();
350 Sequence
< sal_Int32
> SAL_CALL
NestedKeyImpl::getLongListValue( )
352 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
355 if ( m_localKey
.is() && m_localKey
->isValid() )
357 return m_localKey
->getLongListValue();
359 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
361 return m_defaultKey
->getLongListValue();
365 throw InvalidRegistryException();
370 void SAL_CALL
NestedKeyImpl::setLongListValue( const Sequence
< sal_Int32
>& seqValue
)
372 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
375 if ( m_localKey
.is() && m_localKey
->isValid() )
377 m_localKey
->setLongListValue(seqValue
);
379 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
381 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
382 m_localKey
= rootKey
->createKey(m_name
);
383 m_localKey
->setLongListValue(seqValue
);
384 m_state
= m_xRegistry
->m_state
++;
388 throw InvalidRegistryException();
393 OUString SAL_CALL
NestedKeyImpl::getAsciiValue( )
395 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
398 if ( m_localKey
.is() && m_localKey
->isValid() )
400 return m_localKey
->getAsciiValue();
402 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
404 return m_defaultKey
->getAsciiValue();
408 throw InvalidRegistryException();
413 void SAL_CALL
NestedKeyImpl::setAsciiValue( const OUString
& value
)
415 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
418 if ( m_localKey
.is() && m_localKey
->isValid() )
420 m_localKey
->setAsciiValue(value
);
422 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
424 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
425 m_localKey
= rootKey
->createKey(m_name
);
426 m_localKey
->setAsciiValue(value
);
427 m_state
= m_xRegistry
->m_state
++;
431 throw InvalidRegistryException();
436 Sequence
< OUString
> SAL_CALL
NestedKeyImpl::getAsciiListValue( )
438 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
441 if ( m_localKey
.is() && m_localKey
->isValid() )
443 return m_localKey
->getAsciiListValue();
445 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
447 return m_defaultKey
->getAsciiListValue();
451 throw InvalidRegistryException();
456 void SAL_CALL
NestedKeyImpl::setAsciiListValue( const Sequence
< OUString
>& seqValue
)
458 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
461 if ( m_localKey
.is() && m_localKey
->isValid() )
463 m_localKey
->setAsciiListValue(seqValue
);
465 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
467 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
468 m_localKey
= rootKey
->createKey(m_name
);
469 m_localKey
->setAsciiListValue(seqValue
);
470 m_state
= m_xRegistry
->m_state
++;
474 throw InvalidRegistryException();
479 OUString SAL_CALL
NestedKeyImpl::getStringValue( )
481 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
484 if ( m_localKey
.is() && m_localKey
->isValid() )
486 return m_localKey
->getStringValue();
488 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
490 return m_defaultKey
->getStringValue();
494 throw InvalidRegistryException();
499 void SAL_CALL
NestedKeyImpl::setStringValue( const OUString
& value
)
501 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
504 if ( m_localKey
.is() && m_localKey
->isValid() )
506 m_localKey
->setStringValue(value
);
508 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
510 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
511 m_localKey
= rootKey
->createKey(m_name
);
512 m_localKey
->setStringValue(value
);
513 m_state
= m_xRegistry
->m_state
++;
517 throw InvalidRegistryException();
522 Sequence
< OUString
> SAL_CALL
NestedKeyImpl::getStringListValue( )
524 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
527 if ( m_localKey
.is() && m_localKey
->isValid() )
529 return m_localKey
->getStringListValue();
531 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
533 return m_defaultKey
->getStringListValue();
537 throw InvalidRegistryException();
542 void SAL_CALL
NestedKeyImpl::setStringListValue( const Sequence
< OUString
>& seqValue
)
544 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
547 if ( m_localKey
.is() && m_localKey
->isValid() )
549 m_localKey
->setStringListValue(seqValue
);
551 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
553 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
554 m_localKey
= rootKey
->createKey(m_name
);
555 m_localKey
->setStringListValue(seqValue
);
556 m_state
= m_xRegistry
->m_state
++;
560 throw InvalidRegistryException();
565 Sequence
< sal_Int8
> SAL_CALL
NestedKeyImpl::getBinaryValue( )
567 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
570 if ( m_localKey
.is() && m_localKey
->isValid() )
572 return m_localKey
->getBinaryValue();
574 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
576 return m_defaultKey
->getBinaryValue();
580 throw InvalidRegistryException();
585 void SAL_CALL
NestedKeyImpl::setBinaryValue( const Sequence
< sal_Int8
>& value
)
587 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
590 if ( m_localKey
.is() && m_localKey
->isValid() )
592 m_localKey
->setBinaryValue(value
);
594 else if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
596 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
597 m_localKey
= rootKey
->createKey(m_name
);
598 m_localKey
->setBinaryValue(value
);
599 m_state
= m_xRegistry
->m_state
++;
603 throw InvalidRegistryException();
608 Reference
< XRegistryKey
> SAL_CALL
NestedKeyImpl::openKey( const OUString
& aKeyName
)
610 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
611 if ( !m_localKey
.is() && !m_defaultKey
.is() )
613 throw InvalidRegistryException();
616 OUString resolvedName
= computeName(aKeyName
);
618 if ( resolvedName
.isEmpty() )
619 throw InvalidRegistryException();
621 Reference
<XRegistryKey
> localKey
, defaultKey
;
623 if ( m_localKey
.is() && m_localKey
->isValid() )
625 localKey
= m_xRegistry
->m_localReg
->getRootKey()->openKey(resolvedName
);
627 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
629 defaultKey
= m_xRegistry
->m_defaultReg
->getRootKey()->openKey(resolvedName
);
632 if ( localKey
.is() || defaultKey
.is() )
634 return new NestedKeyImpl(m_xRegistry
.get(), localKey
, defaultKey
);
638 return Reference
<XRegistryKey
>();
643 Reference
< XRegistryKey
> SAL_CALL
NestedKeyImpl::createKey( const OUString
& aKeyName
)
645 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
646 if ( (!m_localKey
.is() && !m_defaultKey
.is()) ||
647 (m_localKey
.is() && m_localKey
->isReadOnly()) )
649 throw InvalidRegistryException();
652 OUString resolvedName
= computeName(aKeyName
);
654 if ( resolvedName
.isEmpty() )
655 throw InvalidRegistryException();
657 if ( m_localKey
.is() && m_localKey
->isValid() )
659 Reference
<XRegistryKey
> localKey
, defaultKey
;
661 localKey
= m_xRegistry
->m_localReg
->getRootKey()->createKey(resolvedName
);
664 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
666 defaultKey
= m_xRegistry
->m_defaultReg
->getRootKey()->openKey(resolvedName
);
669 m_state
= m_xRegistry
->m_state
++;
671 return new NestedKeyImpl(m_xRegistry
.get(), localKey
, defaultKey
);
676 Reference
<XRegistryKey
> localKey
, defaultKey
;
678 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
680 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
681 m_localKey
= rootKey
->createKey(m_name
);
683 localKey
= m_xRegistry
->m_localReg
->getRootKey()->createKey(resolvedName
);
687 defaultKey
= m_xRegistry
->m_defaultReg
->getRootKey()->openKey(resolvedName
);
689 m_state
= m_xRegistry
->m_state
++;
691 return new NestedKeyImpl(m_xRegistry
.get(), localKey
, defaultKey
);
696 return Reference
<XRegistryKey
>();
700 void SAL_CALL
NestedKeyImpl::closeKey( )
702 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
703 if ( m_localKey
.is() && m_localKey
->isValid() )
705 m_localKey
->closeKey();
707 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
709 m_defaultKey
->closeKey();
714 void SAL_CALL
NestedKeyImpl::deleteKey( const OUString
& rKeyName
)
716 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
717 if ( !m_localKey
.is() || !m_localKey
->isValid() ||
718 m_localKey
->isReadOnly() )
720 throw InvalidRegistryException();
723 OUString resolvedName
= computeName(rKeyName
);
725 if ( resolvedName
.isEmpty() )
727 throw InvalidRegistryException();
730 m_xRegistry
->m_localReg
->getRootKey()->deleteKey(resolvedName
);
734 Sequence
< Reference
< XRegistryKey
> > SAL_CALL
NestedKeyImpl::openKeys( )
736 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
737 if ( !m_localKey
.is() && !m_defaultKey
.is() )
739 throw InvalidRegistryException();
742 Sequence
<OUString
> localSeq
, defaultSeq
;
744 if ( m_localKey
.is() && m_localKey
->isValid() )
746 localSeq
= m_localKey
->getKeyNames();
748 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
750 defaultSeq
= m_defaultKey
->getKeyNames();
753 std::vector
< Reference
<XRegistryKey
> > retVec
;
754 retVec
.reserve(localSeq
.getLength() + defaultSeq
.getLength());
756 auto lKeyNameToRegKey
= [this](const OUString
& rName
) -> Reference
<XRegistryKey
> {
757 sal_Int32 lastIndex
= rName
.lastIndexOf('/');
758 OUString name
= rName
.copy(lastIndex
);
759 return new NestedKeyImpl(name
, this);
762 for (const auto& rKeyName
: std::as_const(localSeq
))
763 retVec
.push_back(lKeyNameToRegKey(rKeyName
));
765 for (const auto& rKeyName
: std::as_const(defaultSeq
))
767 if ( comphelper::findValue(localSeq
, rKeyName
) == -1 )
769 retVec
.push_back(lKeyNameToRegKey(rKeyName
));
773 return comphelper::containerToSequence(retVec
);
777 Sequence
< OUString
> SAL_CALL
NestedKeyImpl::getKeyNames( )
779 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
780 if ( !m_localKey
.is() && !m_defaultKey
.is() )
782 throw InvalidRegistryException();
785 Sequence
<OUString
> localSeq
, defaultSeq
;
787 if ( m_localKey
.is() && m_localKey
->isValid() )
789 localSeq
= m_localKey
->getKeyNames();
791 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
793 defaultSeq
= m_defaultKey
->getKeyNames();
796 return comphelper::combineSequences(localSeq
, defaultSeq
);
800 sal_Bool SAL_CALL
NestedKeyImpl::createLink( const OUString
& aLinkName
, const OUString
& aLinkTarget
)
802 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
804 bool isCreated
= false;
805 if ( !m_localKey
.is() && !m_defaultKey
.is() )
807 throw InvalidRegistryException();
810 OUString resolvedName
;
811 sal_Int32 lastIndex
= aLinkName
.lastIndexOf('/');
815 OUString linkName
= aLinkName
.copy(0, lastIndex
);
817 resolvedName
= computeName(linkName
);
819 if ( resolvedName
.isEmpty() )
821 throw InvalidRegistryException();
824 resolvedName
+= aLinkName
.subView(lastIndex
);
828 if ( lastIndex
== 0 )
829 resolvedName
= m_name
+ aLinkName
;
831 resolvedName
= m_name
+ "/" + aLinkName
;
834 if ( m_localKey
.is() && m_localKey
->isValid() )
836 isCreated
= m_xRegistry
->m_localReg
->getRootKey()->createLink(resolvedName
, aLinkTarget
);
840 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
842 Reference
<XRegistryKey
> rootKey(m_xRegistry
->m_localReg
->getRootKey());
843 m_localKey
= rootKey
->createKey(m_name
);
845 isCreated
= m_xRegistry
->m_localReg
->getRootKey()->createLink(resolvedName
, aLinkTarget
);
850 m_state
= m_xRegistry
->m_state
++;
856 void SAL_CALL
NestedKeyImpl::deleteLink( const OUString
& rLinkName
)
858 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
859 if ( !m_localKey
.is() && !m_defaultKey
.is() )
861 throw InvalidRegistryException();
864 OUString resolvedName
;
865 sal_Int32 lastIndex
= rLinkName
.lastIndexOf('/');
869 OUString linkName
= rLinkName
.copy(0, lastIndex
);
871 resolvedName
= computeName(linkName
);
873 if ( resolvedName
.isEmpty() )
875 throw InvalidRegistryException();
878 resolvedName
+= rLinkName
.subView(lastIndex
);
882 if ( lastIndex
== 0 )
883 resolvedName
= m_name
+ rLinkName
;
885 resolvedName
= m_name
+ "/" + rLinkName
;
888 if ( !m_localKey
.is() || !m_localKey
->isValid() ||
889 m_localKey
->isReadOnly() )
891 throw InvalidRegistryException();
894 m_xRegistry
->m_localReg
->getRootKey()->deleteLink(resolvedName
);
898 OUString SAL_CALL
NestedKeyImpl::getLinkTarget( const OUString
& rLinkName
)
900 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
901 if ( !m_localKey
.is() && !m_defaultKey
.is() )
903 throw InvalidRegistryException();
906 OUString resolvedName
;
907 sal_Int32 lastIndex
= rLinkName
.lastIndexOf('/');
911 OUString linkName
= rLinkName
.copy(0, lastIndex
);
913 resolvedName
= computeName(linkName
);
915 if ( resolvedName
.isEmpty() )
917 throw InvalidRegistryException();
920 resolvedName
+= rLinkName
.subView(lastIndex
);
924 if ( lastIndex
== 0 )
925 resolvedName
= m_name
+ rLinkName
;
927 resolvedName
= m_name
+ "/" + rLinkName
;
931 if ( m_localKey
.is() && m_localKey
->isValid() )
935 linkTarget
= m_xRegistry
->m_localReg
->getRootKey()->getLinkTarget(resolvedName
);
938 catch(InvalidRegistryException
& )
943 if ( m_defaultKey
.is() && m_defaultKey
->isValid() )
944 linkTarget
= m_xRegistry
->m_defaultReg
->getRootKey()->getLinkTarget(resolvedName
);
950 OUString SAL_CALL
NestedKeyImpl::getResolvedName( const OUString
& aKeyName
)
952 Guard
< Mutex
> aGuard( m_xRegistry
->m_mutex
);
953 if ( !m_localKey
.is() && !m_defaultKey
.is() )
955 throw InvalidRegistryException();
958 OUString resolvedName
= computeName(aKeyName
);
960 if ( resolvedName
.isEmpty() )
962 throw InvalidRegistryException();
969 // DefaultRegistry Implementation
972 NestedRegistryImpl::NestedRegistryImpl( )
976 class RegistryEnumueration
: public WeakImplHelper
< XEnumeration
>
979 RegistryEnumueration(
980 const Reference
< XSimpleRegistry
> &r1
,
981 const Reference
< XSimpleRegistry
> &r2
)
982 : m_xReg1( r1
) , m_xReg2( r2
)
985 virtual sal_Bool SAL_CALL
hasMoreElements( ) override
;
986 virtual Any SAL_CALL
nextElement( ) override
;
989 Reference
< XSimpleRegistry
> m_xReg1
;
990 Reference
< XSimpleRegistry
> m_xReg2
;
993 sal_Bool
RegistryEnumueration::hasMoreElements( )
995 return m_xReg1
.is() || m_xReg2
.is();
998 Any
RegistryEnumueration::nextElement( )
1006 else if( m_xReg2
.is() )
1013 throw NoSuchElementException( "NestedRegistry: no nextElement() !" );
1019 Reference
< XEnumeration
> NestedRegistryImpl::createEnumeration( )
1021 MutexGuard
guard( m_mutex
);
1022 return new RegistryEnumueration( m_localReg
, m_defaultReg
);
1025 Type
NestedRegistryImpl::getElementType( )
1027 return cppu::UnoType
<decltype(m_localReg
)>::get();
1030 sal_Bool SAL_CALL
NestedRegistryImpl::hasElements( )
1032 MutexGuard
guard( m_mutex
);
1033 return m_localReg
.is() || m_defaultReg
.is();
1037 OUString SAL_CALL
NestedRegistryImpl::getImplementationName( )
1039 return "com.sun.star.comp.stoc.NestedRegistry";
1042 sal_Bool SAL_CALL
NestedRegistryImpl::supportsService( const OUString
& ServiceName
)
1044 return cppu::supportsService(this, ServiceName
);
1047 Sequence
<OUString
> SAL_CALL
NestedRegistryImpl::getSupportedServiceNames( )
1049 Sequence
< OUString
> seqNames
{ "com.sun.star.registry.NestedRegistry" };
1054 void SAL_CALL
NestedRegistryImpl::initialize( const Sequence
< Any
>& aArguments
)
1056 Guard
< Mutex
> aGuard( m_mutex
);
1057 if ( (aArguments
.getLength() == 2) &&
1058 (aArguments
[0].getValueType().getTypeClass() == TypeClass_INTERFACE
) &&
1059 (aArguments
[1].getValueType().getTypeClass() == TypeClass_INTERFACE
) )
1061 aArguments
[0] >>= m_localReg
;
1062 aArguments
[1] >>= m_defaultReg
;
1063 if ( m_localReg
== m_defaultReg
)
1064 m_defaultReg
.clear();
1069 OUString SAL_CALL
NestedRegistryImpl::getURL()
1071 Guard
< Mutex
> aGuard( m_mutex
);
1074 if ( m_localReg
.is() && m_localReg
->isValid() )
1075 return m_localReg
->getURL();
1077 catch(InvalidRegistryException
& )
1085 void SAL_CALL
NestedRegistryImpl::open( const OUString
&, sal_Bool
, sal_Bool
)
1087 throw InvalidRegistryException(
1088 "the 'open' method is not specified for a nested registry" );
1092 sal_Bool SAL_CALL
NestedRegistryImpl::isValid( )
1094 Guard
< Mutex
> aGuard( m_mutex
);
1097 if ( (m_localReg
.is() && m_localReg
->isValid()) ||
1098 (m_defaultReg
.is() && m_defaultReg
->isValid()) )
1101 catch(InvalidRegistryException
& )
1109 void SAL_CALL
NestedRegistryImpl::close( )
1111 Guard
< Mutex
> aGuard( m_mutex
);
1112 if ( m_localReg
.is() && m_localReg
->isValid() )
1114 m_localReg
->close();
1116 if ( m_defaultReg
.is() && m_defaultReg
->isValid() )
1118 m_defaultReg
->close();
1123 void SAL_CALL
NestedRegistryImpl::destroy( )
1125 throw InvalidRegistryException(
1126 "the 'destroy' method is not specified for a nested registry" );
1130 Reference
< XRegistryKey
> SAL_CALL
NestedRegistryImpl::getRootKey( )
1132 Guard
< Mutex
> aGuard( m_mutex
);
1133 if ( !m_localReg
.is() || !m_localReg
->isValid() )
1135 throw InvalidRegistryException();
1138 Reference
<XRegistryKey
> localKey
, defaultKey
;
1140 localKey
= m_localReg
->getRootKey();
1142 if ( localKey
.is() )
1144 if ( m_defaultReg
.is() && m_defaultReg
->isValid() )
1146 defaultKey
= m_defaultReg
->getRootKey();
1149 return new NestedKeyImpl(this, localKey
, defaultKey
);
1152 return Reference
<XRegistryKey
>();
1156 sal_Bool SAL_CALL
NestedRegistryImpl::isReadOnly( )
1158 Guard
< Mutex
> aGuard( m_mutex
);
1161 if ( m_localReg
.is() && m_localReg
->isValid() )
1162 return m_localReg
->isReadOnly();
1164 catch(InvalidRegistryException
& )
1172 void SAL_CALL
NestedRegistryImpl::mergeKey( const OUString
&, const OUString
& )
1174 throw css::uno::RuntimeException("css.registry.NestedRegistry::mergeKey: not implemented");
1179 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1180 com_sun_star_comp_stoc_NestedRegistry_get_implementation(
1181 SAL_UNUSED_PARAMETER
css::uno::XComponentContext
*,
1182 css::uno::Sequence
<css::uno::Any
> const &)
1184 return cppu::acquire(new NestedRegistryImpl
);
1187 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */