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