Version 5.4.3.2, tag libreoffice-5.4.3.2
[LibreOffice.git] / stoc / source / defaultregistry / defaultregistry.cxx
blobdb3e7666c1ba6b2fd423a879cf5493706cf0cb9f
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 return m_localKey->isReadOnly();
268 else
269 throw InvalidRegistryException();
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 OUString resolvedName = computeName(rKeyName);
732 if ( resolvedName.isEmpty() )
734 throw InvalidRegistryException();
737 m_xRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
739 else
741 throw InvalidRegistryException();
746 Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( )
748 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
749 if ( !m_localKey.is() && !m_defaultKey.is() )
751 throw InvalidRegistryException();
754 Sequence<OUString> localSeq, defaultSeq;
756 if ( m_localKey.is() && m_localKey->isValid() )
758 localSeq = m_localKey->getKeyNames();
760 if ( m_defaultKey.is() && m_defaultKey->isValid() )
762 defaultSeq = m_defaultKey->getKeyNames();
765 sal_uInt32 local = localSeq.getLength();
766 sal_uInt32 def = defaultSeq.getLength();
767 sal_uInt32 len = 0;
769 sal_uInt32 i, j;
770 for (i=0; i < local; i++)
772 for (j=0 ; j < def; j++)
774 if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
776 len++;
777 break;
782 Sequence< Reference<XRegistryKey> > retSeq(local + def - len);
783 OUString name;
784 sal_Int32 lastIndex;
786 for (i=0; i < local; i++)
788 name = localSeq.getConstArray()[i];
789 lastIndex = name.lastIndexOf('/');
790 name = name.copy(lastIndex);
791 retSeq.getArray()[i] =
792 static_cast<XRegistryKey*>(new NestedKeyImpl(name, this));
795 sal_uInt32 k = local;
796 for (i=0; i < def; i++)
798 bool insert = true;
800 for (j=0 ; j < local; j++)
802 if ( retSeq.getConstArray()[j]->getKeyName()
803 == defaultSeq.getConstArray()[i] )
805 insert = false;
806 break;
810 if ( insert )
812 name = defaultSeq.getConstArray()[i];
813 lastIndex = name.lastIndexOf('/');
814 name = name.copy(lastIndex);
815 retSeq.getArray()[k++] =
816 static_cast<XRegistryKey*>(new NestedKeyImpl(name, this));
820 return retSeq;
824 Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( )
826 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
827 if ( !m_localKey.is() && !m_defaultKey.is() )
829 throw InvalidRegistryException();
832 Sequence<OUString> localSeq, defaultSeq;
834 if ( m_localKey.is() && m_localKey->isValid() )
836 localSeq = m_localKey->getKeyNames();
838 if ( m_defaultKey.is() && m_defaultKey->isValid() )
840 defaultSeq = m_defaultKey->getKeyNames();
843 sal_uInt32 local = localSeq.getLength();
844 sal_uInt32 def = defaultSeq.getLength();
845 sal_uInt32 len = 0;
847 sal_uInt32 i, j;
848 for (i=0; i < local; i++)
850 for (j=0 ; j < def; j++)
852 if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
854 len++;
855 break;
860 Sequence<OUString> retSeq(local + def - len);
862 for (i=0; i < local; i++)
864 retSeq.getArray()[i] = localSeq.getConstArray()[i];
867 sal_uInt32 k = local;
868 for (i=0; i < def; i++)
870 bool insert = true;
872 for (j=0 ; j < local; j++)
874 if ( retSeq.getConstArray()[j] == defaultSeq.getConstArray()[i] )
876 insert = false;
877 break;
881 if ( insert )
882 retSeq.getArray()[k++] = defaultSeq.getConstArray()[i];
885 return retSeq;
889 sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
891 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
893 bool isCreated = false;
894 if ( !m_localKey.is() && !m_defaultKey.is() )
896 throw InvalidRegistryException();
899 OUString linkName;
900 OUString resolvedName;
901 sal_Int32 lastIndex = aLinkName.lastIndexOf('/');
903 if ( lastIndex > 0 )
905 linkName = aLinkName.copy(0, lastIndex);
907 resolvedName = computeName(linkName);
909 if ( resolvedName.isEmpty() )
911 throw InvalidRegistryException();
914 resolvedName = resolvedName + aLinkName.copy(lastIndex);
916 else
918 if ( lastIndex == 0 )
919 resolvedName = m_name + aLinkName;
920 else
921 resolvedName = m_name + "/" + aLinkName;
924 if ( m_localKey.is() && m_localKey->isValid() )
926 isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
928 else
930 if ( m_defaultKey.is() && m_defaultKey->isValid() )
932 Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
933 m_localKey = rootKey->createKey(m_name);
935 isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
939 if ( isCreated )
940 m_state = m_xRegistry->m_state++;
942 return isCreated;
946 void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
948 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
949 if ( !m_localKey.is() && !m_defaultKey.is() )
951 throw InvalidRegistryException();
954 OUString linkName;
955 OUString resolvedName;
956 sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
958 if ( lastIndex > 0 )
960 linkName = rLinkName.copy(0, lastIndex);
962 resolvedName = computeName(linkName);
964 if ( resolvedName.isEmpty() )
966 throw InvalidRegistryException();
969 resolvedName = resolvedName + rLinkName.copy(lastIndex);
971 else
973 if ( lastIndex == 0 )
974 resolvedName = m_name + rLinkName;
975 else
976 resolvedName = m_name + "/" + rLinkName;
979 if ( m_localKey.is() && m_localKey->isValid() &&
980 !m_localKey->isReadOnly() )
982 m_xRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
984 else
986 throw InvalidRegistryException();
991 OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
993 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
994 if ( !m_localKey.is() && !m_defaultKey.is() )
996 throw InvalidRegistryException();
999 OUString linkName;
1000 OUString resolvedName;
1001 sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
1003 if ( lastIndex > 0 )
1005 linkName = rLinkName.copy(0, lastIndex);
1007 resolvedName = computeName(linkName);
1009 if ( resolvedName.isEmpty() )
1011 throw InvalidRegistryException();
1014 resolvedName = resolvedName + rLinkName.copy(lastIndex);
1016 else
1018 if ( lastIndex == 0 )
1019 resolvedName = m_name + rLinkName;
1020 else
1021 resolvedName = m_name + "/" + rLinkName;
1024 OUString linkTarget;
1025 if ( m_localKey.is() && m_localKey->isValid() )
1029 linkTarget = m_xRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
1030 return linkTarget;
1032 catch(InvalidRegistryException& )
1037 if ( m_defaultKey.is() && m_defaultKey->isValid() )
1038 linkTarget = m_xRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
1040 return linkTarget;
1044 OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
1046 Guard< Mutex > aGuard( m_xRegistry->m_mutex );
1047 if ( !m_localKey.is() && !m_defaultKey.is() )
1049 throw InvalidRegistryException();
1052 OUString resolvedName = computeName(aKeyName);
1054 if ( resolvedName.isEmpty() )
1056 throw InvalidRegistryException();
1059 return resolvedName;
1063 // DefaultRegistry Implementation
1066 NestedRegistryImpl::NestedRegistryImpl( )
1067 : m_state(0)
1070 class RegistryEnumueration : public WeakImplHelper< XEnumeration >
1072 public:
1073 RegistryEnumueration(
1074 const Reference< XSimpleRegistry > &r1,
1075 const Reference< XSimpleRegistry > &r2 )
1076 : m_xReg1( r1 ) , m_xReg2( r2 )
1078 public:
1079 virtual sal_Bool SAL_CALL hasMoreElements( ) override;
1080 virtual Any SAL_CALL nextElement( ) override;
1082 private:
1083 Reference< XSimpleRegistry > m_xReg1;
1084 Reference< XSimpleRegistry > m_xReg2;
1087 sal_Bool RegistryEnumueration::hasMoreElements( )
1089 return m_xReg1.is() || m_xReg2.is();
1092 Any RegistryEnumueration::nextElement( )
1094 Any a;
1095 if( m_xReg1.is() )
1097 a <<= m_xReg1;
1098 m_xReg1.clear();
1100 else if( m_xReg2.is() )
1102 a <<= m_xReg2;
1103 m_xReg2.clear();
1105 else
1107 throw NoSuchElementException( "NestedRegistry: no nextElement() !" );
1109 return a;
1113 Reference< XEnumeration > NestedRegistryImpl::createEnumeration( )
1115 MutexGuard guard( m_mutex );
1116 return new RegistryEnumueration( m_localReg, m_defaultReg );
1119 Type NestedRegistryImpl::getElementType( )
1121 return cppu::UnoType<decltype(m_localReg)>::get();
1124 sal_Bool SAL_CALL NestedRegistryImpl::hasElements( )
1126 MutexGuard guard( m_mutex );
1127 return m_localReg.is() || m_defaultReg.is();
1131 OUString SAL_CALL NestedRegistryImpl::getImplementationName( )
1133 return OUString("com.sun.star.comp.stoc.NestedRegistry");
1136 sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
1138 return cppu::supportsService(this, ServiceName);
1141 Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( )
1143 Sequence< OUString > seqNames { "com.sun.star.registry.NestedRegistry" };
1144 return seqNames;
1148 void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
1150 Guard< Mutex > aGuard( m_mutex );
1151 if ( (aArguments.getLength() == 2) &&
1152 (aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) &&
1153 (aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) )
1155 aArguments[0] >>= m_localReg;
1156 aArguments[1] >>= m_defaultReg;
1157 if ( m_localReg == m_defaultReg )
1158 m_defaultReg.clear();
1163 OUString SAL_CALL NestedRegistryImpl::getURL()
1165 Guard< Mutex > aGuard( m_mutex );
1168 if ( m_localReg.is() && m_localReg->isValid() )
1169 return m_localReg->getURL();
1171 catch(InvalidRegistryException& )
1175 return OUString();
1179 void SAL_CALL NestedRegistryImpl::open( const OUString&, sal_Bool, sal_Bool )
1181 throw InvalidRegistryException(
1182 "the 'open' method is not specified for a nested registry" );
1186 sal_Bool SAL_CALL NestedRegistryImpl::isValid( )
1188 Guard< Mutex > aGuard( m_mutex );
1191 if ( (m_localReg.is() && m_localReg->isValid()) ||
1192 (m_defaultReg.is() && m_defaultReg->isValid()) )
1193 return true;
1195 catch(InvalidRegistryException& )
1199 return false;
1203 void SAL_CALL NestedRegistryImpl::close( )
1205 Guard< Mutex > aGuard( m_mutex );
1206 if ( m_localReg.is() && m_localReg->isValid() )
1208 m_localReg->close();
1210 if ( m_defaultReg.is() && m_defaultReg->isValid() )
1212 m_defaultReg->close();
1217 void SAL_CALL NestedRegistryImpl::destroy( )
1219 throw InvalidRegistryException(
1220 "the 'destroy' method is not specified for a nested registry" );
1224 Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( )
1226 Guard< Mutex > aGuard( m_mutex );
1227 if ( m_localReg.is() && m_localReg->isValid() )
1229 Reference<XRegistryKey> localKey, defaultKey;
1231 localKey = m_localReg->getRootKey();
1233 if ( localKey.is() )
1235 if ( m_defaultReg.is() && m_defaultReg->isValid() )
1237 defaultKey = m_defaultReg->getRootKey();
1240 return (static_cast<XRegistryKey*>(new NestedKeyImpl(this, localKey, defaultKey)));
1243 else
1245 throw InvalidRegistryException();
1248 return Reference<XRegistryKey>();
1252 sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( )
1254 Guard< Mutex > aGuard( m_mutex );
1257 if ( m_localReg.is() && m_localReg->isValid() )
1258 return m_localReg->isReadOnly();
1260 catch(InvalidRegistryException& )
1264 return false;
1268 void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl )
1270 Guard< Mutex > aGuard( m_mutex );
1271 if ( m_localReg.is() && m_localReg->isValid() )
1273 m_localReg->mergeKey(aKeyName, aUrl);
1275 m_state++;
1279 } // namespace
1281 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
1282 com_sun_star_comp_stoc_NestedRegistry_get_implementation(
1283 SAL_UNUSED_PARAMETER css::uno::XComponentContext *,
1284 css::uno::Sequence<css::uno::Any> const &)
1286 return cppu::acquire(new NestedRegistryImpl);
1289 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */