bump product version to 4.1.6.2
[LibreOffice.git] / ucb / source / cacher / cachedcontentresultsetstub.cxx
blob23b986353e525af39cc86161985ea5d011e0e6e2
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( sal_False )
39 , m_bNeedToPropagateFetchSize( sal_True )
40 , m_bFirstFetchSizePropagationDone( sal_False )
41 , m_nLastFetchSize( 1 )//this value is not important at all
42 , m_bLastFetchDirection( sal_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();
54 //--------------------------------------------------------------------------
55 // XInterface methods.
56 //--------------------------------------------------------------------------
57 XINTERFACE_COMMON_IMPL( CachedContentResultSetStub )
59 Any SAL_CALL CachedContentResultSetStub
60 ::queryInterface( const Type& rType )
61 throw ( RuntimeException )
63 //list all interfaces inclusive baseclasses of interfaces
65 Any aRet = ContentResultSetWrapper::queryInterface( rType );
66 if( aRet.hasValue() )
67 return aRet;
69 aRet = cppu::queryInterface( rType
70 , static_cast< XTypeProvider* >( this )
71 , static_cast< XServiceInfo* >( this )
72 , static_cast< XFetchProvider* >( this )
73 , static_cast< XFetchProviderForContentAccess* >( this )
76 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
79 //--------------------------------------------------------------------------
80 // own methods. ( inherited )
81 //--------------------------------------------------------------------------
83 //virtual
84 void SAL_CALL CachedContentResultSetStub
85 ::impl_propertyChange( const PropertyChangeEvent& rEvt )
86 throw( RuntimeException )
88 impl_EnsureNotDisposed();
90 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
91 //because it will ignore them anyway and we can save this remote calls
92 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
93 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
94 return;
96 PropertyChangeEvent aEvt( rEvt );
97 aEvt.Source = static_cast< XPropertySet * >( this );
98 aEvt.Further = sal_False;
100 impl_notifyPropertyChangeListeners( aEvt );
104 //virtual
105 void SAL_CALL CachedContentResultSetStub
106 ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
107 throw( PropertyVetoException,
108 RuntimeException )
110 impl_EnsureNotDisposed();
112 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
113 //because it will ignore them anyway and we can save this remote calls
114 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
115 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
116 return;
118 PropertyChangeEvent aEvt( rEvt );
119 aEvt.Source = static_cast< XPropertySet * >( this );
120 aEvt.Further = sal_False;
122 impl_notifyVetoableChangeListeners( aEvt );
125 //--------------------------------------------------------------------------
126 // XTypeProvider methods.
127 //--------------------------------------------------------------------------
129 XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
130 //list all interfaces exclusive baseclasses
131 Sequence< Type > SAL_CALL CachedContentResultSetStub
132 ::getTypes()
133 throw( RuntimeException )
135 static Sequence< Type >* pTypes = NULL;
136 if( !pTypes )
138 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
139 if( !pTypes )
141 pTypes = new Sequence< Type >(13);
142 (*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider );
143 (*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo );
144 (*pTypes)[2] = CPPU_TYPE_REF( XComponent );
145 (*pTypes)[3] = CPPU_TYPE_REF( XCloseable );
146 (*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier );
147 (*pTypes)[5] = CPPU_TYPE_REF( XPropertySet );
148 (*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener );
149 (*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener );
150 (*pTypes)[8] = CPPU_TYPE_REF( XResultSet );
151 (*pTypes)[9] = CPPU_TYPE_REF( XContentAccess );
152 (*pTypes)[10] = CPPU_TYPE_REF( XRow );
153 (*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider );
154 (*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess );
157 return *pTypes;
160 //--------------------------------------------------------------------------
161 // XServiceInfo methods.
162 //--------------------------------------------------------------------------
164 XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub,
165 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStub" ),
166 OUString( CACHED_CRS_STUB_SERVICE_NAME ) );
168 //-----------------------------------------------------------------
169 // XFetchProvider methods.
170 //-----------------------------------------------------------------
172 #define FETCH_XXX( impl_loadRow, loadInterface ) \
173 impl_EnsureNotDisposed(); \
174 if( !m_xResultSetOrigin.is() ) \
176 OSL_FAIL( "broadcaster was disposed already" ); \
177 throw RuntimeException(); \
179 impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \
180 FetchResult aRet; \
181 aRet.StartIndex = nRowStartPosition; \
182 aRet.Orientation = bDirection; \
183 aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \
184 sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \
185 if( impl_isForwardOnly() ) \
187 if( nOldOriginal_Pos != nRowStartPosition ) \
189 /*@todo*/ \
190 aRet.FetchError = FetchError::EXCEPTION; \
191 return aRet; \
193 if( nRowCount != 1 ) \
194 aRet.FetchError = FetchError::EXCEPTION; \
196 aRet.Rows.realloc( 1 ); \
198 try \
200 impl_loadRow( aRet.Rows[0], loadInterface ); \
202 catch( SQLException& ) \
204 aRet.Rows.realloc( 0 ); \
205 aRet.FetchError = FetchError::EXCEPTION; \
206 return aRet; \
208 return aRet; \
210 aRet.Rows.realloc( nRowCount ); \
211 sal_Bool bOldOriginal_AfterLast = sal_False; \
212 if( !nOldOriginal_Pos ) \
213 bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
214 sal_Int32 nN = 1; \
215 sal_Bool bValidNewPos = sal_False; \
216 try \
218 try \
220 /*if( nOldOriginal_Pos != nRowStartPosition )*/ \
221 bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
223 catch( SQLException& ) \
225 aRet.Rows.realloc( 0 ); \
226 aRet.FetchError = FetchError::EXCEPTION; \
227 return aRet; \
229 if( !bValidNewPos ) \
231 aRet.Rows.realloc( 0 ); \
232 aRet.FetchError = FetchError::EXCEPTION; \
234 /*restore old position*/ \
235 if( nOldOriginal_Pos ) \
236 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
237 else if( bOldOriginal_AfterLast ) \
238 m_xResultSetOrigin->afterLast(); \
239 else \
240 m_xResultSetOrigin->beforeFirst(); \
242 return aRet; \
244 for( ; nN <= nRowCount; ) \
246 impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
247 nN++; \
248 if( nN <= nRowCount ) \
250 if( bDirection ) \
252 if( !m_xResultSetOrigin->next() ) \
254 aRet.Rows.realloc( nN-1 ); \
255 aRet.FetchError = FetchError::ENDOFDATA; \
256 break; \
259 else \
261 if( !m_xResultSetOrigin->previous() ) \
263 aRet.Rows.realloc( nN-1 ); \
264 aRet.FetchError = FetchError::ENDOFDATA; \
265 break; \
271 catch( SQLException& ) \
273 aRet.Rows.realloc( nN-1 ); \
274 aRet.FetchError = FetchError::EXCEPTION; \
276 /*restore old position*/ \
277 if( nOldOriginal_Pos ) \
278 m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \
279 else if( bOldOriginal_AfterLast ) \
280 m_xResultSetOrigin->afterLast(); \
281 else \
282 m_xResultSetOrigin->beforeFirst(); \
283 return aRet;
285 FetchResult SAL_CALL CachedContentResultSetStub
286 ::fetch( sal_Int32 nRowStartPosition
287 , sal_Int32 nRowCount, sal_Bool bDirection )
288 throw( RuntimeException )
290 impl_init_xRowOrigin();
291 FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin );
294 sal_Int32 SAL_CALL CachedContentResultSetStub
295 ::impl_getColumnCount()
297 sal_Int32 nCount;
298 sal_Bool bCached;
300 osl::Guard< osl::Mutex > aGuard( m_aMutex );
301 nCount = m_nColumnCount;
302 bCached = m_bColumnCountCached;
304 if( !bCached )
308 Reference< XResultSetMetaData > xMetaData = getMetaData();
309 if( xMetaData.is() )
310 nCount = xMetaData->getColumnCount();
312 catch( SQLException& )
314 OSL_FAIL( "couldn't determine the column count" );
315 nCount = 0;
318 osl::Guard< osl::Mutex > aGuard( m_aMutex );
319 m_nColumnCount = nCount;
320 m_bColumnCountCached = sal_True;
321 return m_nColumnCount;
324 void SAL_CALL CachedContentResultSetStub
325 ::impl_getCurrentRowContent( Any& rRowContent
326 , Reference< XRow > xRow )
327 throw ( SQLException, RuntimeException )
329 sal_Int32 nCount = impl_getColumnCount();
331 Sequence< Any > aContent( nCount );
332 for( sal_Int32 nN = 1; nN <= nCount; nN++ )
334 aContent[nN-1] = xRow->getObject( nN, NULL );
337 rRowContent <<= aContent;
340 void SAL_CALL CachedContentResultSetStub
341 ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection )
342 throw ( RuntimeException )
344 //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets
346 //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
348 //if the underlying ResultSet has a property FetchSize and FetchDirection,
349 //we will set these properties, if the new given parameters are different from the last ones
351 if( !m_bNeedToPropagateFetchSize )
352 return;
354 sal_Bool bNeedAction;
355 sal_Int32 nLastSize;
356 sal_Bool bLastDirection;
357 sal_Bool bFirstPropagationDone;
359 osl::Guard< osl::Mutex > aGuard( m_aMutex );
360 bNeedAction = m_bNeedToPropagateFetchSize;
361 nLastSize = m_nLastFetchSize;
362 bLastDirection = m_bLastFetchDirection;
363 bFirstPropagationDone = m_bFirstFetchSizePropagationDone;
365 if( bNeedAction )
367 if( nLastSize == nFetchSize
368 && bLastDirection == bFetchDirection
369 && bFirstPropagationDone == sal_True )
370 return;
372 if(!bFirstPropagationDone)
374 //check whether the properties 'FetchSize' and 'FetchDirection' do exist
376 Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
377 sal_Bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
378 sal_Bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
380 if(!bHasSize || !bHasDirection)
382 osl::Guard< osl::Mutex > aGuard( m_aMutex );
383 m_bNeedToPropagateFetchSize = sal_False;
384 return;
388 sal_Bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone;
389 sal_Bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone;
392 osl::Guard< osl::Mutex > aGuard( m_aMutex );
393 m_bFirstFetchSizePropagationDone = sal_True;
394 m_nLastFetchSize = nFetchSize;
395 m_bLastFetchDirection = bFetchDirection;
398 if( bSetSize )
400 Any aValue;
401 aValue <<= nFetchSize;
404 setPropertyValue( m_aPropertyNameForFetchSize, aValue );
406 catch( com::sun::star::uno::Exception& ) {}
408 if( bSetDirection )
410 sal_Int32 nFetchDirection = FetchDirection::FORWARD;
411 if( !bFetchDirection )
412 nFetchDirection = FetchDirection::REVERSE;
413 Any aValue;
414 aValue <<= nFetchDirection;
417 setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
419 catch( com::sun::star::uno::Exception& ) {}
425 //-----------------------------------------------------------------
426 // XFetchProviderForContentAccess methods.
427 //-----------------------------------------------------------------
429 void SAL_CALL CachedContentResultSetStub
430 ::impl_getCurrentContentIdentifierString( Any& rAny
431 , Reference< XContentAccess > xContentAccess )
432 throw ( RuntimeException )
434 rAny <<= xContentAccess->queryContentIdentifierString();
437 void SAL_CALL CachedContentResultSetStub
438 ::impl_getCurrentContentIdentifier( Any& rAny
439 , Reference< XContentAccess > xContentAccess )
440 throw ( RuntimeException )
442 rAny <<= xContentAccess->queryContentIdentifier();
445 void SAL_CALL CachedContentResultSetStub
446 ::impl_getCurrentContent( Any& rAny
447 , Reference< XContentAccess > xContentAccess )
448 throw ( RuntimeException )
450 rAny <<= xContentAccess->queryContent();
453 //virtual
454 FetchResult SAL_CALL CachedContentResultSetStub
455 ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
456 , sal_Int32 nRowCount, sal_Bool bDirection )
457 throw( com::sun::star::uno::RuntimeException )
459 impl_init_xContentAccessOrigin();
460 FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin );
463 //virtual
464 FetchResult SAL_CALL CachedContentResultSetStub
465 ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
466 , sal_Int32 nRowCount, sal_Bool bDirection )
467 throw( com::sun::star::uno::RuntimeException )
469 impl_init_xContentAccessOrigin();
470 FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin );
473 //virtual
474 FetchResult SAL_CALL CachedContentResultSetStub
475 ::fetchContents( sal_Int32 nRowStartPosition
476 , sal_Int32 nRowCount, sal_Bool bDirection )
477 throw( com::sun::star::uno::RuntimeException )
479 impl_init_xContentAccessOrigin();
480 FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin );
483 //--------------------------------------------------------------------------
484 //--------------------------------------------------------------------------
485 // class CachedContentResultSetStubFactory
486 //--------------------------------------------------------------------------
487 //--------------------------------------------------------------------------
489 CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
490 const Reference< XMultiServiceFactory > & rSMgr )
492 m_xSMgr = rSMgr;
495 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
499 //--------------------------------------------------------------------------
500 // CachedContentResultSetStubFactory XInterface methods.
501 //--------------------------------------------------------------------------
503 XINTERFACE_IMPL_3( CachedContentResultSetStubFactory,
504 XTypeProvider,
505 XServiceInfo,
506 XCachedContentResultSetStubFactory );
508 //--------------------------------------------------------------------------
509 // CachedContentResultSetStubFactory XTypeProvider methods.
510 //--------------------------------------------------------------------------
512 XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
513 XTypeProvider,
514 XServiceInfo,
515 XCachedContentResultSetStubFactory );
517 //--------------------------------------------------------------------------
518 // CachedContentResultSetStubFactory XServiceInfo methods.
519 //--------------------------------------------------------------------------
521 XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory,
522 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ),
523 OUString( CACHED_CRS_STUB_FACTORY_NAME ) );
525 //--------------------------------------------------------------------------
526 // Service factory implementation.
527 //--------------------------------------------------------------------------
529 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
531 //--------------------------------------------------------------------------
532 // CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
533 //--------------------------------------------------------------------------
535 //virtual
536 Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
537 ::createCachedContentResultSetStub(
538 const Reference< XResultSet > & xSource )
539 throw( RuntimeException )
541 if( xSource.is() )
543 Reference< XResultSet > xRet;
544 xRet = new CachedContentResultSetStub( xSource );
545 return xRet;
547 return NULL;
551 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */