| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_connectivity.hxx" |
| #include <connectivity/paramwrapper.hxx> |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/sdbc/DataType.hpp> |
| #include <com/sun/star/lang/WrappedTargetException.hpp> |
| #include <com/sun/star/sdb/XParametersSupplier.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <tools/diagnose_ex.h> |
| #include <comphelper/enumhelper.hxx> |
| |
| #define PROPERTY_ID_VALUE 1000 |
| |
| //........................................................................ |
| namespace dbtools |
| { |
| namespace param |
| { |
| //........................................................................ |
| |
| /** === begin UNO using === **/ |
| using ::com::sun::star::uno::Reference; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::sdbc::XParameters; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Type; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::XWeak; |
| using ::com::sun::star::beans::XPropertySet; |
| using ::com::sun::star::beans::XFastPropertySet; |
| using ::com::sun::star::beans::XMultiPropertySet; |
| using ::com::sun::star::beans::XPropertySetInfo; |
| using ::com::sun::star::beans::Property; |
| using ::com::sun::star::uno::Exception; |
| using ::com::sun::star::uno::UNO_QUERY_THROW; |
| using ::com::sun::star::uno::Any; |
| using ::com::sun::star::lang::IllegalArgumentException; |
| using ::com::sun::star::sdbc::SQLException; |
| using ::com::sun::star::lang::WrappedTargetException; |
| using ::com::sun::star::lang::IndexOutOfBoundsException; |
| using ::com::sun::star::container::XEnumeration; |
| using ::com::sun::star::sdb::XSingleSelectQueryAnalyzer; |
| using ::com::sun::star::sdb::XParametersSupplier; |
| using ::com::sun::star::lang::DisposedException; |
| /** === end UNO using === **/ |
| namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute; |
| namespace DataType = ::com::sun::star::sdbc::DataType; |
| |
| //==================================================================== |
| //= ParameterWrapper |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn ) |
| :PropertyBase( m_aBHelper ) |
| ,m_xDelegator( _rxColumn ) |
| { |
| if ( m_xDelegator.is() ) |
| m_xDelegatorPSI = m_xDelegator->getPropertySetInfo(); |
| if ( !m_xDelegatorPSI.is() ) |
| throw RuntimeException(); |
| } |
| |
| //-------------------------------------------------------------------- |
| ParameterWrapper::ParameterWrapper( const Reference< XPropertySet >& _rxColumn, |
| const Reference< XParameters >& _rxAllParameters, const ::std::vector< sal_Int32 >& _rIndexes ) |
| :PropertyBase( m_aBHelper ) |
| ,m_aIndexes( _rIndexes ) |
| ,m_xDelegator( _rxColumn ) |
| ,m_xValueDestination( _rxAllParameters ) |
| { |
| if ( m_xDelegator.is() ) |
| m_xDelegatorPSI = m_xDelegator->getPropertySetInfo(); |
| if ( !m_xDelegatorPSI.is() ) |
| throw RuntimeException(); |
| |
| OSL_ENSURE( !m_aIndexes.empty(), "ParameterWrapper::ParameterWrapper: sure about the indexes?" ); |
| } |
| |
| //-------------------------------------------------------------------- |
| ParameterWrapper::~ParameterWrapper() |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| IMPLEMENT_FORWARD_XINTERFACE2( ParameterWrapper, UnoBase, PropertyBase ) |
| |
| //-------------------------------------------------------------------- |
| Sequence< Type > SAL_CALL ParameterWrapper::getTypes( ) throw(RuntimeException) |
| { |
| Sequence< Type > aTypes( 4 ); |
| aTypes[ 1 ] = ::getCppuType( static_cast< Reference< XWeak >* >( NULL ) ); |
| aTypes[ 1 ] = ::getCppuType( static_cast< Reference< XPropertySet >* >( NULL ) ); |
| aTypes[ 2 ] = ::getCppuType( static_cast< Reference< XFastPropertySet >* >( NULL ) ); |
| aTypes[ 3 ] = ::getCppuType( static_cast< Reference< XMultiPropertySet >* >( NULL ) ); |
| return aTypes; |
| } |
| |
| //-------------------------------------------------------------------- |
| IMPLEMENT_GET_IMPLEMENTATION_ID( ParameterWrapper ) |
| |
| //-------------------------------------------------------------------- |
| ::rtl::OUString ParameterWrapper::impl_getPseudoAggregatePropertyName( sal_Int32 _nHandle ) const |
| { |
| Reference< XPropertySetInfo > xInfo = const_cast<ParameterWrapper*>( this )->getPropertySetInfo(); |
| Sequence< Property > aProperties = xInfo->getProperties(); |
| const Property* pProperties = aProperties.getConstArray(); |
| for ( sal_Int32 i = 0; i < aProperties.getLength(); ++i, ++pProperties ) |
| { |
| if ( pProperties->Handle == _nHandle ) |
| return pProperties->Name; |
| } |
| |
| OSL_ENSURE( sal_False, "ParameterWrapper::impl_getPseudoAggregatePropertyName: invalid argument!" ); |
| return ::rtl::OUString(); |
| } |
| |
| //-------------------------------------------------------------------- |
| Reference< XPropertySetInfo > ParameterWrapper::getPropertySetInfo() throw( RuntimeException ) |
| { |
| return createPropertySetInfo( getInfoHelper() ); |
| } |
| |
| //-------------------------------------------------------------------- |
| ::cppu::IPropertyArrayHelper& ParameterWrapper::getInfoHelper() |
| { |
| if ( !m_pInfoHelper.get() ) |
| { |
| Sequence< Property > aProperties; |
| try |
| { |
| aProperties = m_xDelegatorPSI->getProperties(); |
| sal_Int32 nProperties( aProperties.getLength() ); |
| aProperties.realloc( nProperties + 1 ); |
| aProperties[ nProperties ] = Property( |
| ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value" ) ), |
| PROPERTY_ID_VALUE, |
| ::cppu::UnoType< Any >::get(), |
| PropertyAttribute::TRANSIENT | PropertyAttribute::MAYBEVOID |
| ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| |
| m_pInfoHelper.reset( new ::cppu::OPropertyArrayHelper( aProperties, false ) ); |
| } |
| return *m_pInfoHelper; |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool ParameterWrapper::convertFastPropertyValue(Any& rConvertedValue, Any& rOldValue, sal_Int32 nHandle, const Any& rValue) throw( IllegalArgumentException ) |
| { |
| OSL_ENSURE( PROPERTY_ID_VALUE == nHandle, "ParameterWrapper::convertFastPropertyValue: the only non-readonly prop should be our PROPERTY_VALUE!" ); |
| (void)nHandle; |
| |
| // we're lazy here ... |
| rOldValue = m_aValue.makeAny(); |
| rConvertedValue = rValue; |
| return sal_True; // assume "modified" ... |
| } |
| |
| //-------------------------------------------------------------------- |
| void ParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw( Exception ) |
| { |
| if ( nHandle == PROPERTY_ID_VALUE ) |
| { |
| try |
| { |
| // TODO : aParamType & nScale can be obtained within the constructor .... |
| sal_Int32 nParamType = DataType::VARCHAR; |
| OSL_VERIFY( m_xDelegator->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Type" ) ) ) >>= nParamType ); |
| |
| sal_Int32 nScale = 0; |
| if ( m_xDelegatorPSI->hasPropertyByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) ) |
| OSL_VERIFY( m_xDelegator->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Scale" ) ) ) >>= nScale ); |
| |
| if ( m_xValueDestination.is() ) |
| { |
| for ( ::std::vector< sal_Int32 >::iterator aIter = m_aIndexes.begin(); aIter != m_aIndexes.end(); ++aIter ) |
| { |
| m_xValueDestination->setObjectWithInfo( *aIter + 1, rValue, nParamType, nScale ); |
| // (the index of the parameters is one-based) |
| } |
| } |
| |
| m_aValue = rValue; |
| } |
| catch( SQLException& e ) |
| { |
| WrappedTargetException aExceptionWrapper; |
| aExceptionWrapper.Context = e.Context; |
| aExceptionWrapper.Message = e.Message; |
| aExceptionWrapper.TargetException <<= e; |
| throw WrappedTargetException( aExceptionWrapper ); |
| } |
| } |
| else |
| { |
| ::rtl::OUString aName = impl_getPseudoAggregatePropertyName( nHandle ); |
| m_xDelegator->setPropertyValue( aName, rValue ); |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void ParameterWrapper::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const |
| { |
| if ( nHandle == PROPERTY_ID_VALUE ) |
| { |
| rValue = m_aValue.makeAny(); |
| } |
| else |
| { |
| ::rtl::OUString aName = impl_getPseudoAggregatePropertyName( nHandle ); |
| rValue = m_xDelegator->getPropertyValue( aName ); |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL ParameterWrapper::dispose() |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| |
| m_aValue.setNull(); |
| m_aIndexes.resize(0); |
| m_xDelegator.clear(); |
| m_xDelegatorPSI.clear(); |
| m_xValueDestination.clear(); |
| |
| m_aBHelper.bDisposed = sal_True; |
| } |
| |
| //==================================================================== |
| //= ParameterWrapperContainer |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| ParameterWrapperContainer::ParameterWrapperContainer() |
| :ParameterWrapperContainer_Base( m_aMutex ) |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| ParameterWrapperContainer::ParameterWrapperContainer( const Reference< XSingleSelectQueryAnalyzer >& _rxComposer ) |
| :ParameterWrapperContainer_Base( m_aMutex ) |
| { |
| Reference< XParametersSupplier > xSuppParams( _rxComposer, UNO_QUERY_THROW ); |
| Reference< XIndexAccess > xParameters( xSuppParams->getParameters(), UNO_QUERY_THROW ); |
| sal_Int32 nParamCount( xParameters->getCount() ); |
| m_aParameters.reserve( nParamCount ); |
| for ( sal_Int32 i=0; i<nParamCount; ++i ) |
| { |
| m_aParameters.push_back( new ParameterWrapper( Reference< XPropertySet >( xParameters->getByIndex( i ), UNO_QUERY_THROW ) ) ); |
| } |
| } |
| |
| //-------------------------------------------------------------------- |
| ParameterWrapperContainer::~ParameterWrapperContainer() |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| Type SAL_CALL ParameterWrapperContainer::getElementType() throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| impl_checkDisposed_throw(); |
| return ::getCppuType( static_cast< Reference< XPropertySet >* >( NULL ) ); |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool SAL_CALL ParameterWrapperContainer::hasElements() throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| impl_checkDisposed_throw(); |
| return !m_aParameters.empty(); |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Int32 SAL_CALL ParameterWrapperContainer::getCount() throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| impl_checkDisposed_throw(); |
| return m_aParameters.size(); |
| } |
| |
| //-------------------------------------------------------------------- |
| Any SAL_CALL ParameterWrapperContainer::getByIndex( sal_Int32 _nIndex ) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| impl_checkDisposed_throw(); |
| |
| if ( ( _nIndex < 0 ) || ( _nIndex >= (sal_Int32)m_aParameters.size() ) ) |
| throw IndexOutOfBoundsException(); |
| |
| return makeAny( Reference< XPropertySet >( m_aParameters[ _nIndex ].get() ) ); |
| } |
| |
| //-------------------------------------------------------------------- |
| Reference< XEnumeration > ParameterWrapperContainer::createEnumeration() throw( RuntimeException ) |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| impl_checkDisposed_throw(); |
| |
| return new ::comphelper::OEnumerationByIndex( static_cast< XIndexAccess* >( this ) ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void ParameterWrapperContainer::impl_checkDisposed_throw() |
| { |
| if ( rBHelper.bDisposed ) |
| throw DisposedException( ::rtl::OUString(), *this ); |
| } |
| |
| //-------------------------------------------------------------------- |
| void SAL_CALL ParameterWrapperContainer::disposing() |
| { |
| ::osl::MutexGuard aGuard( m_aMutex ); |
| impl_checkDisposed_throw(); |
| |
| for ( Parameters::const_iterator param = m_aParameters.begin(); |
| param != m_aParameters.end(); |
| ++param |
| ) |
| { |
| (*param)->dispose(); |
| } |
| |
| Parameters aEmpty; |
| m_aParameters.swap( aEmpty ); |
| } |
| |
| //........................................................................ |
| } } // namespace dbtools::param |
| //........................................................................ |
| |