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