Update ooo320-m1
[ooovba.git] / ucb / source / cacher / cachedcontentresultsetstub.cxx
blob45813514208dd1666dfa2a6757dc06a58968eed9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: cachedcontentresultsetstub.cxx,v $
10 * $Revision: 1.11 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_ucb.hxx"
34 #include <cachedcontentresultsetstub.hxx>
35 #include <com/sun/star/sdbc/FetchDirection.hpp>
36 #include <com/sun/star/ucb/FetchError.hpp>
37 #include <osl/diagnose.h>
39 using namespace com::sun::star::beans;
40 using namespace com::sun::star::lang;
41 using namespace com::sun::star::sdbc;
42 using namespace com::sun::star::ucb;
43 using namespace com::sun::star::uno;
44 using namespace com::sun::star::util;
45 using namespace cppu;
46 using namespace rtl;
48 CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > xOrigin )
49 : ContentResultSetWrapper( xOrigin )
50 , m_nColumnCount( 0 )
51 , m_bColumnCountCached( sal_False )
52 , m_bNeedToPropagateFetchSize( sal_True )
53 , m_bFirstFetchSizePropagationDone( sal_False )
54 , m_nLastFetchSize( 1 )//this value is not important at all
55 , m_bLastFetchDirection( sal_True )//this value is not important at all
56 , m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) )
57 , m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) )
59 impl_init();
62 CachedContentResultSetStub::~CachedContentResultSetStub()
64 impl_deinit();
67 //--------------------------------------------------------------------------
68 // XInterface methods.
69 //--------------------------------------------------------------------------
70 XINTERFACE_COMMON_IMPL( CachedContentResultSetStub )
72 Any SAL_CALL CachedContentResultSetStub
73 ::queryInterface( const Type& rType )
74 throw ( RuntimeException )
76 //list all interfaces inclusive baseclasses of interfaces
78 Any aRet = ContentResultSetWrapper::queryInterface( rType );
79 if( aRet.hasValue() )
80 return aRet;
82 aRet = cppu::queryInterface( rType
83 , static_cast< XTypeProvider* >( this )
84 , static_cast< XServiceInfo* >( this )
85 , static_cast< XFetchProvider* >( this )
86 , static_cast< XFetchProviderForContentAccess* >( this )
89 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
92 //--------------------------------------------------------------------------
93 // own methods. ( inherited )
94 //--------------------------------------------------------------------------
96 //virtual
97 void SAL_CALL CachedContentResultSetStub
98 ::impl_propertyChange( const PropertyChangeEvent& rEvt )
99 throw( RuntimeException )
101 impl_EnsureNotDisposed();
103 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
104 //because it will ignore them anyway and we can save this remote calls
105 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
106 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
107 return;
109 PropertyChangeEvent aEvt( rEvt );
110 aEvt.Source = static_cast< XPropertySet * >( this );
111 aEvt.Further = sal_False;
113 impl_notifyPropertyChangeListeners( aEvt );
117 //virtual
118 void SAL_CALL CachedContentResultSetStub
119 ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
120 throw( PropertyVetoException,
121 RuntimeException )
123 impl_EnsureNotDisposed();
125 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
126 //because it will ignore them anyway and we can save this remote calls
127 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
128 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
129 return;
131 PropertyChangeEvent aEvt( rEvt );
132 aEvt.Source = static_cast< XPropertySet * >( this );
133 aEvt.Further = sal_False;
135 impl_notifyVetoableChangeListeners( aEvt );
138 //--------------------------------------------------------------------------
139 // XTypeProvider methods.
140 //--------------------------------------------------------------------------
142 XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
143 //list all interfaces exclusive baseclasses
144 Sequence< Type > SAL_CALL CachedContentResultSetStub
145 ::getTypes()
146 throw( RuntimeException )
148 static Sequence< Type >* pTypes = NULL;
149 if( !pTypes )
151 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
152 if( !pTypes )
154 pTypes = new Sequence< Type >(13);
155 (*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider );
156 (*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo );
157 (*pTypes)[2] = CPPU_TYPE_REF( XComponent );
158 (*pTypes)[3] = CPPU_TYPE_REF( XCloseable );
159 (*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier );
160 (*pTypes)[5] = CPPU_TYPE_REF( XPropertySet );
161 (*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener );
162 (*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener );
163 (*pTypes)[8] = CPPU_TYPE_REF( XResultSet );
164 (*pTypes)[9] = CPPU_TYPE_REF( XContentAccess );
165 (*pTypes)[10] = CPPU_TYPE_REF( XRow );
166 (*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider );
167 (*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess );
170 return *pTypes;
172 static cppu::OTypeCollection * pCollection = 0;
173 if (!pCollection)
175 osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex());
176 if (!pCollection)
178 static cppu::OTypeCollection
179 aTheCollection(
180 getCppuType(
181 static_cast< Reference< XTypeProvider >
182 const * >(
183 0)),
184 getCppuType(
185 static_cast< Reference< XServiceInfo >
186 const * >(
187 0)),
188 getCppuType(
189 static_cast< Reference< XComponent >
190 const * >(
191 0)),
192 getCppuType(
193 static_cast< Reference< XCloseable >
194 const * >(
195 0)),
196 getCppuType(
197 static_cast< Reference< XResultSetMetaDataSupplier >
198 const * >(
199 0)),
200 getCppuType(
201 static_cast< Reference< XPropertySet >
202 const * >(
203 0)),
204 getCppuType(
205 static_cast< Reference< XPropertyChangeListener >
206 const * >(
207 0)),
208 getCppuType(
209 static_cast< Reference< XVetoableChangeListener >
210 const * >(
211 0)),
212 getCppuType(
213 static_cast< Reference< XResultSet >
214 const * >(
215 0)),
216 getCppuType(
217 static_cast< Reference< XContentAccess >
218 const * >(
219 0)),
220 getCppuType(
221 static_cast< Reference< XRow >
222 const * >(
223 0)),
224 getCppuType(
225 static_cast< Reference< XFetchProvider >
226 const * >(
227 0)),
228 getCppuType(
229 static_cast< Reference< XFetchProviderForContentAccess >
230 const * >(
233 pCollection = &aTheCollection;
236 return pCollection->getTypes();
240 //--------------------------------------------------------------------------
241 // XServiceInfo methods.
242 //--------------------------------------------------------------------------
244 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub,
245 OUString::createFromAscii(
246 "com.sun.star.comp.ucb.CachedContentResultSetStub" ),
247 OUString::createFromAscii(
248 CACHED_CRS_STUB_SERVICE_NAME ) );
250 //-----------------------------------------------------------------
251 // XFetchProvider methods.
252 //-----------------------------------------------------------------
254 #define FETCH_XXX( impl_loadRow, loadInterface ) \
255 impl_EnsureNotDisposed(); \
256 if( !m_xResultSetOrigin.is() ) \
258 OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \
259 throw RuntimeException(); \
261 impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \
262 FetchResult aRet; \
263 aRet.StartIndex = nRowStartPosition; \
264 aRet.Orientation = bDirection; \
265 aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \
266 sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \
267 if( impl_isForwardOnly() ) \
269 if( nOldOriginal_Pos != nRowStartPosition ) \
271 /*@todo*/ \
272 aRet.FetchError = FetchError::EXCEPTION; \
273 return aRet; \
275 if( nRowCount != 1 ) \
276 aRet.FetchError = FetchError::EXCEPTION; \
278 aRet.Rows.realloc( 1 ); \
280 try \
282 impl_loadRow( aRet.Rows[0], loadInterface ); \
284 catch( SQLException& ) \
286 aRet.Rows.realloc( 0 ); \
287 aRet.FetchError = FetchError::EXCEPTION; \
288 return aRet; \
290 return aRet; \
292 aRet.Rows.realloc( nRowCount ); \
293 sal_Bool bOldOriginal_AfterLast = sal_False; \
294 if( !nOldOriginal_Pos ) \
295 bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
296 sal_Int32 nN = 1; \
297 sal_Bool bValidNewPos = sal_False; \
298 try \
300 try \
302 /*if( nOldOriginal_Pos != nRowStartPosition )*/ \
303 bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
305 catch( SQLException& ) \
307 aRet.Rows.realloc( 0 ); \
308 aRet.FetchError = FetchError::EXCEPTION; \
309 return aRet; \
311 if( !bValidNewPos ) \
313 aRet.Rows.realloc( 0 ); \
314 aRet.FetchError = FetchError::EXCEPTION; \
316 /*restore old position*/ \
317 if( nOldOriginal_Pos ) \
318 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
319 else if( bOldOriginal_AfterLast ) \
320 m_xResultSetOrigin->afterLast(); \
321 else \
322 m_xResultSetOrigin->beforeFirst(); \
324 return aRet; \
326 for( ; nN <= nRowCount; ) \
328 impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
329 nN++; \
330 if( nN <= nRowCount ) \
332 if( bDirection ) \
334 if( !m_xResultSetOrigin->next() ) \
336 aRet.Rows.realloc( nN-1 ); \
337 aRet.FetchError = FetchError::ENDOFDATA; \
338 break; \
341 else \
343 if( !m_xResultSetOrigin->previous() ) \
345 aRet.Rows.realloc( nN-1 ); \
346 aRet.FetchError = FetchError::ENDOFDATA; \
347 break; \
353 catch( SQLException& ) \
355 aRet.Rows.realloc( nN-1 ); \
356 aRet.FetchError = FetchError::EXCEPTION; \
358 /*restore old position*/ \
359 if( nOldOriginal_Pos ) \
360 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
361 else if( bOldOriginal_AfterLast ) \
362 m_xResultSetOrigin->afterLast(); \
363 else \
364 m_xResultSetOrigin->beforeFirst(); \
365 return aRet;
367 FetchResult SAL_CALL CachedContentResultSetStub
368 ::fetch( sal_Int32 nRowStartPosition
369 , sal_Int32 nRowCount, sal_Bool bDirection )
370 throw( RuntimeException )
372 impl_init_xRowOrigin();
373 FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin );
376 sal_Int32 SAL_CALL CachedContentResultSetStub
377 ::impl_getColumnCount()
379 sal_Int32 nCount;
380 sal_Bool bCached;
382 osl::Guard< osl::Mutex > aGuard( m_aMutex );
383 nCount = m_nColumnCount;
384 bCached = m_bColumnCountCached;
386 if( !bCached )
390 Reference< XResultSetMetaData > xMetaData = getMetaData();
391 if( xMetaData.is() )
392 nCount = xMetaData->getColumnCount();
394 catch( SQLException& )
396 OSL_ENSURE( sal_False, "couldn't determine the column count" );
397 nCount = 0;
400 osl::Guard< osl::Mutex > aGuard( m_aMutex );
401 m_nColumnCount = nCount;
402 m_bColumnCountCached = sal_True;
403 return m_nColumnCount;
406 void SAL_CALL CachedContentResultSetStub
407 ::impl_getCurrentRowContent( Any& rRowContent
408 , Reference< XRow > xRow )
409 throw ( SQLException, RuntimeException )
411 sal_Int32 nCount = impl_getColumnCount();
413 Sequence< Any > aContent( nCount );
414 for( sal_Int32 nN = 1; nN <= nCount; nN++ )
416 aContent[nN-1] = xRow->getObject( nN, NULL );
419 rRowContent <<= aContent;
422 void SAL_CALL CachedContentResultSetStub
423 ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection )
424 throw ( RuntimeException )
426 //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets
428 //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
430 //if the underlying ResultSet has a property FetchSize and FetchDirection,
431 //we will set these properties, if the new given parameters are different from the last ones
433 if( !m_bNeedToPropagateFetchSize )
434 return;
436 sal_Bool bNeedAction;
437 sal_Int32 nLastSize;
438 sal_Bool bLastDirection;
439 sal_Bool bFirstPropagationDone;
441 osl::Guard< osl::Mutex > aGuard( m_aMutex );
442 bNeedAction = m_bNeedToPropagateFetchSize;
443 nLastSize = m_nLastFetchSize;
444 bLastDirection = m_bLastFetchDirection;
445 bFirstPropagationDone = m_bFirstFetchSizePropagationDone;
447 if( bNeedAction )
449 if( nLastSize == nFetchSize
450 && bLastDirection == bFetchDirection
451 && bFirstPropagationDone == sal_True )
452 return;
454 if(!bFirstPropagationDone)
456 //check wether the properties 'FetchSize' and 'FetchDirection' do exist
458 Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
459 sal_Bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
460 sal_Bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
462 if(!bHasSize || !bHasDirection)
464 osl::Guard< osl::Mutex > aGuard( m_aMutex );
465 m_bNeedToPropagateFetchSize = sal_False;
466 return;
470 sal_Bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone;
471 sal_Bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone;
474 osl::Guard< osl::Mutex > aGuard( m_aMutex );
475 m_bFirstFetchSizePropagationDone = sal_True;
476 m_nLastFetchSize = nFetchSize;
477 m_bLastFetchDirection = bFetchDirection;
480 if( bSetSize )
482 Any aValue;
483 aValue <<= nFetchSize;
486 setPropertyValue( m_aPropertyNameForFetchSize, aValue );
488 catch( com::sun::star::uno::Exception& ) {}
490 if( bSetDirection )
492 sal_Int32 nFetchDirection = FetchDirection::FORWARD;
493 if( !bFetchDirection )
494 nFetchDirection = FetchDirection::REVERSE;
495 Any aValue;
496 aValue <<= nFetchDirection;
499 setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
501 catch( com::sun::star::uno::Exception& ) {}
507 //-----------------------------------------------------------------
508 // XFetchProviderForContentAccess methods.
509 //-----------------------------------------------------------------
511 void SAL_CALL CachedContentResultSetStub
512 ::impl_getCurrentContentIdentifierString( Any& rAny
513 , Reference< XContentAccess > xContentAccess )
514 throw ( RuntimeException )
516 rAny <<= xContentAccess->queryContentIdentifierString();
519 void SAL_CALL CachedContentResultSetStub
520 ::impl_getCurrentContentIdentifier( Any& rAny
521 , Reference< XContentAccess > xContentAccess )
522 throw ( RuntimeException )
524 rAny <<= xContentAccess->queryContentIdentifier();
527 void SAL_CALL CachedContentResultSetStub
528 ::impl_getCurrentContent( Any& rAny
529 , Reference< XContentAccess > xContentAccess )
530 throw ( RuntimeException )
532 rAny <<= xContentAccess->queryContent();
535 //virtual
536 FetchResult SAL_CALL CachedContentResultSetStub
537 ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
538 , sal_Int32 nRowCount, sal_Bool bDirection )
539 throw( com::sun::star::uno::RuntimeException )
541 impl_init_xContentAccessOrigin();
542 FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin );
545 //virtual
546 FetchResult SAL_CALL CachedContentResultSetStub
547 ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
548 , sal_Int32 nRowCount, sal_Bool bDirection )
549 throw( com::sun::star::uno::RuntimeException )
551 impl_init_xContentAccessOrigin();
552 FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin );
555 //virtual
556 FetchResult SAL_CALL CachedContentResultSetStub
557 ::fetchContents( sal_Int32 nRowStartPosition
558 , sal_Int32 nRowCount, sal_Bool bDirection )
559 throw( com::sun::star::uno::RuntimeException )
561 impl_init_xContentAccessOrigin();
562 FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin );
565 //--------------------------------------------------------------------------
566 //--------------------------------------------------------------------------
567 // class CachedContentResultSetStubFactory
568 //--------------------------------------------------------------------------
569 //--------------------------------------------------------------------------
571 CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
572 const Reference< XMultiServiceFactory > & rSMgr )
574 m_xSMgr = rSMgr;
577 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
581 //--------------------------------------------------------------------------
582 // CachedContentResultSetStubFactory XInterface methods.
583 //--------------------------------------------------------------------------
585 XINTERFACE_IMPL_3( CachedContentResultSetStubFactory,
586 XTypeProvider,
587 XServiceInfo,
588 XCachedContentResultSetStubFactory );
590 //--------------------------------------------------------------------------
591 // CachedContentResultSetStubFactory XTypeProvider methods.
592 //--------------------------------------------------------------------------
594 XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
595 XTypeProvider,
596 XServiceInfo,
597 XCachedContentResultSetStubFactory );
599 //--------------------------------------------------------------------------
600 // CachedContentResultSetStubFactory XServiceInfo methods.
601 //--------------------------------------------------------------------------
603 XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory,
604 OUString::createFromAscii(
605 "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ),
606 OUString::createFromAscii(
607 CACHED_CRS_STUB_FACTORY_NAME ) );
609 //--------------------------------------------------------------------------
610 // Service factory implementation.
611 //--------------------------------------------------------------------------
613 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
615 //--------------------------------------------------------------------------
616 // CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
617 //--------------------------------------------------------------------------
619 //virtual
620 Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
621 ::createCachedContentResultSetStub(
622 const Reference< XResultSet > & xSource )
623 throw( RuntimeException )
625 if( xSource.is() )
627 Reference< XResultSet > xRet;
628 xRet = new CachedContentResultSetStub( xSource );
629 return xRet;
631 return NULL;