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