blob: 40575f38ce0624b4d794a36a763376ffee4bf452 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_stoc.hxx"
#include <osl/mutex.hxx>
#ifndef _OSL_DIAGNOSE_HXX_
#include <osl/diagnose.h>
#endif
#include <cppuhelper/queryinterface.hxx>
#include <cppuhelper/weak.hxx>
#include <cppuhelper/factory.hxx>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implbase4.hxx>
#include <cppuhelper/implbase3.hxx>
#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
#include <cppuhelper/implementationentry.hxx>
#endif
#include <registry/registry.hxx>
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XTypeProvider.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/container/XEnumerationAccess.hpp>
#include <bootstrapservices.hxx>
using namespace com::sun::star::uno;
using namespace com::sun::star::registry;
using namespace com::sun::star::lang;
using namespace com::sun::star::container;
using namespace cppu;
using namespace osl;
using namespace rtl;
#define SERVICENAME "com.sun.star.registry.NestedRegistry"
#define IMPLNAME "com.sun.star.comp.stoc.NestedRegistry"
extern rtl_StandardModuleCount g_moduleCount;
namespace stoc_bootstrap
{
Sequence< OUString > defreg_getSupportedServiceNames()
{
static Sequence < OUString > *pNames = 0;
if( ! pNames )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( !pNames )
{
static Sequence< OUString > seqNames(1);
seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
pNames = &seqNames;
}
}
return *pNames;
}
OUString defreg_getImplementationName()
{
static OUString *pImplName = 0;
if( ! pImplName )
{
MutexGuard guard( Mutex::getGlobalMutex() );
if( ! pImplName )
{
static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
pImplName = &implName;
}
}
return *pImplName;
}
}
namespace stoc_defreg
{
//*************************************************************************
// NestedRegistryImpl
//*************************************************************************
class NestedKeyImpl;
class NestedRegistryImpl : public WeakAggImplHelper4 < XSimpleRegistry, XInitialization, XServiceInfo, XEnumerationAccess >
{
public:
NestedRegistryImpl( );
~NestedRegistryImpl();
// XServiceInfo
virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
// XInitialization
virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
throw(Exception, RuntimeException);
// XSimpleRegistry
virtual OUString SAL_CALL getURL() throw(RuntimeException);
virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) throw(InvalidRegistryException, RuntimeException);
virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException);
virtual void SAL_CALL close( ) throw(InvalidRegistryException, RuntimeException);
virtual void SAL_CALL destroy( ) throw(InvalidRegistryException, RuntimeException);
virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) throw(InvalidRegistryException, RuntimeException);
virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException);
virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) throw(InvalidRegistryException, MergeConflictException, RuntimeException);
// XEnumerationAccess
virtual Reference< XEnumeration > SAL_CALL createEnumeration( ) throw (RuntimeException);
virtual Type SAL_CALL getElementType( ) throw (RuntimeException);
virtual sal_Bool SAL_CALL hasElements( ) throw (RuntimeException);
friend class NestedKeyImpl;
protected:
Mutex m_mutex;
sal_uInt32 m_state;
Reference<XSimpleRegistry> m_localReg;
Reference<XSimpleRegistry> m_defaultReg;
};
//*************************************************************************
// class NestedKeyImpl the implenetation of interface XRegistryKey
//*************************************************************************
class NestedKeyImpl : public WeakImplHelper1< XRegistryKey >
{
public:
NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
Reference<XRegistryKey>& localKey,
Reference<XRegistryKey>& defaultKey);
NestedKeyImpl( const OUString& aKeyName,
NestedKeyImpl* pKey);
~NestedKeyImpl();
// XRegistryKey
virtual OUString SAL_CALL getKeyName() throw(RuntimeException);
virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException);
virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException);
virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException);
virtual RegistryValueType SAL_CALL getValueType( ) throw(InvalidRegistryException, RuntimeException);
virtual sal_Int32 SAL_CALL getLongValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setLongValue( sal_Int32 value ) throw(InvalidRegistryException, RuntimeException);
virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setLongListValue( const ::com::sun::star::uno::Sequence< sal_Int32 >& seqValue ) throw(InvalidRegistryException, RuntimeException);
virtual OUString SAL_CALL getAsciiValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setAsciiValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException);
virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setAsciiListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException);
virtual OUString SAL_CALL getStringValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setStringValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException);
virtual Sequence< OUString > SAL_CALL getStringListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setStringListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException);
virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
virtual void SAL_CALL setBinaryValue( const ::com::sun::star::uno::Sequence< sal_Int8 >& value ) throw(InvalidRegistryException, RuntimeException);
virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
virtual void SAL_CALL closeKey( ) throw(InvalidRegistryException, RuntimeException);
virtual void SAL_CALL deleteKey( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException);
virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) throw(InvalidRegistryException, RuntimeException);
virtual Sequence< OUString > SAL_CALL getKeyNames( ) throw(InvalidRegistryException, RuntimeException);
virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) throw(InvalidRegistryException, RuntimeException);
virtual void SAL_CALL deleteLink( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException);
virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException);
virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
protected:
void computeChanges();
OUString computeName(const OUString& name);
OUString m_name;
sal_uInt32 m_state;
NestedRegistryImpl* m_pRegistry;
Reference<XRegistryKey> m_localKey;
Reference<XRegistryKey> m_defaultKey;
};
//*************************************************************************
NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
Reference<XRegistryKey>& localKey,
Reference<XRegistryKey>& defaultKey )
: m_pRegistry(pDefaultRegistry)
{
m_pRegistry->acquire();
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();
}
m_state = m_pRegistry->m_state;
}
//*************************************************************************
NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName,
NestedKeyImpl* pKey)
: m_pRegistry(pKey->m_pRegistry)
{
m_pRegistry->acquire();
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_pRegistry->m_state;
}
//*************************************************************************
NestedKeyImpl::~NestedKeyImpl()
{
if ( m_pRegistry )
m_pRegistry->release();
}
//*************************************************************************
void NestedKeyImpl::computeChanges()
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( m_state != m_pRegistry->m_state )
{
Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name);
if ( tmpKey.is() )
{
m_localKey = rootKey->openKey(m_name);
}
m_state = m_pRegistry->m_state;
}
}
//*************************************************************************
// NestedKey_Impl::computeName()
//
OUString NestedKeyImpl::computeName(const OUString& name)
{
OUString resLocalName, resDefaultName;
Guard< Mutex > aGuard( m_pRegistry->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.getLength() > 0 && m_pRegistry->m_defaultReg->isValid() )
{
Reference<XRegistryKey> localRoot(m_pRegistry->m_localReg->getRootKey());
Reference<XRegistryKey> defaultRoot(m_pRegistry->m_defaultReg->getRootKey());
resDefaultName = defaultRoot->getResolvedName(resLocalName);
sal_uInt32 count = 100;
while (resLocalName != resDefaultName && count > 0)
{
count--;
if (resLocalName.getLength() == 0 || resDefaultName.getLength() == 0)
throw InvalidRegistryException();
resLocalName = localRoot->getResolvedName(resDefaultName);
resDefaultName = defaultRoot->getResolvedName(resLocalName);
}
}
}
catch(InvalidRegistryException& )
{
}
return resLocalName;
}
//*************************************************************************
OUString SAL_CALL NestedKeyImpl::getKeyName() throw(RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
return m_name;
}
//*************************************************************************
sal_Bool SAL_CALL NestedKeyImpl::isReadOnly( )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
computeChanges();
if ( m_localKey.is() && m_localKey->isValid() )
return m_localKey->isReadOnly();
else
throw InvalidRegistryException();
}
//*************************************************************************
sal_Bool SAL_CALL NestedKeyImpl::isValid( ) throw(RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
return ((m_localKey.is() && m_localKey->isValid()) ||
(m_defaultKey.is() && m_defaultKey->isValid()) );
}
//*************************************************************************
RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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( )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setLongValue(value);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setLongListValue(seqValue);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
OUString SAL_CALL NestedKeyImpl::getAsciiValue( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setAsciiValue(value);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setAsciiListValue(seqValue);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
OUString SAL_CALL NestedKeyImpl::getStringValue( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setStringValue(value);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setStringListValue(seqValue);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue( )
throw(InvalidRegistryException, InvalidValueException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
m_localKey->setBinaryValue(value);
m_state = m_pRegistry->m_state++;
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( !m_localKey.is() && !m_defaultKey.is() )
{
throw InvalidRegistryException();
}
OUString resolvedName = computeName(aKeyName);
if ( resolvedName.getLength() == 0 )
throw InvalidRegistryException();
Reference<XRegistryKey> localKey, defaultKey;
if ( m_localKey.is() && m_localKey->isValid() )
{
localKey = m_pRegistry->m_localReg->getRootKey()->openKey(resolvedName);
}
if ( m_defaultKey.is() && m_defaultKey->isValid() )
{
defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
}
if ( localKey.is() || defaultKey.is() )
{
return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
} else
{
return Reference<XRegistryKey>();
}
}
//*************************************************************************
Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( (!m_localKey.is() && !m_defaultKey.is()) ||
(m_localKey.is() && m_localKey->isReadOnly()) )
{
throw InvalidRegistryException();
}
OUString resolvedName = computeName(aKeyName);
if ( resolvedName.getLength() == 0 )
throw InvalidRegistryException();
if ( m_localKey.is() && m_localKey->isValid() )
{
Reference<XRegistryKey> localKey, defaultKey;
localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName);
if ( localKey.is() )
{
if ( m_defaultKey.is() && m_defaultKey->isValid() )
{
defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
}
m_state = m_pRegistry->m_state++;
return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
}
} else
{
Reference<XRegistryKey> localKey, defaultKey;
if ( m_defaultKey.is() && m_defaultKey->isValid() )
{
Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName);
if ( localKey.is() )
{
defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
m_state = m_pRegistry->m_state++;
return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
}
}
}
return Reference<XRegistryKey>();
}
//*************************************************************************
void SAL_CALL NestedKeyImpl::closeKey( )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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 )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( m_localKey.is() && m_localKey->isValid() &&
!m_localKey->isReadOnly() )
{
OUString resolvedName = computeName(rKeyName);
if ( resolvedName.getLength() == 0 )
{
throw InvalidRegistryException();
}
m_pRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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();
}
sal_uInt32 local = localSeq.getLength();
sal_uInt32 def = defaultSeq.getLength();
sal_uInt32 len = 0;
sal_uInt32 i, j;
for (i=0; i < local; i++)
{
for (j=0 ; j < def; j++)
{
if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
{
len++;
break;
}
}
}
Sequence< Reference<XRegistryKey> > retSeq(local + def - len);
sal_Bool insert = sal_True;
OUString name;
sal_Int32 lastIndex;
for (i=0; i < local; i++)
{
name = localSeq.getConstArray()[i];
lastIndex = name.lastIndexOf('/');
name = name.copy(lastIndex);
retSeq.getArray()[i] =
(XRegistryKey*)new NestedKeyImpl(name, this);
}
sal_uInt32 k = local;
for (i=0; i < def; i++)
{
insert = sal_True;
for (j=0 ; j < local; j++)
{
if ( retSeq.getConstArray()[j]->getKeyName()
== defaultSeq.getConstArray()[i] )
{
insert = sal_False;
break;
}
}
if ( insert )
{
name = defaultSeq.getConstArray()[i];
lastIndex = name.lastIndexOf('/');
name = name.copy(lastIndex);
retSeq.getArray()[k++] =
(XRegistryKey*)new NestedKeyImpl(name, this);
}
}
return retSeq;
}
//*************************************************************************
Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->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();
}
sal_uInt32 local = localSeq.getLength();
sal_uInt32 def = defaultSeq.getLength();
sal_uInt32 len = 0;
sal_uInt32 i, j;
for (i=0; i < local; i++)
{
for (j=0 ; j < def; j++)
{
if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
{
len++;
break;
}
}
}
Sequence<OUString> retSeq(local + def - len);
sal_Bool insert = sal_True;
for (i=0; i < local; i++)
{
retSeq.getArray()[i] = localSeq.getConstArray()[i];
}
sal_uInt32 k = local;
for (i=0; i < def; i++)
{
insert = sal_True;
for (j=0 ; j < local; j++)
{
if ( retSeq.getConstArray()[j] == defaultSeq.getConstArray()[i] )
{
insert = sal_False;
break;
}
}
if ( insert )
retSeq.getArray()[k++] = defaultSeq.getConstArray()[i];
}
return retSeq;
}
//*************************************************************************
sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
sal_Bool isCreated = sal_False;
if ( !m_localKey.is() && !m_defaultKey.is() )
{
throw InvalidRegistryException();
}
OUString linkName;
OUString resolvedName;
sal_Int32 lastIndex = aLinkName.lastIndexOf('/');
if ( lastIndex > 0 )
{
linkName = aLinkName.copy(0, lastIndex);
resolvedName = computeName(linkName);
if ( resolvedName.getLength() == 0 )
{
throw InvalidRegistryException();
}
resolvedName = resolvedName + aLinkName.copy(lastIndex);
} else
{
if ( lastIndex == 0 )
resolvedName = m_name + aLinkName;
else
resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + aLinkName;
}
if ( m_localKey.is() && m_localKey->isValid() )
{
isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
} else
{
if ( m_defaultKey.is() && m_defaultKey->isValid() )
{
Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
m_localKey = rootKey->createKey(m_name);
isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
}
}
if ( isCreated )
m_state = m_pRegistry->m_state++;
return isCreated;
}
//*************************************************************************
void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( !m_localKey.is() && !m_defaultKey.is() )
{
throw InvalidRegistryException();
}
OUString linkName;
OUString resolvedName;
sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
if ( lastIndex > 0 )
{
linkName = rLinkName.copy(0, lastIndex);
resolvedName = computeName(linkName);
if ( resolvedName.getLength() == 0 )
{
throw InvalidRegistryException();
}
resolvedName = resolvedName + rLinkName.copy(lastIndex);
} else
{
if ( lastIndex == 0 )
resolvedName = m_name + rLinkName;
else
resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName;
}
if ( m_localKey.is() && m_localKey->isValid() &&
!m_localKey->isReadOnly() )
{
m_pRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
} else
{
throw InvalidRegistryException();
}
}
//*************************************************************************
OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( !m_localKey.is() && !m_defaultKey.is() )
{
throw InvalidRegistryException();
}
OUString linkName;
OUString resolvedName;
sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
if ( lastIndex > 0 )
{
linkName = rLinkName.copy(0, lastIndex);
resolvedName = computeName(linkName);
if ( resolvedName.getLength() == 0 )
{
throw InvalidRegistryException();
}
resolvedName = resolvedName + rLinkName.copy(lastIndex);
} else
{
if ( lastIndex == 0 )
resolvedName = m_name + rLinkName;
else
resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName;
}
OUString linkTarget;
if ( m_localKey.is() && m_localKey->isValid() )
{
try
{
linkTarget = m_pRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
return linkTarget;
}
catch(InvalidRegistryException& )
{
}
}
if ( m_defaultKey.is() && m_defaultKey->isValid() )
linkTarget = m_pRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
return linkTarget;
}
//*************************************************************************
OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_pRegistry->m_mutex );
if ( !m_localKey.is() && !m_defaultKey.is() )
{
throw InvalidRegistryException();
}
OUString resolvedName = computeName(aKeyName);
if ( resolvedName.getLength() == 0 )
{
throw InvalidRegistryException();
}
return resolvedName;
}
//*************************************************************************
//
// DefaultRegistry Implementation
//
//*************************************************************************
NestedRegistryImpl::NestedRegistryImpl( )
: m_state(0)
{
g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
}
//*************************************************************************
NestedRegistryImpl::~NestedRegistryImpl()
{
g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
}
class RegistryEnumueration : public WeakImplHelper1< XEnumeration >
{
public:
RegistryEnumueration(
const Reference< XSimpleRegistry > &r1,
const Reference< XSimpleRegistry > &r2 )
: m_xReg1( r1 ) , m_xReg2( r2 )
{}
public:
virtual sal_Bool SAL_CALL hasMoreElements( ) throw (RuntimeException);
virtual Any SAL_CALL nextElement( ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
private:
Reference< XSimpleRegistry > m_xReg1;
Reference< XSimpleRegistry > m_xReg2;
};
sal_Bool RegistryEnumueration::hasMoreElements( ) throw (RuntimeException)
{
return m_xReg1.is() || m_xReg2.is();
}
Any RegistryEnumueration::nextElement( )
throw (NoSuchElementException, WrappedTargetException, RuntimeException)
{
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( OUString( RTL_CONSTASCII_USTRINGPARAM(
"NestedRegistry: no nextElement() !" ) ),Reference< XInterface > () );
}
return a;
}
Reference< XEnumeration > NestedRegistryImpl::createEnumeration( ) throw (RuntimeException)
{
MutexGuard guard( m_mutex );
return new RegistryEnumueration( m_localReg, m_defaultReg );
}
Type NestedRegistryImpl::getElementType( ) throw (RuntimeException)
{
return getCppuType( &m_localReg );
}
sal_Bool SAL_CALL NestedRegistryImpl::hasElements( ) throw (RuntimeException)
{
MutexGuard guard( m_mutex );
return m_localReg.is() || m_defaultReg.is();
}
//*************************************************************************
OUString SAL_CALL NestedRegistryImpl::getImplementationName( )
throw(RuntimeException)
{
return stoc_bootstrap::defreg_getImplementationName();
}
//*************************************************************************
sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
throw(RuntimeException)
{
Guard< Mutex > aGuard( m_mutex );
Sequence< OUString > aSNL = getSupportedServiceNames();
const OUString * pArray = aSNL.getArray();
for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
if( pArray[i] == ServiceName )
return sal_True;
return sal_False;
}
//*************************************************************************
Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( )
throw(RuntimeException)
{
return stoc_bootstrap::defreg_getSupportedServiceNames();
}
//*************************************************************************
void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
throw( Exception, RuntimeException )
{
Guard< Mutex > aGuard( m_mutex );
if ( (aArguments.getLength() == 2) &&
(aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) &&
(aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) )
{
aArguments[0] >>= m_localReg;
aArguments[1] >>= m_defaultReg;
if ( m_localReg == m_defaultReg )
m_defaultReg = Reference< XSimpleRegistry >();
}
}
//*************************************************************************
OUString SAL_CALL NestedRegistryImpl::getURL() throw(RuntimeException)
{
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, RuntimeException)
{
throw InvalidRegistryException(
OUString::createFromAscii("the 'open' method is not specified for a nested registry"),
Reference< XInterface >() );
}
//*************************************************************************
sal_Bool SAL_CALL NestedRegistryImpl::isValid( ) throw(RuntimeException)
{
Guard< Mutex > aGuard( m_mutex );
try
{
if ( (m_localReg.is() && m_localReg->isValid()) ||
(m_defaultReg.is() && m_defaultReg->isValid()) )
return sal_True;
}
catch(InvalidRegistryException& )
{
}
return sal_False;
}
//*************************************************************************
void SAL_CALL NestedRegistryImpl::close( )
throw(InvalidRegistryException, RuntimeException)
{
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();
}
/*
throw InvalidRegistryException(
OUString::createFromAscii("the 'close' method is not specified for a nested registry"),
Reference< XInterface >() );
*/
}
//*************************************************************************
void SAL_CALL NestedRegistryImpl::destroy( )
throw(InvalidRegistryException, RuntimeException)
{
throw InvalidRegistryException(
OUString::createFromAscii("the 'destroy' method is not specified for a nested registry"),
Reference< XInterface >() );
}
//*************************************************************************
Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( )
throw(InvalidRegistryException, RuntimeException)
{
Reference<XRegistryKey> tmpKey;
Guard< Mutex > aGuard( m_mutex );
if ( m_localReg.is() && m_localReg->isValid() )
{
Reference<XRegistryKey> localKey, defaultKey;
localKey = m_localReg->getRootKey();
if ( localKey.is() )
{
if ( m_defaultReg.is() && m_defaultReg->isValid() )
{
defaultKey = m_defaultReg->getRootKey();
}
return ((XRegistryKey*)new NestedKeyImpl(this, localKey, defaultKey));
}
} else
{
throw InvalidRegistryException();
}
return Reference<XRegistryKey>();
}
//*************************************************************************
sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( )
throw(InvalidRegistryException, RuntimeException)
{
Guard< Mutex > aGuard( m_mutex );
try
{
if ( m_localReg.is() && m_localReg->isValid() )
return m_localReg->isReadOnly();
}
catch(InvalidRegistryException& )
{
}
return sal_False;
}
//*************************************************************************
void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl )
throw(InvalidRegistryException, MergeConflictException, RuntimeException)
{
Guard< Mutex > aGuard( m_mutex );
if ( m_localReg.is() && m_localReg->isValid() )
{
m_localReg->mergeKey(aKeyName, aUrl);
m_state++;
}
}
} // namespace stco_defreg
namespace stoc_bootstrap
{
//*************************************************************************
Reference<XInterface> SAL_CALL NestedRegistry_CreateInstance( const Reference<XComponentContext>& )
throw(Exception)
{
Reference<XInterface> xRet;
XSimpleRegistry *pRegistry = (XSimpleRegistry*) new stoc_defreg::NestedRegistryImpl;
if (pRegistry)
{
xRet = Reference<XInterface>::query(pRegistry);
}
return xRet;
}
}