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]

Reply via email to