1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #include <connectivity/paramwrapper.hxx>
21 #include <com/sun/star/beans/PropertyAttribute.hpp>
22 #include <com/sun/star/sdbc/DataType.hpp>
23 #include <com/sun/star/lang/WrappedTargetException.hpp>
24 #include <com/sun/star/sdb/XParametersSupplier.hpp>
25 #include <com/sun/star/lang/DisposedException.hpp>
27 #include <tools/diagnose_ex.h>
28 #include <comphelper/enumhelper.hxx>
30 #define PROPERTY_ID_VALUE 1000
32 //........................................................................
37 //........................................................................
39 using ::com::sun::star::uno::Reference
;
40 using ::com::sun::star::sdbc::XParameters
;
41 using ::com::sun::star::uno::Sequence
;
42 using ::com::sun::star::uno::Type
;
43 using ::com::sun::star::uno::RuntimeException
;
44 using ::com::sun::star::uno::XWeak
;
45 using ::com::sun::star::beans::XPropertySet
;
46 using ::com::sun::star::beans::XFastPropertySet
;
47 using ::com::sun::star::beans::XMultiPropertySet
;
48 using ::com::sun::star::beans::XPropertySetInfo
;
49 using ::com::sun::star::beans::Property
;
50 using ::com::sun::star::uno::Exception
;
51 using ::com::sun::star::uno::UNO_QUERY_THROW
;
52 using ::com::sun::star::uno::Any
;
53 using ::com::sun::star::lang::IllegalArgumentException
;
54 using ::com::sun::star::sdbc::SQLException
;
55 using ::com::sun::star::lang::WrappedTargetException
;
56 using ::com::sun::star::lang::IndexOutOfBoundsException
;
57 using ::com::sun::star::container::XEnumeration
;
58 using ::com::sun::star::sdb::XSingleSelectQueryAnalyzer
;
59 using ::com::sun::star::sdb::XParametersSupplier
;
60 using ::com::sun::star::lang::DisposedException
;
62 namespace PropertyAttribute
= ::com::sun::star::beans::PropertyAttribute
;
63 namespace DataType
= ::com::sun::star::sdbc::DataType
;
65 //====================================================================
67 //====================================================================
68 //--------------------------------------------------------------------
69 ParameterWrapper::ParameterWrapper( const Reference
< XPropertySet
>& _rxColumn
)
70 :PropertyBase( m_aBHelper
)
71 ,m_xDelegator( _rxColumn
)
73 if ( m_xDelegator
.is() )
74 m_xDelegatorPSI
= m_xDelegator
->getPropertySetInfo();
75 if ( !m_xDelegatorPSI
.is() )
76 throw RuntimeException();
79 //--------------------------------------------------------------------
80 ParameterWrapper::ParameterWrapper( const Reference
< XPropertySet
>& _rxColumn
,
81 const Reference
< XParameters
>& _rxAllParameters
, const ::std::vector
< sal_Int32
>& _rIndexes
)
82 :PropertyBase( m_aBHelper
)
83 ,m_aIndexes( _rIndexes
)
84 ,m_xDelegator( _rxColumn
)
85 ,m_xValueDestination( _rxAllParameters
)
87 if ( m_xDelegator
.is() )
88 m_xDelegatorPSI
= m_xDelegator
->getPropertySetInfo();
89 if ( !m_xDelegatorPSI
.is() )
90 throw RuntimeException();
92 OSL_ENSURE( !m_aIndexes
.empty(), "ParameterWrapper::ParameterWrapper: sure about the indexes?" );
95 //--------------------------------------------------------------------
96 ParameterWrapper::~ParameterWrapper()
100 //--------------------------------------------------------------------
101 IMPLEMENT_FORWARD_XINTERFACE2( ParameterWrapper
, UnoBase
, PropertyBase
)
103 //--------------------------------------------------------------------
104 Sequence
< Type
> SAL_CALL
ParameterWrapper::getTypes( ) throw(RuntimeException
)
106 Sequence
< Type
> aTypes( 4 );
107 aTypes
[ 1 ] = ::getCppuType( static_cast< Reference
< XWeak
>* >( NULL
) );
108 aTypes
[ 1 ] = ::getCppuType( static_cast< Reference
< XPropertySet
>* >( NULL
) );
109 aTypes
[ 2 ] = ::getCppuType( static_cast< Reference
< XFastPropertySet
>* >( NULL
) );
110 aTypes
[ 3 ] = ::getCppuType( static_cast< Reference
< XMultiPropertySet
>* >( NULL
) );
114 //--------------------------------------------------------------------
115 IMPLEMENT_GET_IMPLEMENTATION_ID( ParameterWrapper
)
117 //--------------------------------------------------------------------
118 OUString
ParameterWrapper::impl_getPseudoAggregatePropertyName( sal_Int32 _nHandle
) const
120 Reference
< XPropertySetInfo
> xInfo
= const_cast<ParameterWrapper
*>( this )->getPropertySetInfo();
121 Sequence
< Property
> aProperties
= xInfo
->getProperties();
122 const Property
* pProperties
= aProperties
.getConstArray();
123 for ( sal_Int32 i
= 0; i
< aProperties
.getLength(); ++i
, ++pProperties
)
125 if ( pProperties
->Handle
== _nHandle
)
126 return pProperties
->Name
;
129 OSL_FAIL( "ParameterWrapper::impl_getPseudoAggregatePropertyName: invalid argument!" );
133 //--------------------------------------------------------------------
134 Reference
< XPropertySetInfo
> ParameterWrapper::getPropertySetInfo() throw( RuntimeException
)
136 return createPropertySetInfo( getInfoHelper() );
139 //--------------------------------------------------------------------
140 ::cppu::IPropertyArrayHelper
& ParameterWrapper::getInfoHelper()
142 if ( !m_pInfoHelper
.get() )
144 Sequence
< Property
> aProperties
;
147 aProperties
= m_xDelegatorPSI
->getProperties();
148 sal_Int32
nProperties( aProperties
.getLength() );
149 aProperties
.realloc( nProperties
+ 1 );
150 aProperties
[ nProperties
] = Property(
153 ::cppu::UnoType
< Any
>::get(),
154 PropertyAttribute::TRANSIENT
| PropertyAttribute::MAYBEVOID
157 catch( const Exception
& )
159 DBG_UNHANDLED_EXCEPTION();
162 m_pInfoHelper
.reset( new ::cppu::OPropertyArrayHelper( aProperties
, false ) );
164 return *m_pInfoHelper
;
167 //--------------------------------------------------------------------
168 sal_Bool
ParameterWrapper::convertFastPropertyValue(Any
& rConvertedValue
, Any
& rOldValue
, sal_Int32 nHandle
, const Any
& rValue
) throw( IllegalArgumentException
)
170 OSL_ENSURE( PROPERTY_ID_VALUE
== nHandle
, "ParameterWrapper::convertFastPropertyValue: the only non-readonly prop should be our PROPERTY_VALUE!" );
173 // we're lazy here ...
174 rOldValue
= m_aValue
.makeAny();
175 rConvertedValue
= rValue
;
176 return sal_True
; // assume "modified" ...
179 //--------------------------------------------------------------------
180 void ParameterWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
, const Any
& rValue
) throw( Exception
)
182 if ( nHandle
== PROPERTY_ID_VALUE
)
186 // TODO : aParamType & nScale can be obtained within the constructor ....
187 sal_Int32 nParamType
= DataType::VARCHAR
;
188 OSL_VERIFY( m_xDelegator
->getPropertyValue( OUString( "Type" ) ) >>= nParamType
);
190 sal_Int32 nScale
= 0;
191 if ( m_xDelegatorPSI
->hasPropertyByName( OUString( "Scale" ) ) )
192 OSL_VERIFY( m_xDelegator
->getPropertyValue( OUString( "Scale" ) ) >>= nScale
);
194 if ( m_xValueDestination
.is() )
196 for ( ::std::vector
< sal_Int32
>::iterator aIter
= m_aIndexes
.begin(); aIter
!= m_aIndexes
.end(); ++aIter
)
198 m_xValueDestination
->setObjectWithInfo( *aIter
+ 1, rValue
, nParamType
, nScale
);
199 // (the index of the parameters is one-based)
205 catch( SQLException
& e
)
207 WrappedTargetException aExceptionWrapper
;
208 aExceptionWrapper
.Context
= e
.Context
;
209 aExceptionWrapper
.Message
= e
.Message
;
210 aExceptionWrapper
.TargetException
<<= e
;
211 throw WrappedTargetException( aExceptionWrapper
);
216 OUString aName
= impl_getPseudoAggregatePropertyName( nHandle
);
217 m_xDelegator
->setPropertyValue( aName
, rValue
);
221 //--------------------------------------------------------------------
222 void ParameterWrapper::getFastPropertyValue( Any
& rValue
, sal_Int32 nHandle
) const
224 if ( nHandle
== PROPERTY_ID_VALUE
)
226 rValue
= m_aValue
.makeAny();
230 OUString aName
= impl_getPseudoAggregatePropertyName( nHandle
);
231 rValue
= m_xDelegator
->getPropertyValue( aName
);
235 //--------------------------------------------------------------------
236 void SAL_CALL
ParameterWrapper::dispose()
238 ::osl::MutexGuard
aGuard( m_aMutex
);
241 m_aIndexes
.resize(0);
242 m_xDelegator
.clear();
243 m_xDelegatorPSI
.clear();
244 m_xValueDestination
.clear();
246 m_aBHelper
.bDisposed
= sal_True
;
249 //====================================================================
250 //= ParameterWrapperContainer
251 //====================================================================
252 //--------------------------------------------------------------------
253 ParameterWrapperContainer::ParameterWrapperContainer()
254 :ParameterWrapperContainer_Base( m_aMutex
)
258 //--------------------------------------------------------------------
259 ParameterWrapperContainer::ParameterWrapperContainer( const Reference
< XSingleSelectQueryAnalyzer
>& _rxComposer
)
260 :ParameterWrapperContainer_Base( m_aMutex
)
262 Reference
< XParametersSupplier
> xSuppParams( _rxComposer
, UNO_QUERY_THROW
);
263 Reference
< XIndexAccess
> xParameters( xSuppParams
->getParameters(), UNO_QUERY_THROW
);
264 sal_Int32
nParamCount( xParameters
->getCount() );
265 m_aParameters
.reserve( nParamCount
);
266 for ( sal_Int32 i
=0; i
<nParamCount
; ++i
)
268 m_aParameters
.push_back( new ParameterWrapper( Reference
< XPropertySet
>( xParameters
->getByIndex( i
), UNO_QUERY_THROW
) ) );
272 //--------------------------------------------------------------------
273 ParameterWrapperContainer::~ParameterWrapperContainer()
277 //--------------------------------------------------------------------
278 Type SAL_CALL
ParameterWrapperContainer::getElementType() throw( RuntimeException
)
280 ::osl::MutexGuard
aGuard( m_aMutex
);
281 impl_checkDisposed_throw();
282 return ::getCppuType( static_cast< Reference
< XPropertySet
>* >( NULL
) );
285 //--------------------------------------------------------------------
286 sal_Bool SAL_CALL
ParameterWrapperContainer::hasElements() throw( RuntimeException
)
288 ::osl::MutexGuard
aGuard( m_aMutex
);
289 impl_checkDisposed_throw();
290 return !m_aParameters
.empty();
293 //--------------------------------------------------------------------
294 sal_Int32 SAL_CALL
ParameterWrapperContainer::getCount() throw( RuntimeException
)
296 ::osl::MutexGuard
aGuard( m_aMutex
);
297 impl_checkDisposed_throw();
298 return m_aParameters
.size();
301 //--------------------------------------------------------------------
302 Any SAL_CALL
ParameterWrapperContainer::getByIndex( sal_Int32 _nIndex
) throw( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
304 ::osl::MutexGuard
aGuard( m_aMutex
);
305 impl_checkDisposed_throw();
307 if ( ( _nIndex
< 0 ) || ( _nIndex
>= (sal_Int32
)m_aParameters
.size() ) )
308 throw IndexOutOfBoundsException();
310 return makeAny( Reference
< XPropertySet
>( m_aParameters
[ _nIndex
].get() ) );
313 //--------------------------------------------------------------------
314 Reference
< XEnumeration
> ParameterWrapperContainer::createEnumeration() throw( RuntimeException
)
316 ::osl::MutexGuard
aGuard( m_aMutex
);
317 impl_checkDisposed_throw();
319 return new ::comphelper::OEnumerationByIndex( static_cast< XIndexAccess
* >( this ) );
322 //--------------------------------------------------------------------
323 void ParameterWrapperContainer::impl_checkDisposed_throw()
325 if ( rBHelper
.bDisposed
)
326 throw DisposedException( OUString(), *this );
329 //--------------------------------------------------------------------
330 void SAL_CALL
ParameterWrapperContainer::disposing()
332 ::osl::MutexGuard
aGuard( m_aMutex
);
333 impl_checkDisposed_throw();
335 for ( Parameters::const_iterator param
= m_aParameters
.begin();
336 param
!= m_aParameters
.end();
344 m_aParameters
.swap( aEmpty
);
347 //........................................................................
348 } } // namespace dbtools::param
349 //........................................................................
351 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */