1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
;
35 CachedContentResultSetStub::CachedContentResultSetStub( Reference
< XResultSet
> xOrigin
)
36 : ContentResultSetWrapper( xOrigin
)
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") )
49 CachedContentResultSetStub::~CachedContentResultSetStub()
55 // XInterface methods.
56 void SAL_CALL
CachedContentResultSetStub::acquire()
59 OWeakObject::acquire();
62 void SAL_CALL
CachedContentResultSetStub::release()
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
);
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 )
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
)
105 PropertyChangeEvent
aEvt( rEvt
);
106 aEvt
.Source
= static_cast< XPropertySet
* >( this );
107 aEvt
.Further
= sal_False
;
109 impl_notifyPropertyChangeListeners( aEvt
);
114 void SAL_CALL CachedContentResultSetStub
115 ::impl_vetoableChange( const PropertyChangeEvent
& rEvt
)
116 throw( PropertyVetoException
,
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
)
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
142 throw( RuntimeException
, std::exception
)
144 static Sequence
< Type
>* pTypes
= NULL
;
147 osl::Guard
< osl::Mutex
> aGuard( osl::Mutex::getGlobalMutex() );
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
);
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 ); \
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 ) \
199 aRet.FetchError = FetchError::EXCEPTION; \
202 if( nRowCount != 1 ) \
203 aRet.FetchError = FetchError::EXCEPTION; \
205 aRet.Rows.realloc( 1 ); \
209 impl_loadRow( aRet.Rows[0], loadInterface ); \
211 catch( SQLException& ) \
213 aRet.Rows.realloc( 0 ); \
214 aRet.FetchError = FetchError::EXCEPTION; \
219 aRet.Rows.realloc( nRowCount ); \
220 bool bOldOriginal_AfterLast = false; \
221 if( !nOldOriginal_Pos ) \
222 bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \
224 bool bValidNewPos = false; \
229 /*if( nOldOriginal_Pos != nRowStartPosition )*/ \
230 bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \
232 catch( SQLException& ) \
234 aRet.Rows.realloc( 0 ); \
235 aRet.FetchError = FetchError::EXCEPTION; \
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(); \
249 m_xResultSetOrigin->beforeFirst(); \
253 for( ; nN <= nRowCount; ) \
255 impl_loadRow( aRet.Rows[nN-1], loadInterface ); \
257 if( nN <= nRowCount ) \
261 if( !m_xResultSetOrigin->next() ) \
263 aRet.Rows.realloc( nN-1 ); \
264 aRet.FetchError = FetchError::ENDOFDATA; \
270 if( !m_xResultSetOrigin->previous() ) \
272 aRet.Rows.realloc( nN-1 ); \
273 aRet.FetchError = FetchError::ENDOFDATA; \
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(); \
291 m_xResultSetOrigin->beforeFirst(); \
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()
309 osl::Guard
< osl::Mutex
> aGuard( m_aMutex
);
310 nCount
= m_nColumnCount
;
311 bCached
= m_bColumnCountCached
;
317 Reference
< XResultSetMetaData
> xMetaData
= getMetaData();
319 nCount
= xMetaData
->getColumnCount();
321 catch( SQLException
& )
323 OSL_FAIL( "couldn't determine the column count" );
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
)
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
;
376 if( nLastSize
== nFetchSize
377 && bLastDirection
== bFetchDirection
378 && bFirstPropagationDone
)
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;
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
;
410 aValue
<<= nFetchSize
;
413 setPropertyValue( m_aPropertyNameForFetchSize
, aValue
);
415 catch( com::sun::star::uno::Exception
& ) {}
419 sal_Int32 nFetchDirection
= FetchDirection::FORWARD
;
420 if( !bFetchDirection
)
421 nFetchDirection
= FetchDirection::REVERSE
;
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();
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
);
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
);
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
)
504 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
509 // CachedContentResultSetStubFactory XInterface methods.
510 void SAL_CALL
CachedContentResultSetStubFactory::acquire()
513 OWeakObject::acquire();
516 void SAL_CALL
CachedContentResultSetStubFactory::release()
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
,
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.
560 Reference
< XResultSet
> SAL_CALL CachedContentResultSetStubFactory
561 ::createCachedContentResultSetStub(
562 const Reference
< XResultSet
> & xSource
)
563 throw( RuntimeException
, std::exception
)
567 Reference
< XResultSet
> xRet
;
568 xRet
= new CachedContentResultSetStub( xSource
);
575 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */