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