Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / stoc / source / defaultregistry / defaultregistry.cxx
blob90153bb123e8490963a9fe6505c53e08bb196803
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <cppuhelper/queryinterface.hxx>
22 #include <cppuhelper/weak.hxx>
23 #include <cppuhelper/implbase.hxx>
24 #include <cppuhelper/implbase4.hxx>
25 #include <cppuhelper/implementationentry.hxx>
26 #include <cppuhelper/supportsservice.hxx>
27 #include <registry/registry.hxx>
28 #include <rtl/ref.hxx>
30 #include <com/sun/star/registry/XSimpleRegistry.hpp>
31 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include <com/sun/star/lang/XTypeProvider.hpp>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/lang/XInitialization.hpp>
36 #include <com/sun/star/container/XEnumerationAccess.hpp>
38 using namespace css::uno;
39 using namespace css::registry;
40 using namespace css::lang;
41 using namespace css::container;
42 using namespace cppu;
43 using namespace osl;
45 namespace {
47 class NestedKeyImpl;
49 class NestedRegistryImpl : public WeakAggImplHelper4 < XSimpleRegistry, XInitialization, XServiceInfo, XEnumerationAccess >
51 public:
52 NestedRegistryImpl( );
54 // XServiceInfo
55 virtual OUString SAL_CALL getImplementationName( ) override;
56 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
57 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
59 // XInitialization
60 virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
62 // XSimpleRegistry
63 virtual OUString SAL_CALL getURL() override;
64 virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) override;
65 virtual sal_Bool SAL_CALL isValid( ) override;
66 virtual void SAL_CALL close( ) override;
67 virtual void SAL_CALL destroy( ) override;
68 virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) override;
69 virtual sal_Bool SAL_CALL isReadOnly( ) override;
70 virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) override;
72 // XEnumerationAccess
73 virtual Reference< XEnumeration > SAL_CALL createEnumeration( ) override;
74 virtual Type SAL_CALL getElementType( ) override;
75 virtual sal_Bool SAL_CALL hasElements( ) override;
77 friend class NestedKeyImpl;
78 protected:
79 Mutex m_mutex;
80 sal_uInt32 m_state;
81 Reference<XSimpleRegistry> m_localReg;
82 Reference<XSimpleRegistry> m_defaultReg;
87 // class NestedKeyImpl the implementation of interface XRegistryKey
89 class NestedKeyImpl : public WeakImplHelper< XRegistryKey >
91 public:
92 NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
93 Reference<XRegistryKey>& localKey,
94 Reference<XRegistryKey>& defaultKey);
96 NestedKeyImpl( const OUString& aKeyName,
97 NestedKeyImpl* pKey);
99 // XRegistryKey
100 virtual OUString SAL_CALL getKeyName() override;
101 virtual sal_Bool SAL_CALL isReadOnly( ) override;
102 virtual sal_Bool SAL_CALL isValid( ) override;
103 virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) override;
104 virtual RegistryValueType SAL_CALL getValueType( ) override;
105 virtual sal_Int32 SAL_CALL getLongValue( ) override;
106 virtual void SAL_CALL setLongValue( sal_Int32 value ) override;
107 virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) override;
108 virtual void SAL_CALL setLongListValue( const css::uno::Sequence< sal_Int32 >& seqValue ) override;
109 virtual OUString SAL_CALL getAsciiValue( ) override;
110 virtual void SAL_CALL setAsciiValue( const OUString& value ) override;
111 virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) override;
112 virtual void SAL_CALL setAsciiListValue( const css::uno::Sequence< OUString >& seqValue ) override;
113 virtual OUString SAL_CALL getStringValue( ) override;
114 virtual void SAL_CALL setStringValue( const OUString& value ) override;
115 virtual Sequence< OUString > SAL_CALL getStringListValue( ) override;
116 virtual void SAL_CALL setStringListValue( const css::uno::Sequence< OUString >& seqValue ) override;
117 virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) override;
118 virtual void SAL_CALL setBinaryValue( const css::uno::Sequence< sal_Int8 >& value ) override;
119 virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) override;
120 virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) override;
121 virtual void SAL_CALL closeKey( ) override;
122 virtual void SAL_CALL deleteKey( const OUString& rKeyName ) override;
123 virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) override;
124 virtual Sequence< OUString > SAL_CALL getKeyNames( ) override;
125 virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) override;
126 virtual void SAL_CALL deleteLink( const OUString& rLinkName ) override;
127 virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) override;
128 virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) override;
130 protected:
131 void computeChanges();
132 OUString computeName(const OUString& name);
134 OUString m_name;
135 sal_uInt32 m_state;
136 rtl::Reference<NestedRegistryImpl> m_xRegistry;
137 Reference<XRegistryKey> m_localKey;
138 Reference<XRegistryKey> m_defaultKey;
142 NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
143 Reference<XRegistryKey>& localKey,
144 Reference<XRegistryKey>& defaultKey )
145 : m_xRegistry(pDefaultRegistry)
147 m_localKey = localKey;
148 m_defaultKey = defaultKey;
150 if (m_localKey.is())
152 m_name = m_localKey->getKeyName();
154 else if (m_defaultKey.is())
156 m_name = m_defaultKey->getKeyName();
159 m_state = m_xRegistry->m_state;
163 NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName,
164 NestedKeyImpl* pKey)
165 : m_xRegistry(pKey->m_xRegistry)
167 if (pKey->m_localKey.is() && pKey->m_localKey->isValid())
169 m_localKey = pKey->m_localKey->openKey(rKeyName);
171 if (pKey->m_defaultKey.is() && pKey->m_defaultKey->isValid())
173 m_defaultKey = pKey->m_defaultKey->openKey(rKeyName);
176 if (m_localKey.is())
178 m_name = m_localKey->getKeyName();
180 else if (m_defaultKey.is())
182 m_name = m_defaultKey->getKeyName();
185 m_state = m_xRegistry->m_state;
188 void NestedKeyImpl::computeChanges()
190 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
191 if ( m_state != m_xRegistry->m_state )
193 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
195 Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name);
197 if ( tmpKey.is() )
199 m_localKey = rootKey->openKey(m_name);
202 m_state = m_xRegistry->m_state;
207 // NestedKey_Impl::computeName()
209 OUString NestedKeyImpl::computeName(const OUString& name)
211 OUString resLocalName, resDefaultName;
213 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
216 if ( m_localKey.is() && m_localKey->isValid() )
218 resLocalName = m_localKey->getResolvedName(name);
220 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
222 return m_defaultKey->getResolvedName(name);
225 if ( !resLocalName.isEmpty() && m_xRegistry->m_defaultReg->isValid() )
227 Reference<XRegistryKey> localRoot(m_xRegistry->m_localReg->getRootKey());
228 Reference<XRegistryKey> defaultRoot(m_xRegistry->m_defaultReg->getRootKey());
230 resDefaultName = defaultRoot->getResolvedName(resLocalName);
232 sal_uInt32 count = 100;
234 while (resLocalName != resDefaultName && count > 0)
236 count--;
238 if (resLocalName.isEmpty() || resDefaultName.isEmpty())
239 throw InvalidRegistryException();
241 resLocalName = localRoot->getResolvedName(resDefaultName);
242 resDefaultName = defaultRoot->getResolvedName(resLocalName);
246 catch(InvalidRegistryException& )
250 return resLocalName;
254 OUString SAL_CALL NestedKeyImpl::getKeyName()
256 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
257 return m_name;
261 sal_Bool SAL_CALL NestedKeyImpl::isReadOnly( )
263 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
264 computeChanges();
266 if ( !m_localKey.is() || !m_localKey->isValid() )
267 throw InvalidRegistryException();
269 return m_localKey->isReadOnly();
273 sal_Bool SAL_CALL NestedKeyImpl::isValid( )
275 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
276 return ((m_localKey.is() && m_localKey->isValid()) ||
277 (m_defaultKey.is() && m_defaultKey->isValid()) );
281 RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName )
283 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
284 computeChanges();
286 if ( m_localKey.is() && m_localKey->isValid() )
288 return m_localKey->getKeyType(rKeyName);
290 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
292 return m_defaultKey->getKeyType(rKeyName);
295 return RegistryKeyType_KEY;
299 RegistryValueType SAL_CALL NestedKeyImpl::getValueType( )
301 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
302 computeChanges();
304 if ( m_localKey.is() && m_localKey->isValid() )
306 return m_localKey->getValueType();
308 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
310 return m_defaultKey->getValueType();
313 return RegistryValueType_NOT_DEFINED;
317 sal_Int32 SAL_CALL NestedKeyImpl::getLongValue( )
319 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
320 computeChanges();
322 if ( m_localKey.is() && m_localKey->isValid() )
324 return m_localKey->getLongValue();
326 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
328 return m_defaultKey->getLongValue();
330 else
332 throw InvalidRegistryException();
337 void SAL_CALL NestedKeyImpl::setLongValue( sal_Int32 value )
339 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
340 computeChanges();
342 if ( m_localKey.is() && m_localKey->isValid() )
344 m_localKey->setLongValue(value);
346 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
348 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
349 m_localKey = rootKey->createKey(m_name);
350 m_localKey->setLongValue(value);
351 m_state = m_xRegistry->m_state++;
353 else
355 throw InvalidRegistryException();
360 Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue( )
362 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
363 computeChanges();
365 if ( m_localKey.is() && m_localKey->isValid() )
367 return m_localKey->getLongListValue();
369 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
371 return m_defaultKey->getLongListValue();
373 else
375 throw InvalidRegistryException();
380 void SAL_CALL NestedKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue )
382 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
383 computeChanges();
385 if ( m_localKey.is() && m_localKey->isValid() )
387 m_localKey->setLongListValue(seqValue);
389 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
391 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
392 m_localKey = rootKey->createKey(m_name);
393 m_localKey->setLongListValue(seqValue);
394 m_state = m_xRegistry->m_state++;
396 else
398 throw InvalidRegistryException();
403 OUString SAL_CALL NestedKeyImpl::getAsciiValue( )
405 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
406 computeChanges();
408 if ( m_localKey.is() && m_localKey->isValid() )
410 return m_localKey->getAsciiValue();
412 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
414 return m_defaultKey->getAsciiValue();
416 else
418 throw InvalidRegistryException();
423 void SAL_CALL NestedKeyImpl::setAsciiValue( const OUString& value )
425 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
426 computeChanges();
428 if ( m_localKey.is() && m_localKey->isValid() )
430 m_localKey->setAsciiValue(value);
432 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
434 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
435 m_localKey = rootKey->createKey(m_name);
436 m_localKey->setAsciiValue(value);
437 m_state = m_xRegistry->m_state++;
439 else
441 throw InvalidRegistryException();
446 Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue( )
448 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
449 computeChanges();
451 if ( m_localKey.is() && m_localKey->isValid() )
453 return m_localKey->getAsciiListValue();
455 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
457 return m_defaultKey->getAsciiListValue();
459 else
461 throw InvalidRegistryException();
466 void SAL_CALL NestedKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue )
468 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
469 computeChanges();
471 if ( m_localKey.is() && m_localKey->isValid() )
473 m_localKey->setAsciiListValue(seqValue);
475 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
477 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
478 m_localKey = rootKey->createKey(m_name);
479 m_localKey->setAsciiListValue(seqValue);
480 m_state = m_xRegistry->m_state++;
482 else
484 throw InvalidRegistryException();
489 OUString SAL_CALL NestedKeyImpl::getStringValue( )
491 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
492 computeChanges();
494 if ( m_localKey.is() && m_localKey->isValid() )
496 return m_localKey->getStringValue();
498 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
500 return m_defaultKey->getStringValue();
502 else
504 throw InvalidRegistryException();
509 void SAL_CALL NestedKeyImpl::setStringValue( const OUString& value )
511 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
512 computeChanges();
514 if ( m_localKey.is() && m_localKey->isValid() )
516 m_localKey->setStringValue(value);
518 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
520 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
521 m_localKey = rootKey->createKey(m_name);
522 m_localKey->setStringValue(value);
523 m_state = m_xRegistry->m_state++;
525 else
527 throw InvalidRegistryException();
532 Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue( )
534 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
535 computeChanges();
537 if ( m_localKey.is() && m_localKey->isValid() )
539 return m_localKey->getStringListValue();
541 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
543 return m_defaultKey->getStringListValue();
545 else
547 throw InvalidRegistryException();
552 void SAL_CALL NestedKeyImpl::setStringListValue( const Sequence< OUString >& seqValue )
554 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
555 computeChanges();
557 if ( m_localKey.is() && m_localKey->isValid() )
559 m_localKey->setStringListValue(seqValue);
561 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
563 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
564 m_localKey = rootKey->createKey(m_name);
565 m_localKey->setStringListValue(seqValue);
566 m_state = m_xRegistry->m_state++;
568 else
570 throw InvalidRegistryException();
575 Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue( )
577 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
578 computeChanges();
580 if ( m_localKey.is() && m_localKey->isValid() )
582 return m_localKey->getBinaryValue();
584 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
586 return m_defaultKey->getBinaryValue();
588 else
590 throw InvalidRegistryException();
595 void SAL_CALL NestedKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value )
597 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
598 computeChanges();
600 if ( m_localKey.is() && m_localKey->isValid() )
602 m_localKey->setBinaryValue(value);
604 else if ( m_defaultKey.is() && m_defaultKey->isValid() )
606 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
607 m_localKey = rootKey->createKey(m_name);
608 m_localKey->setBinaryValue(value);
609 m_state = m_xRegistry->m_state++;
611 else
613 throw InvalidRegistryException();
618 Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName )
620 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
621 if ( !m_localKey.is() && !m_defaultKey.is() )
623 throw InvalidRegistryException();
626 OUString resolvedName = computeName(aKeyName);
628 if ( resolvedName.isEmpty() )
629 throw InvalidRegistryException();
631 Reference<XRegistryKey> localKey, defaultKey;
633 if ( m_localKey.is() && m_localKey->isValid() )
635 localKey = m_xRegistry->m_localReg->getRootKey()->openKey(resolvedName);
637 if ( m_defaultKey.is() && m_defaultKey->isValid() )
639 defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
642 if ( localKey.is() || defaultKey.is() )
644 return static_cast<XRegistryKey*>(new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey));
646 else
648 return Reference<XRegistryKey>();
653 Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName )
655 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
656 if ( (!m_localKey.is() && !m_defaultKey.is()) ||
657 (m_localKey.is() && m_localKey->isReadOnly()) )
659 throw InvalidRegistryException();
662 OUString resolvedName = computeName(aKeyName);
664 if ( resolvedName.isEmpty() )
665 throw InvalidRegistryException();
667 if ( m_localKey.is() && m_localKey->isValid() )
669 Reference<XRegistryKey> localKey, defaultKey;
671 localKey = m_xRegistry->m_localReg->getRootKey()->createKey(resolvedName);
672 if ( localKey.is() )
674 if ( m_defaultKey.is() && m_defaultKey->isValid() )
676 defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
679 m_state = m_xRegistry->m_state++;
681 return static_cast<XRegistryKey*>(new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey));
684 else
686 Reference<XRegistryKey> localKey, defaultKey;
688 if ( m_defaultKey.is() && m_defaultKey->isValid() )
690 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
691 m_localKey = rootKey->createKey(m_name);
693 localKey = m_xRegistry->m_localReg->getRootKey()->createKey(resolvedName);
695 if ( localKey.is() )
697 defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
699 m_state = m_xRegistry->m_state++;
701 return static_cast<XRegistryKey*>(new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey));
706 return Reference<XRegistryKey>();
710 void SAL_CALL NestedKeyImpl::closeKey( )
712 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
713 if ( m_localKey.is() && m_localKey->isValid() )
715 m_localKey->closeKey();
717 if ( m_defaultKey.is() && m_defaultKey->isValid() )
719 m_defaultKey->closeKey();
724 void SAL_CALL NestedKeyImpl::deleteKey( const OUString& rKeyName )
726 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
727 if ( !m_localKey.is() || !m_localKey->isValid() ||
728 m_localKey->isReadOnly() )
730 throw InvalidRegistryException();
733 OUString resolvedName = computeName(rKeyName);
735 if ( resolvedName.isEmpty() )
737 throw InvalidRegistryException();
740 m_xRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
744 Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( )
746 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
747 if ( !m_localKey.is() && !m_defaultKey.is() )
749 throw InvalidRegistryException();
752 Sequence<OUString> localSeq, defaultSeq;
754 if ( m_localKey.is() && m_localKey->isValid() )
756 localSeq = m_localKey->getKeyNames();
758 if ( m_defaultKey.is() && m_defaultKey->isValid() )
760 defaultSeq = m_defaultKey->getKeyNames();
763 sal_uInt32 local = localSeq.getLength();
764 sal_uInt32 def = defaultSeq.getLength();
765 sal_uInt32 len = 0;
767 sal_uInt32 i, j;
768 for (i=0; i < local; i++)
770 for (j=0 ; j < def; j++)
772 if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
774 len++;
775 break;
780 Sequence< Reference<XRegistryKey> > retSeq(local + def - len);
781 OUString name;
782 sal_Int32 lastIndex;
784 for (i=0; i < local; i++)
786 name = localSeq.getConstArray()[i];
787 lastIndex = name.lastIndexOf('/');
788 name = name.copy(lastIndex);
789 retSeq.getArray()[i] =
790 static_cast<XRegistryKey*>(new NestedKeyImpl(name, this));
793 sal_uInt32 k = local;
794 for (i=0; i < def; i++)
796 bool insert = true;
798 for (j=0 ; j < local; j++)
800 if ( retSeq.getConstArray()[j]->getKeyName()
801 == defaultSeq.getConstArray()[i] )
803 insert = false;
804 break;
808 if ( insert )
810 name = defaultSeq.getConstArray()[i];
811 lastIndex = name.lastIndexOf('/');
812 name = name.copy(lastIndex);
813 retSeq.getArray()[k++] =
814 static_cast<XRegistryKey*>(new NestedKeyImpl(name, this));
818 return retSeq;
822 Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( )
824 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
825 if ( !m_localKey.is() && !m_defaultKey.is() )
827 throw InvalidRegistryException();
830 Sequence<OUString> localSeq, defaultSeq;
832 if ( m_localKey.is() && m_localKey->isValid() )
834 localSeq = m_localKey->getKeyNames();
836 if ( m_defaultKey.is() && m_defaultKey->isValid() )
838 defaultSeq = m_defaultKey->getKeyNames();
841 sal_uInt32 local = localSeq.getLength();
842 sal_uInt32 def = defaultSeq.getLength();
843 sal_uInt32 len = 0;
845 sal_uInt32 i, j;
846 for (i=0; i < local; i++)
848 for (j=0 ; j < def; j++)
850 if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
852 len++;
853 break;
858 Sequence<OUString> retSeq(local + def - len);
860 for (i=0; i < local; i++)
862 retSeq.getArray()[i] = localSeq.getConstArray()[i];
865 sal_uInt32 k = local;
866 for (i=0; i < def; i++)
868 bool insert = true;
870 for (j=0 ; j < local; j++)
872 if ( retSeq.getConstArray()[j] == defaultSeq.getConstArray()[i] )
874 insert = false;
875 break;
879 if ( insert )
880 retSeq.getArray()[k++] = defaultSeq.getConstArray()[i];
883 return retSeq;
887 sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
889 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
891 bool isCreated = false;
892 if ( !m_localKey.is() && !m_defaultKey.is() )
894 throw InvalidRegistryException();
897 OUString linkName;
898 OUString resolvedName;
899 sal_Int32 lastIndex = aLinkName.lastIndexOf('/');
901 if ( lastIndex > 0 )
903 linkName = aLinkName.copy(0, lastIndex);
905 resolvedName = computeName(linkName);
907 if ( resolvedName.isEmpty() )
909 throw InvalidRegistryException();
912 resolvedName = resolvedName + aLinkName.copy(lastIndex);
914 else
916 if ( lastIndex == 0 )
917 resolvedName = m_name + aLinkName;
918 else
919 resolvedName = m_name + "/" + aLinkName;
922 if ( m_localKey.is() && m_localKey->isValid() )
924 isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
926 else
928 if ( m_defaultKey.is() && m_defaultKey->isValid() )
930 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
931 m_localKey = rootKey->createKey(m_name);
933 isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
937 if ( isCreated )
938 m_state = m_xRegistry->m_state++;
940 return isCreated;
944 void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
946 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
947 if ( !m_localKey.is() && !m_defaultKey.is() )
949 throw InvalidRegistryException();
952 OUString linkName;
953 OUString resolvedName;
954 sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
956 if ( lastIndex > 0 )
958 linkName = rLinkName.copy(0, lastIndex);
960 resolvedName = computeName(linkName);
962 if ( resolvedName.isEmpty() )
964 throw InvalidRegistryException();
967 resolvedName = resolvedName + rLinkName.copy(lastIndex);
969 else
971 if ( lastIndex == 0 )
972 resolvedName = m_name + rLinkName;
973 else
974 resolvedName = m_name + "/" + rLinkName;
977 if ( !m_localKey.is() || !m_localKey->isValid() ||
978 m_localKey->isReadOnly() )
980 throw InvalidRegistryException();
983 m_xRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
987 OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
989 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
990 if ( !m_localKey.is() && !m_defaultKey.is() )
992 throw InvalidRegistryException();
995 OUString linkName;
996 OUString resolvedName;
997 sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
999 if ( lastIndex > 0 )
1001 linkName = rLinkName.copy(0, lastIndex);
1003 resolvedName = computeName(linkName);
1005 if ( resolvedName.isEmpty() )
1007 throw InvalidRegistryException();
1010 resolvedName = resolvedName + rLinkName.copy(lastIndex);
1012 else
1014 if ( lastIndex == 0 )
1015 resolvedName = m_name + rLinkName;
1016 else
1017 resolvedName = m_name + "/" + rLinkName;
1020 OUString linkTarget;
1021 if ( m_localKey.is() && m_localKey->isValid() )
1025 linkTarget = m_xRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
1026 return linkTarget;
1028 catch(InvalidRegistryException& )
1033 if ( m_defaultKey.is() && m_defaultKey->isValid() )
1034 linkTarget = m_xRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
1036 return linkTarget;
1040 OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
1042 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
1043 if ( !m_localKey.is() && !m_defaultKey.is() )
1045 throw InvalidRegistryException();
1048 OUString resolvedName = computeName(aKeyName);
1050 if ( resolvedName.isEmpty() )
1052 throw InvalidRegistryException();
1055 return resolvedName;
1059 // DefaultRegistry Implementation
1062 NestedRegistryImpl::NestedRegistryImpl( )
1063 : m_state(0)
1066 class RegistryEnumueration : public WeakImplHelper< XEnumeration >
1068 public:
1069 RegistryEnumueration(
1070 const Reference< XSimpleRegistry > &r1,
1071 const Reference< XSimpleRegistry > &r2 )
1072 : m_xReg1( r1 ) , m_xReg2( r2 )
1074 public:
1075 virtual sal_Bool SAL_CALL hasMoreElements( ) override;
1076 virtual Any SAL_CALL nextElement( ) override;
1078 private:
1079 Reference< XSimpleRegistry > m_xReg1;
1080 Reference< XSimpleRegistry > m_xReg2;
1083 sal_Bool RegistryEnumueration::hasMoreElements( )
1085 return m_xReg1.is() || m_xReg2.is();
1088 Any RegistryEnumueration::nextElement( )
1090 Any a;
1091 if( m_xReg1.is() )
1093 a <<= m_xReg1;
1094 m_xReg1.clear();
1096 else if( m_xReg2.is() )
1098 a <<= m_xReg2;
1099 m_xReg2.clear();
1101 else
1103 throw NoSuchElementException( "NestedRegistry: no nextElement() !" );
1105 return a;
1109 Reference< XEnumeration > NestedRegistryImpl::createEnumeration( )
1111 MutexGuard guard( m_mutex );
1112 return new RegistryEnumueration( m_localReg, m_defaultReg );
1115 Type NestedRegistryImpl::getElementType( )
1117 return cppu::UnoType<decltype(m_localReg)>::get();
1120 sal_Bool SAL_CALL NestedRegistryImpl::hasElements( )
1122 MutexGuard guard( m_mutex );
1123 return m_localReg.is() || m_defaultReg.is();
1127 OUString SAL_CALL NestedRegistryImpl::getImplementationName( )
1129 return OUString("com.sun.star.comp.stoc.NestedRegistry");
1132 sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
1134 return cppu::supportsService(this, ServiceName);
1137 Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( )
1139 Sequence< OUString > seqNames { "com.sun.star.registry.NestedRegistry" };
1140 return seqNames;
1144 void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
1146 Guard< Mutex > aGuard( m_mutex );
1147 if ( (aArguments.getLength() == 2) &&
1148 (aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) &&
1149 (aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) )
1151 aArguments[0] >>= m_localReg;
1152 aArguments[1] >>= m_defaultReg;
1153 if ( m_localReg == m_defaultReg )
1154 m_defaultReg.clear();
1159 OUString SAL_CALL NestedRegistryImpl::getURL()
1161 Guard< Mutex > aGuard( m_mutex );
1164 if ( m_localReg.is() && m_localReg->isValid() )
1165 return m_localReg->getURL();
1167 catch(InvalidRegistryException& )
1171 return OUString();
1175 void SAL_CALL NestedRegistryImpl::open( const OUString&, sal_Bool, sal_Bool )
1177 throw InvalidRegistryException(
1178 "the 'open' method is not specified for a nested registry" );
1182 sal_Bool SAL_CALL NestedRegistryImpl::isValid( )
1184 Guard< Mutex > aGuard( m_mutex );
1187 if ( (m_localReg.is() && m_localReg->isValid()) ||
1188 (m_defaultReg.is() && m_defaultReg->isValid()) )
1189 return true;
1191 catch(InvalidRegistryException& )
1195 return false;
1199 void SAL_CALL NestedRegistryImpl::close( )
1201 Guard< Mutex > aGuard( m_mutex );
1202 if ( m_localReg.is() && m_localReg->isValid() )
1204 m_localReg->close();
1206 if ( m_defaultReg.is() && m_defaultReg->isValid() )
1208 m_defaultReg->close();
1213 void SAL_CALL NestedRegistryImpl::destroy( )
1215 throw InvalidRegistryException(
1216 "the 'destroy' method is not specified for a nested registry" );
1220 Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( )
1222 Guard< Mutex > aGuard( m_mutex );
1223 if ( !m_localReg.is() || !m_localReg->isValid() )
1225 throw InvalidRegistryException();
1228 Reference<XRegistryKey> localKey, defaultKey;
1230 localKey = m_localReg->getRootKey();
1232 if ( localKey.is() )
1234 if ( m_defaultReg.is() && m_defaultReg->isValid() )
1236 defaultKey = m_defaultReg->getRootKey();
1239 return static_cast<XRegistryKey*>(new NestedKeyImpl(this, localKey, defaultKey));
1242 return Reference<XRegistryKey>();
1246 sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( )
1248 Guard< Mutex > aGuard( m_mutex );
1251 if ( m_localReg.is() && m_localReg->isValid() )
1252 return m_localReg->isReadOnly();
1254 catch(InvalidRegistryException& )
1258 return false;
1262 void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl )
1264 Guard< Mutex > aGuard( m_mutex );
1265 if ( m_localReg.is() && m_localReg->isValid() )
1267 m_localReg->mergeKey(aKeyName, aUrl);
1269 m_state++;
1273 } // namespace
1275 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1276 com_sun_star_comp_stoc_NestedRegistry_get_implementation(
1277 SAL_UNUSED_PARAMETER css::uno::XComponentContext *,
1278 css::uno::Sequence<css::uno::Any> const &)
1280 return cppu::acquire(new NestedRegistryImpl);
1283 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */