1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 // MARKER(update_precomp.py): autogen include statement, do not remove 28 #include "precompiled_connectivity.hxx" 29 #include <connectivity/paramwrapper.hxx> 30 31 /** === begin UNO includes === **/ 32 #include <com/sun/star/beans/PropertyAttribute.hpp> 33 #include <com/sun/star/sdbc/DataType.hpp> 34 #include <com/sun/star/lang/WrappedTargetException.hpp> 35 #include <com/sun/star/sdb/XParametersSupplier.hpp> 36 #include <com/sun/star/lang/DisposedException.hpp> 37 /** === end UNO includes === **/ 38 39 #include <tools/diagnose_ex.h> 40 #include <comphelper/enumhelper.hxx> 41 42 #define PROPERTY_ID_VALUE 1000 43 44 //........................................................................ 45 namespace dbtools 46 { 47 namespace param 48 { 49 //........................................................................ 50 51 /** === begin UNO using === **/ 52 using ::com::sun::star::uno::Reference; 53 using ::com::sun::star::beans::XPropertySet; 54 using ::com::sun::star::sdbc::XParameters; 55 using ::com::sun::star::uno::Sequence; 56 using ::com::sun::star::uno::Type; 57 using ::com::sun::star::uno::RuntimeException; 58 using ::com::sun::star::uno::XWeak; 59 using ::com::sun::star::beans::XPropertySet; 60 using ::com::sun::star::beans::XFastPropertySet; 61 using ::com::sun::star::beans::XMultiPropertySet; 62 using ::com::sun::star::beans::XPropertySetInfo; 63 using ::com::sun::star::beans::Property; 64 using ::com::sun::star::uno::Exception; 65 using ::com::sun::star::uno::UNO_QUERY_THROW; 66 using ::com::sun::star::uno::Any; 67 using ::com::sun::star::lang::IllegalArgumentException; 68 using ::com::sun::star::sdbc::SQLException; 69 using ::com::sun::star::lang::WrappedTargetException; 70 using ::com::sun::star::lang::IndexOutOfBoundsException; 71 using ::com::sun::star::container::XEnumeration; 72 using ::com::sun::star::sdb::XSingleSelectQueryAnalyzer; 73 using ::com::sun::star::sdb::XParametersSupplier; 74 using ::com::sun::star::lang::DisposedException; 75 /** === end UNO using === **/ 76 namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute; 77 namespace DataType = ::com::sun::star::sdbc::DataType; 78 79 //==================================================================== 80 //= ParameterWrapper 81 //==================================================================== 82 //-------------------------------------------------------------------- 83 ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn ) 84 :PropertyBase( m_aBHelper ) 85 ,m_xDelegator( _rxColumn ) 86 { 87 if ( m_xDelegator.is() ) 88 m_xDelegatorPSI = m_xDelegator->getPropertySetInfo(); 89 if ( !m_xDelegatorPSI.is() ) 90 throw RuntimeException(); 91 } 92 93 //-------------------------------------------------------------------- 94 ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn, 95 const Reference< XParameters >& _rxAllParameters, const ::std::vector< sal_Int32 >& _rIndexes ) 96 :PropertyBase( m_aBHelper ) 97 ,m_aIndexes( _rIndexes ) 98 ,m_xDelegator( _rxColumn ) 99 ,m_xValueDestination( _rxAllParameters ) 100 { 101 if ( m_xDelegator.is() ) 102 m_xDelegatorPSI = m_xDelegator->getPropertySetInfo(); 103 if ( !m_xDelegatorPSI.is() ) 104 throw RuntimeException(); 105 106 OSL_ENSURE( !m_aIndexes.empty(), "ParameterWrapper::ParameterWrapper: sure about the indexes?" ); 107 } 108 109 //-------------------------------------------------------------------- 110 ParameterWrapper::~ParameterWrapper() 111 { 112 } 113 114 //-------------------------------------------------------------------- 115 IMPLEMENT_FORWARD_XINTERFACE2( ParameterWrapper, UnoBase, PropertyBase ) 116 117 //-------------------------------------------------------------------- 118 Sequence< Type > SAL_CALL ParameterWrapper::getTypes( ) throw(RuntimeException) 119 { 120 Sequence< Type > aTypes( 4 ); 121 aTypes[ 1 ] = ::getCppuType( static_cast< Reference< XWeak >* >( NULL ) ); 122 aTypes[ 1 ] = ::getCppuType( static_cast< Reference< XPropertySet >* >( NULL ) ); 123 aTypes[ 2 ] = ::getCppuType( static_cast< Reference< XFastPropertySet >* >( NULL ) ); 124 aTypes[ 3 ] = ::getCppuType( static_cast< Reference< XMultiPropertySet >* >( NULL ) ); 125 return aTypes; 126 } 127 128 //-------------------------------------------------------------------- 129 IMPLEMENT_GET_IMPLEMENTATION_ID( ParameterWrapper ) 130 131 //-------------------------------------------------------------------- 132 ::rtl::OUString ParameterWrapper::impl_getPseudoAggregatePropertyName( sal_Int32 _nHandle ) const 133 { 134 Reference< XPropertySetInfo > xInfo = const_cast<ParameterWrapper*>( this )->getPropertySetInfo(); 135 Sequence< Property > aProperties = xInfo->getProperties(); 136 const Property* pProperties = aProperties.getConstArray(); 137 for ( sal_Int32 i = 0; i < aProperties.getLength(); ++i, ++pProperties ) 138 { 139 if ( pProperties->Handle == _nHandle ) 140 return pProperties->Name; 141 } 142 143 OSL_ENSURE( sal_False, "ParameterWrapper::impl_getPseudoAggregatePropertyName: invalid argument!" ); 144 return ::rtl::OUString(); 145 } 146 147 //-------------------------------------------------------------------- 148 Reference< XPropertySetInfo > ParameterWrapper::getPropertySetInfo() throw( RuntimeException ) 149 { 150 return createPropertySetInfo( getInfoHelper() ); 151 } 152 153 //-------------------------------------------------------------------- 154 ::cppu::IPropertyArrayHelper& ParameterWrapper::getInfoHelper() 155 { 156 if ( !m_pInfoHelper.get() ) 157 { 158 Sequence< Property > aProperties; 159 try 160 { 161 aProperties = m_xDelegatorPSI->getProperties(); 162 sal_Int32 nProperties( aProperties.getLength() ); 163 aProperties.realloc( nProperties + 1 ); 164 aProperties[ nProperties ] = Property( 165 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ) ), 166 PROPERTY_ID_VALUE, 167 ::cppu::UnoType< Any >::get(), 168 PropertyAttribute::TRANSIENT | PropertyAttribute::MAYBEVOID 169 ); 170 } 171 catch( const Exception& ) 172 { 173 DBG_UNHANDLED_EXCEPTION(); 174 } 175 176 m_pInfoHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties, false ) ); 177 } 178 return *m_pInfoHelper; 179 } 180 181 //-------------------------------------------------------------------- 182 sal_Bool ParameterWrapper::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw( IllegalArgumentException ) 183 { 184 OSL_ENSURE( PROPERTY_ID_VALUE == nHandle, "ParameterWrapper::convertFastPropertyValue: the only non-readonly prop should be our PROPERTY_VALUE!" ); 185 (void)nHandle; 186 187 // we're lazy here ... 188 rOldValue = m_aValue.makeAny(); 189 rConvertedValue = rValue; 190 return sal_True; // assume "modified" ... 191 } 192 193 //-------------------------------------------------------------------- 194 void ParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception ) 195 { 196 if ( nHandle == PROPERTY_ID_VALUE ) 197 { 198 try 199 { 200 // TODO : aParamType & nScale can be obtained within the constructor .... 201 sal_Int32 nParamType = DataType::VARCHAR; 202 OSL_VERIFY( m_xDelegator->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nParamType ); 203 204 sal_Int32 nScale = 0; 205 if ( m_xDelegatorPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) ) 206 OSL_VERIFY( m_xDelegator->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) >>= nScale ); 207 208 if ( m_xValueDestination.is() ) 209 { 210 for ( ::std::vector< sal_Int32 >::iterator aIter = m_aIndexes.begin(); aIter != m_aIndexes.end(); ++aIter ) 211 { 212 m_xValueDestination->setObjectWithInfo( *aIter + 1, rValue, nParamType, nScale ); 213 // (the index of the parameters is one-based) 214 } 215 } 216 217 m_aValue = rValue; 218 } 219 catch( SQLException& e ) 220 { 221 WrappedTargetException aExceptionWrapper; 222 aExceptionWrapper.Context = e.Context; 223 aExceptionWrapper.Message = e.Message; 224 aExceptionWrapper.TargetException <<= e; 225 throw WrappedTargetException( aExceptionWrapper ); 226 } 227 } 228 else 229 { 230 ::rtl::OUString aName = impl_getPseudoAggregatePropertyName( nHandle ); 231 m_xDelegator->setPropertyValue( aName, rValue ); 232 } 233 } 234 235 //-------------------------------------------------------------------- 236 void ParameterWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const 237 { 238 if ( nHandle == PROPERTY_ID_VALUE ) 239 { 240 rValue = m_aValue.makeAny(); 241 } 242 else 243 { 244 ::rtl::OUString aName = impl_getPseudoAggregatePropertyName( nHandle ); 245 rValue = m_xDelegator->getPropertyValue( aName ); 246 } 247 } 248 249 //-------------------------------------------------------------------- 250 void SAL_CALL ParameterWrapper::dispose() 251 { 252 ::osl::MutexGuard aGuard( m_aMutex ); 253 254 m_aValue.setNull(); 255 m_aIndexes.resize(0); 256 m_xDelegator.clear(); 257 m_xDelegatorPSI.clear(); 258 m_xValueDestination.clear(); 259 260 m_aBHelper.bDisposed = sal_True; 261 } 262 263 //==================================================================== 264 //= ParameterWrapperContainer 265 //==================================================================== 266 //-------------------------------------------------------------------- 267 ParameterWrapperContainer::ParameterWrapperContainer() 268 :ParameterWrapperContainer_Base( m_aMutex ) 269 { 270 } 271 272 //-------------------------------------------------------------------- 273 ParameterWrapperContainer::ParameterWrapperContainer( const Reference< XSingleSelectQueryAnalyzer >& _rxComposer ) 274 :ParameterWrapperContainer_Base( m_aMutex ) 275 { 276 Reference< XParametersSupplier > xSuppParams( _rxComposer, UNO_QUERY_THROW ); 277 Reference< XIndexAccess > xParameters( xSuppParams->getParameters(), UNO_QUERY_THROW ); 278 sal_Int32 nParamCount( xParameters->getCount() ); 279 m_aParameters.reserve( nParamCount ); 280 for ( sal_Int32 i=0; i<nParamCount; ++i ) 281 { 282 m_aParameters.push_back( new ParameterWrapper( Reference< XPropertySet >( xParameters->getByIndex( i ), UNO_QUERY_THROW ) ) ); 283 } 284 } 285 286 //-------------------------------------------------------------------- 287 ParameterWrapperContainer::~ParameterWrapperContainer() 288 { 289 } 290 291 //-------------------------------------------------------------------- 292 Type SAL_CALL ParameterWrapperContainer::getElementType() throw( RuntimeException ) 293 { 294 ::osl::MutexGuard aGuard( m_aMutex ); 295 impl_checkDisposed_throw(); 296 return ::getCppuType( static_cast< Reference< XPropertySet >* >( NULL ) ); 297 } 298 299 //-------------------------------------------------------------------- 300 sal_Bool SAL_CALL ParameterWrapperContainer::hasElements() throw( RuntimeException ) 301 { 302 ::osl::MutexGuard aGuard( m_aMutex ); 303 impl_checkDisposed_throw(); 304 return !m_aParameters.empty(); 305 } 306 307 //-------------------------------------------------------------------- 308 sal_Int32 SAL_CALL ParameterWrapperContainer::getCount() throw( RuntimeException ) 309 { 310 ::osl::MutexGuard aGuard( m_aMutex ); 311 impl_checkDisposed_throw(); 312 return m_aParameters.size(); 313 } 314 315 //-------------------------------------------------------------------- 316 Any SAL_CALL ParameterWrapperContainer::getByIndex( sal_Int32 _nIndex ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) 317 { 318 ::osl::MutexGuard aGuard( m_aMutex ); 319 impl_checkDisposed_throw(); 320 321 if ( ( _nIndex < 0 ) || ( _nIndex >= (sal_Int32)m_aParameters.size() ) ) 322 throw IndexOutOfBoundsException(); 323 324 return makeAny( Reference< XPropertySet >( m_aParameters[ _nIndex ].get() ) ); 325 } 326 327 //-------------------------------------------------------------------- 328 Reference< XEnumeration > ParameterWrapperContainer::createEnumeration() throw( RuntimeException ) 329 { 330 ::osl::MutexGuard aGuard( m_aMutex ); 331 impl_checkDisposed_throw(); 332 333 return new ::comphelper::OEnumerationByIndex( static_cast< XIndexAccess* >( this ) ); 334 } 335 336 //-------------------------------------------------------------------- 337 void ParameterWrapperContainer::impl_checkDisposed_throw() 338 { 339 if ( rBHelper.bDisposed ) 340 throw DisposedException( ::rtl::OUString(), *this ); 341 } 342 343 //-------------------------------------------------------------------- 344 void SAL_CALL ParameterWrapperContainer::disposing() 345 { 346 ::osl::MutexGuard aGuard( m_aMutex ); 347 impl_checkDisposed_throw(); 348 349 for ( Parameters::const_iterator param = m_aParameters.begin(); 350 param != m_aParameters.end(); 351 ++param 352 ) 353 { 354 (*param)->dispose(); 355 } 356 357 Parameters aEmpty; 358 m_aParameters.swap( aEmpty ); 359 } 360 361 //........................................................................ 362 } } // namespace dbtools::param 363 //........................................................................ 364 365