Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / ucb / source / cacher / cachedcontentresultsetstub.cxx
blob03f66fc897a3f9f7601d9c6e2068f1d2ed93c8f0
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;
35 CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > xOrigin )
36 : ContentResultSetWrapper( xOrigin )
37 , m_nColumnCount( 0 )
38 , m_bColumnCountCached( false )
39 , m_bNeedToPropagateFetchSize( true )
40 , m_bFirstFetchSizePropagationDone( false )
41 , m_nLastFetchSize( 1 )//this value is not important at all
42 , m_bLastFetchDirection( true )//this value is not important at all
43 , m_aPropertyNameForFetchSize( OUString("FetchSize") )
44 , m_aPropertyNameForFetchDirection( OUString("FetchDirection") )
46 impl_init();
49 CachedContentResultSetStub::~CachedContentResultSetStub()
51 impl_deinit();
55 // XInterface methods.
56 void SAL_CALL CachedContentResultSetStub::acquire()
57 throw()
59 OWeakObject::acquire();
62 void SAL_CALL CachedContentResultSetStub::release()
63 throw()
65 OWeakObject::release();
68 Any SAL_CALL CachedContentResultSetStub
69 ::queryInterface( const Type& rType )
70 throw ( RuntimeException, std::exception )
72 //list all interfaces inclusive baseclasses of interfaces
74 Any aRet = ContentResultSetWrapper::queryInterface( rType );
75 if( aRet.hasValue() )
76 return aRet;
78 aRet = cppu::queryInterface( rType
79 , static_cast< XTypeProvider* >( this )
80 , static_cast< XServiceInfo* >( this )
81 , static_cast< XFetchProvider* >( this )
82 , static_cast< XFetchProviderForContentAccess* >( this )
85 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
89 // own methods. ( inherited )
92 //virtual
93 void SAL_CALL CachedContentResultSetStub
94 ::impl_propertyChange( const PropertyChangeEvent& rEvt )
95 throw( RuntimeException )
97 impl_EnsureNotDisposed();
99 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
100 //because it will ignore them anyway and we can save this remote calls
101 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
102 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
103 return;
105 PropertyChangeEvent aEvt( rEvt );
106 aEvt.Source = static_cast< XPropertySet * >( this );
107 aEvt.Further = sal_False;
109 impl_notifyPropertyChangeListeners( aEvt );
113 //virtual
114 void SAL_CALL CachedContentResultSetStub
115 ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
116 throw( PropertyVetoException,
117 RuntimeException )
119 impl_EnsureNotDisposed();
121 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
122 //because it will ignore them anyway and we can save this remote calls
123 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
124 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
125 return;
127 PropertyChangeEvent aEvt( rEvt );
128 aEvt.Source = static_cast< XPropertySet * >( this );
129 aEvt.Further = sal_False;
131 impl_notifyVetoableChangeListeners( aEvt );
135 // XTypeProvider methods.
138 XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
139 //list all interfaces exclusive baseclasses
140 Sequence< Type > SAL_CALL CachedContentResultSetStub
141 ::getTypes()
142 throw( RuntimeException, std::exception )
144 static Sequence< Type >* pTypes = NULL;
145 if( !pTypes )
147 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
148 if( !pTypes )
150 pTypes = new Sequence< Type >(13);
151 (*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider );
152 (*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo );
153 (*pTypes)[2] = CPPU_TYPE_REF( XComponent );
154 (*pTypes)[3] = CPPU_TYPE_REF( XCloseable );
155 (*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier );
156 (*pTypes)[5] = CPPU_TYPE_REF( XPropertySet );
157 (*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener );
158 (*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener );
159 (*pTypes)[8] = CPPU_TYPE_REF( XResultSet );
160 (*pTypes)[9] = CPPU_TYPE_REF( XContentAccess );
161 (*pTypes)[10] = CPPU_TYPE_REF( XRow );
162 (*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider );
163 (*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess );
166 return *pTypes;
170 // XServiceInfo methods.
173 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub,
174 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStub" ),
175 OUString( CACHED_CRS_STUB_SERVICE_NAME ) );
178 // XFetchProvider methods.
181 #define FETCH_XXX( impl_loadRow, loadInterface ) \
182 impl_EnsureNotDisposed(); \
183 if( !m_xResultSetOrigin.is() ) \
185 OSL_FAIL( "broadcaster was disposed already" ); \
186 throw RuntimeException(); \
188 impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \
189 FetchResult aRet; \
190 aRet.StartIndex = nRowStartPosition; \
191 aRet.Orientation = bDirection; \
192 aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \
193 sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \
194 if( impl_isForwardOnly() ) \
196 if( nOldOriginal_Pos != nRowStartPosition ) \
198 /*@todo*/ \
199 aRet.FetchError = FetchError::EXCEPTION; \
200 return aRet; \
202 if( nRowCount != 1 ) \
203 aRet.FetchError = FetchError::EXCEPTION; \
205 aRet.Rows.realloc( 1 ); \
207 try \
209 impl_loadRow( aRet.Rows[0], loadInterface ); \
211 catch( SQLException& ) \
213 aRet.Rows.realloc( 0 ); \
214 aRet.FetchError = FetchError::EXCEPTION; \
215 return aRet; \
217 return aRet; \
219 aRet.Rows.realloc( nRowCount ); \
220 bool bOldOriginal_AfterLast = false; \
221 if( !nOldOriginal_Pos ) \
222 bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
223 sal_Int32 nN = 1; \
224 bool bValidNewPos = false; \
225 try \
227 try \
229 /*if( nOldOriginal_Pos != nRowStartPosition )*/ \
230 bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
232 catch( SQLException& ) \
234 aRet.Rows.realloc( 0 ); \
235 aRet.FetchError = FetchError::EXCEPTION; \
236 return aRet; \
238 if( !bValidNewPos ) \
240 aRet.Rows.realloc( 0 ); \
241 aRet.FetchError = FetchError::EXCEPTION; \
243 /*restore old position*/ \
244 if( nOldOriginal_Pos ) \
245 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
246 else if( bOldOriginal_AfterLast ) \
247 m_xResultSetOrigin->afterLast(); \
248 else \
249 m_xResultSetOrigin->beforeFirst(); \
251 return aRet; \
253 for( ; nN <= nRowCount; ) \
255 impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
256 nN++; \
257 if( nN <= nRowCount ) \
259 if( bDirection ) \
261 if( !m_xResultSetOrigin->next() ) \
263 aRet.Rows.realloc( nN-1 ); \
264 aRet.FetchError = FetchError::ENDOFDATA; \
265 break; \
268 else \
270 if( !m_xResultSetOrigin->previous() ) \
272 aRet.Rows.realloc( nN-1 ); \
273 aRet.FetchError = FetchError::ENDOFDATA; \
274 break; \
280 catch( SQLException& ) \
282 aRet.Rows.realloc( nN-1 ); \
283 aRet.FetchError = FetchError::EXCEPTION; \
285 /*restore old position*/ \
286 if( nOldOriginal_Pos ) \
287 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
288 else if( bOldOriginal_AfterLast ) \
289 m_xResultSetOrigin->afterLast(); \
290 else \
291 m_xResultSetOrigin->beforeFirst(); \
292 return aRet;
294 FetchResult SAL_CALL CachedContentResultSetStub
295 ::fetch( sal_Int32 nRowStartPosition
296 , sal_Int32 nRowCount, sal_Bool bDirection )
297 throw( RuntimeException, std::exception )
299 impl_init_xRowOrigin();
300 FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin );
303 sal_Int32 SAL_CALL CachedContentResultSetStub
304 ::impl_getColumnCount()
306 sal_Int32 nCount;
307 bool bCached;
309 osl::Guard< osl::Mutex > aGuard( m_aMutex );
310 nCount = m_nColumnCount;
311 bCached = m_bColumnCountCached;
313 if( !bCached )
317 Reference< XResultSetMetaData > xMetaData = getMetaData();
318 if( xMetaData.is() )
319 nCount = xMetaData->getColumnCount();
321 catch( SQLException& )
323 OSL_FAIL( "couldn't determine the column count" );
324 nCount = 0;
327 osl::Guard< osl::Mutex > aGuard( m_aMutex );
328 m_nColumnCount = nCount;
329 m_bColumnCountCached = true;
330 return m_nColumnCount;
333 void SAL_CALL CachedContentResultSetStub
334 ::impl_getCurrentRowContent( Any& rRowContent
335 , Reference< XRow > xRow )
336 throw ( SQLException, RuntimeException )
338 sal_Int32 nCount = impl_getColumnCount();
340 Sequence< Any > aContent( nCount );
341 for( sal_Int32 nN = 1; nN <= nCount; nN++ )
343 aContent[nN-1] = xRow->getObject( nN, NULL );
346 rRowContent <<= aContent;
349 void SAL_CALL CachedContentResultSetStub
350 ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, bool bFetchDirection )
351 throw ( RuntimeException )
353 //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets
355 //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
357 //if the underlying ResultSet has a property FetchSize and FetchDirection,
358 //we will set these properties, if the new given parameters are different from the last ones
360 if( !m_bNeedToPropagateFetchSize )
361 return;
363 bool bNeedAction;
364 sal_Int32 nLastSize;
365 bool bLastDirection;
366 bool bFirstPropagationDone;
368 osl::Guard< osl::Mutex > aGuard( m_aMutex );
369 bNeedAction = m_bNeedToPropagateFetchSize;
370 nLastSize = m_nLastFetchSize;
371 bLastDirection = m_bLastFetchDirection;
372 bFirstPropagationDone = m_bFirstFetchSizePropagationDone;
374 if( bNeedAction )
376 if( nLastSize == nFetchSize
377 && bLastDirection == bFetchDirection
378 && bFirstPropagationDone )
379 return;
381 if(!bFirstPropagationDone)
383 //check whether the properties 'FetchSize' and 'FetchDirection' do exist
385 Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
386 bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
387 bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
389 if(!bHasSize || !bHasDirection)
391 osl::Guard< osl::Mutex > aGuard( m_aMutex );
392 m_bNeedToPropagateFetchSize = false;
393 return;
397 bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone;
398 bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone;
401 osl::Guard< osl::Mutex > aGuard( m_aMutex );
402 m_bFirstFetchSizePropagationDone = true;
403 m_nLastFetchSize = nFetchSize;
404 m_bLastFetchDirection = bFetchDirection;
407 if( bSetSize )
409 Any aValue;
410 aValue <<= nFetchSize;
413 setPropertyValue( m_aPropertyNameForFetchSize, aValue );
415 catch( com::sun::star::uno::Exception& ) {}
417 if( bSetDirection )
419 sal_Int32 nFetchDirection = FetchDirection::FORWARD;
420 if( !bFetchDirection )
421 nFetchDirection = FetchDirection::REVERSE;
422 Any aValue;
423 aValue <<= nFetchDirection;
426 setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
428 catch( com::sun::star::uno::Exception& ) {}
435 // XFetchProviderForContentAccess methods.
438 void SAL_CALL CachedContentResultSetStub
439 ::impl_getCurrentContentIdentifierString( Any& rAny
440 , Reference< XContentAccess > xContentAccess )
441 throw ( RuntimeException )
443 rAny <<= xContentAccess->queryContentIdentifierString();
446 void SAL_CALL CachedContentResultSetStub
447 ::impl_getCurrentContentIdentifier( Any& rAny
448 , Reference< XContentAccess > xContentAccess )
449 throw ( RuntimeException )
451 rAny <<= xContentAccess->queryContentIdentifier();
454 void SAL_CALL CachedContentResultSetStub
455 ::impl_getCurrentContent( Any& rAny
456 , Reference< XContentAccess > xContentAccess )
457 throw ( RuntimeException )
459 rAny <<= xContentAccess->queryContent();
462 //virtual
463 FetchResult SAL_CALL CachedContentResultSetStub
464 ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
465 , sal_Int32 nRowCount, sal_Bool bDirection )
466 throw( com::sun::star::uno::RuntimeException, std::exception )
468 impl_init_xContentAccessOrigin();
469 FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin );
472 //virtual
473 FetchResult SAL_CALL CachedContentResultSetStub
474 ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
475 , sal_Int32 nRowCount, sal_Bool bDirection )
476 throw( com::sun::star::uno::RuntimeException, std::exception )
478 impl_init_xContentAccessOrigin();
479 FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin );
482 //virtual
483 FetchResult SAL_CALL CachedContentResultSetStub
484 ::fetchContents( sal_Int32 nRowStartPosition
485 , sal_Int32 nRowCount, sal_Bool bDirection )
486 throw( com::sun::star::uno::RuntimeException, std::exception )
488 impl_init_xContentAccessOrigin();
489 FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin );
494 // class CachedContentResultSetStubFactory
498 CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
499 const Reference< XMultiServiceFactory > & rSMgr )
501 m_xSMgr = rSMgr;
504 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
509 // CachedContentResultSetStubFactory XInterface methods.
510 void SAL_CALL CachedContentResultSetStubFactory::acquire()
511 throw()
513 OWeakObject::acquire();
516 void SAL_CALL CachedContentResultSetStubFactory::release()
517 throw()
519 OWeakObject::release();
522 css::uno::Any SAL_CALL CachedContentResultSetStubFactory::queryInterface( const css::uno::Type & rType )
523 throw( css::uno::RuntimeException, std::exception )
525 css::uno::Any aRet = cppu::queryInterface( rType,
526 (static_cast< XTypeProvider* >(this)),
527 (static_cast< XServiceInfo* >(this)),
528 (static_cast< XCachedContentResultSetStubFactory* >(this))
530 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
533 // CachedContentResultSetStubFactory XTypeProvider methods.
536 XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
537 XTypeProvider,
538 XServiceInfo,
539 XCachedContentResultSetStubFactory );
542 // CachedContentResultSetStubFactory XServiceInfo methods.
545 XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory,
546 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ),
547 OUString( CACHED_CRS_STUB_FACTORY_NAME ) );
550 // Service factory implementation.
553 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
556 // CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
559 //virtual
560 Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
561 ::createCachedContentResultSetStub(
562 const Reference< XResultSet > & xSource )
563 throw( RuntimeException, std::exception )
565 if( xSource.is() )
567 Reference< XResultSet > xRet;
568 xRet = new CachedContentResultSetStub( xSource );
569 return xRet;
571 return NULL;
575 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */