Version 4.0.0.1, tag libreoffice-4.0.0.1
[LibreOffice.git] / ucb / source / cacher / cachedcontentresultsetstub.cxx
blob4069056c0d44b2f2ce4464d5f03a5262227541a3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 #include <cachedcontentresultsetstub.hxx>
22 #include <com/sun/star/sdbc/FetchDirection.hpp>
23 #include <com/sun/star/ucb/FetchError.hpp>
24 #include <osl/diagnose.h>
26 using namespace com::sun::star::beans;
27 using namespace com::sun::star::lang;
28 using namespace com::sun::star::sdbc;
29 using namespace com::sun::star::ucb;
30 using namespace com::sun::star::uno;
31 using namespace com::sun::star::util;
32 using namespace cppu;
34 using ::rtl::OUString;
36 CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > xOrigin )
37 : ContentResultSetWrapper( xOrigin )
38 , m_nColumnCount( 0 )
39 , m_bColumnCountCached( sal_False )
40 , m_bNeedToPropagateFetchSize( sal_True )
41 , m_bFirstFetchSizePropagationDone( sal_False )
42 , m_nLastFetchSize( 1 )//this value is not important at all
43 , m_bLastFetchDirection( sal_True )//this value is not important at all
44 , m_aPropertyNameForFetchSize( OUString("FetchSize") )
45 , m_aPropertyNameForFetchDirection( OUString("FetchDirection") )
47 impl_init();
50 CachedContentResultSetStub::~CachedContentResultSetStub()
52 impl_deinit();
55 //--------------------------------------------------------------------------
56 // XInterface methods.
57 //--------------------------------------------------------------------------
58 XINTERFACE_COMMON_IMPL( CachedContentResultSetStub )
60 Any SAL_CALL CachedContentResultSetStub
61 ::queryInterface( const Type& rType )
62 throw ( RuntimeException )
64 //list all interfaces inclusive baseclasses of interfaces
66 Any aRet = ContentResultSetWrapper::queryInterface( rType );
67 if( aRet.hasValue() )
68 return aRet;
70 aRet = cppu::queryInterface( rType
71 , static_cast< XTypeProvider* >( this )
72 , static_cast< XServiceInfo* >( this )
73 , static_cast< XFetchProvider* >( this )
74 , static_cast< XFetchProviderForContentAccess* >( this )
77 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
80 //--------------------------------------------------------------------------
81 // own methods. ( inherited )
82 //--------------------------------------------------------------------------
84 //virtual
85 void SAL_CALL CachedContentResultSetStub
86 ::impl_propertyChange( const PropertyChangeEvent& rEvt )
87 throw( RuntimeException )
89 impl_EnsureNotDisposed();
91 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
92 //because it will ignore them anyway and we can save this remote calls
93 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
94 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
95 return;
97 PropertyChangeEvent aEvt( rEvt );
98 aEvt.Source = static_cast< XPropertySet * >( this );
99 aEvt.Further = sal_False;
101 impl_notifyPropertyChangeListeners( aEvt );
105 //virtual
106 void SAL_CALL CachedContentResultSetStub
107 ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
108 throw( PropertyVetoException,
109 RuntimeException )
111 impl_EnsureNotDisposed();
113 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
114 //because it will ignore them anyway and we can save this remote calls
115 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
116 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
117 return;
119 PropertyChangeEvent aEvt( rEvt );
120 aEvt.Source = static_cast< XPropertySet * >( this );
121 aEvt.Further = sal_False;
123 impl_notifyVetoableChangeListeners( aEvt );
126 //--------------------------------------------------------------------------
127 // XTypeProvider methods.
128 //--------------------------------------------------------------------------
130 XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
131 //list all interfaces exclusive baseclasses
132 Sequence< Type > SAL_CALL CachedContentResultSetStub
133 ::getTypes()
134 throw( RuntimeException )
136 static Sequence< Type >* pTypes = NULL;
137 if( !pTypes )
139 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
140 if( !pTypes )
142 pTypes = new Sequence< Type >(13);
143 (*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider );
144 (*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo );
145 (*pTypes)[2] = CPPU_TYPE_REF( XComponent );
146 (*pTypes)[3] = CPPU_TYPE_REF( XCloseable );
147 (*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier );
148 (*pTypes)[5] = CPPU_TYPE_REF( XPropertySet );
149 (*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener );
150 (*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener );
151 (*pTypes)[8] = CPPU_TYPE_REF( XResultSet );
152 (*pTypes)[9] = CPPU_TYPE_REF( XContentAccess );
153 (*pTypes)[10] = CPPU_TYPE_REF( XRow );
154 (*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider );
155 (*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess );
158 return *pTypes;
161 //--------------------------------------------------------------------------
162 // XServiceInfo methods.
163 //--------------------------------------------------------------------------
165 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub,
166 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStub" ),
167 OUString( CACHED_CRS_STUB_SERVICE_NAME ) );
169 //-----------------------------------------------------------------
170 // XFetchProvider methods.
171 //-----------------------------------------------------------------
173 #define FETCH_XXX( impl_loadRow, loadInterface ) \
174 impl_EnsureNotDisposed(); \
175 if( !m_xResultSetOrigin.is() ) \
177 OSL_FAIL( "broadcaster was disposed already" ); \
178 throw RuntimeException(); \
180 impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \
181 FetchResult aRet; \
182 aRet.StartIndex = nRowStartPosition; \
183 aRet.Orientation = bDirection; \
184 aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \
185 sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \
186 if( impl_isForwardOnly() ) \
188 if( nOldOriginal_Pos != nRowStartPosition ) \
190 /*@todo*/ \
191 aRet.FetchError = FetchError::EXCEPTION; \
192 return aRet; \
194 if( nRowCount != 1 ) \
195 aRet.FetchError = FetchError::EXCEPTION; \
197 aRet.Rows.realloc( 1 ); \
199 try \
201 impl_loadRow( aRet.Rows[0], loadInterface ); \
203 catch( SQLException& ) \
205 aRet.Rows.realloc( 0 ); \
206 aRet.FetchError = FetchError::EXCEPTION; \
207 return aRet; \
209 return aRet; \
211 aRet.Rows.realloc( nRowCount ); \
212 sal_Bool bOldOriginal_AfterLast = sal_False; \
213 if( !nOldOriginal_Pos ) \
214 bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
215 sal_Int32 nN = 1; \
216 sal_Bool bValidNewPos = sal_False; \
217 try \
219 try \
221 /*if( nOldOriginal_Pos != nRowStartPosition )*/ \
222 bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
224 catch( SQLException& ) \
226 aRet.Rows.realloc( 0 ); \
227 aRet.FetchError = FetchError::EXCEPTION; \
228 return aRet; \
230 if( !bValidNewPos ) \
232 aRet.Rows.realloc( 0 ); \
233 aRet.FetchError = FetchError::EXCEPTION; \
235 /*restore old position*/ \
236 if( nOldOriginal_Pos ) \
237 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
238 else if( bOldOriginal_AfterLast ) \
239 m_xResultSetOrigin->afterLast(); \
240 else \
241 m_xResultSetOrigin->beforeFirst(); \
243 return aRet; \
245 for( ; nN <= nRowCount; ) \
247 impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
248 nN++; \
249 if( nN <= nRowCount ) \
251 if( bDirection ) \
253 if( !m_xResultSetOrigin->next() ) \
255 aRet.Rows.realloc( nN-1 ); \
256 aRet.FetchError = FetchError::ENDOFDATA; \
257 break; \
260 else \
262 if( !m_xResultSetOrigin->previous() ) \
264 aRet.Rows.realloc( nN-1 ); \
265 aRet.FetchError = FetchError::ENDOFDATA; \
266 break; \
272 catch( SQLException& ) \
274 aRet.Rows.realloc( nN-1 ); \
275 aRet.FetchError = FetchError::EXCEPTION; \
277 /*restore old position*/ \
278 if( nOldOriginal_Pos ) \
279 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
280 else if( bOldOriginal_AfterLast ) \
281 m_xResultSetOrigin->afterLast(); \
282 else \
283 m_xResultSetOrigin->beforeFirst(); \
284 return aRet;
286 FetchResult SAL_CALL CachedContentResultSetStub
287 ::fetch( sal_Int32 nRowStartPosition
288 , sal_Int32 nRowCount, sal_Bool bDirection )
289 throw( RuntimeException )
291 impl_init_xRowOrigin();
292 FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin );
295 sal_Int32 SAL_CALL CachedContentResultSetStub
296 ::impl_getColumnCount()
298 sal_Int32 nCount;
299 sal_Bool bCached;
301 osl::Guard< osl::Mutex > aGuard( m_aMutex );
302 nCount = m_nColumnCount;
303 bCached = m_bColumnCountCached;
305 if( !bCached )
309 Reference< XResultSetMetaData > xMetaData = getMetaData();
310 if( xMetaData.is() )
311 nCount = xMetaData->getColumnCount();
313 catch( SQLException& )
315 OSL_FAIL( "couldn't determine the column count" );
316 nCount = 0;
319 osl::Guard< osl::Mutex > aGuard( m_aMutex );
320 m_nColumnCount = nCount;
321 m_bColumnCountCached = sal_True;
322 return m_nColumnCount;
325 void SAL_CALL CachedContentResultSetStub
326 ::impl_getCurrentRowContent( Any& rRowContent
327 , Reference< XRow > xRow )
328 throw ( SQLException, RuntimeException )
330 sal_Int32 nCount = impl_getColumnCount();
332 Sequence< Any > aContent( nCount );
333 for( sal_Int32 nN = 1; nN <= nCount; nN++ )
335 aContent[nN-1] = xRow->getObject( nN, NULL );
338 rRowContent <<= aContent;
341 void SAL_CALL CachedContentResultSetStub
342 ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection )
343 throw ( RuntimeException )
345 //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets
347 //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
349 //if the underlying ResultSet has a property FetchSize and FetchDirection,
350 //we will set these properties, if the new given parameters are different from the last ones
352 if( !m_bNeedToPropagateFetchSize )
353 return;
355 sal_Bool bNeedAction;
356 sal_Int32 nLastSize;
357 sal_Bool bLastDirection;
358 sal_Bool bFirstPropagationDone;
360 osl::Guard< osl::Mutex > aGuard( m_aMutex );
361 bNeedAction = m_bNeedToPropagateFetchSize;
362 nLastSize = m_nLastFetchSize;
363 bLastDirection = m_bLastFetchDirection;
364 bFirstPropagationDone = m_bFirstFetchSizePropagationDone;
366 if( bNeedAction )
368 if( nLastSize == nFetchSize
369 && bLastDirection == bFetchDirection
370 && bFirstPropagationDone == sal_True )
371 return;
373 if(!bFirstPropagationDone)
375 //check whether the properties 'FetchSize' and 'FetchDirection' do exist
377 Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
378 sal_Bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
379 sal_Bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
381 if(!bHasSize || !bHasDirection)
383 osl::Guard< osl::Mutex > aGuard( m_aMutex );
384 m_bNeedToPropagateFetchSize = sal_False;
385 return;
389 sal_Bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone;
390 sal_Bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone;
393 osl::Guard< osl::Mutex > aGuard( m_aMutex );
394 m_bFirstFetchSizePropagationDone = sal_True;
395 m_nLastFetchSize = nFetchSize;
396 m_bLastFetchDirection = bFetchDirection;
399 if( bSetSize )
401 Any aValue;
402 aValue <<= nFetchSize;
405 setPropertyValue( m_aPropertyNameForFetchSize, aValue );
407 catch( com::sun::star::uno::Exception& ) {}
409 if( bSetDirection )
411 sal_Int32 nFetchDirection = FetchDirection::FORWARD;
412 if( !bFetchDirection )
413 nFetchDirection = FetchDirection::REVERSE;
414 Any aValue;
415 aValue <<= nFetchDirection;
418 setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
420 catch( com::sun::star::uno::Exception& ) {}
426 //-----------------------------------------------------------------
427 // XFetchProviderForContentAccess methods.
428 //-----------------------------------------------------------------
430 void SAL_CALL CachedContentResultSetStub
431 ::impl_getCurrentContentIdentifierString( Any& rAny
432 , Reference< XContentAccess > xContentAccess )
433 throw ( RuntimeException )
435 rAny <<= xContentAccess->queryContentIdentifierString();
438 void SAL_CALL CachedContentResultSetStub
439 ::impl_getCurrentContentIdentifier( Any& rAny
440 , Reference< XContentAccess > xContentAccess )
441 throw ( RuntimeException )
443 rAny <<= xContentAccess->queryContentIdentifier();
446 void SAL_CALL CachedContentResultSetStub
447 ::impl_getCurrentContent( Any& rAny
448 , Reference< XContentAccess > xContentAccess )
449 throw ( RuntimeException )
451 rAny <<= xContentAccess->queryContent();
454 //virtual
455 FetchResult SAL_CALL CachedContentResultSetStub
456 ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
457 , sal_Int32 nRowCount, sal_Bool bDirection )
458 throw( com::sun::star::uno::RuntimeException )
460 impl_init_xContentAccessOrigin();
461 FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin );
464 //virtual
465 FetchResult SAL_CALL CachedContentResultSetStub
466 ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
467 , sal_Int32 nRowCount, sal_Bool bDirection )
468 throw( com::sun::star::uno::RuntimeException )
470 impl_init_xContentAccessOrigin();
471 FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin );
474 //virtual
475 FetchResult SAL_CALL CachedContentResultSetStub
476 ::fetchContents( sal_Int32 nRowStartPosition
477 , sal_Int32 nRowCount, sal_Bool bDirection )
478 throw( com::sun::star::uno::RuntimeException )
480 impl_init_xContentAccessOrigin();
481 FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin );
484 //--------------------------------------------------------------------------
485 //--------------------------------------------------------------------------
486 // class CachedContentResultSetStubFactory
487 //--------------------------------------------------------------------------
488 //--------------------------------------------------------------------------
490 CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
491 const Reference< XMultiServiceFactory > & rSMgr )
493 m_xSMgr = rSMgr;
496 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
500 //--------------------------------------------------------------------------
501 // CachedContentResultSetStubFactory XInterface methods.
502 //--------------------------------------------------------------------------
504 XINTERFACE_IMPL_3( CachedContentResultSetStubFactory,
505 XTypeProvider,
506 XServiceInfo,
507 XCachedContentResultSetStubFactory );
509 //--------------------------------------------------------------------------
510 // CachedContentResultSetStubFactory XTypeProvider methods.
511 //--------------------------------------------------------------------------
513 XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
514 XTypeProvider,
515 XServiceInfo,
516 XCachedContentResultSetStubFactory );
518 //--------------------------------------------------------------------------
519 // CachedContentResultSetStubFactory XServiceInfo methods.
520 //--------------------------------------------------------------------------
522 XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory,
523 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ),
524 OUString( CACHED_CRS_STUB_FACTORY_NAME ) );
526 //--------------------------------------------------------------------------
527 // Service factory implementation.
528 //--------------------------------------------------------------------------
530 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
532 //--------------------------------------------------------------------------
533 // CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
534 //--------------------------------------------------------------------------
536 //virtual
537 Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
538 ::createCachedContentResultSetStub(
539 const Reference< XResultSet > & xSource )
540 throw( RuntimeException )
542 if( xSource.is() )
544 Reference< XResultSet > xRet;
545 xRet = new CachedContentResultSetStub( xSource );
546 return xRet;
548 return NULL;
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */