lok: vcl: fix multiple floatwin removal case more robustly.
[LibreOffice.git] / ucb / source / cacher / cachedcontentresultsetstub.cxx
blobb9085f7ac32386a940730c5bcdfecfe9600e4a48
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/sdbc/SQLException.hpp>
24 #include <com/sun/star/ucb/FetchError.hpp>
25 #include <osl/diagnose.h>
26 #include <cppuhelper/queryinterface.hxx>
28 using namespace com::sun::star::beans;
29 using namespace com::sun::star::lang;
30 using namespace com::sun::star::sdbc;
31 using namespace com::sun::star::ucb;
32 using namespace com::sun::star::uno;
33 using namespace com::sun::star::util;
34 using namespace cppu;
37 CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > const & xOrigin )
38 : ContentResultSetWrapper( xOrigin )
39 , m_nColumnCount( 0 )
40 , m_bColumnCountCached( false )
41 , m_bNeedToPropagateFetchSize( true )
42 , m_bFirstFetchSizePropagationDone( false )
43 , m_nLastFetchSize( 1 )//this value is not important at all
44 , m_bLastFetchDirection( true )//this value is not important at all
45 , m_aPropertyNameForFetchSize( OUString("FetchSize") )
46 , m_aPropertyNameForFetchDirection( OUString("FetchDirection") )
48 impl_init();
51 CachedContentResultSetStub::~CachedContentResultSetStub()
53 impl_deinit();
57 // XInterface methods.
58 void SAL_CALL CachedContentResultSetStub::acquire()
59 throw()
61 OWeakObject::acquire();
64 void SAL_CALL CachedContentResultSetStub::release()
65 throw()
67 OWeakObject::release();
70 Any SAL_CALL CachedContentResultSetStub
71 ::queryInterface( const Type& rType )
73 //list all interfaces inclusive baseclasses of interfaces
75 Any aRet = ContentResultSetWrapper::queryInterface( rType );
76 if( aRet.hasValue() )
77 return aRet;
79 aRet = cppu::queryInterface( rType
80 , static_cast< XTypeProvider* >( this )
81 , static_cast< XServiceInfo* >( this )
82 , static_cast< XFetchProvider* >( this )
83 , static_cast< XFetchProviderForContentAccess* >( this )
86 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
90 // own methods. ( inherited )
93 //virtual
94 void CachedContentResultSetStub
95 ::impl_propertyChange( const PropertyChangeEvent& rEvt )
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 = false;
109 impl_notifyPropertyChangeListeners( aEvt );
113 //virtual
114 void CachedContentResultSetStub
115 ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
117 impl_EnsureNotDisposed();
119 //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet
120 //because it will ignore them anyway and we can save this remote calls
121 if( rEvt.PropertyName == m_aPropertyNameForFetchSize
122 || rEvt.PropertyName == m_aPropertyNameForFetchDirection )
123 return;
125 PropertyChangeEvent aEvt( rEvt );
126 aEvt.Source = static_cast< XPropertySet * >( this );
127 aEvt.Further = false;
129 impl_notifyVetoableChangeListeners( aEvt );
133 // XTypeProvider methods.
136 XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub )
137 //list all interfaces exclusive baseclasses
138 Sequence< Type > SAL_CALL CachedContentResultSetStub
139 ::getTypes()
141 static Sequence<Type> ourTypes(
142 { CPPU_TYPE_REF( XTypeProvider ),
143 CPPU_TYPE_REF( XServiceInfo ),
144 CPPU_TYPE_REF( XComponent ),
145 CPPU_TYPE_REF( XCloseable ),
146 CPPU_TYPE_REF( XResultSetMetaDataSupplier ),
147 CPPU_TYPE_REF( XPropertySet ),
148 CPPU_TYPE_REF( XPropertyChangeListener ),
149 CPPU_TYPE_REF( XVetoableChangeListener ),
150 CPPU_TYPE_REF( XResultSet ),
151 CPPU_TYPE_REF( XContentAccess ),
152 CPPU_TYPE_REF( XRow ),
153 CPPU_TYPE_REF( XFetchProvider ),
154 CPPU_TYPE_REF( XFetchProviderForContentAccess ) } );
156 return ourTypes;
160 // XServiceInfo methods.
162 OUString SAL_CALL CachedContentResultSetStub::getImplementationName()
164 return OUString( "com.sun.star.comp.ucb.CachedContentResultSetStub" );
167 sal_Bool SAL_CALL CachedContentResultSetStub::supportsService( const OUString& ServiceName )
169 return cppu::supportsService( this, ServiceName );
172 css::uno::Sequence< OUString > SAL_CALL CachedContentResultSetStub::getSupportedServiceNames()
174 return { CACHED_CRS_STUB_SERVICE_NAME };
179 // XFetchProvider methods.
182 FetchResult CachedContentResultSetStub::impl_fetchHelper(
183 sal_Int32 nRowStartPosition, sal_Int32 nRowCount, bool bDirection,
184 std::function<void( css::uno::Any& rRowContent)> impl_loadRow)
186 impl_EnsureNotDisposed();
187 if( !m_xResultSetOrigin.is() )
189 OSL_FAIL( "broadcaster was disposed already" );
190 throw RuntimeException();
192 impl_propagateFetchSizeAndDirection( nRowCount, bDirection );
193 FetchResult aRet;
194 aRet.StartIndex = nRowStartPosition;
195 aRet.Orientation = bDirection;
196 aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/
197 sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow();
198 if( impl_isForwardOnly() )
200 if( nOldOriginal_Pos != nRowStartPosition )
202 /*@todo*/
203 aRet.FetchError = FetchError::EXCEPTION;
204 return aRet;
206 if( nRowCount != 1 )
207 aRet.FetchError = FetchError::EXCEPTION;
209 aRet.Rows.realloc( 1 );
213 impl_loadRow( aRet.Rows[0] );
215 catch( SQLException& )
217 aRet.Rows.realloc( 0 );
218 aRet.FetchError = FetchError::EXCEPTION;
219 return aRet;
221 return aRet;
223 aRet.Rows.realloc( nRowCount );
224 bool bOldOriginal_AfterLast = false;
225 if( !nOldOriginal_Pos )
226 bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast();
227 sal_Int32 nN = 1;
228 bool bValidNewPos = false;
233 /*if( nOldOriginal_Pos != nRowStartPosition )*/
234 bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition );
236 catch( SQLException& )
238 aRet.Rows.realloc( 0 );
239 aRet.FetchError = FetchError::EXCEPTION;
240 return aRet;
242 if( !bValidNewPos )
244 aRet.Rows.realloc( 0 );
245 aRet.FetchError = FetchError::EXCEPTION;
247 /*restore old position*/
248 if( nOldOriginal_Pos )
249 m_xResultSetOrigin->absolute( nOldOriginal_Pos );
250 else if( bOldOriginal_AfterLast )
251 m_xResultSetOrigin->afterLast();
252 else
253 m_xResultSetOrigin->beforeFirst();
255 return aRet;
257 for( ; nN <= nRowCount; )
259 impl_loadRow( aRet.Rows[nN-1] );
260 nN++;
261 if( nN <= nRowCount )
263 if( bDirection )
265 if( !m_xResultSetOrigin->next() )
267 aRet.Rows.realloc( nN-1 );
268 aRet.FetchError = FetchError::ENDOFDATA;
269 break;
272 else
274 if( !m_xResultSetOrigin->previous() )
276 aRet.Rows.realloc( nN-1 );
277 aRet.FetchError = FetchError::ENDOFDATA;
278 break;
284 catch( SQLException& )
286 aRet.Rows.realloc( nN-1 );
287 aRet.FetchError = FetchError::EXCEPTION;
289 /*restore old position*/
290 if( nOldOriginal_Pos )
291 m_xResultSetOrigin->absolute( nOldOriginal_Pos );
292 else if( bOldOriginal_AfterLast )
293 m_xResultSetOrigin->afterLast();
294 else
295 m_xResultSetOrigin->beforeFirst();
296 return aRet;
299 FetchResult SAL_CALL CachedContentResultSetStub
300 ::fetch( sal_Int32 nRowStartPosition
301 , sal_Int32 nRowCount, sal_Bool bDirection )
303 impl_init_xRowOrigin();
304 return impl_fetchHelper( nRowStartPosition, nRowCount, bDirection,
305 [&](css::uno::Any& rRowContent)
306 { return impl_getCurrentRowContent(rRowContent, m_xRowOrigin); });
309 sal_Int32 CachedContentResultSetStub
310 ::impl_getColumnCount()
312 sal_Int32 nCount;
313 bool bCached;
315 osl::Guard< osl::Mutex > aGuard( m_aMutex );
316 nCount = m_nColumnCount;
317 bCached = m_bColumnCountCached;
319 if( !bCached )
323 Reference< XResultSetMetaData > xMetaData = getMetaData();
324 if( xMetaData.is() )
325 nCount = xMetaData->getColumnCount();
327 catch( SQLException& )
329 OSL_FAIL( "couldn't determine the column count" );
330 nCount = 0;
333 osl::Guard< osl::Mutex > aGuard( m_aMutex );
334 m_nColumnCount = nCount;
335 m_bColumnCountCached = true;
336 return m_nColumnCount;
339 void CachedContentResultSetStub
340 ::impl_getCurrentRowContent( Any& rRowContent
341 , const Reference< XRow >& xRow )
343 sal_Int32 nCount = impl_getColumnCount();
345 Sequence< Any > aContent( nCount );
346 for( sal_Int32 nN = 1; nN <= nCount; nN++ )
348 aContent[nN-1] = xRow->getObject( nN, nullptr );
351 rRowContent <<= aContent;
354 void CachedContentResultSetStub
355 ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, bool bFetchDirection )
357 //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResultSets
359 //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls
361 //if the underlying ResultSet has a property FetchSize and FetchDirection,
362 //we will set these properties, if the new given parameters are different from the last ones
364 if( !m_bNeedToPropagateFetchSize )
365 return;
367 bool bNeedAction;
368 sal_Int32 nLastSize;
369 bool bLastDirection;
370 bool bFirstPropagationDone;
372 osl::Guard< osl::Mutex > aGuard( m_aMutex );
373 bNeedAction = m_bNeedToPropagateFetchSize;
374 nLastSize = m_nLastFetchSize;
375 bLastDirection = m_bLastFetchDirection;
376 bFirstPropagationDone = m_bFirstFetchSizePropagationDone;
378 if( bNeedAction )
380 if( nLastSize == nFetchSize
381 && bLastDirection == bFetchDirection
382 && bFirstPropagationDone )
383 return;
385 if(!bFirstPropagationDone)
387 //check whether the properties 'FetchSize' and 'FetchDirection' do exist
389 Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo();
390 bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize );
391 bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection );
393 if(!bHasSize || !bHasDirection)
395 osl::Guard< osl::Mutex > aGuard( m_aMutex );
396 m_bNeedToPropagateFetchSize = false;
397 return;
401 bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone;
402 bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone;
405 osl::Guard< osl::Mutex > aGuard( m_aMutex );
406 m_bFirstFetchSizePropagationDone = true;
407 m_nLastFetchSize = nFetchSize;
408 m_bLastFetchDirection = bFetchDirection;
411 if( bSetSize )
413 Any aValue;
414 aValue <<= nFetchSize;
417 setPropertyValue( m_aPropertyNameForFetchSize, aValue );
419 catch( css::uno::Exception& ) {}
421 if( bSetDirection )
423 sal_Int32 nFetchDirection = FetchDirection::FORWARD;
424 if( !bFetchDirection )
425 nFetchDirection = FetchDirection::REVERSE;
426 Any aValue;
427 aValue <<= nFetchDirection;
430 setPropertyValue( m_aPropertyNameForFetchDirection, aValue );
432 catch( css::uno::Exception& ) {}
439 // XFetchProviderForContentAccess methods.
442 void CachedContentResultSetStub
443 ::impl_getCurrentContentIdentifierString( Any& rAny
444 , const Reference< XContentAccess >& xContentAccess )
446 rAny <<= xContentAccess->queryContentIdentifierString();
449 void CachedContentResultSetStub
450 ::impl_getCurrentContentIdentifier( Any& rAny
451 , const Reference< XContentAccess >& xContentAccess )
453 rAny <<= xContentAccess->queryContentIdentifier();
456 void CachedContentResultSetStub
457 ::impl_getCurrentContent( Any& rAny
458 , const Reference< XContentAccess >& xContentAccess )
460 rAny <<= xContentAccess->queryContent();
463 //virtual
464 FetchResult SAL_CALL CachedContentResultSetStub
465 ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition
466 , sal_Int32 nRowCount, sal_Bool bDirection )
468 impl_init_xContentAccessOrigin();
469 return impl_fetchHelper( nRowStartPosition, nRowCount, bDirection,
470 [&](css::uno::Any& rRowContent)
471 { return impl_getCurrentContentIdentifierString(rRowContent, m_xContentAccessOrigin); });
474 //virtual
475 FetchResult SAL_CALL CachedContentResultSetStub
476 ::fetchContentIdentifiers( sal_Int32 nRowStartPosition
477 , sal_Int32 nRowCount, sal_Bool bDirection )
479 impl_init_xContentAccessOrigin();
480 return impl_fetchHelper( nRowStartPosition, nRowCount, bDirection,
481 [&](css::uno::Any& rRowContent)
482 { return impl_getCurrentContentIdentifier(rRowContent, m_xContentAccessOrigin); });
485 //virtual
486 FetchResult SAL_CALL CachedContentResultSetStub
487 ::fetchContents( sal_Int32 nRowStartPosition
488 , sal_Int32 nRowCount, sal_Bool bDirection )
490 impl_init_xContentAccessOrigin();
491 return impl_fetchHelper( nRowStartPosition, nRowCount, bDirection,
492 [&](css::uno::Any& rRowContent)
493 { return impl_getCurrentContent(rRowContent, m_xContentAccessOrigin); });
497 // class CachedContentResultSetStubFactory
500 CachedContentResultSetStubFactory::CachedContentResultSetStubFactory(
501 const Reference< XMultiServiceFactory > & rSMgr )
503 m_xSMgr = rSMgr;
506 CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory()
511 // CachedContentResultSetStubFactory XInterface methods.
512 void SAL_CALL CachedContentResultSetStubFactory::acquire()
513 throw()
515 OWeakObject::acquire();
518 void SAL_CALL CachedContentResultSetStubFactory::release()
519 throw()
521 OWeakObject::release();
524 css::uno::Any SAL_CALL CachedContentResultSetStubFactory::queryInterface( const css::uno::Type & rType )
526 css::uno::Any aRet = cppu::queryInterface( rType,
527 static_cast< XTypeProvider* >(this),
528 static_cast< XServiceInfo* >(this),
529 static_cast< XCachedContentResultSetStubFactory* >(this)
531 return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
534 // CachedContentResultSetStubFactory XTypeProvider methods.
537 XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory,
538 XTypeProvider,
539 XServiceInfo,
540 XCachedContentResultSetStubFactory );
543 // CachedContentResultSetStubFactory XServiceInfo methods.
545 XSERVICEINFO_COMMOM_IMPL( CachedContentResultSetStubFactory,
546 OUString( "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ) )
547 /// @throws css::uno::Exception
548 static css::uno::Reference< css::uno::XInterface >
549 CachedContentResultSetStubFactory_CreateInstance( const css::uno::Reference< css::lang::XMultiServiceFactory> & rSMgr )
551 css::lang::XServiceInfo* pX =
552 static_cast<css::lang::XServiceInfo*>(new CachedContentResultSetStubFactory( rSMgr ));
553 return css::uno::Reference< css::uno::XInterface >::query( pX );
555 css::uno::Sequence< OUString >
556 CachedContentResultSetStubFactory::getSupportedServiceNames_Static()
558 return { CACHED_CRS_STUB_FACTORY_NAME };
561 // Service factory implementation.
564 ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory );
567 // CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods.
570 //virtual
571 Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory
572 ::createCachedContentResultSetStub(
573 const Reference< XResultSet > & xSource )
575 if( xSource.is() )
577 Reference< XResultSet > xRet;
578 xRet = new CachedContentResultSetStub( xSource );
579 return xRet;
581 return nullptr;
585 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */