diff options
Diffstat (limited to 'ucb/source/core/ucbstore.cxx')
-rw-r--r-- | ucb/source/core/ucbstore.cxx | 2770 |
1 files changed, 2770 insertions, 0 deletions
diff --git a/ucb/source/core/ucbstore.cxx b/ucb/source/core/ucbstore.cxx new file mode 100644 index 000000000000..cd5cb7856d7a --- /dev/null +++ b/ucb/source/core/ucbstore.cxx @@ -0,0 +1,2770 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" + +/************************************************************************** + TODO + ************************************************************************** + + *************************************************************************/ + +#include <list> +#include <hash_map> +#include <osl/diagnose.h> +#include <rtl/ustrbuf.hxx> +#include <cppuhelper/interfacecontainer.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertySetInfoChange.hpp> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> +#include "ucbstore.hxx" + +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::lang; +using namespace com::sun::star::ucb; +using namespace com::sun::star::uno; +using namespace com::sun::star::util; +using namespace cppu; +using namespace rtl; + +//========================================================================= +rtl::OUString makeHierarchalNameSegment( const rtl::OUString & rIn ) +{ + rtl::OUStringBuffer aBuffer; + aBuffer.appendAscii( "['" ); + + sal_Int32 nCount = rIn.getLength(); + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const sal_Unicode c = rIn.getStr()[ n ]; + switch ( c ) + { + case '&': + aBuffer.appendAscii( "&" ); + break; + + case '"': + aBuffer.appendAscii( """ ); + break; + + case '\'': + aBuffer.appendAscii( "'" ); + break; + + case '<': + aBuffer.appendAscii( "<" ); + break; + + case '>': + aBuffer.appendAscii( ">" ); + break; + + default: + aBuffer.append( c ); + break; + } + } + + aBuffer.appendAscii( "']" ); + return rtl::OUString( aBuffer.makeStringAndClear() ); +} + +//========================================================================= + +#define STORE_CONTENTPROPERTIES_KEY "/org.openoffice.ucb.Store/ContentProperties" + +// describe path of cfg entry +#define CFGPROPERTY_NODEPATH "nodepath" +// true->async. update; false->sync. update +#define CFGPROPERTY_LAZYWRITE "lazywrite" + +//========================================================================= + +struct equalString_Impl +{ + bool operator()( const OUString& s1, const OUString& s2 ) const + { + return !!( s1 == s2 ); + } +}; + +struct hashString_Impl +{ + size_t operator()( const OUString & rName ) const + { + return rName.hashCode(); + } +}; + +//========================================================================= +// +// PropertySetMap_Impl. +// +//========================================================================= + +typedef std::hash_map +< + OUString, + PersistentPropertySet*, + hashString_Impl, + equalString_Impl +> +PropertySetMap_Impl; + +//========================================================================= +// +// class PropertySetInfo_Impl +// +//========================================================================= + +class PropertySetInfo_Impl : + public OWeakObject, public XTypeProvider, public XPropertySetInfo +{ + Reference< XMultiServiceFactory > m_xSMgr; + Sequence< Property >* m_pProps; + PersistentPropertySet* m_pOwner; + +public: + PropertySetInfo_Impl( const Reference< XMultiServiceFactory >& rxSMgr, + PersistentPropertySet* pOwner ); + virtual ~PropertySetInfo_Impl(); + + // XInterface + XINTERFACE_DECL() + + // XTypeProvider + XTYPEPROVIDER_DECL() + + // XPropertySetInfo + virtual Sequence< Property > SAL_CALL getProperties() + throw( RuntimeException ); + virtual Property SAL_CALL getPropertyByName( const OUString& aName ) + throw( UnknownPropertyException, RuntimeException ); + virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) + throw( RuntimeException ); + + // Non-interface methods. + void reset() { delete m_pProps; m_pProps = 0; } +}; + +//========================================================================= +// +// UcbStore_Impl. +// +//========================================================================= + +struct UcbStore_Impl +{ + osl::Mutex m_aMutex; + Sequence< Any > m_aInitArgs; + Reference< XPropertySetRegistry > m_xTheRegistry; +}; + +//========================================================================= +//========================================================================= +//========================================================================= +// +// UcbStore Implementation. +// +//========================================================================= +//========================================================================= +//========================================================================= + +UcbStore::UcbStore( const Reference< XMultiServiceFactory >& rXSMgr ) +: m_xSMgr( rXSMgr ), + m_pImpl( new UcbStore_Impl() ) +{ +} + +//========================================================================= +// virtual +UcbStore::~UcbStore() +{ + delete m_pImpl; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_4( UcbStore, + XTypeProvider, + XServiceInfo, + XPropertySetRegistryFactory, + XInitialization ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_4( UcbStore, + XTypeProvider, + XServiceInfo, + XPropertySetRegistryFactory, + XInitialization ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_IMPL_1( UcbStore, + OUString::createFromAscii( + "com.sun.star.comp.ucb.UcbStore" ), + OUString::createFromAscii( + STORE_SERVICE_NAME ) ); + +//========================================================================= +// +// Service factory implementation. +// +//========================================================================= + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( UcbStore ); + +//========================================================================= +// +// XPropertySetRegistryFactory methods. +// +//========================================================================= + +// virtual +Reference< XPropertySetRegistry > SAL_CALL +UcbStore::createPropertySetRegistry( const OUString& ) + throw( RuntimeException ) +{ + // The URL parameter is ignored by this interface implementation. It always + // uses the configuration server as storage medium. + + if ( !m_pImpl->m_xTheRegistry.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + if ( !m_pImpl->m_xTheRegistry.is() ) + m_pImpl->m_xTheRegistry = new PropertySetRegistry( m_xSMgr, getInitArgs() ); + } + + return m_pImpl->m_xTheRegistry; +} + +//========================================================================= +// +// XInitialization methods. +// +//========================================================================= + +// virtual +void SAL_CALL UcbStore::initialize( const Sequence< Any >& aArguments ) + throw( Exception, RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + m_pImpl->m_aInitArgs = aArguments; +} + +//========================================================================= +const Sequence< Any >& UcbStore::getInitArgs() const +{ + return m_pImpl->m_aInitArgs; +} + +//========================================================================= +// +// PropertySetRegistry_Impl. +// +//========================================================================= + +struct PropertySetRegistry_Impl +{ + const Sequence< Any > m_aInitArgs; + PropertySetMap_Impl m_aPropSets; + Reference< XMultiServiceFactory > m_xConfigProvider; + Reference< XInterface > m_xRootReadAccess; + Reference< XInterface > m_xRootWriteAccess; + osl::Mutex m_aMutex; + sal_Bool m_bTriedToGetRootReadAccess; // #82494# + sal_Bool m_bTriedToGetRootWriteAccess; // #82494# + + PropertySetRegistry_Impl( const Sequence< Any > &rInitArgs ) + : m_aInitArgs( rInitArgs ), + m_bTriedToGetRootReadAccess( sal_False ), + m_bTriedToGetRootWriteAccess( sal_False ) + { + } +}; + +//========================================================================= +//========================================================================= +//========================================================================= +// +// PropertySetRegistry Implementation. +// +//========================================================================= +//========================================================================= +//========================================================================= + +PropertySetRegistry::PropertySetRegistry( + const Reference< XMultiServiceFactory >& rXSMgr, + const Sequence< Any > &rInitArgs ) +: m_xSMgr( rXSMgr ), + m_pImpl( new PropertySetRegistry_Impl( rInitArgs ) ) +{ +} + +//========================================================================= +// virtual +PropertySetRegistry::~PropertySetRegistry() +{ + delete m_pImpl; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_5( PropertySetRegistry, + XTypeProvider, + XServiceInfo, + XPropertySetRegistry, + XElementAccess, /* base of XNameAccess */ + XNameAccess ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_4( PropertySetRegistry, + XTypeProvider, + XServiceInfo, + XPropertySetRegistry, + XNameAccess ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_NOFACTORY_IMPL_1( PropertySetRegistry, + OUString::createFromAscii( + "com.sun.star.comp.ucb.PropertySetRegistry" ), + OUString::createFromAscii( + PROPSET_REG_SERVICE_NAME ) ); + +//========================================================================= +// +// XPropertySetRegistry methods. +// +//========================================================================= + +// virtual +Reference< XPersistentPropertySet > SAL_CALL +PropertySetRegistry::openPropertySet( const OUString& key, sal_Bool create ) + throw( RuntimeException ) +{ + if ( key.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets; + + PropertySetMap_Impl::const_iterator it = rSets.find( key ); + if ( it != rSets.end() ) + { + // Already instanciated. + return Reference< XPersistentPropertySet >( (*it).second ); + } + else + { + // Create new instance. + Reference< XNameAccess > xRootNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootNameAccess.is() ) + { + // Propertyset in registry? + if ( xRootNameAccess->hasByName( key ) ) + { + // Yep! + return Reference< XPersistentPropertySet >( + new PersistentPropertySet( + m_xSMgr, *this, key ) ); + } + else if ( create ) + { + // No. Create entry for propertyset. + + Reference< XSingleServiceFactory > xFac( + getConfigWriteAccess( OUString() ), UNO_QUERY ); + Reference< XChangesBatch > xBatch( xFac, UNO_QUERY ); + Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); + + OSL_ENSURE( xFac.is(), + "PropertySetRegistry::openPropertySet - " + "No factory!" ); + + OSL_ENSURE( xBatch.is(), + "PropertySetRegistry::openPropertySet - " + "No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PropertySetRegistry::openPropertySet - " + "No conteiner!" ); + + if ( xFac.is() && xBatch.is() && xContainer.is() ) + { + try + { + // Create new "Properties" config item. + Reference< XNameReplace > xNameReplace( + xFac->createInstance(), UNO_QUERY ); + + if ( xNameReplace.is() ) + { + // Fill new item... + +// // Set Values +// xNameReplace->replaceByName( +// OUString::createFromAscii( "Values" ), +// makeAny( ... ) ); + + // Insert new item. + xContainer->insertByName( + key, makeAny( xNameReplace ) ); + // Commit changes. + xBatch->commitChanges(); + + return Reference< XPersistentPropertySet >( + new PersistentPropertySet( + m_xSMgr, *this, key ) ); + } + } + catch ( IllegalArgumentException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught IllegalArgumentException!" ); + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught ElementExistException!" ); + } + catch ( WrappedTargetException& ) + { + // insertByName, commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught WrappedTargetException!" ); + } + catch ( RuntimeException& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught RuntimeException!" ); + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - " + "caught Exception!" ); + } + } + } + else + { + // No entry. Fail, but no error. + return Reference< XPersistentPropertySet >(); + } + } + + OSL_ENSURE( sal_False, + "PropertySetRegistry::openPropertySet - Error!" ); + } + } + + return Reference< XPersistentPropertySet >(); +} + +//========================================================================= +// virtual +void SAL_CALL PropertySetRegistry::removePropertySet( const OUString& key ) + throw( RuntimeException ) +{ + if ( !key.getLength() ) + return; + + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xRootNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootNameAccess.is() ) + { + // Propertyset in registry? + if ( !xRootNameAccess->hasByName( key ) ) + return; + Reference< XChangesBatch > xBatch( + getConfigWriteAccess( OUString() ), UNO_QUERY ); + Reference< XNameContainer > xContainer( xBatch, UNO_QUERY ); + + OSL_ENSURE( xBatch.is(), + "PropertySetRegistry::removePropertySet - " + "No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PropertySetRegistry::removePropertySet - " + "No conteiner!" ); + + if ( xBatch.is() && xContainer.is() ) + { + try + { + // Remove item. + xContainer->removeByName( key ); + // Commit changes. + xBatch->commitChanges(); + + // Success. + return; + } + catch ( NoSuchElementException& ) + { + // removeByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::removePropertySet - " + "caught NoSuchElementException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::removePropertySet - " + "caught WrappedTargetException!" ); + return; + } + } + + return; + } + + OSL_ENSURE( sal_False, "PropertySetRegistry::removePropertySet - Error!" ); +} + +//========================================================================= +// +// XElementAccess methods. +// +//========================================================================= + +// virtual +com::sun::star::uno::Type SAL_CALL PropertySetRegistry::getElementType() + throw( RuntimeException ) +{ + return getCppuType( ( Reference< XPersistentPropertySet > * ) 0 ); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL PropertySetRegistry::hasElements() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XElementAccess > xElemAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xElemAccess.is() ) + return xElemAccess->hasElements(); + + return sal_False; +} + +//========================================================================= +// +// XNameAccess methods. +// +//========================================================================= + +// virtual +Any SAL_CALL PropertySetRegistry::getByName( const OUString& aName ) + throw( NoSuchElementException, WrappedTargetException, RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + + try + { + return xNameAccess->getByName( aName ); + } + catch ( NoSuchElementException& ) + { + // getByName + } + catch ( WrappedTargetException& ) + { + // getByName + } + } + + return Any(); +} + +//========================================================================= +// virtual +Sequence< OUString > SAL_CALL PropertySetRegistry::getElementNames() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + return xNameAccess->getElementNames(); + } + return Sequence< OUString >( 0 ); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL PropertySetRegistry::hasByName( const OUString& aName ) + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XNameAccess > xNameAccess( + getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + return xNameAccess->hasByName( aName ); + } + + return sal_False; +} + +//========================================================================= +void PropertySetRegistry::add( PersistentPropertySet* pSet ) +{ + OUString key( pSet->getKey() ); + + if ( key.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + m_pImpl->m_aPropSets[ key ] = pSet; + } +} + +//========================================================================= +void PropertySetRegistry::remove( PersistentPropertySet* pSet ) +{ + OUString key( pSet->getKey() ); + + if ( key.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + PropertySetMap_Impl& rSets = m_pImpl->m_aPropSets; + + PropertySetMap_Impl::iterator it = rSets.find( key ); + if ( it != rSets.end() ) + { + // Found. + rSets.erase( it ); + } + } +} + +//========================================================================= +void PropertySetRegistry::renamePropertySet( const OUString& rOldKey, + const OUString& rNewKey ) +{ + if ( rOldKey == rNewKey ) + return; + + Reference< XNameAccess > xRootNameAccess( + getConfigWriteAccess( OUString() ), UNO_QUERY ); + if ( xRootNameAccess.is() ) + { + // Old key present? + if ( xRootNameAccess->hasByName( rOldKey ) ) + { + // New key not present? + if ( xRootNameAccess->hasByName( rNewKey ) ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "New key exists!" ); + return; + } + Reference< XSingleServiceFactory > xFac( + xRootNameAccess, UNO_QUERY ); + Reference< XChangesBatch > xBatch( xFac, UNO_QUERY ); + Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); + + OSL_ENSURE( xFac.is(), + "PropertySetRegistry::renamePropertySet - " + "No factory!" ); + + OSL_ENSURE( xBatch.is(), + "PropertySetRegistry::renamePropertySet - " + "No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PropertySetRegistry::renamePropertySet - " + "No container!" ); + + if ( xFac.is() && xBatch.is() && xContainer.is() ) + { + ////////////////////////////////////////////////////// + // Create new "Properties" config item. + ////////////////////////////////////////////////////// + + try + { + Reference< XNameReplace > xNameReplace( + xFac->createInstance(), UNO_QUERY ); + + if ( xNameReplace.is() ) + { + // Insert new item. + xContainer->insertByName( + rNewKey, makeAny( xNameReplace ) ); + // Commit changes. + xBatch->commitChanges(); + } + } + catch ( IllegalArgumentException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught IllegalArgumentException!" ); + return; + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught ElementExistException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // insertByName, commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught WrappedTargetException!" ); + return; + } + catch ( RuntimeException& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught RuntimeException!" ); + return; + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught Exception!" ); + return; + } + + ////////////////////////////////////////////////////// + // Copy data... + ////////////////////////////////////////////////////// + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + xRootNameAccess, UNO_QUERY ); + if ( !xRootHierNameAccess.is() ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "No hierarchical name access!" ); + return; + } + + try + { + rtl::OUString aOldValuesKey + = makeHierarchalNameSegment( rOldKey ); + aOldValuesKey += OUString::createFromAscii( "/Values" ); + + Reference< XNameAccess > xOldNameAccess; + xRootHierNameAccess->getByHierarchicalName( + aOldValuesKey ) + >>= xOldNameAccess; + if ( !xOldNameAccess.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No old name access!" ); + return; + } + + // Obtain property names. + Sequence< OUString > aElems + = xOldNameAccess->getElementNames(); + sal_Int32 nCount = aElems.getLength(); + if ( nCount ) + { + rtl::OUString aNewValuesKey + = makeHierarchalNameSegment( rNewKey ); + aNewValuesKey += OUString::createFromAscii( "/Values" ); + + Reference< XSingleServiceFactory > xNewFac; + xRootHierNameAccess->getByHierarchicalName( + aNewValuesKey ) + >>= xNewFac; + if ( !xNewFac.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No new factory!" ); + return; + } + + Reference< XNameContainer > xNewContainer( + xNewFac, UNO_QUERY ); + if ( !xNewContainer.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No new container!" ); + return; + } + + aOldValuesKey += OUString::createFromAscii( "/" ); + + OUString aHandleKey + = OUString::createFromAscii( "/Handle" ); + OUString aValueKey + = OUString::createFromAscii( "/Value" ); + OUString aStateKey + = OUString::createFromAscii( "/State" ); + OUString aAttrKey + = OUString::createFromAscii( "/Attributes" ); + + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const OUString& rPropName = aElems[ n ]; + + // Create new item. + Reference< XNameReplace > xNewPropNameReplace( + xNewFac->createInstance(), UNO_QUERY ); + + if ( !xNewPropNameReplace.is() ) + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::renamePropertySet - " + "No new prop name replace!" ); + return; + } + + // Fill new item... + + // Set Values + OUString aKey = aOldValuesKey; + aKey += makeHierarchalNameSegment( rPropName ); + + // ... handle + OUString aNewKey1 = aKey; + aNewKey1 += aHandleKey; + Any aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "Handle" ), + aAny ); + + // ... value + aNewKey1 = aKey; + aNewKey1 += aValueKey; + aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + aAny ); + + // ... state + aNewKey1 = aKey; + aNewKey1 += aStateKey; + aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + aAny ); + + // ... attributes + aNewKey1 = aKey; + aNewKey1 += aAttrKey; + aAny = + xRootHierNameAccess->getByHierarchicalName( + aNewKey1 ); + xNewPropNameReplace->replaceByName( + OUString::createFromAscii( "Attributes" ), + aAny ); + + // Insert new item. + xNewContainer->insertByName( + rPropName, makeAny( xNewPropNameReplace ) ); + + // Commit changes. + xBatch->commitChanges(); + } + } + } + catch ( IllegalArgumentException& ) + { + // insertByName, replaceByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught IllegalArgumentException!" ); + return; + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught ElementExistException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // insertByName, replaceByName, commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught WrappedTargetException!" ); + return; + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName, replaceByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught NoSuchElementException!" ); + return; + } + catch ( RuntimeException& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught RuntimeException!" ); + return; + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught Exception!" ); + return; + } + + ////////////////////////////////////////////////////// + // Remove old entry... + ////////////////////////////////////////////////////// + + try + { + // Remove item. + xContainer->removeByName( rOldKey ); + // Commit changes. + xBatch->commitChanges(); + + // Success. + return; + } + catch ( NoSuchElementException& ) + { + // removeByName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught NoSuchElementException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // commitChanges + + OSL_ENSURE( sal_False, + "PropertySetRegistry::renamePropertySet - " + "caught WrappedTargetException!" ); + return; + } + } + } + } + + OSL_ENSURE( sal_False, "PropertySetRegistry::renamePropertySet - Error!" ); +} + +//========================================================================= +Reference< XMultiServiceFactory > PropertySetRegistry::getConfigProvider() +{ + if ( !m_pImpl->m_xConfigProvider.is() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + if ( !m_pImpl->m_xConfigProvider.is() ) + { + const Sequence< Any >& rInitArgs = m_pImpl->m_aInitArgs; + + if ( rInitArgs.getLength() > 0 ) + { + // Extract config provider from service init args. + rInitArgs[ 0 ] >>= m_pImpl->m_xConfigProvider; + + OSL_ENSURE( m_pImpl->m_xConfigProvider.is(), + "PropertySetRegistry::getConfigProvider - " + "No config provider!" ); + } + else + { + try + { + m_pImpl->m_xConfigProvider + = Reference< XMultiServiceFactory >( + m_xSMgr->createInstance( + OUString::createFromAscii( + "com.sun.star.configuration." + "ConfigurationProvider" ) ), + UNO_QUERY ); + + OSL_ENSURE( m_pImpl->m_xConfigProvider.is(), + "PropertySetRegistry::getConfigProvider - " + "No config provider!" ); + + } + catch ( Exception& ) + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigProvider - " + "caught exception!" ); + } + } + } + } + + return m_pImpl->m_xConfigProvider; +} + +//========================================================================= +Reference< XInterface > PropertySetRegistry::getRootConfigReadAccess() +{ + try + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + if ( !m_pImpl->m_xRootReadAccess.is() ) + { + if ( m_pImpl->m_bTriedToGetRootReadAccess ) // #82494# + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::getRootConfigReadAccess - " + "Unable to read any config data! -> #82494#" ); + return Reference< XInterface >(); + } + + getConfigProvider(); + + if ( m_pImpl->m_xConfigProvider.is() ) + { + Sequence< Any > aArguments( 1 ); + PropertyValue aProperty; + aProperty.Name + = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + CFGPROPERTY_NODEPATH ) ); + aProperty.Value + <<= rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( + STORE_CONTENTPROPERTIES_KEY ) ); + aArguments[ 0 ] <<= aProperty; + + m_pImpl->m_bTriedToGetRootReadAccess = sal_True; + + m_pImpl->m_xRootReadAccess = + m_pImpl->m_xConfigProvider->createInstanceWithArguments( + OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationAccess" ), + aArguments ); + + if ( m_pImpl->m_xRootReadAccess.is() ) + return m_pImpl->m_xRootReadAccess; + } + } + else + return m_pImpl->m_xRootReadAccess; + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + // createInstance, createInstanceWithArguments + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getRootConfigReadAccess - caught Exception!" ); + return Reference< XInterface >(); + } + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getRootConfigReadAccess - Error!" ); + return Reference< XInterface >(); +} + +//========================================================================= +Reference< XInterface > PropertySetRegistry::getConfigWriteAccess( + const OUString& rPath ) +{ + try + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + if ( !m_pImpl->m_xRootWriteAccess.is() ) + { + if ( m_pImpl->m_bTriedToGetRootWriteAccess ) // #82494# + { + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - " + "Unable to write any config data! -> #82494#" ); + return Reference< XInterface >(); + } + + getConfigProvider(); + + if ( m_pImpl->m_xConfigProvider.is() ) + { + Sequence< Any > aArguments( 2 ); + PropertyValue aProperty; + + aProperty.Name + = OUString( RTL_CONSTASCII_USTRINGPARAM( + CFGPROPERTY_NODEPATH ) ); + aProperty.Value + <<= OUString( RTL_CONSTASCII_USTRINGPARAM( + STORE_CONTENTPROPERTIES_KEY ) ); + aArguments[ 0 ] <<= aProperty; + + aProperty.Name + = OUString( RTL_CONSTASCII_USTRINGPARAM( + CFGPROPERTY_LAZYWRITE ) ); + aProperty.Value <<= sal_True; + aArguments[ 1 ] <<= aProperty; + + m_pImpl->m_bTriedToGetRootWriteAccess = sal_True; + + m_pImpl->m_xRootWriteAccess = + m_pImpl->m_xConfigProvider->createInstanceWithArguments( + OUString::createFromAscii( + "com.sun.star.configuration.ConfigurationUpdateAccess" ), + aArguments ); + + OSL_ENSURE( m_pImpl->m_xRootWriteAccess.is(), + "PropertySetRegistry::getConfigWriteAccess - " + "No config update access!" ); + } + } + + if ( m_pImpl->m_xRootWriteAccess.is() ) + { + if ( rPath.getLength() ) + { + Reference< XHierarchicalNameAccess > xNA( + m_pImpl->m_xRootWriteAccess, UNO_QUERY ); + if ( xNA.is() ) + { + Reference< XInterface > xInterface; + xNA->getByHierarchicalName( rPath ) >>= xInterface; + + if ( xInterface.is() ) + return xInterface; + } + } + else + return m_pImpl->m_xRootWriteAccess; + } + } + catch ( RuntimeException& ) + { + throw; + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - " + "caught NoSuchElementException!" ); + return Reference< XInterface >(); + } + catch ( Exception& ) + { + // createInstance, createInstanceWithArguments + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - " + "caught Exception!" ); + return Reference< XInterface >(); + } + + OSL_ENSURE( sal_False, + "PropertySetRegistry::getConfigWriteAccess - Error!" ); + return Reference< XInterface >(); +} + +//========================================================================= +// +// PropertyListeners_Impl. +// +//========================================================================= + +typedef OMultiTypeInterfaceContainerHelperVar +< + OUString, + hashString_Impl, + equalString_Impl +> PropertyListeners_Impl; + +//========================================================================= +// +// PersistentPropertySet_Impl. +// +//========================================================================= + +struct PersistentPropertySet_Impl +{ + PropertySetRegistry* m_pCreator; + PropertySetInfo_Impl* m_pInfo; + OUString m_aKey; + OUString m_aFullKey; + osl::Mutex m_aMutex; + OInterfaceContainerHelper* m_pDisposeEventListeners; + OInterfaceContainerHelper* m_pPropSetChangeListeners; + PropertyListeners_Impl* m_pPropertyChangeListeners; + + PersistentPropertySet_Impl( PropertySetRegistry& rCreator, + const OUString& rKey ) + : m_pCreator( &rCreator ), m_pInfo( NULL ), m_aKey( rKey ), + m_pDisposeEventListeners( NULL ), m_pPropSetChangeListeners( NULL ), + m_pPropertyChangeListeners( NULL ) + { + m_pCreator->acquire(); + } + + ~PersistentPropertySet_Impl() + { + m_pCreator->release(); + + if ( m_pInfo ) + m_pInfo->release(); + + delete m_pDisposeEventListeners; + delete m_pPropSetChangeListeners; + delete m_pPropertyChangeListeners; + } +}; + +//========================================================================= +//========================================================================= +//========================================================================= +// +// PersistentPropertySet Implementation. +// +//========================================================================= +//========================================================================= +//========================================================================= + +PersistentPropertySet::PersistentPropertySet( + const Reference< XMultiServiceFactory >& rXSMgr, + PropertySetRegistry& rCreator, + const OUString& rKey ) +: m_xSMgr( rXSMgr ), + m_pImpl( new PersistentPropertySet_Impl( rCreator, rKey ) ) +{ + // register at creator. + rCreator.add( this ); +} + +//========================================================================= +// virtual +PersistentPropertySet::~PersistentPropertySet() +{ + // deregister at creator. + m_pImpl->m_pCreator->remove( this ); + + delete m_pImpl; +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_9( PersistentPropertySet, + XTypeProvider, + XServiceInfo, + XComponent, + XPropertySet, /* base of XPersistentPropertySet */ + XNamed, + XPersistentPropertySet, + XPropertyContainer, + XPropertySetInfoChangeNotifier, + XPropertyAccess ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_8( PersistentPropertySet, + XTypeProvider, + XServiceInfo, + XComponent, + XPersistentPropertySet, + XNamed, + XPropertyContainer, + XPropertySetInfoChangeNotifier, + XPropertyAccess ); + +//========================================================================= +// +// XServiceInfo methods. +// +//========================================================================= + +XSERVICEINFO_NOFACTORY_IMPL_1( PersistentPropertySet, + OUString::createFromAscii( + "com.sun.star.comp.ucb.PersistentPropertySet" ), + OUString::createFromAscii( + PERS_PROPSET_SERVICE_NAME ) ); + +//========================================================================= +// +// XComponent methods. +// +//========================================================================= + +// virtual +void SAL_CALL PersistentPropertySet::dispose() + throw( RuntimeException ) +{ + if ( m_pImpl->m_pDisposeEventListeners && + m_pImpl->m_pDisposeEventListeners->getLength() ) + { + EventObject aEvt; + aEvt.Source = static_cast< XComponent * >( this ); + m_pImpl->m_pDisposeEventListeners->disposeAndClear( aEvt ); + } + + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + EventObject aEvt; + aEvt.Source = static_cast< XPropertySetInfoChangeNotifier * >( this ); + m_pImpl->m_pPropSetChangeListeners->disposeAndClear( aEvt ); + } + + if ( m_pImpl->m_pPropertyChangeListeners ) + { + EventObject aEvt; + aEvt.Source = static_cast< XPropertySet * >( this ); + m_pImpl->m_pPropertyChangeListeners->disposeAndClear( aEvt ); + } +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::addEventListener( + const Reference< XEventListener >& Listener ) + throw( RuntimeException ) +{ + if ( !m_pImpl->m_pDisposeEventListeners ) + m_pImpl->m_pDisposeEventListeners = + new OInterfaceContainerHelper( m_pImpl->m_aMutex ); + + m_pImpl->m_pDisposeEventListeners->addInterface( Listener ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removeEventListener( + const Reference< XEventListener >& Listener ) + throw( RuntimeException ) +{ + if ( m_pImpl->m_pDisposeEventListeners ) + m_pImpl->m_pDisposeEventListeners->removeInterface( Listener ); + + // Note: Don't want to delete empty container here -> performance. +} + +//========================================================================= +// +// XPropertySet methods. +// +//========================================================================= + +// virtual +Reference< XPropertySetInfo > SAL_CALL + PersistentPropertySet::getPropertySetInfo() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + PropertySetInfo_Impl*& rpInfo = m_pImpl->m_pInfo; + if ( !rpInfo ) + { + rpInfo = new PropertySetInfo_Impl( m_xSMgr, this ); + rpInfo->acquire(); + } + return Reference< XPropertySetInfo >( rpInfo ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::setPropertyValue( + const OUString& aPropertyName, const Any& aValue ) + throw( UnknownPropertyException, + PropertyVetoException, + IllegalArgumentException, + WrappedTargetException, + RuntimeException ) +{ + if ( !aPropertyName.getLength() ) + throw UnknownPropertyException(); + + osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + OUString aFullPropName( getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( aPropertyName ); + + // Does property exist? + if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + { + Reference< XNameReplace > xNameReplace( + m_pImpl->m_pCreator->getConfigWriteAccess( + aFullPropName ), UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( + OUString() ), UNO_QUERY ); + + if ( xNameReplace.is() && xBatch.is() ) + { + try + { + // Obtain old value + OUString aValueName = aFullPropName; + aValueName += OUString::createFromAscii( "/Value" ); + Any aOldValue + = xRootHierNameAccess->getByHierarchicalName( + aValueName ); + // Check value type. + if ( aOldValue.getValueType() != aValue.getValueType() ) + { + aCGuard.clear(); + throw IllegalArgumentException(); + } + + // Write value + xNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + aValue ); + + // Write state ( Now it is a directly set value ) + xNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + makeAny( + sal_Int32( + PropertyState_DIRECT_VALUE ) ) ); + + // Commit changes. + xBatch->commitChanges(); + + PropertyChangeEvent aEvt; + if ( m_pImpl->m_pPropertyChangeListeners ) + { + // Obtain handle + aValueName = aFullPropName; + aValueName += OUString::createFromAscii( "/Handle" ); + sal_Int32 nHandle = -1; + xRootHierNameAccess->getByHierarchicalName( aValueName ) + >>= nHandle; + + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = aPropertyName; + aEvt.PropertyHandle = nHandle; + aEvt.Further = sal_False; + aEvt.OldValue = aOldValue; + aEvt.NewValue = aValue; + + // Callback follows! + aCGuard.clear(); + + notifyPropertyChangeEvent( aEvt ); + } + return; + } + catch ( IllegalArgumentException& ) + { + // replaceByName + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName, replaceByName + } + catch ( WrappedTargetException& ) + { + // replaceByName, commitChanges + } + } + } + } + + throw UnknownPropertyException(); +} + +//========================================================================= +// virtual +Any SAL_CALL PersistentPropertySet::getPropertyValue( + const OUString& PropertyName ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ + if ( !PropertyName.getLength() ) + throw UnknownPropertyException(); + + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xNameAccess.is() ) + { + OUString aFullPropName( getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( PropertyName ); + aFullPropName += OUString::createFromAscii( "/Value" ); + try + { + return xNameAccess->getByHierarchicalName( aFullPropName ); + } + catch ( NoSuchElementException& ) + { + throw UnknownPropertyException(); + } + } + + throw UnknownPropertyException(); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::addPropertyChangeListener( + const OUString& aPropertyName, + const Reference< XPropertyChangeListener >& xListener ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); + + if ( !m_pImpl->m_pPropertyChangeListeners ) + m_pImpl->m_pPropertyChangeListeners = + new PropertyListeners_Impl( m_pImpl->m_aMutex ); + + m_pImpl->m_pPropertyChangeListeners->addInterface( + aPropertyName, xListener ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removePropertyChangeListener( + const OUString& aPropertyName, + const Reference< XPropertyChangeListener >& aListener ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); + + if ( m_pImpl->m_pPropertyChangeListeners ) + m_pImpl->m_pPropertyChangeListeners->removeInterface( + aPropertyName, aListener ); + + // Note: Don't want to delete empty container here -> performance. +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::addVetoableChangeListener( + const OUString&, + const Reference< XVetoableChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); +// OSL_ENSURE( sal_False, +// "PersistentPropertySet::addVetoableChangeListener - N.Y.I." ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removeVetoableChangeListener( + const OUString&, + const Reference< XVetoableChangeListener >& ) + throw( UnknownPropertyException, + WrappedTargetException, + RuntimeException ) +{ +// load(); +// OSL_ENSURE( sal_False, +// "PersistentPropertySet::removeVetoableChangeListener - N.Y.I." ); +} + +//========================================================================= +// +// XPersistentPropertySet methods. +// +//========================================================================= + +// virtual +Reference< XPropertySetRegistry > SAL_CALL PersistentPropertySet::getRegistry() + throw( RuntimeException ) +{ + return Reference< XPropertySetRegistry >( m_pImpl->m_pCreator ); +} + +//========================================================================= +// virtual +OUString SAL_CALL PersistentPropertySet::getKey() + throw( RuntimeException ) +{ + return m_pImpl->m_aKey; +} + +//========================================================================= +// +// XNamed methods. +// +//========================================================================= + +// virtual +rtl::OUString SAL_CALL PersistentPropertySet::getName() + throw( RuntimeException ) +{ + // same as getKey() + return m_pImpl->m_aKey; +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::setName( const OUString& aName ) + throw( RuntimeException ) +{ + if ( aName != m_pImpl->m_aKey ) + m_pImpl->m_pCreator->renamePropertySet( m_pImpl->m_aKey, aName ); +} + +//========================================================================= +// +// XPropertyContainer methods. +// +//========================================================================= + +// virtual +void SAL_CALL PersistentPropertySet::addProperty( + const OUString& Name, sal_Int16 Attributes, const Any& DefaultValue ) + throw( PropertyExistException, + IllegalTypeException, + IllegalArgumentException, + RuntimeException ) +{ + if ( !Name.getLength() ) + throw IllegalArgumentException(); + + // @@@ What other types can't be written to config server? + + // Check type class ( Not all types can be written to storage ) + TypeClass eTypeClass = DefaultValue.getValueTypeClass(); + if ( eTypeClass == TypeClass_INTERFACE ) + throw IllegalTypeException(); + + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + // Property already in set? + + OUString aFullValuesName; + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + aFullValuesName = getFullKey(); + OUString aFullPropName = aFullValuesName; + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( Name ); + + if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + { + // Already in set. + throw PropertyExistException(); + } + } + + // Property is always removeable. + Attributes |= PropertyAttribute::REMOVEABLE; + + // Add property. + + Reference< XSingleServiceFactory > xFac( + m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ), + UNO_QUERY ); + Reference< XNameContainer > xContainer( xFac, UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ), + UNO_QUERY ); + + OSL_ENSURE( xFac.is(), + "PersistentPropertySet::addProperty - No factory!" ); + + OSL_ENSURE( xBatch.is(), + "PersistentPropertySet::addProperty - No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PersistentPropertySet::addProperty - No container!" ); + + if ( xFac.is() && xBatch.is() && xContainer.is() ) + { + try + { + // Create new "PropertyValue" config item. + Reference< XNameReplace > xNameReplace( + xFac->createInstance(), UNO_QUERY ); + + if ( xNameReplace.is() ) + { + // Fill new item... + + // Set handle + xNameReplace->replaceByName( + OUString::createFromAscii( "Handle" ), + makeAny( sal_Int32( -1 ) ) ); + + // Set default value + xNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + DefaultValue ); + + // Set state ( always "default" ) + xNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + makeAny( + sal_Int32( + PropertyState_DEFAULT_VALUE ) ) ); + + // Set attributes + xNameReplace->replaceByName( + OUString::createFromAscii( "Attributes" ), + makeAny( sal_Int32( Attributes ) ) ); + + // Insert new item. + xContainer->insertByName( Name, makeAny( xNameReplace ) ); + + // Commit changes. + xBatch->commitChanges(); + + // Property set info is invalid. + if ( m_pImpl->m_pInfo ) + m_pImpl->m_pInfo->reset(); + + // Notify propertyset info change listeners. + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + PropertySetInfoChangeEvent evt( + static_cast< OWeakObject * >( this ), + Name, + -1, + PropertySetInfoChange::PROPERTY_INSERTED ); + notifyPropertySetInfoChange( evt ); + } + + // Success. + return; + } + } + catch ( IllegalArgumentException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught IllegalArgumentException!" ); + return; + } + catch ( ElementExistException& ) + { + // insertByName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught ElementExistException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // replaceByName, insertByName, commitChanges + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught WrappedTargetException!" ); + return; + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + // createInstance + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - " + "caught Exception!" ); + return; + } + } + + OSL_ENSURE( sal_False, + "PersistentPropertySet::addProperty - Error!" ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removeProperty( const OUString& Name ) + throw( UnknownPropertyException, + NotRemoveableException, + RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + OUString aFullValuesName; + OUString aFullPropName; + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + aFullValuesName = getFullKey(); + aFullPropName = aFullValuesName; + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( Name ); + + // Property in set? + if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + throw UnknownPropertyException(); + + // Property removeable? + try + { + OUString aFullAttrName = aFullPropName; + aFullAttrName += OUString::createFromAscii( "/Attributes" ); + + sal_Int32 nAttribs = 0; + if ( xRootHierNameAccess->getByHierarchicalName( aFullAttrName ) + >>= nAttribs ) + { + if ( !( nAttribs & PropertyAttribute::REMOVEABLE ) ) + { + // Not removeable! + throw NotRemoveableException(); + } + } + else + { + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "No attributes!" ); + return; + } + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught NoSuchElementException!" ); + } + + // Remove property... + + Reference< XNameContainer > xContainer( + m_pImpl->m_pCreator->getConfigWriteAccess( aFullValuesName ), + UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( OUString() ), + UNO_QUERY ); + + OSL_ENSURE( xBatch.is(), + "PersistentPropertySet::removeProperty - No batch!" ); + + OSL_ENSURE( xContainer.is(), + "PersistentPropertySet::removeProperty - No container!" ); + + if ( xBatch.is() && xContainer.is() ) + { + try + { + sal_Int32 nHandle = -1; + + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + // Obtain property handle ( needed for propertysetinfo + // change event )... + + try + { + OUString aFullHandleName = aFullPropName; + aFullHandleName + += OUString::createFromAscii( "/Handle" ); + + if ( ! ( xRootHierNameAccess->getByHierarchicalName( + aFullHandleName ) >>= nHandle ) ) + nHandle = -1; + + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught NoSuchElementException!" ); + nHandle = -1; + } + } + + xContainer->removeByName( Name ); + xBatch->commitChanges(); + + // Property set info is invalid. + if ( m_pImpl->m_pInfo ) + m_pImpl->m_pInfo->reset(); + + // Notify propertyset info change listeners. + if ( m_pImpl->m_pPropSetChangeListeners && + m_pImpl->m_pPropSetChangeListeners->getLength() ) + { + PropertySetInfoChangeEvent evt( + static_cast< OWeakObject * >( this ), + Name, + nHandle, + PropertySetInfoChange::PROPERTY_REMOVED ); + notifyPropertySetInfoChange( evt ); + } + + // Success. + return; + } + catch ( NoSuchElementException& ) + { + // removeByName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught NoSuchElementException!" ); + return; + } + catch ( WrappedTargetException& ) + { + // commitChanges + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - " + "caught WrappedTargetException!" ); + return; + } + } + } + + OSL_ENSURE( sal_False, + "PersistentPropertySet::removeProperty - Error!" ); +} + +//========================================================================= +// +// XPropertySetInfoChangeNotifier methods. +// +//========================================================================= + +// virtual +void SAL_CALL PersistentPropertySet::addPropertySetInfoChangeListener( + const Reference< XPropertySetInfoChangeListener >& Listener ) + throw( RuntimeException ) +{ + if ( !m_pImpl->m_pPropSetChangeListeners ) + m_pImpl->m_pPropSetChangeListeners = + new OInterfaceContainerHelper( m_pImpl->m_aMutex ); + + m_pImpl->m_pPropSetChangeListeners->addInterface( Listener ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::removePropertySetInfoChangeListener( + const Reference< XPropertySetInfoChangeListener >& Listener ) + throw( RuntimeException ) +{ + if ( m_pImpl->m_pPropSetChangeListeners ) + m_pImpl->m_pPropSetChangeListeners->removeInterface( Listener ); +} + +//========================================================================= +// +// XPropertyAccess methods. +// +//========================================================================= + +// virtual +Sequence< PropertyValue > SAL_CALL PersistentPropertySet::getPropertyValues() + throw( RuntimeException ) +{ + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + try + { + Reference< XNameAccess > xNameAccess; + xRootHierNameAccess->getByHierarchicalName(getFullKey()) + >>= xNameAccess; + if ( xNameAccess.is() ) + { + // Obtain property names. + + Sequence< OUString > aElems = xNameAccess->getElementNames(); + + sal_Int32 nCount = aElems.getLength(); + if ( nCount ) + { + Reference< XHierarchicalNameAccess > xHierNameAccess( + xNameAccess, UNO_QUERY ); + + OSL_ENSURE( xHierNameAccess.is(), + "PersistentPropertySet::getPropertyValues - " + "No hierarchical name access!" ); + + if ( xHierNameAccess.is() ) + { + Sequence< PropertyValue > aValues( nCount ); + + const OUString aHandleName + = OUString::createFromAscii( "/Handle" ); + const OUString aValueName + = OUString::createFromAscii( "/Value" ); + const OUString aStateName + = OUString::createFromAscii( "/State" ); + + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + PropertyValue& rValue = aValues[ n ]; + OUString rName = aElems[ n ]; + OUString aXMLName + = makeHierarchalNameSegment( rName ); + + // Set property name. + + rValue.Name = rName; + + try + { + // Obtain and set property handle + OUString aHierName = aXMLName; + aHierName += aHandleName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + if ( !( aKeyValue >>= rValue.Handle ) ) + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "Error getting property handle!" ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property value + OUString aHierName = aXMLName; + aHierName += aValueName; + rValue.Value + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + // Note: The value may be void if addProperty + // was called with a default value + // of type void. + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property state + OUString aHierName = aXMLName; + aHierName += aStateName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + sal_Int32 nState = 0; + if ( !( aKeyValue >>= nState ) ) + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "Error getting property state!" ); + else + rValue.State = PropertyState( nState ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PersistentPropertySet::getPropertyValues - " + "NoSuchElementException!" ); + } + } + + return aValues; + } + } + } + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + } + } + + return Sequence< PropertyValue >( 0 ); +} + +//========================================================================= +// virtual +void SAL_CALL PersistentPropertySet::setPropertyValues( + const Sequence< PropertyValue >& aProps ) + throw( UnknownPropertyException, + PropertyVetoException, + IllegalArgumentException, + WrappedTargetException, + RuntimeException ) +{ + sal_Int32 nCount = aProps.getLength(); + if ( !nCount ) + return; + + osl::ClearableGuard< osl::Mutex > aCGuard( m_pImpl->m_aMutex ); + + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pImpl->m_pCreator->getRootConfigReadAccess(), UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + const PropertyValue* pNewValues = aProps.getConstArray(); + + typedef std::list< PropertyChangeEvent > Events; + Events aEvents; + + OUString aFullPropNamePrefix( getFullKey() ); + aFullPropNamePrefix += OUString::createFromAscii( "/" ); + + // Iterate over given property value sequence. + for ( sal_Int32 n = 0; n < nCount; ++n ) + { + const PropertyValue& rNewValue = pNewValues[ n ]; + const OUString& rName = rNewValue.Name; + + OUString aFullPropName = aFullPropNamePrefix; + aFullPropName += makeHierarchalNameSegment( rName ); + + // Does property exist? + if ( xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + { + Reference< XNameReplace > xNameReplace( + m_pImpl->m_pCreator->getConfigWriteAccess( + aFullPropName ), UNO_QUERY ); + Reference< XChangesBatch > xBatch( + m_pImpl->m_pCreator->getConfigWriteAccess( + OUString() ), UNO_QUERY ); + + if ( xNameReplace.is() && xBatch.is() ) + { + try + { + // Write handle + xNameReplace->replaceByName( + OUString::createFromAscii( "Handle" ), + makeAny( rNewValue.Handle ) ); + + // Save old value + OUString aValueName = aFullPropName; + aValueName += OUString::createFromAscii( "/Value" ); + Any aOldValue + = xRootHierNameAccess->getByHierarchicalName( + aValueName ); + // Write value + xNameReplace->replaceByName( + OUString::createFromAscii( "Value" ), + rNewValue.Value ); + + // Write state ( Now it is a directly set value ) + xNameReplace->replaceByName( + OUString::createFromAscii( "State" ), + makeAny( + sal_Int32( + PropertyState_DIRECT_VALUE ) ) ); + + // Commit changes. + xBatch->commitChanges(); + + if ( m_pImpl->m_pPropertyChangeListeners ) + { + PropertyChangeEvent aEvt; + aEvt.Source = (OWeakObject*)this; + aEvt.PropertyName = rNewValue.Name; + aEvt.PropertyHandle = rNewValue.Handle; + aEvt.Further = sal_False; + aEvt.OldValue = aOldValue; + aEvt.NewValue = rNewValue.Value; + + aEvents.push_back( aEvt ); + } + } + catch ( IllegalArgumentException& ) + { + // replaceByName + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName, replaceByName + } + catch ( WrappedTargetException& ) + { + // replaceByName, commitChanges + } + } + } + } + + // Callback follows! + aCGuard.clear(); + + if ( m_pImpl->m_pPropertyChangeListeners ) + { + // Notify property changes. + Events::const_iterator it = aEvents.begin(); + Events::const_iterator end = aEvents.end(); + + while ( it != end ) + { + notifyPropertyChangeEvent( (*it) ); + it++; + } + } + + return; + } + + OSL_ENSURE( sal_False, + "PersistentPropertySet::setPropertyValues - Nothing set!" ); +} + +//========================================================================= +// +// Non-interface methods +// +//========================================================================= + +void PersistentPropertySet::notifyPropertyChangeEvent( + const PropertyChangeEvent& rEvent ) const +{ + // Get "normal" listeners for the property. + OInterfaceContainerHelper* pContainer = + m_pImpl->m_pPropertyChangeListeners->getContainer( + rEvent.PropertyName ); + if ( pContainer && pContainer->getLength() ) + { + OInterfaceIteratorHelper aIter( *pContainer ); + while ( aIter.hasMoreElements() ) + { + // Propagate event. + Reference< XPropertyChangeListener > xListener( + aIter.next(), UNO_QUERY ); + if ( xListener.is() ) + xListener->propertyChange( rEvent ); + } + } + + // Get "normal" listeners for all properties. + OInterfaceContainerHelper* pNoNameContainer = + m_pImpl->m_pPropertyChangeListeners->getContainer( OUString() ); + if ( pNoNameContainer && pNoNameContainer->getLength() ) + { + OInterfaceIteratorHelper aIter( *pNoNameContainer ); + while ( aIter.hasMoreElements() ) + { + // Propagate event. + Reference< XPropertyChangeListener > xListener( + aIter.next(), UNO_QUERY ); + if ( xListener.is() ) + xListener->propertyChange( rEvent ); + } + } +} + +//========================================================================= +void PersistentPropertySet::notifyPropertySetInfoChange( + const PropertySetInfoChangeEvent& evt ) const +{ + if ( !m_pImpl->m_pPropSetChangeListeners ) + return; + + // Notify event listeners. + OInterfaceIteratorHelper aIter( *( m_pImpl->m_pPropSetChangeListeners ) ); + while ( aIter.hasMoreElements() ) + { + // Propagate event. + Reference< XPropertySetInfoChangeListener > + xListener( aIter.next(), UNO_QUERY ); + if ( xListener.is() ) + xListener->propertySetInfoChange( evt ); + } +} + +//========================================================================= +const OUString& PersistentPropertySet::getFullKey() +{ + if ( !m_pImpl->m_aFullKey.getLength() ) + { + osl::Guard< osl::Mutex > aGuard( m_pImpl->m_aMutex ); + if ( !m_pImpl->m_aFullKey.getLength() ) + { + m_pImpl->m_aFullKey + = makeHierarchalNameSegment( m_pImpl->m_aKey ); + m_pImpl->m_aFullKey + += rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/Values" ) ); + } + } + + return m_pImpl->m_aFullKey; +} + +//========================================================================= +PropertySetRegistry& PersistentPropertySet::getPropertySetRegistry() +{ + return *m_pImpl->m_pCreator; +} + +//========================================================================= +//========================================================================= +// +// PropertySetInfo_Impl Implementation. +// +//========================================================================= +//========================================================================= + +PropertySetInfo_Impl::PropertySetInfo_Impl( + const Reference< XMultiServiceFactory >& rxSMgr, + PersistentPropertySet* pOwner ) +: m_xSMgr( rxSMgr ), + m_pProps( NULL ), + m_pOwner( pOwner ) +{ +} + +//========================================================================= +// virtual +PropertySetInfo_Impl::~PropertySetInfo_Impl() +{ + delete m_pProps; + + // !!! Do not delete m_pOwner !!! +} + +//========================================================================= +// +// XInterface methods. +// +//========================================================================= + +XINTERFACE_IMPL_2( PropertySetInfo_Impl, + XTypeProvider, + XPropertySetInfo ); + +//========================================================================= +// +// XTypeProvider methods. +// +//========================================================================= + +XTYPEPROVIDER_IMPL_2( PropertySetInfo_Impl, + XTypeProvider, + XPropertySetInfo ); + +//========================================================================= +// +// XPropertySetInfo methods. +// +//========================================================================= + +// virtual +Sequence< Property > SAL_CALL PropertySetInfo_Impl::getProperties() + throw( RuntimeException ) +{ + if ( !m_pProps ) + { + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), + UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + try + { + Reference< XNameAccess > xNameAccess; + xRootHierNameAccess->getByHierarchicalName( + m_pOwner->getFullKey() ) + >>= xNameAccess; + if ( xNameAccess.is() ) + { + // Obtain property names. + + Sequence< OUString > aElems + = xNameAccess->getElementNames(); + + sal_uInt32 nCount = aElems.getLength(); + Sequence< Property >* pPropSeq + = new Sequence< Property >( nCount ); + + if ( nCount ) + { + Reference< XHierarchicalNameAccess > xHierNameAccess( + xNameAccess, UNO_QUERY ); + + OSL_ENSURE( xHierNameAccess.is(), + "PropertySetInfo_Impl::getProperties - " + "No hierarchical name access!" ); + + if ( xHierNameAccess.is() ) + { + const OUString aHandleName + = OUString::createFromAscii( "/Handle" ); + const OUString aValueName + = OUString::createFromAscii( "/Value" ); + const OUString aAttrName + = OUString::createFromAscii( "/Attributes" ); + + Property* pProps = pPropSeq->getArray(); + + for ( sal_uInt32 n = 0; n < nCount; ++n ) + { + Property& rProp = pProps[ n ]; + OUString rName = aElems[ n ]; + OUString aXMLName + = makeHierarchalNameSegment( rName ); + + // Set property name. + + rProp.Name = rName; + + try + { + // Obtain and set property handle + rtl::OUString aHierName = aXMLName; + aHierName += aHandleName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + if ( !( aKeyValue >>= rProp.Handle ) ) + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "Error getting property handle!" ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property type + rtl::OUString aHierName = aXMLName; + aHierName += aValueName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + // Note: The type may be void if addProperty + // was called with a default value + // of type void. + + rProp.Type = aKeyValue.getValueType(); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "NoSuchElementException!" ); + } + + try + { + // Obtain and set property attributes + rtl::OUString aHierName = aXMLName; + aHierName += aAttrName; + Any aKeyValue + = xHierNameAccess->getByHierarchicalName( + aHierName ); + + sal_Int32 nAttribs = 0; + if ( aKeyValue >>= nAttribs ) + rProp.Attributes + = sal_Int16( nAttribs ); + else + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "Error getting property attributes!" ); + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getProperties - " + "NoSuchElementException!" ); + } + } + } + } + + // Success. + m_pProps = pPropSeq; + return *m_pProps; + } + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + } + } + + OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getProperties - Error!" ); + m_pProps = new Sequence< Property >( 0 ); + } + + return *m_pProps; +} + +//========================================================================= +// virtual +Property SAL_CALL PropertySetInfo_Impl::getPropertyByName( + const OUString& aName ) + throw( UnknownPropertyException, RuntimeException ) +{ + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), + UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + OUString aFullPropName( m_pOwner->getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( aName ); + + // Does property exist? + if ( !xRootHierNameAccess->hasByHierarchicalName( aFullPropName ) ) + throw UnknownPropertyException(); + + try + { + Property aProp; + + // Obtain handle. + OUString aKey = aFullPropName; + aKey += OUString::createFromAscii( "/Handle" ); + + if ( !( xRootHierNameAccess->getByHierarchicalName( aKey ) + >>= aProp.Handle ) ) + { + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "No handle!" ); + return Property(); + } + + // Obtain Value and extract type. + aKey = aFullPropName; + aKey += OUString::createFromAscii( "/Value" ); + + Any aValue = xRootHierNameAccess->getByHierarchicalName( aKey ); + if ( !aValue.hasValue() ) + { + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "No Value!" ); + return Property(); + } + + aProp.Type = aValue.getValueType(); + + // Obtain Attributes. + aKey = aFullPropName; + aKey += OUString::createFromAscii( "/Attributes" ); + + sal_Int32 nAttribs = 0; + if ( xRootHierNameAccess->getByHierarchicalName( aKey ) + >>= nAttribs ) + aProp.Attributes = sal_Int16( nAttribs ); + else + { + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "No attributes!" ); + return Property(); + } + + // set name. + aProp.Name = aName; + + // Success. + return aProp; + } + catch ( NoSuchElementException& ) + { + // getByHierarchicalName + + OSL_ENSURE( sal_False, + "PropertySetInfo_Impl::getPropertyByName - " + "caught NoSuchElementException!" ); + } + + } + + OSL_ENSURE( sal_False, "PropertySetInfo_Impl::getPropertyByName - Error!" ); + return Property(); +} + +//========================================================================= +// virtual +sal_Bool SAL_CALL PropertySetInfo_Impl::hasPropertyByName( + const OUString& Name ) + throw( RuntimeException ) +{ + Reference< XHierarchicalNameAccess > xRootHierNameAccess( + m_pOwner->getPropertySetRegistry().getRootConfigReadAccess(), + UNO_QUERY ); + if ( xRootHierNameAccess.is() ) + { + OUString aFullPropName( m_pOwner->getFullKey() ); + aFullPropName += OUString::createFromAscii( "/" ); + aFullPropName += makeHierarchalNameSegment( Name ); + + return xRootHierNameAccess->hasByHierarchicalName( aFullPropName ); + } + + return sal_False; +} + |