56f3dbffdf
Change-Id: I618b0f8bcb2e8032ee12367c73e1136685f66b3e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176183 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
1186 lines
31 KiB
C++
1186 lines
31 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <osl/mutex.hxx>
|
|
#include <comphelper/sequence.hxx>
|
|
#include <cppuhelper/weak.hxx>
|
|
#include <cppuhelper/implbase.hxx>
|
|
#include <cppuhelper/supportsservice.hxx>
|
|
#include <rtl/ref.hxx>
|
|
|
|
#include <com/sun/star/registry/XSimpleRegistry.hpp>
|
|
#include <com/sun/star/lang/XServiceInfo.hpp>
|
|
#include <com/sun/star/lang/XInitialization.hpp>
|
|
#include <com/sun/star/container/XEnumerationAccess.hpp>
|
|
|
|
namespace com::sun::star::uno { class XComponentContext; }
|
|
|
|
using namespace css::uno;
|
|
using namespace css::registry;
|
|
using namespace css::lang;
|
|
using namespace css::container;
|
|
using namespace cppu;
|
|
using namespace osl;
|
|
|
|
namespace {
|
|
|
|
class NestedRegistryImpl : public WeakImplHelper < XSimpleRegistry, XInitialization, XServiceInfo, XEnumerationAccess >
|
|
{
|
|
public:
|
|
NestedRegistryImpl( );
|
|
|
|
// XServiceInfo
|
|
virtual OUString SAL_CALL getImplementationName( ) override;
|
|
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
|
|
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) override;
|
|
|
|
// XInitialization
|
|
virtual void SAL_CALL initialize( const Sequence< Any >& aArguments ) override;
|
|
|
|
// XSimpleRegistry
|
|
virtual OUString SAL_CALL getURL() override;
|
|
virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) override;
|
|
virtual sal_Bool SAL_CALL isValid( ) override;
|
|
virtual void SAL_CALL close( ) override;
|
|
virtual void SAL_CALL destroy( ) override;
|
|
virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) override;
|
|
virtual sal_Bool SAL_CALL isReadOnly( ) override;
|
|
virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) override;
|
|
|
|
// XEnumerationAccess
|
|
virtual Reference< XEnumeration > SAL_CALL createEnumeration( ) override;
|
|
virtual Type SAL_CALL getElementType( ) override;
|
|
virtual sal_Bool SAL_CALL hasElements( ) override;
|
|
|
|
friend class NestedKeyImpl;
|
|
protected:
|
|
Mutex m_mutex;
|
|
sal_uInt32 m_state;
|
|
Reference<XSimpleRegistry> m_localReg;
|
|
Reference<XSimpleRegistry> m_defaultReg;
|
|
|
|
};
|
|
|
|
|
|
// class NestedKeyImpl the implementation of interface XRegistryKey
|
|
|
|
class NestedKeyImpl : public WeakImplHelper< XRegistryKey >
|
|
{
|
|
public:
|
|
NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
|
|
Reference<XRegistryKey>& localKey,
|
|
Reference<XRegistryKey>& defaultKey);
|
|
|
|
NestedKeyImpl( const OUString& aKeyName,
|
|
NestedKeyImpl* pKey);
|
|
|
|
// XRegistryKey
|
|
virtual OUString SAL_CALL getKeyName() override;
|
|
virtual sal_Bool SAL_CALL isReadOnly( ) override;
|
|
virtual sal_Bool SAL_CALL isValid( ) override;
|
|
virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) override;
|
|
virtual RegistryValueType SAL_CALL getValueType( ) override;
|
|
virtual sal_Int32 SAL_CALL getLongValue( ) override;
|
|
virtual void SAL_CALL setLongValue( sal_Int32 value ) override;
|
|
virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) override;
|
|
virtual void SAL_CALL setLongListValue( const css::uno::Sequence< sal_Int32 >& seqValue ) override;
|
|
virtual OUString SAL_CALL getAsciiValue( ) override;
|
|
virtual void SAL_CALL setAsciiValue( const OUString& value ) override;
|
|
virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) override;
|
|
virtual void SAL_CALL setAsciiListValue( const css::uno::Sequence< OUString >& seqValue ) override;
|
|
virtual OUString SAL_CALL getStringValue( ) override;
|
|
virtual void SAL_CALL setStringValue( const OUString& value ) override;
|
|
virtual Sequence< OUString > SAL_CALL getStringListValue( ) override;
|
|
virtual void SAL_CALL setStringListValue( const css::uno::Sequence< OUString >& seqValue ) override;
|
|
virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) override;
|
|
virtual void SAL_CALL setBinaryValue( const css::uno::Sequence< sal_Int8 >& value ) override;
|
|
virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) override;
|
|
virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) override;
|
|
virtual void SAL_CALL closeKey( ) override;
|
|
virtual void SAL_CALL deleteKey( const OUString& rKeyName ) override;
|
|
virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) override;
|
|
virtual Sequence< OUString > SAL_CALL getKeyNames( ) override;
|
|
virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) override;
|
|
virtual void SAL_CALL deleteLink( const OUString& rLinkName ) override;
|
|
virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) override;
|
|
virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) override;
|
|
|
|
protected:
|
|
void computeChanges();
|
|
OUString computeName(const OUString& name);
|
|
|
|
OUString m_name;
|
|
sal_uInt32 m_state;
|
|
rtl::Reference<NestedRegistryImpl> m_xRegistry;
|
|
Reference<XRegistryKey> m_localKey;
|
|
Reference<XRegistryKey> m_defaultKey;
|
|
};
|
|
|
|
|
|
NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
|
|
Reference<XRegistryKey>& localKey,
|
|
Reference<XRegistryKey>& defaultKey )
|
|
: m_state(pDefaultRegistry->m_state), m_xRegistry(pDefaultRegistry), m_localKey(localKey), m_defaultKey(defaultKey)
|
|
{
|
|
if (m_localKey.is())
|
|
{
|
|
m_name = m_localKey->getKeyName();
|
|
}
|
|
else if (m_defaultKey.is())
|
|
{
|
|
m_name = m_defaultKey->getKeyName();
|
|
}
|
|
}
|
|
|
|
|
|
NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName,
|
|
NestedKeyImpl* pKey)
|
|
: m_xRegistry(pKey->m_xRegistry)
|
|
{
|
|
if (pKey->m_localKey.is() && pKey->m_localKey->isValid())
|
|
{
|
|
m_localKey = pKey->m_localKey->openKey(rKeyName);
|
|
}
|
|
if (pKey->m_defaultKey.is() && pKey->m_defaultKey->isValid())
|
|
{
|
|
m_defaultKey = pKey->m_defaultKey->openKey(rKeyName);
|
|
}
|
|
|
|
if (m_localKey.is())
|
|
{
|
|
m_name = m_localKey->getKeyName();
|
|
}
|
|
else if (m_defaultKey.is())
|
|
{
|
|
m_name = m_defaultKey->getKeyName();
|
|
}
|
|
|
|
m_state = m_xRegistry->m_state;
|
|
}
|
|
|
|
void NestedKeyImpl::computeChanges()
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( m_state == m_xRegistry->m_state )
|
|
return;
|
|
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
|
|
Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name);
|
|
|
|
if ( tmpKey.is() )
|
|
{
|
|
m_localKey = rootKey->openKey(m_name);
|
|
}
|
|
|
|
m_state = m_xRegistry->m_state;
|
|
}
|
|
|
|
|
|
// NestedKey_Impl::computeName()
|
|
|
|
OUString NestedKeyImpl::computeName(const OUString& name)
|
|
{
|
|
OUString resLocalName, resDefaultName;
|
|
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
try
|
|
{
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
resLocalName = m_localKey->getResolvedName(name);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getResolvedName(name);
|
|
}
|
|
|
|
if ( !resLocalName.isEmpty() && m_xRegistry->m_defaultReg->isValid() )
|
|
{
|
|
Reference<XRegistryKey> localRoot(m_xRegistry->m_localReg->getRootKey());
|
|
Reference<XRegistryKey> defaultRoot(m_xRegistry->m_defaultReg->getRootKey());
|
|
|
|
resDefaultName = defaultRoot->getResolvedName(resLocalName);
|
|
|
|
sal_uInt32 count = 100;
|
|
|
|
while (resLocalName != resDefaultName && count > 0)
|
|
{
|
|
count--;
|
|
|
|
if (resLocalName.isEmpty() || resDefaultName.isEmpty())
|
|
throw InvalidRegistryException();
|
|
|
|
resLocalName = localRoot->getResolvedName(resDefaultName);
|
|
resDefaultName = defaultRoot->getResolvedName(resLocalName);
|
|
}
|
|
}
|
|
}
|
|
catch(InvalidRegistryException& )
|
|
{
|
|
}
|
|
|
|
return resLocalName;
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedKeyImpl::getKeyName()
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
return m_name;
|
|
}
|
|
|
|
|
|
sal_Bool SAL_CALL NestedKeyImpl::isReadOnly( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( !m_localKey.is() || !m_localKey->isValid() )
|
|
throw InvalidRegistryException();
|
|
|
|
return m_localKey->isReadOnly();
|
|
}
|
|
|
|
|
|
sal_Bool SAL_CALL NestedKeyImpl::isValid( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
return ((m_localKey.is() && m_localKey->isValid()) ||
|
|
(m_defaultKey.is() && m_defaultKey->isValid()) );
|
|
}
|
|
|
|
|
|
RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getKeyType(rKeyName);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getKeyType(rKeyName);
|
|
}
|
|
|
|
return RegistryKeyType_KEY;
|
|
}
|
|
|
|
|
|
RegistryValueType SAL_CALL NestedKeyImpl::getValueType( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getValueType();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getValueType();
|
|
}
|
|
|
|
return RegistryValueType_NOT_DEFINED;
|
|
}
|
|
|
|
|
|
sal_Int32 SAL_CALL NestedKeyImpl::getLongValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getLongValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getLongValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setLongValue( sal_Int32 value )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setLongValue(value);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setLongValue(value);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getLongListValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getLongListValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setLongListValue(seqValue);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setLongListValue(seqValue);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedKeyImpl::getAsciiValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getAsciiValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getAsciiValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setAsciiValue( const OUString& value )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setAsciiValue(value);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setAsciiValue(value);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getAsciiListValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getAsciiListValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setAsciiListValue(seqValue);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setAsciiListValue(seqValue);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedKeyImpl::getStringValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getStringValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getStringValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setStringValue( const OUString& value )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setStringValue(value);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setStringValue(value);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getStringListValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getStringListValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setStringListValue( const Sequence< OUString >& seqValue )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setStringListValue(seqValue);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setStringListValue(seqValue);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
return m_localKey->getBinaryValue();
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
return m_defaultKey->getBinaryValue();
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
computeChanges();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->setBinaryValue(value);
|
|
}
|
|
else if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
m_localKey->setBinaryValue(value);
|
|
m_state = m_xRegistry->m_state++;
|
|
}
|
|
else
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
}
|
|
|
|
|
|
Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName = computeName(aKeyName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
throw InvalidRegistryException();
|
|
|
|
Reference<XRegistryKey> localKey, defaultKey;
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
localKey = m_xRegistry->m_localReg->getRootKey()->openKey(resolvedName);
|
|
}
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
|
|
}
|
|
|
|
if ( localKey.is() || defaultKey.is() )
|
|
{
|
|
return new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey);
|
|
}
|
|
else
|
|
{
|
|
return Reference<XRegistryKey>();
|
|
}
|
|
}
|
|
|
|
|
|
Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( (!m_localKey.is() && !m_defaultKey.is()) ||
|
|
(m_localKey.is() && m_localKey->isReadOnly()) )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName = computeName(aKeyName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
throw InvalidRegistryException();
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> localKey, defaultKey;
|
|
|
|
localKey = m_xRegistry->m_localReg->getRootKey()->createKey(resolvedName);
|
|
if ( localKey.is() )
|
|
{
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
|
|
}
|
|
|
|
m_state = m_xRegistry->m_state++;
|
|
|
|
return new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Reference<XRegistryKey> localKey, defaultKey;
|
|
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
|
|
localKey = m_xRegistry->m_localReg->getRootKey()->createKey(resolvedName);
|
|
|
|
if ( localKey.is() )
|
|
{
|
|
defaultKey = m_xRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
|
|
|
|
m_state = m_xRegistry->m_state++;
|
|
|
|
return new NestedKeyImpl(m_xRegistry.get(), localKey, defaultKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
return Reference<XRegistryKey>();
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::closeKey( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
m_localKey->closeKey();
|
|
}
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
m_defaultKey->closeKey();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::deleteKey( const OUString& rKeyName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() || !m_localKey->isValid() ||
|
|
m_localKey->isReadOnly() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName = computeName(rKeyName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
m_xRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
|
|
}
|
|
|
|
|
|
Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
Sequence<OUString> localSeq, defaultSeq;
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
localSeq = m_localKey->getKeyNames();
|
|
}
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
defaultSeq = m_defaultKey->getKeyNames();
|
|
}
|
|
|
|
std::vector< Reference<XRegistryKey> > retVec;
|
|
retVec.reserve(localSeq.getLength() + defaultSeq.getLength());
|
|
|
|
auto lKeyNameToRegKey = [this](const OUString& rName) -> Reference<XRegistryKey> {
|
|
sal_Int32 lastIndex = rName.lastIndexOf('/');
|
|
OUString name = rName.copy(lastIndex);
|
|
return new NestedKeyImpl(name, this);
|
|
};
|
|
|
|
for (const auto& rKeyName : localSeq)
|
|
retVec.push_back(lKeyNameToRegKey(rKeyName));
|
|
|
|
for (const auto& rKeyName : defaultSeq)
|
|
{
|
|
if ( comphelper::findValue(localSeq, rKeyName) == -1 )
|
|
{
|
|
retVec.push_back(lKeyNameToRegKey(rKeyName));
|
|
}
|
|
}
|
|
|
|
return comphelper::containerToSequence(retVec);
|
|
}
|
|
|
|
|
|
Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
Sequence<OUString> localSeq, defaultSeq;
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
localSeq = m_localKey->getKeyNames();
|
|
}
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
defaultSeq = m_defaultKey->getKeyNames();
|
|
}
|
|
|
|
return comphelper::combineSequences(localSeq, defaultSeq);
|
|
}
|
|
|
|
|
|
sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
|
|
bool isCreated = false;
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName;
|
|
sal_Int32 lastIndex = aLinkName.lastIndexOf('/');
|
|
|
|
if ( lastIndex > 0 )
|
|
{
|
|
OUString linkName = aLinkName.copy(0, lastIndex);
|
|
|
|
resolvedName = computeName(linkName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
resolvedName += aLinkName.subView(lastIndex);
|
|
}
|
|
else
|
|
{
|
|
if ( lastIndex == 0 )
|
|
resolvedName = m_name + aLinkName;
|
|
else
|
|
resolvedName = m_name + "/" + aLinkName;
|
|
}
|
|
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
|
|
}
|
|
else
|
|
{
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
{
|
|
Reference<XRegistryKey> rootKey(m_xRegistry->m_localReg->getRootKey());
|
|
m_localKey = rootKey->createKey(m_name);
|
|
|
|
isCreated = m_xRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
|
|
}
|
|
}
|
|
|
|
if ( isCreated )
|
|
m_state = m_xRegistry->m_state++;
|
|
|
|
return isCreated;
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName;
|
|
sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
|
|
|
|
if ( lastIndex > 0 )
|
|
{
|
|
OUString linkName = rLinkName.copy(0, lastIndex);
|
|
|
|
resolvedName = computeName(linkName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
resolvedName += rLinkName.subView(lastIndex);
|
|
}
|
|
else
|
|
{
|
|
if ( lastIndex == 0 )
|
|
resolvedName = m_name + rLinkName;
|
|
else
|
|
resolvedName = m_name + "/" + rLinkName;
|
|
}
|
|
|
|
if ( !m_localKey.is() || !m_localKey->isValid() ||
|
|
m_localKey->isReadOnly() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
m_xRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName;
|
|
sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
|
|
|
|
if ( lastIndex > 0 )
|
|
{
|
|
OUString linkName = rLinkName.copy(0, lastIndex);
|
|
|
|
resolvedName = computeName(linkName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
resolvedName += rLinkName.subView(lastIndex);
|
|
}
|
|
else
|
|
{
|
|
if ( lastIndex == 0 )
|
|
resolvedName = m_name + rLinkName;
|
|
else
|
|
resolvedName = m_name + "/" + rLinkName;
|
|
}
|
|
|
|
OUString linkTarget;
|
|
if ( m_localKey.is() && m_localKey->isValid() )
|
|
{
|
|
try
|
|
{
|
|
linkTarget = m_xRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
|
|
return linkTarget;
|
|
}
|
|
catch(InvalidRegistryException& )
|
|
{
|
|
}
|
|
}
|
|
|
|
if ( m_defaultKey.is() && m_defaultKey->isValid() )
|
|
linkTarget = m_xRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
|
|
|
|
return linkTarget;
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
|
|
{
|
|
Guard< Mutex > aGuard( m_xRegistry->m_mutex );
|
|
if ( !m_localKey.is() && !m_defaultKey.is() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
OUString resolvedName = computeName(aKeyName);
|
|
|
|
if ( resolvedName.isEmpty() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
return resolvedName;
|
|
}
|
|
|
|
|
|
// DefaultRegistry Implementation
|
|
|
|
|
|
NestedRegistryImpl::NestedRegistryImpl( )
|
|
: m_state(0)
|
|
{}
|
|
|
|
class RegistryEnumueration : public WeakImplHelper< XEnumeration >
|
|
{
|
|
public:
|
|
RegistryEnumueration(
|
|
const Reference< XSimpleRegistry > &r1,
|
|
const Reference< XSimpleRegistry > &r2 )
|
|
: m_xReg1( r1 ) , m_xReg2( r2 )
|
|
{}
|
|
public:
|
|
virtual sal_Bool SAL_CALL hasMoreElements( ) override;
|
|
virtual Any SAL_CALL nextElement( ) override;
|
|
|
|
private:
|
|
Reference< XSimpleRegistry > m_xReg1;
|
|
Reference< XSimpleRegistry > m_xReg2;
|
|
};
|
|
|
|
sal_Bool RegistryEnumueration::hasMoreElements( )
|
|
{
|
|
return m_xReg1.is() || m_xReg2.is();
|
|
}
|
|
|
|
Any RegistryEnumueration::nextElement( )
|
|
{
|
|
Any a;
|
|
if( m_xReg1.is() )
|
|
{
|
|
a <<= m_xReg1;
|
|
m_xReg1.clear();
|
|
}
|
|
else if( m_xReg2.is() )
|
|
{
|
|
a <<= m_xReg2;
|
|
m_xReg2.clear();
|
|
}
|
|
else
|
|
{
|
|
throw NoSuchElementException( u"NestedRegistry: no nextElement() !"_ustr );
|
|
}
|
|
return a;
|
|
}
|
|
|
|
|
|
Reference< XEnumeration > NestedRegistryImpl::createEnumeration( )
|
|
{
|
|
MutexGuard guard( m_mutex );
|
|
return new RegistryEnumueration( m_localReg, m_defaultReg );
|
|
}
|
|
|
|
Type NestedRegistryImpl::getElementType( )
|
|
{
|
|
return cppu::UnoType<decltype(m_localReg)>::get();
|
|
}
|
|
|
|
sal_Bool SAL_CALL NestedRegistryImpl::hasElements( )
|
|
{
|
|
MutexGuard guard( m_mutex );
|
|
return m_localReg.is() || m_defaultReg.is();
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedRegistryImpl::getImplementationName( )
|
|
{
|
|
return u"com.sun.star.comp.stoc.NestedRegistry"_ustr;
|
|
}
|
|
|
|
sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
|
|
{
|
|
return cppu::supportsService(this, ServiceName);
|
|
}
|
|
|
|
Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( )
|
|
{
|
|
Sequence< OUString > seqNames { u"com.sun.star.registry.NestedRegistry"_ustr };
|
|
return seqNames;
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
|
|
{
|
|
Guard< Mutex > aGuard( m_mutex );
|
|
if ( (aArguments.getLength() == 2) &&
|
|
(aArguments[0].getValueTypeClass() == TypeClass_INTERFACE) &&
|
|
(aArguments[1].getValueTypeClass() == TypeClass_INTERFACE) )
|
|
{
|
|
aArguments[0] >>= m_localReg;
|
|
aArguments[1] >>= m_defaultReg;
|
|
if ( m_localReg == m_defaultReg )
|
|
m_defaultReg.clear();
|
|
}
|
|
}
|
|
|
|
|
|
OUString SAL_CALL NestedRegistryImpl::getURL()
|
|
{
|
|
Guard< Mutex > aGuard( m_mutex );
|
|
try
|
|
{
|
|
if ( m_localReg.is() && m_localReg->isValid() )
|
|
return m_localReg->getURL();
|
|
}
|
|
catch(InvalidRegistryException& )
|
|
{
|
|
}
|
|
|
|
return OUString();
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedRegistryImpl::open( const OUString&, sal_Bool, sal_Bool )
|
|
{
|
|
throw InvalidRegistryException(
|
|
u"the 'open' method is not specified for a nested registry"_ustr );
|
|
}
|
|
|
|
|
|
sal_Bool SAL_CALL NestedRegistryImpl::isValid( )
|
|
{
|
|
Guard< Mutex > aGuard( m_mutex );
|
|
try
|
|
{
|
|
if ( (m_localReg.is() && m_localReg->isValid()) ||
|
|
(m_defaultReg.is() && m_defaultReg->isValid()) )
|
|
return true;
|
|
}
|
|
catch(InvalidRegistryException& )
|
|
{
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedRegistryImpl::close( )
|
|
{
|
|
Guard< Mutex > aGuard( m_mutex );
|
|
if ( m_localReg.is() && m_localReg->isValid() )
|
|
{
|
|
m_localReg->close();
|
|
}
|
|
if ( m_defaultReg.is() && m_defaultReg->isValid() )
|
|
{
|
|
m_defaultReg->close();
|
|
}
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedRegistryImpl::destroy( )
|
|
{
|
|
throw InvalidRegistryException(
|
|
u"the 'destroy' method is not specified for a nested registry"_ustr );
|
|
}
|
|
|
|
|
|
Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( )
|
|
{
|
|
Guard< Mutex > aGuard( m_mutex );
|
|
if ( !m_localReg.is() || !m_localReg->isValid() )
|
|
{
|
|
throw InvalidRegistryException();
|
|
}
|
|
|
|
Reference<XRegistryKey> localKey, defaultKey;
|
|
|
|
localKey = m_localReg->getRootKey();
|
|
|
|
if ( localKey.is() )
|
|
{
|
|
if ( m_defaultReg.is() && m_defaultReg->isValid() )
|
|
{
|
|
defaultKey = m_defaultReg->getRootKey();
|
|
}
|
|
|
|
return new NestedKeyImpl(this, localKey, defaultKey);
|
|
}
|
|
|
|
return Reference<XRegistryKey>();
|
|
}
|
|
|
|
|
|
sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( )
|
|
{
|
|
Guard< Mutex > aGuard( m_mutex );
|
|
try
|
|
{
|
|
if ( m_localReg.is() && m_localReg->isValid() )
|
|
return m_localReg->isReadOnly();
|
|
}
|
|
catch(InvalidRegistryException& )
|
|
{
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void SAL_CALL NestedRegistryImpl::mergeKey( const OUString&, const OUString& )
|
|
{
|
|
throw css::uno::RuntimeException(u"css.registry.NestedRegistry::mergeKey: not implemented"_ustr);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
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 &)
|
|
{
|
|
return cppu::acquire(new NestedRegistryImpl);
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|