User: rt Date: 2007-07-24 12:05:32+0000 Modified: dba/dbaccess/source/core/misc/propertybag.cxx
Log: INTEGRATION: CWS dba23b (1.6.14); FILE MERGED 2007/07/08 11:41:45 fs 1.6.14.3: #i10000# 2007/07/07 20:22:44 fs 1.6.14.2: #i78593# overload getPropertyStateByHandle, to respect the MAYBEDEFAULT attribute (especially when it's *not* set) 2007/07/07 19:20:32 fs 1.6.14.1: in preparation of #i78593#: refactor so that comphelper/propertybag is used File Changes: Directory: /dba/dbaccess/source/core/misc/ ========================================== File [changed]: propertybag.cxx Url: http://dba.openoffice.org/source/browse/dba/dbaccess/source/core/misc/propertybag.cxx?r1=1.6&r2=1.7 Delta lines: +138 -206 ----------------------- --- propertybag.cxx 2007-05-10 10:14:19+0000 1.6 +++ propertybag.cxx 2007-07-24 12:05:29+0000 1.7 @@ -50,8 +50,12 @@ #include <com/sun/star/beans/NamedValue.hpp> #endif -#include <osl/thread.h> +#include <tools/diagnose_ex.h> + +#include <comphelper/namedvaluecollection.hxx> + #include <cppuhelper/exc_hlp.hxx> +#include <osl/thread.h> #include <algorithm> #include <functional> @@ -76,9 +80,8 @@ //==================================================================== //-------------------------------------------------------------------- OPropertyBag::OPropertyBag( const Reference< XMultiServiceFactory >& _rxORB ) - :OPropertyBag_CBase( GetBroadcastHelper() ) + :OPropertyBag_PBase( GetBroadcastHelper() ) ,m_xORB( _rxORB ) - ,m_bArrayHelperDirty( true ) ,m_bAutoAddProperties( false ) { } @@ -89,8 +92,8 @@ } //-------------------------------------------------------------------- - IMPLEMENT_FORWARD_XINTERFACE2( OPropertyBag, OPropertyBag_Base, OPropertyBag_CBase ) - IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyBag, OPropertyBag_Base, OPropertyBag_CBase ) + IMPLEMENT_FORWARD_XINTERFACE2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase ) + IMPLEMENT_FORWARD_XTYPEPROVIDER2( OPropertyBag, OPropertyBag_Base, OPropertyBag_PBase ) //-------------------------------------------------------------------- Sequence< ::rtl::OUString > OPropertyBag::getSupportedServiceNames_Static() throw( RuntimeException ) @@ -101,62 +104,19 @@ } //-------------------------------------------------------------------- - namespace - { - template < typename BAG > - struct BagInserter : public ::std::unary_function< typename BAG::key_type, void > - { - BAG& m_rBag; - - BagInserter( BAG& _rBag ) - :m_rBag( _rBag ) - { - } - - void operator()( const typename BAG::key_type& _rType ) - { - m_rBag.insert( _rType ); - } - }; - } - //-------------------------------------------------------------------- void SAL_CALL OPropertyBag::initialize( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) { - NamedValue aValue; - const Any* pArguments = _rArguments.getConstArray(); - const Any* pArgumentsEnd = _rArguments.getConstArray() + _rArguments.getLength(); - for ( ; pArguments != pArgumentsEnd; ++pArguments ) - { - if ( !( *pArguments >>= aValue ) ) - throw IllegalArgumentException( ::rtl::OUString(), *this, sal::static_int_cast< sal_Int16 >( pArguments - _rArguments.getConstArray() ) ); - if ( aValue.Name.equalsAscii( "AllowedTypes" ) ) - { - Sequence< Type > aTypes; - if ( !( aValue.Value >>= aTypes ) ) - throw IllegalArgumentException( ::rtl::OUString(), *this, sal::static_int_cast< sal_Int16 >( pArguments - _rArguments.getConstArray() ) ); + ::comphelper::NamedValueCollection aArguments( _rArguments ); - ::std::for_each( + Sequence< Type > aTypes; + if ( aArguments.get_ensureType( "AllowedTypes", aTypes ) ) + ::std::copy( aTypes.getConstArray(), aTypes.getConstArray() + aTypes.getLength(), - BagInserter< TypeBag >( m_aAllowedTypes ) + ::std::insert_iterator< TypeBag >( m_aAllowedTypes, m_aAllowedTypes.begin() ) ); - continue; - } - if ( aValue.Name.equalsAscii( "AutomaticAddition" ) ) - { - if ( !( aValue.Value >>= m_bAutoAddProperties ) ) - throw IllegalArgumentException( ::rtl::OUString(), *this, sal::static_int_cast< sal_Int16 >( pArguments - _rArguments.getConstArray() ) ); - continue; - } -#if OSL_DEBUG_LEVEL > 0 - ::rtl::OString sName( aValue.Name.getStr(), aValue.Name.getLength(), osl_getThreadTextEncoding() ); - ::rtl::OString sMessage( "OPropertyBag::initialize: don't know what to do with an argument named '" ); - sMessage += sName; - sMessage += ::rtl::OString( "'!" ); - OSL_ENSURE( sal_False, sMessage.getStr() ); -#endif - } + aArguments.get_ensureType( "AutomaticAddition", m_bAutoAddProperties ); } //-------------------------------------------------------------------- @@ -199,14 +159,31 @@ } //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::getFastPropertyValue( Any& _rValue, sal_Int32 _nHandle ) const + { + m_aDynamicProperties.getFastPropertyValue( _nHandle, _rValue ); + } + + //-------------------------------------------------------------------- + sal_Bool SAL_CALL OPropertyBag::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw (IllegalArgumentException) + { + return m_aDynamicProperties.convertFastPropertyValue( _nHandle, _rValue, _rConvertedValue, _rOldValue ); + } + + //-------------------------------------------------------------------- + void SAL_CALL OPropertyBag::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception) + { + m_aDynamicProperties.setFastPropertyValue( nHandle, rValue ); + } + + //-------------------------------------------------------------------- ::cppu::IPropertyArrayHelper& SAL_CALL OPropertyBag::getInfoHelper() { - if ( m_bArrayHelperDirty ) + if ( !m_pArrayHelper.get() ) { Sequence< Property > aProperties; - describeProperties( aProperties ); + m_aDynamicProperties.describeProperties( aProperties ); m_pArrayHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties ) ); - m_bArrayHelperDirty = false; } return *m_pArrayHelper; @@ -219,7 +196,7 @@ const sal_Int32 nSeed = 11; sal_Int32 nCheck = nSeed; - while ( isRegisteredProperty( nCheck ) && ( nCheck != 1 ) ) + while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) && ( nCheck != 1 ) ) { nCheck = ( nCheck * nSeed ) % nPrime; } @@ -227,7 +204,7 @@ if ( nCheck == 1 ) { // uh ... we already have 1008 handles used up // -> simply count upwards - while ( isRegisteredProperty( nCheck ) ) + while ( m_aDynamicProperties.hasPropertyByHandle( nCheck ) ) ++nCheck; } @@ -239,46 +216,19 @@ { ::osl::MutexGuard aGuard( m_aMutex ); - //---------------------------------------------- - // check type sanity + // check whether the type is allowed, everything else will be checked + // by m_aDynamicProperties Type aPropertyType = _rInitialValue.getValueType(); - bool bValidType = ( aPropertyType.getTypeClass() != TypeClass_VOID ); - if ( bValidType ) - { - if ( !m_aAllowedTypes.empty() ) - bValidType = ( m_aAllowedTypes.find( aPropertyType ) != m_aAllowedTypes.end() ); - } - - if ( !bValidType ) + if ( _rInitialValue.hasValue() + && !m_aAllowedTypes.empty() + && m_aAllowedTypes.find( aPropertyType ) == m_aAllowedTypes.end() + ) throw IllegalTypeException( ::rtl::OUString(), *this ); - //---------------------------------------------- - // check name sanity - if ( !_rName.getLength() ) - throw IllegalArgumentException( ::rtl::OUString(), *this, 1 ); - if ( isRegisteredProperty( _rName ) ) - throw PropertyExistException( ::rtl::OUString(), *this ); - - //---------------------------------------------- - // normalize the REMOVEABLE attribute - if ( _nAttributes & PropertyAttribute::REMOVABLE ) - { - _nAttributes |= PropertyAttribute::REMOVEABLE; - _nAttributes &= ~PropertyAttribute::REMOVABLE; - } - - //---------------------------------------------- - // find a free handle - sal_Int32 nHandle = findFreeHandle(); - - //---------------------------------------------- - registerPropertyNoMember( _rName, nHandle, _nAttributes, aPropertyType, - _rInitialValue.hasValue() ? _rInitialValue.getValue() : NULL ); - m_bArrayHelperDirty = true; - - //---------------------------------------------- - // remember the default - m_aDefaultValues.insert( MapInt2Any::value_type( nHandle, _rInitialValue ) ); + m_aDynamicProperties.addProperty( _rName, findFreeHandle(), _nAttributes, _rInitialValue ); + + // our property info is dirty + m_pArrayHelper.reset(); } //-------------------------------------------------------------------- @@ -286,20 +236,10 @@ { ::osl::MutexGuard aGuard( m_aMutex ); - //---------------------------------------------- - const Property& rProp = getProperty( _rName ); - // will throw an UnknownPropertyException if necessary - - //---------------------------------------------- - if ( ( rProp.Attributes & PropertyAttribute::REMOVEABLE ) == 0 ) - throw NotRemoveableException( ::rtl::OUString(), *this ); - - //---------------------------------------------- - revokeProperty( rProp.Handle ); - m_bArrayHelperDirty = true; + m_aDynamicProperties.removeProperty( _rName ); - //---------------------------------------------- - m_aDefaultValues.erase( rProp.Handle ); + // our property info is dirty + m_pArrayHelper.reset(); } //-------------------------------------------------------------------- @@ -334,9 +274,11 @@ //-------------------------------------------------------------------- Sequence< PropertyValue > SAL_CALL OPropertyBag::getPropertyValues( ) throw (RuntimeException) { + ::osl::MutexGuard aGuard( m_aMutex ); + // all registered properties Sequence< Property > aProperties; - describeProperties( aProperties ); + m_aDynamicProperties.describeProperties( aProperties ); // their names Sequence< ::rtl::OUString > aNames( aProperties.getLength() ); @@ -351,18 +293,19 @@ Sequence< Any > aValues; try { - aValues = OPropertyBag_CBase::getPropertyValues( aNames ); + aValues = OPropertyBag_PBase::getPropertyValues( aNames ); + if ( aValues.getLength() != aNames.getLength() ) + throw RuntimeException(); + } + catch( const RuntimeException& ) + { + throw; } catch( const Exception& ) { + DBG_UNHANDLED_EXCEPTION(); } - // safety: if something went wrong, go outta here with an empty sequence - OSL_ENSURE( aValues.getLength() == aNames.getLength(), - "OPropertyBag::getPropertyValues: inconsistence!" ); - if ( aValues.getLength() != aNames.getLength() ) - return Sequence< PropertyValue >(); - // merge names and values, and retrieve the state/handle ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); @@ -384,7 +327,7 @@ } //-------------------------------------------------------------------- - void OPropertyBag::implSetPropertyValues( const Sequence< PropertyValue >& _rProps, bool _bTolerateUnknownProperties ) + void OPropertyBag::impl_setPropertyValues_throw( const Sequence< PropertyValue >& _rProps ) { // sort (the XMultiPropertySet interface requires this) Sequence< PropertyValue > aProperties( _rProps ); @@ -394,9 +337,6 @@ ComparePropertyValueByName() ); - bool bDoAddProperties = false; - try - { // a sequence of names Sequence< ::rtl::OUString > aNames( aProperties.getLength() ); ::std::transform( @@ -405,6 +345,47 @@ aNames.getArray(), TransformPropertyToName< PropertyValue >() ); + + try + { + ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); + + // check for unknown properties + // we cannot simply rely on the XMultiPropertySet::setPropertyValues + // implementation of our base class, since it does not throw + // an UnknownPropertyException. More precise, XMultiPropertySet::setPropertyValues + // does not allow to throw this exception, while XPropertyAccess::setPropertyValues + // requires it + sal_Int32 nCount = aNames.getLength(); + + Sequence< sal_Int32 > aHandles( nCount ); + sal_Int32* pHandle = aHandles.getArray(); + const PropertyValue* pProperty = aProperties.getConstArray(); + for ( const ::rtl::OUString* pName = aNames.getConstArray(); + pName != aNames.getConstArray() + aNames.getLength(); + ++pName, ++pHandle, ++pProperty + ) + { + *pHandle = rPropInfo.getHandleByName( *pName ); + if ( *pHandle != -1 ) + continue; + + // there's a property requested which we do not know + if ( m_bAutoAddProperties ) + { + // add the property + sal_Int16 nAttributes = PropertyAttribute::BOUND | PropertyAttribute::REMOVEABLE | PropertyAttribute::MAYBEDEFAULT; + addProperty( *pName, nAttributes, pProperty->Value ); + // rPropInfo is invalid, refetch + rPropInfo = getInfoHelper(); + *pHandle = rPropInfo.getHandleByName( *pName ); + continue; + } + + // no way out + throw UnknownPropertyException( *pName, *this ); + } + // a sequence of values Sequence< Any > aValues( aProperties.getLength() ); ::std::transform( @@ -413,102 +394,53 @@ aValues.getArray(), ExtractPropertyValue() ); - // propagate - // we cannot simply rely on the XMultiPropertySet::setPropertyValues - // implementation of our base class, since it does not throw - // an UnknownPropertyException. More precise, XMultiPropertySet::setPropertyValues - // does not allow to throw this exception, while XPropertyAccess::setPropertyValues - // requires it - sal_Int32 nCount = aNames.getLength(); - Sequence< sal_Int32 > aHandles( nCount ); - ::cppu::IPropertyArrayHelper& rPH = getInfoHelper(); - sal_Int32 nHitCount = rPH.fillHandles( aHandles.getArray(), aNames ); - if ( nHitCount != nCount ) - throw UnknownPropertyException( ::rtl::OUString(), *this ); - - if( nHitCount > 0 ) - setFastPropertyValues( nCount, aHandles.getArray(), - aValues.getConstArray(), nHitCount ); + + setFastPropertyValues( nCount, aHandles.getArray(), aValues.getConstArray(), nCount ); } catch( const PropertyVetoException& ) { throw; } catch( const IllegalArgumentException& ) { throw; } catch( const WrappedTargetException& ) { throw; } catch( const RuntimeException& ) { throw; } - catch( const UnknownPropertyException& ) - { - if ( !_bTolerateUnknownProperties ) - throw; - bDoAddProperties = true; - } + catch( const UnknownPropertyException& ) { throw; } catch( const Exception& ) { throw WrappedTargetException( ::rtl::OUString(), *this, ::cppu::getCaughtException() ); } - - if ( bDoAddProperties ) - { - // we had an UnknownPropertyException, and _bTolerateUnknownProperties tells us - // we should tolerate this - // ensure that we contain all properties specified in the sequence - const PropertyValue* pProperties = aProperties.getConstArray(); - const PropertyValue* pPropertiesEnd = aProperties.getConstArray() + aProperties.getLength(); - for ( ; pProperties != pPropertiesEnd; ++pProperties ) - { - if ( !implEnsureContainsProperty( pProperties->Name, pProperties->Value ) ) - { - // the property could not be added. In this case, throw the UnknownPropertyException, - // which caused us to try this addition - throw UnknownPropertyException( ::rtl::OUString(), *this ); - } - } - - // and try again - implSetPropertyValues( aProperties, false ); - // use aProperties, this makes the sorting cheaper - // and don't tolerate any errors this time - } } //-------------------------------------------------------------------- void SAL_CALL OPropertyBag::setPropertyValues( const Sequence< PropertyValue >& _rProps ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException) { - implSetPropertyValues( _rProps, m_bAutoAddProperties ); + ::osl::MutexGuard aGuard( m_aMutex ); + impl_setPropertyValues_throw( _rProps ); } //-------------------------------------------------------------------- - bool OPropertyBag::implEnsureContainsProperty( const ::rtl::OUString& _rName, const Any& _rValue ) + PropertyState OPropertyBag::getPropertyStateByHandle( sal_Int32 _nHandle ) { - if ( isRegisteredProperty( _rName ) ) - // nothing to do - return true; + // for properties which do not support the MAYBEDEFAULT attribute, don't rely on the base class, but + // assume they're always in DIRECT state. + // (Note that this probably would belong into the base class. However, this would mean we would need + // to check all existent usages of the base class, where MAYBEDEFAULT is *not* set, but + // a default is nonetheless supplied/used. This is hard to accomplish reliably, in the + // current phase. + // #i78593# / 2007-07-07 / [EMAIL PROTECTED] - if ( !_rValue.hasValue() ) - // if we cannot determine an initial type, we cannot add this property - return false; + ::cppu::IPropertyArrayHelper& rPropInfo = getInfoHelper(); + sal_Int16 nAttributes(0); + OSL_VERIFY( rPropInfo.fillPropertyMembersByHandle( NULL, &nAttributes, _nHandle ) ); + if ( ( nAttributes & PropertyAttribute::MAYBEDEFAULT ) == 0 ) + return PropertyState_DIRECT_VALUE; - try - { - sal_Int16 nAttributes = PropertyAttribute::BOUND | PropertyAttribute::REMOVEABLE | PropertyAttribute::MAYBEDEFAULT; - addProperty( _rName, nAttributes, _rValue ); - return true; - } - catch( const IllegalTypeException& e ) - { - throw WrappedTargetException( ::rtl::OUString(), *this, makeAny( e ) ); - } - catch( const PropertyExistException& ) - { - OSL_ENSURE( sal_False, "OPropertyBag::implEnsureContainsProperty: PropertyExistException - how this?" ); - } - return false; + return OPropertyBag_PBase::getPropertyStateByHandle( _nHandle ); } //-------------------------------------------------------------------- - void OPropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _rDefault ) const + Any OPropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle ) const { - MapInt2Any::const_iterator aPos = m_aDefaultValues.find( _nHandle ); - OSL_PRECOND( aPos != m_aDefaultValues.end(), "OPropertyBag::getPropertyDefaultByHandle: precondition not met!" ); - _rDefault = aPos->second; + Any aDefault; + m_aDynamicProperties.getPropertyDefaultByHandle( _nHandle, aDefault ); + return aDefault; } //........................................................................ --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
