Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <cachedcontentresultset.hxx>
31 : : #include <com/sun/star/sdbc/FetchDirection.hpp>
32 : : #include <com/sun/star/ucb/FetchError.hpp>
33 : : #include <com/sun/star/ucb/ResultSetException.hpp>
34 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
35 : : #include <com/sun/star/script/XTypeConverter.hpp>
36 : : #include <com/sun/star/sdbc/ResultSetType.hpp>
37 : : #include <rtl/ustring.hxx>
38 : : #include <osl/diagnose.h>
39 : :
40 : : using namespace com::sun::star::beans;
41 : : using namespace com::sun::star::lang;
42 : : using namespace com::sun::star::script;
43 : : using namespace com::sun::star::sdbc;
44 : : using namespace com::sun::star::ucb;
45 : : using namespace com::sun::star::uno;
46 : : using namespace com::sun::star::util;
47 : : using namespace cppu;
48 : :
49 : : using ::rtl::OUString;
50 : :
51 : : #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256
52 : : #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD
53 : :
54 : : //--------------------------------------------------------------------------
55 : : //--------------------------------------------------------------------------
56 : : //define for getXXX methods of interface XRow
57 : : //--------------------------------------------------------------------------
58 : : //--------------------------------------------------------------------------
59 : :
60 : : //if you change this macro please pay attention to
61 : : //function ::getObject, where this is similar implemented
62 : :
63 : : #define XROW_GETXXX( getXXX, Type ) \
64 : : impl_EnsureNotDisposed(); \
65 : : ReacquireableGuard aGuard( m_aMutex ); \
66 : : sal_Int32 nRow = m_nRow; \
67 : : sal_Int32 nFetchSize = m_nFetchSize; \
68 : : sal_Int32 nFetchDirection = m_nFetchDirection; \
69 : : if( !m_aCache.hasRow( nRow ) ) \
70 : : { \
71 : : if( !m_aCache.hasCausedException( nRow ) ) \
72 : : { \
73 : : if( !m_xFetchProvider.is() ) \
74 : : { \
75 : : OSL_FAIL( "broadcaster was disposed already" ); \
76 : : throw SQLException(); \
77 : : } \
78 : : aGuard.clear(); \
79 : : if( impl_isForwardOnly() ) \
80 : : applyPositionToOrigin( nRow ); \
81 : : \
82 : : impl_fetchData( nRow, nFetchSize, nFetchDirection ); \
83 : : } \
84 : : aGuard.reacquire(); \
85 : : if( !m_aCache.hasRow( nRow ) ) \
86 : : { \
87 : : m_bLastReadWasFromCache = sal_False; \
88 : : aGuard.clear(); \
89 : : applyPositionToOrigin( nRow ); \
90 : : impl_init_xRowOrigin(); \
91 : : return m_xRowOrigin->getXXX( columnIndex ); \
92 : : } \
93 : : } \
94 : : const Any& rValue = m_aCache.getAny( nRow, columnIndex );\
95 : : Type aRet = Type(); \
96 : : m_bLastReadWasFromCache = sal_True; \
97 : : m_bLastCachedReadWasNull = !( rValue >>= aRet ); \
98 : : /* Last chance. Try type converter service... */ \
99 : : if ( m_bLastCachedReadWasNull && rValue.hasValue() ) \
100 : : { \
101 : : Reference< XTypeConverter > xConverter \
102 : : = getTypeConverter(); \
103 : : if ( xConverter.is() ) \
104 : : { \
105 : : try \
106 : : { \
107 : : Any aConvAny = xConverter->convertTo( \
108 : : rValue, \
109 : : getCppuType( static_cast< \
110 : : const Type * >( 0 ) ) ); \
111 : : m_bLastCachedReadWasNull = !( aConvAny >>= aRet ); \
112 : : } \
113 : : catch (const IllegalArgumentException&) \
114 : : { \
115 : : } \
116 : : catch (const CannotConvertException&) \
117 : : { \
118 : : } \
119 : : } \
120 : : } \
121 : : return aRet;
122 : :
123 : : //--------------------------------------------------------------------------
124 : : //--------------------------------------------------------------------------
125 : : // CCRS_Cache methoeds.
126 : : //--------------------------------------------------------------------------
127 : : //--------------------------------------------------------------------------
128 : :
129 : 0 : CachedContentResultSet::CCRS_Cache::CCRS_Cache(
130 : : const Reference< XContentIdentifierMapping > & xMapping )
131 : : : m_pResult( NULL )
132 : : , m_xContentIdentifierMapping( xMapping )
133 : 0 : , m_pMappedReminder( NULL )
134 : : {
135 : 0 : }
136 : :
137 : 0 : CachedContentResultSet::CCRS_Cache::~CCRS_Cache()
138 : : {
139 : 0 : delete m_pResult;
140 : 0 : }
141 : :
142 : 0 : void SAL_CALL CachedContentResultSet::CCRS_Cache
143 : : ::clear()
144 : : {
145 : 0 : if( m_pResult )
146 : : {
147 : 0 : delete m_pResult;
148 : 0 : m_pResult = NULL;
149 : : }
150 : 0 : clearMappedReminder();
151 : 0 : }
152 : :
153 : 0 : void SAL_CALL CachedContentResultSet::CCRS_Cache
154 : : ::loadData( const FetchResult& rResult )
155 : : {
156 : 0 : clear();
157 : 0 : m_pResult = new FetchResult( rResult );
158 : 0 : }
159 : :
160 : 0 : sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
161 : : ::hasRow( sal_Int32 row )
162 : : {
163 : 0 : if( !m_pResult )
164 : 0 : return sal_False;
165 : 0 : long nStart = m_pResult->StartIndex;
166 : 0 : long nEnd = nStart;
167 : 0 : if( m_pResult->Orientation )
168 : 0 : nEnd += m_pResult->Rows.getLength() - 1;
169 : : else
170 : 0 : nStart -= m_pResult->Rows.getLength() + 1;
171 : :
172 : 0 : return nStart <= row && row <= nEnd;
173 : : }
174 : :
175 : 0 : sal_Int32 SAL_CALL CachedContentResultSet::CCRS_Cache
176 : : ::getMaxRow()
177 : : {
178 : 0 : if( !m_pResult )
179 : 0 : return 0;
180 : 0 : long nEnd = m_pResult->StartIndex;
181 : 0 : if( m_pResult->Orientation )
182 : 0 : return nEnd += m_pResult->Rows.getLength() - 1;
183 : : else
184 : 0 : return nEnd;
185 : : }
186 : :
187 : 0 : sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
188 : : ::hasKnownLast()
189 : : {
190 : 0 : if( !m_pResult )
191 : 0 : return sal_False;
192 : :
193 : 0 : if( ( m_pResult->FetchError & FetchError::ENDOFDATA )
194 : : && m_pResult->Orientation
195 : 0 : && m_pResult->Rows.getLength() )
196 : 0 : return sal_True;
197 : :
198 : 0 : return sal_False;
199 : : }
200 : :
201 : 0 : sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
202 : : ::hasCausedException( sal_Int32 nRow )
203 : : {
204 : 0 : if( !m_pResult )
205 : 0 : return sal_False;
206 : 0 : if( !( m_pResult->FetchError & FetchError::EXCEPTION ) )
207 : 0 : return sal_False;
208 : :
209 : 0 : long nEnd = m_pResult->StartIndex;
210 : 0 : if( m_pResult->Orientation )
211 : 0 : nEnd += m_pResult->Rows.getLength();
212 : :
213 : 0 : return nRow == nEnd+1;
214 : : }
215 : :
216 : 0 : Any& SAL_CALL CachedContentResultSet::CCRS_Cache
217 : : ::getRowAny( sal_Int32 nRow )
218 : : throw( SQLException,
219 : : RuntimeException )
220 : : {
221 : 0 : if( !nRow )
222 : 0 : throw SQLException();
223 : 0 : if( !m_pResult )
224 : 0 : throw SQLException();
225 : 0 : if( !hasRow( nRow ) )
226 : 0 : throw SQLException();
227 : :
228 : 0 : long nDiff = nRow - m_pResult->StartIndex;
229 : 0 : if( nDiff < 0 )
230 : 0 : nDiff *= -1;
231 : :
232 : 0 : return (m_pResult->Rows)[nDiff];
233 : : }
234 : :
235 : 0 : void SAL_CALL CachedContentResultSet::CCRS_Cache
236 : : ::remindMapped( sal_Int32 nRow )
237 : : {
238 : : //remind that this row was mapped
239 : 0 : if( !m_pResult )
240 : 0 : return;
241 : 0 : long nDiff = nRow - m_pResult->StartIndex;
242 : 0 : if( nDiff < 0 )
243 : 0 : nDiff *= -1;
244 : 0 : Sequence< sal_Bool >* pMappedReminder = getMappedReminder();
245 : 0 : if( nDiff < pMappedReminder->getLength() )
246 : 0 : (*pMappedReminder)[nDiff] = sal_True;
247 : : }
248 : :
249 : 0 : sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache
250 : : ::isRowMapped( sal_Int32 nRow )
251 : : {
252 : 0 : if( !m_pMappedReminder || !m_pResult )
253 : 0 : return sal_False;
254 : 0 : long nDiff = nRow - m_pResult->StartIndex;
255 : 0 : if( nDiff < 0 )
256 : 0 : nDiff *= -1;
257 : 0 : if( nDiff < m_pMappedReminder->getLength() )
258 : 0 : return (*m_pMappedReminder)[nDiff];
259 : 0 : return sal_False;
260 : : }
261 : :
262 : 0 : void SAL_CALL CachedContentResultSet::CCRS_Cache
263 : : ::clearMappedReminder()
264 : : {
265 : 0 : delete m_pMappedReminder;
266 : 0 : m_pMappedReminder = NULL;
267 : 0 : }
268 : :
269 : 0 : Sequence< sal_Bool >* SAL_CALL CachedContentResultSet::CCRS_Cache
270 : : ::getMappedReminder()
271 : : {
272 : 0 : if( !m_pMappedReminder )
273 : : {
274 : 0 : sal_Int32 nCount = m_pResult->Rows.getLength();
275 : 0 : m_pMappedReminder = new Sequence< sal_Bool >( nCount );
276 : 0 : for( ;nCount; nCount-- )
277 : 0 : (*m_pMappedReminder)[nCount] = sal_False;
278 : : }
279 : 0 : return m_pMappedReminder;
280 : : }
281 : :
282 : 0 : const Any& SAL_CALL CachedContentResultSet::CCRS_Cache
283 : : ::getAny( sal_Int32 nRow, sal_Int32 nColumnIndex )
284 : : throw( SQLException,
285 : : RuntimeException )
286 : : {
287 : 0 : if( !nColumnIndex )
288 : 0 : throw SQLException();
289 : 0 : if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
290 : : {
291 : 0 : Any& rRow = getRowAny( nRow );
292 : 0 : Sequence< Any > aValue;
293 : 0 : rRow >>= aValue;
294 : 0 : if( m_xContentIdentifierMapping->mapRow( aValue ) )
295 : : {
296 : 0 : rRow <<= aValue;
297 : 0 : remindMapped( nRow );
298 : : }
299 : : else
300 : 0 : m_xContentIdentifierMapping.clear();
301 : : }
302 : : const Sequence< Any >& rRow =
303 : : (* reinterpret_cast< const Sequence< Any > * >
304 : 0 : (getRowAny( nRow ).getValue() ));
305 : :
306 : 0 : if( nColumnIndex > rRow.getLength() )
307 : 0 : throw SQLException();
308 : 0 : return rRow[nColumnIndex-1];
309 : : }
310 : :
311 : 0 : const OUString& SAL_CALL CachedContentResultSet::CCRS_Cache
312 : : ::getContentIdentifierString( sal_Int32 nRow )
313 : : throw( com::sun::star::uno::RuntimeException )
314 : : {
315 : : try
316 : : {
317 : 0 : if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
318 : : {
319 : 0 : Any& rRow = getRowAny( nRow );
320 : 0 : OUString aValue;
321 : 0 : rRow >>= aValue;
322 : 0 : rRow <<= m_xContentIdentifierMapping->mapContentIdentifierString( aValue );
323 : 0 : remindMapped( nRow );
324 : : }
325 : : return (* reinterpret_cast< const OUString * >
326 : 0 : (getRowAny( nRow ).getValue() ));
327 : : }
328 : 0 : catch(const SQLException&)
329 : : {
330 : 0 : throw RuntimeException();
331 : : }
332 : : }
333 : :
334 : 0 : const Reference< XContentIdentifier >& SAL_CALL CachedContentResultSet::CCRS_Cache
335 : : ::getContentIdentifier( sal_Int32 nRow )
336 : : throw( com::sun::star::uno::RuntimeException )
337 : : {
338 : : try
339 : : {
340 : 0 : if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
341 : : {
342 : 0 : Any& rRow = getRowAny( nRow );
343 : 0 : Reference< XContentIdentifier > aValue;
344 : 0 : rRow >>= aValue;
345 : 0 : rRow <<= m_xContentIdentifierMapping->mapContentIdentifier( aValue );
346 : 0 : remindMapped( nRow );
347 : : }
348 : : return (* reinterpret_cast< const Reference< XContentIdentifier > * >
349 : 0 : (getRowAny( nRow ).getValue() ));
350 : : }
351 : 0 : catch(const SQLException&)
352 : : {
353 : 0 : throw RuntimeException();
354 : : }
355 : : }
356 : :
357 : 0 : const Reference< XContent >& SAL_CALL CachedContentResultSet::CCRS_Cache
358 : : ::getContent( sal_Int32 nRow )
359 : : throw( com::sun::star::uno::RuntimeException )
360 : : {
361 : : try
362 : : {
363 : 0 : if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) )
364 : : {
365 : 0 : Any& rRow = getRowAny( nRow );
366 : 0 : Reference< XContent > aValue;
367 : 0 : rRow >>= aValue;
368 : 0 : rRow <<= m_xContentIdentifierMapping->mapContent( aValue );
369 : 0 : remindMapped( nRow );
370 : : }
371 : : return (* reinterpret_cast< const Reference< XContent > * >
372 : 0 : (getRowAny( nRow ).getValue() ));
373 : : }
374 : 0 : catch (const SQLException&)
375 : : {
376 : 0 : throw RuntimeException();
377 : : }
378 : : }
379 : :
380 : : //--------------------------------------------------------------------------
381 : : //--------------------------------------------------------------------------
382 : : // class CCRS_PropertySetInfo
383 : : //--------------------------------------------------------------------------
384 : : //--------------------------------------------------------------------------
385 : :
386 : : class CCRS_PropertySetInfo :
387 : : public cppu::OWeakObject,
388 : : public com::sun::star::lang::XTypeProvider,
389 : : public com::sun::star::beans::XPropertySetInfo
390 : : {
391 : : friend class CachedContentResultSet;
392 : :
393 : : //my Properties
394 : : Sequence< com::sun::star::beans::Property >*
395 : : m_pProperties;
396 : :
397 : : //some helping variables ( names for my special properties )
398 : : static OUString m_aPropertyNameForCount;
399 : : static OUString m_aPropertyNameForFinalCount;
400 : : static OUString m_aPropertyNameForFetchSize;
401 : : static OUString m_aPropertyNameForFetchDirection;
402 : :
403 : : long m_nFetchSizePropertyHandle;
404 : : long m_nFetchDirectionPropertyHandle;
405 : :
406 : : private:
407 : : sal_Int32 SAL_CALL
408 : : impl_getRemainedHandle() const;
409 : :
410 : : sal_Bool SAL_CALL
411 : : impl_queryProperty(
412 : : const OUString& rName
413 : : , com::sun::star::beans::Property& rProp ) const;
414 : : sal_Int32 SAL_CALL
415 : : impl_getPos( const OUString& rName ) const;
416 : :
417 : : static sal_Bool SAL_CALL
418 : : impl_isMyPropertyName( const OUString& rName );
419 : :
420 : : public:
421 : : CCRS_PropertySetInfo( Reference<
422 : : XPropertySetInfo > xPropertySetInfoOrigin );
423 : :
424 : : virtual ~CCRS_PropertySetInfo();
425 : :
426 : : // XInterface
427 : : XINTERFACE_DECL()
428 : :
429 : : // XTypeProvider
430 : : XTYPEPROVIDER_DECL()
431 : :
432 : : // XPropertySetInfo
433 : : virtual Sequence< com::sun::star::beans::Property > SAL_CALL
434 : : getProperties()
435 : : throw( RuntimeException );
436 : :
437 : : virtual com::sun::star::beans::Property SAL_CALL
438 : : getPropertyByName( const OUString& aName )
439 : : throw( com::sun::star::beans::UnknownPropertyException, RuntimeException );
440 : :
441 : : virtual sal_Bool SAL_CALL
442 : : hasPropertyByName( const OUString& Name )
443 : : throw( RuntimeException );
444 : : };
445 : :
446 : 0 : OUString CCRS_PropertySetInfo::m_aPropertyNameForCount( "RowCount" );
447 : 0 : OUString CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( "IsRowCountFinal" );
448 : 0 : OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( "FetchSize" );
449 : 0 : OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( "FetchDirection" );
450 : :
451 : 0 : CCRS_PropertySetInfo::CCRS_PropertySetInfo(
452 : : Reference< XPropertySetInfo > xInfo )
453 : : : m_pProperties( NULL )
454 : : , m_nFetchSizePropertyHandle( -1 )
455 : 0 : , m_nFetchDirectionPropertyHandle( -1 )
456 : : {
457 : : //initialize list of properties:
458 : :
459 : : // it is required, that the received xInfo contains the two
460 : : // properties with names 'm_aPropertyNameForCount' and
461 : : // 'm_aPropertyNameForFinalCount'
462 : :
463 : 0 : if( xInfo.is() )
464 : : {
465 : 0 : Sequence<Property> aProps = xInfo->getProperties();
466 : 0 : m_pProperties = new Sequence<Property> ( aProps );
467 : : }
468 : : else
469 : : {
470 : : OSL_FAIL( "The received XPropertySetInfo doesn't contain required properties" );
471 : 0 : m_pProperties = new Sequence<Property>;
472 : : }
473 : :
474 : : //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice:
475 : 0 : sal_Int32 nFetchSize = impl_getPos( m_aPropertyNameForFetchSize );
476 : 0 : sal_Int32 nFetchDirection = impl_getPos( m_aPropertyNameForFetchDirection );
477 : 0 : sal_Int32 nDeleted = 0;
478 : 0 : if( nFetchSize != -1 )
479 : 0 : nDeleted++;
480 : 0 : if( nFetchDirection != -1 )
481 : 0 : nDeleted++;
482 : :
483 : 0 : Sequence< Property >* pOrigProps = new Sequence<Property> ( *m_pProperties );
484 : 0 : sal_Int32 nOrigProps = pOrigProps->getLength();
485 : :
486 : 0 : m_pProperties->realloc( nOrigProps + 2 - nDeleted );//note that nDeleted is <= 2
487 : 0 : for( sal_Int32 n = 0, m = 0; n < nOrigProps; n++, m++ )
488 : : {
489 : 0 : if( n == nFetchSize || n == nFetchDirection )
490 : 0 : m--;
491 : : else
492 : 0 : (*m_pProperties)[ m ] = (*pOrigProps)[ n ];
493 : : }
494 : : {
495 : 0 : Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted ];
496 : 0 : rMyProp.Name = m_aPropertyNameForFetchSize;
497 : 0 : rMyProp.Type = getCppuType( static_cast< const sal_Int32 * >( 0 ) );
498 : 0 : rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;
499 : :
500 : 0 : if( nFetchSize != -1 )
501 : 0 : m_nFetchSizePropertyHandle = (*pOrigProps)[nFetchSize].Handle;
502 : : else
503 : 0 : m_nFetchSizePropertyHandle = impl_getRemainedHandle();
504 : :
505 : 0 : rMyProp.Handle = m_nFetchSizePropertyHandle;
506 : :
507 : : }
508 : : {
509 : 0 : Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted + 1 ];
510 : 0 : rMyProp.Name = m_aPropertyNameForFetchDirection;
511 : 0 : rMyProp.Type = getCppuType( static_cast< const sal_Bool * >( 0 ) );
512 : 0 : rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT;
513 : :
514 : 0 : if( nFetchSize != -1 )
515 : 0 : m_nFetchDirectionPropertyHandle = (*pOrigProps)[nFetchDirection].Handle;
516 : : else
517 : 0 : m_nFetchDirectionPropertyHandle = impl_getRemainedHandle();
518 : :
519 : 0 : m_nFetchDirectionPropertyHandle = rMyProp.Handle;
520 : : }
521 : 0 : delete pOrigProps;
522 : 0 : }
523 : :
524 : 0 : CCRS_PropertySetInfo::~CCRS_PropertySetInfo()
525 : : {
526 : 0 : delete m_pProperties;
527 : 0 : }
528 : :
529 : : //--------------------------------------------------------------------------
530 : : // XInterface methods.
531 : : //--------------------------------------------------------------------------
532 : : //list all interfaces inclusive baseclasses of interfaces
533 : 0 : XINTERFACE_IMPL_2( CCRS_PropertySetInfo
534 : : , XTypeProvider
535 : : , XPropertySetInfo
536 : : );
537 : :
538 : : //--------------------------------------------------------------------------
539 : : // XTypeProvider methods.
540 : : //--------------------------------------------------------------------------
541 : : //list all interfaces exclusive baseclasses
542 : 0 : XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo
543 : : , XTypeProvider
544 : : , XPropertySetInfo
545 : : );
546 : : //--------------------------------------------------------------------------
547 : : // XPropertySetInfo methods.
548 : : //--------------------------------------------------------------------------
549 : : //virtual
550 : 0 : Sequence< Property > SAL_CALL CCRS_PropertySetInfo
551 : : ::getProperties() throw( RuntimeException )
552 : : {
553 : 0 : return *m_pProperties;
554 : : }
555 : :
556 : : //virtual
557 : 0 : Property SAL_CALL CCRS_PropertySetInfo
558 : : ::getPropertyByName( const OUString& aName )
559 : : throw( UnknownPropertyException, RuntimeException )
560 : : {
561 : 0 : if ( aName.isEmpty() )
562 : 0 : throw UnknownPropertyException();
563 : :
564 : 0 : Property aProp;
565 : 0 : if ( impl_queryProperty( aName, aProp ) )
566 : 0 : return aProp;
567 : :
568 : 0 : throw UnknownPropertyException();
569 : : }
570 : :
571 : : //virtual
572 : 0 : sal_Bool SAL_CALL CCRS_PropertySetInfo
573 : : ::hasPropertyByName( const OUString& Name )
574 : : throw( RuntimeException )
575 : : {
576 : 0 : return ( impl_getPos( Name ) != -1 );
577 : : }
578 : :
579 : : //--------------------------------------------------------------------------
580 : : // impl_ methods.
581 : : //--------------------------------------------------------------------------
582 : :
583 : 0 : sal_Int32 SAL_CALL CCRS_PropertySetInfo
584 : : ::impl_getPos( const OUString& rName ) const
585 : : {
586 : 0 : for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
587 : : {
588 : 0 : const Property& rMyProp = (*m_pProperties)[nN];
589 : 0 : if( rMyProp.Name == rName )
590 : 0 : return nN;
591 : : }
592 : 0 : return -1;
593 : : }
594 : :
595 : 0 : sal_Bool SAL_CALL CCRS_PropertySetInfo
596 : : ::impl_queryProperty( const OUString& rName, Property& rProp ) const
597 : : {
598 : 0 : for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
599 : : {
600 : 0 : const Property& rMyProp = (*m_pProperties)[nN];
601 : 0 : if( rMyProp.Name == rName )
602 : : {
603 : 0 : rProp.Name = rMyProp.Name;
604 : 0 : rProp.Handle = rMyProp.Handle;
605 : 0 : rProp.Type = rMyProp.Type;
606 : 0 : rProp.Attributes = rMyProp.Attributes;
607 : :
608 : 0 : return sal_True;
609 : : }
610 : : }
611 : 0 : return sal_False;
612 : : }
613 : :
614 : : //static
615 : 0 : sal_Bool SAL_CALL CCRS_PropertySetInfo
616 : : ::impl_isMyPropertyName( const OUString& rPropertyName )
617 : : {
618 : 0 : return ( rPropertyName == m_aPropertyNameForCount
619 : 0 : || rPropertyName == m_aPropertyNameForFinalCount
620 : 0 : || rPropertyName == m_aPropertyNameForFetchSize
621 : 0 : || rPropertyName == m_aPropertyNameForFetchDirection );
622 : : }
623 : :
624 : 0 : sal_Int32 SAL_CALL CCRS_PropertySetInfo
625 : : ::impl_getRemainedHandle( ) const
626 : : {
627 : 0 : sal_Int32 nHandle = 1;
628 : :
629 : 0 : if( !m_pProperties )
630 : : {
631 : : OSL_FAIL( "Properties not initialized yet" );
632 : 0 : return nHandle;
633 : : }
634 : 0 : sal_Bool bFound = sal_True;
635 : 0 : while( bFound )
636 : : {
637 : 0 : bFound = sal_False;
638 : 0 : for( sal_Int32 nN = m_pProperties->getLength(); nN--; )
639 : : {
640 : 0 : if( nHandle == (*m_pProperties)[nN].Handle )
641 : : {
642 : 0 : bFound = sal_True;
643 : 0 : nHandle++;
644 : 0 : break;
645 : : }
646 : : }
647 : : }
648 : 0 : return nHandle;
649 : : }
650 : :
651 : : //--------------------------------------------------------------------------
652 : : //--------------------------------------------------------------------------
653 : : // class CachedContentResultSet
654 : : //--------------------------------------------------------------------------
655 : : //--------------------------------------------------------------------------
656 : :
657 : 0 : CachedContentResultSet::CachedContentResultSet(
658 : : const Reference< XMultiServiceFactory > & xSMgr
659 : : , const Reference< XResultSet > & xOrigin
660 : : , const Reference< XContentIdentifierMapping > &
661 : : xContentIdentifierMapping )
662 : : : ContentResultSetWrapper( xOrigin )
663 : :
664 : : , m_xSMgr( xSMgr )
665 : : , m_xFetchProvider( NULL )
666 : : , m_xFetchProviderForContentAccess( NULL )
667 : :
668 : : , m_xMyPropertySetInfo( NULL )
669 : : , m_pMyPropSetInfo( NULL )
670 : :
671 : : , m_xContentIdentifierMapping( xContentIdentifierMapping )
672 : : , m_nRow( 0 ) // Position is one-based. Zero means: before first element.
673 : : , m_bAfterLast( sal_False )
674 : : , m_nLastAppliedPos( 0 )
675 : : , m_bAfterLastApplied( sal_False )
676 : : , m_nKnownCount( 0 )
677 : : , m_bFinalCount( sal_False )
678 : : , m_nFetchSize(
679 : : COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE )
680 : : , m_nFetchDirection(
681 : : COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION )
682 : :
683 : : , m_bLastReadWasFromCache( sal_False )
684 : : , m_bLastCachedReadWasNull( sal_True )
685 : : , m_aCache( m_xContentIdentifierMapping )
686 : : , m_aCacheContentIdentifierString( m_xContentIdentifierMapping )
687 : : , m_aCacheContentIdentifier( m_xContentIdentifierMapping )
688 : : , m_aCacheContent( m_xContentIdentifierMapping )
689 : : , m_bTriedToGetTypeConverter( sal_False )
690 : 0 : , m_xTypeConverter( NULL )
691 : : {
692 : 0 : m_xFetchProvider = Reference< XFetchProvider >( m_xResultSetOrigin, UNO_QUERY );
693 : : OSL_ENSURE( m_xFetchProvider.is(), "interface XFetchProvider is required" );
694 : :
695 : 0 : m_xFetchProviderForContentAccess = Reference< XFetchProviderForContentAccess >( m_xResultSetOrigin, UNO_QUERY );
696 : : OSL_ENSURE( m_xFetchProviderForContentAccess.is(), "interface XFetchProviderForContentAccess is required" );
697 : :
698 : 0 : impl_init();
699 : 0 : };
700 : :
701 : 0 : CachedContentResultSet::~CachedContentResultSet()
702 : : {
703 : 0 : impl_deinit();
704 : : //do not delete m_pMyPropSetInfo, cause it is hold via reference
705 : 0 : };
706 : :
707 : : //--------------------------------------------------------------------------
708 : : // impl_ methods.
709 : : //--------------------------------------------------------------------------
710 : :
711 : 0 : sal_Bool SAL_CALL CachedContentResultSet
712 : : ::applyPositionToOrigin( sal_Int32 nRow )
713 : : throw( SQLException,
714 : : RuntimeException )
715 : : {
716 : 0 : impl_EnsureNotDisposed();
717 : : //-------------------------------------------------------------------------
718 : : /**
719 : : @returns
720 : : <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off
721 : : the result set.
722 : : */
723 : :
724 : 0 : ReacquireableGuard aGuard( m_aMutex );
725 : : OSL_ENSURE( nRow >= 0, "only positive values supported" );
726 : 0 : if( !m_xResultSetOrigin.is() )
727 : : {
728 : : OSL_FAIL( "broadcaster was disposed already" );
729 : 0 : return sal_False;
730 : : }
731 : : // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" );
732 : :
733 : 0 : sal_Int32 nLastAppliedPos = m_nLastAppliedPos;
734 : 0 : sal_Bool bAfterLastApplied = m_bAfterLastApplied;
735 : 0 : sal_Bool bAfterLast = m_bAfterLast;
736 : 0 : sal_Int32 nForwardOnly = m_nForwardOnly;
737 : :
738 : 0 : aGuard.clear();
739 : :
740 : 0 : if( bAfterLastApplied || nLastAppliedPos != nRow )
741 : : {
742 : 0 : if( nForwardOnly == 1 )
743 : : {
744 : 0 : if( bAfterLastApplied || bAfterLast || !nRow || nRow < nLastAppliedPos )
745 : 0 : throw SQLException();
746 : :
747 : 0 : sal_Int32 nN = nRow - nLastAppliedPos;
748 : : sal_Int32 nM;
749 : 0 : for( nM = 0; nN--; nM++ )
750 : : {
751 : 0 : if( !m_xResultSetOrigin->next() )
752 : 0 : break;
753 : : }
754 : :
755 : 0 : aGuard.reacquire();
756 : 0 : m_nLastAppliedPos += nM;
757 : 0 : m_bAfterLastApplied = nRow != m_nLastAppliedPos;
758 : 0 : return nRow == m_nLastAppliedPos;
759 : : }
760 : :
761 : 0 : if( !nRow ) //absolute( 0 ) will throw exception
762 : : {
763 : 0 : m_xResultSetOrigin->beforeFirst();
764 : :
765 : 0 : aGuard.reacquire();
766 : 0 : m_nLastAppliedPos = 0;
767 : 0 : m_bAfterLastApplied = sal_False;
768 : 0 : return sal_False;
769 : : }
770 : : try
771 : : {
772 : : //move absolute, if !nLastAppliedPos
773 : : //because move relative would throw exception
774 : 0 : if( !nLastAppliedPos || bAfterLast || bAfterLastApplied )
775 : : {
776 : 0 : sal_Bool bValid = m_xResultSetOrigin->absolute( nRow );
777 : :
778 : 0 : aGuard.reacquire();
779 : 0 : m_nLastAppliedPos = nRow;
780 : 0 : m_bAfterLastApplied = !bValid;
781 : 0 : return bValid;
782 : : }
783 : : else
784 : : {
785 : 0 : sal_Bool bValid = m_xResultSetOrigin->relative( nRow - nLastAppliedPos );
786 : :
787 : 0 : aGuard.reacquire();
788 : 0 : m_nLastAppliedPos += ( nRow - nLastAppliedPos );
789 : 0 : m_bAfterLastApplied = !bValid;
790 : 0 : return bValid;
791 : : }
792 : : }
793 : 0 : catch (const SQLException&)
794 : : {
795 : 0 : if( !bAfterLastApplied && !bAfterLast && nRow > nLastAppliedPos && impl_isForwardOnly() )
796 : : {
797 : 0 : sal_Int32 nN = nRow - nLastAppliedPos;
798 : : sal_Int32 nM;
799 : 0 : for( nM = 0; nN--; nM++ )
800 : : {
801 : 0 : if( !m_xResultSetOrigin->next() )
802 : 0 : break;
803 : : }
804 : :
805 : 0 : aGuard.reacquire();
806 : 0 : m_nLastAppliedPos += nM;
807 : 0 : m_bAfterLastApplied = nRow != m_nLastAppliedPos;
808 : : }
809 : : else
810 : 0 : throw;
811 : : }
812 : :
813 : 0 : return nRow == m_nLastAppliedPos;
814 : : }
815 : 0 : return sal_True;
816 : : };
817 : :
818 : : //--------------------------------------------------------------------------
819 : : //--------------------------------------------------------------------------
820 : : //define for fetching data
821 : : //--------------------------------------------------------------------------
822 : : //--------------------------------------------------------------------------
823 : :
824 : : #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \
825 : : sal_Bool bDirection = !!( \
826 : : nFetchDirection != FetchDirection::REVERSE ); \
827 : : FetchResult aResult = \
828 : : fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \
829 : : osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \
830 : : aCache.loadData( aResult ); \
831 : : sal_Int32 nMax = aCache.getMaxRow(); \
832 : : sal_Int32 nCurCount = m_nKnownCount; \
833 : : sal_Bool bIsFinalCount = aCache.hasKnownLast(); \
834 : : sal_Bool bCurIsFinalCount = m_bFinalCount; \
835 : : aGuard2.clear(); \
836 : : if( nMax > nCurCount ) \
837 : : impl_changeRowCount( nCurCount, nMax ); \
838 : : if( bIsFinalCount && !bCurIsFinalCount ) \
839 : : impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount );
840 : :
841 : 0 : void SAL_CALL CachedContentResultSet
842 : : ::impl_fetchData( sal_Int32 nRow
843 : : , sal_Int32 nFetchSize, sal_Int32 nFetchDirection )
844 : : throw( com::sun::star::uno::RuntimeException )
845 : : {
846 : 0 : FETCH_XXX( m_aCache, m_xFetchProvider, fetch );
847 : 0 : }
848 : :
849 : 0 : void SAL_CALL CachedContentResultSet
850 : : ::impl_changeRowCount( sal_Int32 nOld, sal_Int32 nNew )
851 : : {
852 : : OSL_ENSURE( nNew > nOld, "RowCount only can grow" );
853 : 0 : if( nNew <= nOld )
854 : 0 : return;
855 : :
856 : : //create PropertyChangeEvent and set value
857 : 0 : PropertyChangeEvent aEvt;
858 : : {
859 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
860 : 0 : aEvt.Source = static_cast< XPropertySet * >( this );
861 : 0 : aEvt.Further = sal_False;
862 : 0 : aEvt.OldValue <<= nOld;
863 : 0 : aEvt.NewValue <<= nNew;
864 : :
865 : 0 : m_nKnownCount = nNew;
866 : : }
867 : :
868 : : //send PropertyChangeEvent to listeners
869 : 0 : impl_notifyPropertyChangeListeners( aEvt );
870 : : }
871 : :
872 : 0 : void SAL_CALL CachedContentResultSet
873 : : ::impl_changeIsRowCountFinal( sal_Bool bOld, sal_Bool bNew )
874 : : {
875 : : OSL_ENSURE( !bOld && bNew, "This change is not allowed for IsRowCountFinal" );
876 : 0 : if( ! (!bOld && bNew ) )
877 : 0 : return;
878 : :
879 : : //create PropertyChangeEvent and set value
880 : 0 : PropertyChangeEvent aEvt;
881 : : {
882 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
883 : 0 : aEvt.Source = static_cast< XPropertySet * >( this );
884 : 0 : aEvt.Further = sal_False;
885 : 0 : aEvt.OldValue <<= bOld;
886 : 0 : aEvt.NewValue <<= bNew;
887 : :
888 : 0 : m_bFinalCount = bNew;
889 : : }
890 : :
891 : : //send PropertyChangeEvent to listeners
892 : 0 : impl_notifyPropertyChangeListeners( aEvt );
893 : : }
894 : :
895 : 0 : sal_Bool SAL_CALL CachedContentResultSet
896 : : ::impl_isKnownValidPosition( sal_Int32 nRow )
897 : : {
898 : : return m_nKnownCount && nRow
899 : 0 : && nRow <= m_nKnownCount;
900 : : }
901 : :
902 : 0 : sal_Bool SAL_CALL CachedContentResultSet
903 : : ::impl_isKnownInvalidPosition( sal_Int32 nRow )
904 : : {
905 : 0 : if( !nRow )
906 : 0 : return sal_True;
907 : 0 : if( !m_bFinalCount )
908 : 0 : return sal_False;
909 : 0 : return nRow > m_nKnownCount;
910 : : }
911 : :
912 : :
913 : : //virtual
914 : 0 : void SAL_CALL CachedContentResultSet
915 : : ::impl_initPropertySetInfo()
916 : : {
917 : 0 : ContentResultSetWrapper::impl_initPropertySetInfo();
918 : :
919 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
920 : 0 : if( m_pMyPropSetInfo )
921 : 0 : return;
922 : 0 : m_pMyPropSetInfo = new CCRS_PropertySetInfo( m_xPropertySetInfo );
923 : 0 : m_xMyPropertySetInfo = m_pMyPropSetInfo;
924 : 0 : m_xPropertySetInfo = m_xMyPropertySetInfo;
925 : : }
926 : :
927 : : //--------------------------------------------------------------------------
928 : : // XInterface methods. ( inherited )
929 : : //--------------------------------------------------------------------------
930 : 0 : XINTERFACE_COMMON_IMPL( CachedContentResultSet )
931 : :
932 : 0 : Any SAL_CALL CachedContentResultSet
933 : : ::queryInterface( const Type& rType )
934 : : throw ( RuntimeException )
935 : : {
936 : : //list all interfaces inclusive baseclasses of interfaces
937 : :
938 : 0 : Any aRet = ContentResultSetWrapper::queryInterface( rType );
939 : 0 : if( aRet.hasValue() )
940 : 0 : return aRet;
941 : :
942 : : aRet = cppu::queryInterface( rType,
943 : : static_cast< XTypeProvider* >( this ),
944 : 0 : static_cast< XServiceInfo* >( this ) );
945 : :
946 : 0 : return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType );
947 : : }
948 : :
949 : : //--------------------------------------------------------------------------
950 : : // XTypeProvider methods.
951 : : //--------------------------------------------------------------------------
952 : : //list all interfaces exclusive baseclasses
953 : 0 : XTYPEPROVIDER_IMPL_11( CachedContentResultSet
954 : : , XTypeProvider
955 : : , XServiceInfo
956 : : , XComponent
957 : : , XCloseable
958 : : , XResultSetMetaDataSupplier
959 : : , XPropertySet
960 : :
961 : : , XPropertyChangeListener
962 : : , XVetoableChangeListener
963 : :
964 : : , XContentAccess
965 : :
966 : : , XResultSet
967 : : , XRow );
968 : :
969 : : //--------------------------------------------------------------------------
970 : : // XServiceInfo methods.
971 : : //--------------------------------------------------------------------------
972 : :
973 : 0 : XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet,
974 : : OUString(
975 : : "com.sun.star.comp.ucb.CachedContentResultSet" ),
976 : : OUString(
977 : : CACHED_CONTENT_RESULTSET_SERVICE_NAME ) );
978 : :
979 : : //--------------------------------------------------------------------------
980 : : // XPropertySet methods. ( inherited )
981 : : //--------------------------------------------------------------------------
982 : :
983 : : // virtual
984 : 0 : void SAL_CALL CachedContentResultSet
985 : : ::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
986 : : throw( UnknownPropertyException,
987 : : PropertyVetoException,
988 : : IllegalArgumentException,
989 : : WrappedTargetException,
990 : : RuntimeException )
991 : : {
992 : 0 : impl_EnsureNotDisposed();
993 : :
994 : 0 : if( !getPropertySetInfo().is() )
995 : : {
996 : : OSL_FAIL( "broadcaster was disposed already" );
997 : 0 : throw UnknownPropertyException();
998 : : }
999 : :
1000 : 0 : Property aProp = m_pMyPropSetInfo->getPropertyByName( aPropertyName );
1001 : : //throws UnknownPropertyException, if so
1002 : :
1003 : 0 : if( aProp.Attributes & PropertyAttribute::READONLY )
1004 : : {
1005 : : //It is assumed, that the properties
1006 : : //'RowCount' and 'IsRowCountFinal' are readonly!
1007 : 0 : throw IllegalArgumentException();
1008 : : }
1009 : 0 : if( aProp.Name == CCRS_PropertySetInfo
1010 : 0 : ::m_aPropertyNameForFetchDirection )
1011 : : {
1012 : : //check value
1013 : : sal_Int32 nNew;
1014 : 0 : if( !( aValue >>= nNew ) )
1015 : : {
1016 : 0 : throw IllegalArgumentException();
1017 : : }
1018 : :
1019 : 0 : if( nNew == FetchDirection::UNKNOWN )
1020 : : {
1021 : 0 : nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION;
1022 : : }
1023 : 0 : else if( !( nNew == FetchDirection::FORWARD
1024 : 0 : || nNew == FetchDirection::REVERSE ) )
1025 : : {
1026 : 0 : throw IllegalArgumentException();
1027 : : }
1028 : :
1029 : : //create PropertyChangeEvent and set value
1030 : 0 : PropertyChangeEvent aEvt;
1031 : : {
1032 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1033 : 0 : aEvt.Source = static_cast< XPropertySet * >( this );
1034 : 0 : aEvt.PropertyName = aPropertyName;
1035 : 0 : aEvt.Further = sal_False;
1036 : : aEvt.PropertyHandle = m_pMyPropSetInfo->
1037 : 0 : m_nFetchDirectionPropertyHandle;
1038 : 0 : aEvt.OldValue <<= m_nFetchDirection;
1039 : 0 : aEvt.NewValue <<= nNew;
1040 : :
1041 : 0 : m_nFetchDirection = nNew;
1042 : : }
1043 : :
1044 : : //send PropertyChangeEvent to listeners
1045 : 0 : impl_notifyPropertyChangeListeners( aEvt );
1046 : : }
1047 : 0 : else if( aProp.Name == CCRS_PropertySetInfo
1048 : 0 : ::m_aPropertyNameForFetchSize )
1049 : : {
1050 : : //check value
1051 : : sal_Int32 nNew;
1052 : 0 : if( !( aValue >>= nNew ) )
1053 : : {
1054 : 0 : throw IllegalArgumentException();
1055 : : }
1056 : :
1057 : 0 : if( nNew < 0 )
1058 : : {
1059 : 0 : nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE;
1060 : : }
1061 : :
1062 : : //create PropertyChangeEvent and set value
1063 : 0 : PropertyChangeEvent aEvt;
1064 : : {
1065 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1066 : 0 : aEvt.Source = static_cast< XPropertySet * >( this );
1067 : 0 : aEvt.PropertyName = aPropertyName;
1068 : 0 : aEvt.Further = sal_False;
1069 : : aEvt.PropertyHandle = m_pMyPropSetInfo->
1070 : 0 : m_nFetchSizePropertyHandle;
1071 : 0 : aEvt.OldValue <<= m_nFetchSize;
1072 : 0 : aEvt.NewValue <<= nNew;
1073 : :
1074 : 0 : m_nFetchSize = nNew;
1075 : : }
1076 : :
1077 : : //send PropertyChangeEvent to listeners
1078 : 0 : impl_notifyPropertyChangeListeners( aEvt );
1079 : : }
1080 : : else
1081 : : {
1082 : 0 : impl_init_xPropertySetOrigin();
1083 : : {
1084 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1085 : 0 : if( !m_xPropertySetOrigin.is() )
1086 : : {
1087 : : OSL_FAIL( "broadcaster was disposed already" );
1088 : 0 : return;
1089 : 0 : }
1090 : : }
1091 : 0 : m_xPropertySetOrigin->setPropertyValue( aPropertyName, aValue );
1092 : 0 : }
1093 : : }
1094 : :
1095 : : //--------------------------------------------------------------------------
1096 : : // virtual
1097 : 0 : Any SAL_CALL CachedContentResultSet
1098 : : ::getPropertyValue( const OUString& rPropertyName )
1099 : : throw( UnknownPropertyException,
1100 : : WrappedTargetException,
1101 : : RuntimeException )
1102 : : {
1103 : 0 : impl_EnsureNotDisposed();
1104 : :
1105 : 0 : if( !getPropertySetInfo().is() )
1106 : : {
1107 : : OSL_FAIL( "broadcaster was disposed already" );
1108 : 0 : throw UnknownPropertyException();
1109 : : }
1110 : :
1111 : 0 : Property aProp = m_pMyPropSetInfo->getPropertyByName( rPropertyName );
1112 : : //throws UnknownPropertyException, if so
1113 : :
1114 : 0 : Any aValue;
1115 : 0 : if( rPropertyName == CCRS_PropertySetInfo
1116 : 0 : ::m_aPropertyNameForCount )
1117 : : {
1118 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1119 : 0 : aValue <<= m_nKnownCount;
1120 : : }
1121 : 0 : else if( rPropertyName == CCRS_PropertySetInfo
1122 : 0 : ::m_aPropertyNameForFinalCount )
1123 : : {
1124 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1125 : 0 : aValue <<= m_bFinalCount;
1126 : : }
1127 : 0 : else if( rPropertyName == CCRS_PropertySetInfo
1128 : 0 : ::m_aPropertyNameForFetchSize )
1129 : : {
1130 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1131 : 0 : aValue <<= m_nFetchSize;
1132 : : }
1133 : 0 : else if( rPropertyName == CCRS_PropertySetInfo
1134 : 0 : ::m_aPropertyNameForFetchDirection )
1135 : : {
1136 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1137 : 0 : aValue <<= m_nFetchDirection;
1138 : : }
1139 : : else
1140 : : {
1141 : 0 : impl_init_xPropertySetOrigin();
1142 : : {
1143 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1144 : 0 : if( !m_xPropertySetOrigin.is() )
1145 : : {
1146 : : OSL_FAIL( "broadcaster was disposed already" );
1147 : 0 : throw UnknownPropertyException();
1148 : 0 : }
1149 : : }
1150 : 0 : aValue = m_xPropertySetOrigin->getPropertyValue( rPropertyName );
1151 : : }
1152 : 0 : return aValue;
1153 : : }
1154 : :
1155 : : //--------------------------------------------------------------------------
1156 : : // own methods. ( inherited )
1157 : : //--------------------------------------------------------------------------
1158 : :
1159 : : //virtual
1160 : 0 : void SAL_CALL CachedContentResultSet
1161 : : ::impl_disposing( const EventObject& rEventObject )
1162 : : throw( RuntimeException )
1163 : : {
1164 : : {
1165 : 0 : impl_EnsureNotDisposed();
1166 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1167 : : //release all references to the broadcaster:
1168 : 0 : m_xFetchProvider.clear();
1169 : 0 : m_xFetchProviderForContentAccess.clear();
1170 : : }
1171 : 0 : ContentResultSetWrapper::impl_disposing( rEventObject );
1172 : 0 : }
1173 : :
1174 : : //virtual
1175 : 0 : void SAL_CALL CachedContentResultSet
1176 : : ::impl_propertyChange( const PropertyChangeEvent& rEvt )
1177 : : throw( RuntimeException )
1178 : : {
1179 : 0 : impl_EnsureNotDisposed();
1180 : :
1181 : 0 : PropertyChangeEvent aEvt( rEvt );
1182 : 0 : aEvt.Source = static_cast< XPropertySet * >( this );
1183 : 0 : aEvt.Further = sal_False;
1184 : : //---------
1185 : :
1186 : 0 : if( CCRS_PropertySetInfo
1187 : 0 : ::impl_isMyPropertyName( rEvt.PropertyName ) )
1188 : : {
1189 : : //don't notify foreign events on fetchsize and fetchdirection
1190 : 0 : if( aEvt.PropertyName == CCRS_PropertySetInfo
1191 : 0 : ::m_aPropertyNameForFetchSize
1192 : : || aEvt.PropertyName == CCRS_PropertySetInfo
1193 : 0 : ::m_aPropertyNameForFetchDirection )
1194 : : return;
1195 : :
1196 : : //adjust my props 'RowCount' and 'IsRowCountFinal'
1197 : 0 : if( aEvt.PropertyName == CCRS_PropertySetInfo
1198 : 0 : ::m_aPropertyNameForCount )
1199 : : {//RowCount changed
1200 : :
1201 : : //check value
1202 : 0 : sal_Int32 nNew = 0;
1203 : 0 : if( !( aEvt.NewValue >>= nNew ) )
1204 : : {
1205 : : OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1206 : : return;
1207 : : }
1208 : :
1209 : 0 : impl_changeRowCount( m_nKnownCount, nNew );
1210 : : }
1211 : 0 : else if( aEvt.PropertyName == CCRS_PropertySetInfo
1212 : 0 : ::m_aPropertyNameForFinalCount )
1213 : : {//IsRowCountFinal changed
1214 : :
1215 : : //check value
1216 : 0 : sal_Bool bNew = sal_False;
1217 : 0 : if( !( aEvt.NewValue >>= bNew ) )
1218 : : {
1219 : : OSL_FAIL( "PropertyChangeEvent contains wrong data" );
1220 : : return;
1221 : : }
1222 : 0 : impl_changeIsRowCountFinal( m_bFinalCount, bNew );
1223 : : }
1224 : : return;
1225 : : }
1226 : :
1227 : : //-----------
1228 : 0 : impl_notifyPropertyChangeListeners( aEvt );
1229 : : }
1230 : :
1231 : :
1232 : : //virtual
1233 : 0 : void SAL_CALL CachedContentResultSet
1234 : : ::impl_vetoableChange( const PropertyChangeEvent& rEvt )
1235 : : throw( PropertyVetoException,
1236 : : RuntimeException )
1237 : : {
1238 : 0 : impl_EnsureNotDisposed();
1239 : :
1240 : : //don't notify events on my properties, cause they are not vetoable
1241 : 0 : if( CCRS_PropertySetInfo
1242 : 0 : ::impl_isMyPropertyName( rEvt.PropertyName ) )
1243 : : {
1244 : 0 : return;
1245 : : }
1246 : :
1247 : :
1248 : 0 : PropertyChangeEvent aEvt( rEvt );
1249 : 0 : aEvt.Source = static_cast< XPropertySet * >( this );
1250 : 0 : aEvt.Further = sal_False;
1251 : :
1252 : 0 : impl_notifyVetoableChangeListeners( aEvt );
1253 : : }
1254 : :
1255 : : //--------------------------------------------------------------------------
1256 : : // XContentAccess methods. ( inherited ) ( -- position dependent )
1257 : : //--------------------------------------------------------------------------
1258 : :
1259 : : #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \
1260 : : impl_EnsureNotDisposed(); \
1261 : : ReacquireableGuard aGuard( m_aMutex ); \
1262 : : sal_Int32 nRow = m_nRow; \
1263 : : sal_Int32 nFetchSize = m_nFetchSize; \
1264 : : sal_Int32 nFetchDirection = m_nFetchDirection; \
1265 : : if( !m_aCache##XXX.hasRow( nRow ) ) \
1266 : : { \
1267 : : if( !m_aCache##XXX.hasCausedException( nRow ) ) \
1268 : : { \
1269 : : if( !m_xFetchProviderForContentAccess.is() ) \
1270 : : { \
1271 : : OSL_FAIL( "broadcaster was disposed already" );\
1272 : : throw RuntimeException(); \
1273 : : } \
1274 : : aGuard.clear(); \
1275 : : if( impl_isForwardOnly() ) \
1276 : : applyPositionToOrigin( nRow ); \
1277 : : \
1278 : : FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \
1279 : : } \
1280 : : aGuard.reacquire(); \
1281 : : if( !m_aCache##XXX.hasRow( nRow ) ) \
1282 : : { \
1283 : : aGuard.clear(); \
1284 : : applyPositionToOrigin( nRow ); \
1285 : : TYPE aRet = ContentResultSetWrapper::queryXXX(); \
1286 : : if( m_xContentIdentifierMapping.is() ) \
1287 : : return m_xContentIdentifierMapping->map##XXX( aRet );\
1288 : : return aRet; \
1289 : : } \
1290 : : } \
1291 : : return m_aCache##XXX.get##XXX( nRow );
1292 : :
1293 : : //--------------------------------------------------------------------------
1294 : : // virtual
1295 : 0 : OUString SAL_CALL CachedContentResultSet
1296 : : ::queryContentIdentifierString()
1297 : : throw( RuntimeException )
1298 : : {
1299 : 0 : XCONTENTACCESS_queryXXX( queryContentIdentifierString, ContentIdentifierString, OUString )
1300 : : }
1301 : :
1302 : : //--------------------------------------------------------------------------
1303 : : // virtual
1304 : 0 : Reference< XContentIdentifier > SAL_CALL CachedContentResultSet
1305 : : ::queryContentIdentifier()
1306 : : throw( RuntimeException )
1307 : : {
1308 : 0 : XCONTENTACCESS_queryXXX( queryContentIdentifier, ContentIdentifier, Reference< XContentIdentifier > )
1309 : : }
1310 : :
1311 : : //--------------------------------------------------------------------------
1312 : : // virtual
1313 : 0 : Reference< XContent > SAL_CALL CachedContentResultSet
1314 : : ::queryContent()
1315 : : throw( RuntimeException )
1316 : : {
1317 : 0 : XCONTENTACCESS_queryXXX( queryContent, Content, Reference< XContent > )
1318 : : }
1319 : :
1320 : : //-----------------------------------------------------------------
1321 : : // XResultSet methods. ( inherited )
1322 : : //-----------------------------------------------------------------
1323 : : //virtual
1324 : :
1325 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1326 : : ::next()
1327 : : throw( SQLException,
1328 : : RuntimeException )
1329 : : {
1330 : 0 : impl_EnsureNotDisposed();
1331 : :
1332 : 0 : ReacquireableGuard aGuard( m_aMutex );
1333 : : //after last
1334 : 0 : if( m_bAfterLast )
1335 : 0 : return sal_False;
1336 : : //last
1337 : 0 : aGuard.clear();
1338 : 0 : if( isLast() )
1339 : : {
1340 : 0 : aGuard.reacquire();
1341 : 0 : m_nRow++;
1342 : 0 : m_bAfterLast = sal_True;
1343 : 0 : return sal_False;
1344 : : }
1345 : 0 : aGuard.reacquire();
1346 : : //known valid position
1347 : 0 : if( impl_isKnownValidPosition( m_nRow + 1 ) )
1348 : : {
1349 : 0 : m_nRow++;
1350 : 0 : return sal_True;
1351 : : }
1352 : :
1353 : : //unknown position
1354 : 0 : sal_Int32 nRow = m_nRow;
1355 : 0 : aGuard.clear();
1356 : :
1357 : 0 : sal_Bool bValid = applyPositionToOrigin( nRow + 1 );
1358 : :
1359 : 0 : aGuard.reacquire();
1360 : 0 : m_nRow = nRow + 1;
1361 : 0 : m_bAfterLast = !bValid;
1362 : 0 : return bValid;
1363 : : }
1364 : :
1365 : : //virtual
1366 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1367 : : ::previous()
1368 : : throw( SQLException,
1369 : : RuntimeException )
1370 : : {
1371 : 0 : impl_EnsureNotDisposed();
1372 : :
1373 : 0 : if( impl_isForwardOnly() )
1374 : 0 : throw SQLException();
1375 : :
1376 : 0 : ReacquireableGuard aGuard( m_aMutex );
1377 : : //before first ?:
1378 : 0 : if( !m_bAfterLast && !m_nRow )
1379 : 0 : return sal_False;
1380 : : //first ?:
1381 : 0 : if( !m_bAfterLast && m_nKnownCount && m_nRow == 1 )
1382 : : {
1383 : 0 : m_nRow--;
1384 : 0 : m_bAfterLast = sal_False;
1385 : 0 : return sal_False;
1386 : : }
1387 : : //known valid position ?:
1388 : 0 : if( impl_isKnownValidPosition( m_nRow - 1 ) )
1389 : : {
1390 : 0 : m_nRow--;
1391 : 0 : m_bAfterLast = sal_False;
1392 : 0 : return sal_True;
1393 : : }
1394 : : //unknown position:
1395 : 0 : sal_Int32 nRow = m_nRow;
1396 : 0 : aGuard.clear();
1397 : :
1398 : 0 : sal_Bool bValid = applyPositionToOrigin( nRow - 1 );
1399 : :
1400 : 0 : aGuard.reacquire();
1401 : 0 : m_nRow = nRow - 1;
1402 : 0 : m_bAfterLast = sal_False;
1403 : 0 : return bValid;
1404 : : }
1405 : :
1406 : : //virtual
1407 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1408 : : ::absolute( sal_Int32 row )
1409 : : throw( SQLException,
1410 : : RuntimeException )
1411 : : {
1412 : 0 : impl_EnsureNotDisposed();
1413 : :
1414 : 0 : if( !row )
1415 : 0 : throw SQLException();
1416 : :
1417 : 0 : if( impl_isForwardOnly() )
1418 : 0 : throw SQLException();
1419 : :
1420 : 0 : ReacquireableGuard aGuard( m_aMutex );
1421 : :
1422 : 0 : if( !m_xResultSetOrigin.is() )
1423 : : {
1424 : : OSL_FAIL( "broadcaster was disposed already" );
1425 : 0 : return sal_False;
1426 : : }
1427 : 0 : if( row < 0 )
1428 : : {
1429 : 0 : if( m_bFinalCount )
1430 : : {
1431 : 0 : sal_Int32 nNewRow = m_nKnownCount + 1 + row;
1432 : 0 : sal_Bool bValid = sal_True;
1433 : 0 : if( nNewRow <= 0 )
1434 : : {
1435 : 0 : nNewRow = 0;
1436 : 0 : bValid = sal_False;
1437 : : }
1438 : 0 : m_nRow = nNewRow;
1439 : 0 : m_bAfterLast = sal_False;
1440 : 0 : return bValid;
1441 : : }
1442 : : //unknown final count:
1443 : 0 : aGuard.clear();
1444 : :
1445 : : // Solaris has problems catching or propagating derived exceptions
1446 : : // when only the base class is known, so make ResultSetException
1447 : : // (derived from SQLException) known here:
1448 : : sal_Bool bValid;
1449 : : try
1450 : : {
1451 : 0 : bValid = m_xResultSetOrigin->absolute( row );
1452 : : }
1453 : 0 : catch (const ResultSetException&)
1454 : : {
1455 : 0 : throw;
1456 : : }
1457 : :
1458 : 0 : aGuard.reacquire();
1459 : 0 : if( m_bFinalCount )
1460 : : {
1461 : 0 : sal_Int32 nNewRow = m_nKnownCount + 1 + row;
1462 : 0 : if( nNewRow < 0 )
1463 : 0 : nNewRow = 0;
1464 : 0 : m_nLastAppliedPos = nNewRow;
1465 : 0 : m_nRow = nNewRow;
1466 : 0 : m_bAfterLastApplied = m_bAfterLast = sal_False;
1467 : 0 : return bValid;
1468 : : }
1469 : 0 : aGuard.clear();
1470 : :
1471 : 0 : sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
1472 : :
1473 : 0 : aGuard.reacquire();
1474 : 0 : m_nLastAppliedPos = nCurRow;
1475 : 0 : m_nRow = nCurRow;
1476 : 0 : m_bAfterLast = sal_False;
1477 : 0 : return nCurRow != 0;
1478 : : }
1479 : : //row > 0:
1480 : 0 : if( m_bFinalCount )
1481 : : {
1482 : 0 : if( row > m_nKnownCount )
1483 : : {
1484 : 0 : m_nRow = m_nKnownCount + 1;
1485 : 0 : m_bAfterLast = sal_True;
1486 : 0 : return sal_False;
1487 : : }
1488 : 0 : m_nRow = row;
1489 : 0 : m_bAfterLast = sal_False;
1490 : 0 : return sal_True;
1491 : : }
1492 : : //unknown new position:
1493 : 0 : aGuard.clear();
1494 : :
1495 : 0 : sal_Bool bValid = m_xResultSetOrigin->absolute( row );
1496 : :
1497 : 0 : aGuard.reacquire();
1498 : 0 : if( m_bFinalCount )
1499 : : {
1500 : 0 : sal_Int32 nNewRow = row;
1501 : 0 : if( nNewRow > m_nKnownCount )
1502 : : {
1503 : 0 : nNewRow = m_nKnownCount + 1;
1504 : 0 : m_bAfterLastApplied = m_bAfterLast = sal_True;
1505 : : }
1506 : : else
1507 : 0 : m_bAfterLastApplied = m_bAfterLast = sal_False;
1508 : :
1509 : 0 : m_nLastAppliedPos = nNewRow;
1510 : 0 : m_nRow = nNewRow;
1511 : 0 : return bValid;
1512 : : }
1513 : 0 : aGuard.clear();
1514 : :
1515 : 0 : sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
1516 : 0 : sal_Bool bIsAfterLast = m_xResultSetOrigin->isAfterLast();
1517 : :
1518 : 0 : aGuard.reacquire();
1519 : 0 : m_nLastAppliedPos = nCurRow;
1520 : 0 : m_nRow = nCurRow;
1521 : 0 : m_bAfterLastApplied = m_bAfterLast = bIsAfterLast;
1522 : 0 : return nCurRow && !bIsAfterLast;
1523 : : }
1524 : :
1525 : : //virtual
1526 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1527 : : ::relative( sal_Int32 rows )
1528 : : throw( SQLException,
1529 : : RuntimeException )
1530 : : {
1531 : 0 : impl_EnsureNotDisposed();
1532 : :
1533 : 0 : if( impl_isForwardOnly() )
1534 : 0 : throw SQLException();
1535 : :
1536 : 0 : ReacquireableGuard aGuard( m_aMutex );
1537 : 0 : if( m_bAfterLast || impl_isKnownInvalidPosition( m_nRow ) )
1538 : 0 : throw SQLException();
1539 : :
1540 : 0 : if( !rows )
1541 : 0 : return sal_True;
1542 : :
1543 : 0 : sal_Int32 nNewRow = m_nRow + rows;
1544 : 0 : if( nNewRow < 0 )
1545 : 0 : nNewRow = 0;
1546 : :
1547 : 0 : if( impl_isKnownValidPosition( nNewRow ) )
1548 : : {
1549 : 0 : m_nRow = nNewRow;
1550 : 0 : m_bAfterLast = sal_False;
1551 : 0 : return sal_True;
1552 : : }
1553 : : else
1554 : : {
1555 : : //known invalid new position:
1556 : 0 : if( nNewRow == 0 )
1557 : : {
1558 : 0 : m_bAfterLast = sal_False;
1559 : 0 : m_nRow = 0;
1560 : 0 : return sal_False;
1561 : : }
1562 : 0 : if( m_bFinalCount && nNewRow > m_nKnownCount )
1563 : : {
1564 : 0 : m_bAfterLast = sal_True;
1565 : 0 : m_nRow = m_nKnownCount + 1;
1566 : 0 : return sal_False;
1567 : : }
1568 : : //unknown new position:
1569 : 0 : aGuard.clear();
1570 : 0 : sal_Bool bValid = applyPositionToOrigin( nNewRow );
1571 : :
1572 : 0 : aGuard.reacquire();
1573 : 0 : m_nRow = nNewRow;
1574 : 0 : m_bAfterLast = !bValid && nNewRow > 0;
1575 : 0 : return bValid;
1576 : 0 : }
1577 : : }
1578 : :
1579 : :
1580 : : //virtual
1581 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1582 : : ::first()
1583 : : throw( SQLException,
1584 : : RuntimeException )
1585 : : {
1586 : 0 : impl_EnsureNotDisposed();
1587 : :
1588 : 0 : if( impl_isForwardOnly() )
1589 : 0 : throw SQLException();
1590 : :
1591 : 0 : ReacquireableGuard aGuard( m_aMutex );
1592 : 0 : if( impl_isKnownValidPosition( 1 ) )
1593 : : {
1594 : 0 : m_nRow = 1;
1595 : 0 : m_bAfterLast = sal_False;
1596 : 0 : return sal_True;
1597 : : }
1598 : 0 : if( impl_isKnownInvalidPosition( 1 ) )
1599 : : {
1600 : 0 : m_nRow = 1;
1601 : 0 : m_bAfterLast = sal_False;
1602 : 0 : return sal_False;
1603 : : }
1604 : : //unknown position
1605 : 0 : aGuard.clear();
1606 : :
1607 : 0 : sal_Bool bValid = applyPositionToOrigin( 1 );
1608 : :
1609 : 0 : aGuard.reacquire();
1610 : 0 : m_nRow = 1;
1611 : 0 : m_bAfterLast = sal_False;
1612 : 0 : return bValid;
1613 : : }
1614 : :
1615 : : //virtual
1616 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1617 : : ::last()
1618 : : throw( SQLException,
1619 : : RuntimeException )
1620 : : {
1621 : 0 : impl_EnsureNotDisposed();
1622 : :
1623 : 0 : if( impl_isForwardOnly() )
1624 : 0 : throw SQLException();
1625 : :
1626 : 0 : ReacquireableGuard aGuard( m_aMutex );
1627 : 0 : if( m_bFinalCount )
1628 : : {
1629 : 0 : m_nRow = m_nKnownCount;
1630 : 0 : m_bAfterLast = sal_False;
1631 : 0 : return m_nKnownCount != 0;
1632 : : }
1633 : : //unknown position
1634 : 0 : if( !m_xResultSetOrigin.is() )
1635 : : {
1636 : : OSL_FAIL( "broadcaster was disposed already" );
1637 : 0 : return sal_False;
1638 : : }
1639 : 0 : aGuard.clear();
1640 : :
1641 : 0 : sal_Bool bValid = m_xResultSetOrigin->last();
1642 : :
1643 : 0 : aGuard.reacquire();
1644 : 0 : m_bAfterLastApplied = m_bAfterLast = sal_False;
1645 : 0 : if( m_bFinalCount )
1646 : : {
1647 : 0 : m_nLastAppliedPos = m_nKnownCount;
1648 : 0 : m_nRow = m_nKnownCount;
1649 : 0 : return bValid;
1650 : : }
1651 : 0 : aGuard.clear();
1652 : :
1653 : 0 : sal_Int32 nCurRow = m_xResultSetOrigin->getRow();
1654 : :
1655 : 0 : aGuard.reacquire();
1656 : 0 : m_nLastAppliedPos = nCurRow;
1657 : 0 : m_nRow = nCurRow;
1658 : : OSL_ENSURE( nCurRow >= m_nKnownCount, "position of last row < known Count, that could not be" );
1659 : 0 : m_nKnownCount = nCurRow;
1660 : 0 : m_bFinalCount = sal_True;
1661 : 0 : return nCurRow != 0;
1662 : : }
1663 : :
1664 : : //virtual
1665 : 0 : void SAL_CALL CachedContentResultSet
1666 : : ::beforeFirst()
1667 : : throw( SQLException,
1668 : : RuntimeException )
1669 : : {
1670 : 0 : impl_EnsureNotDisposed();
1671 : :
1672 : 0 : if( impl_isForwardOnly() )
1673 : 0 : throw SQLException();
1674 : :
1675 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1676 : 0 : m_nRow = 0;
1677 : 0 : m_bAfterLast = sal_False;
1678 : 0 : }
1679 : :
1680 : : //virtual
1681 : 0 : void SAL_CALL CachedContentResultSet
1682 : : ::afterLast()
1683 : : throw( SQLException,
1684 : : RuntimeException )
1685 : : {
1686 : 0 : impl_EnsureNotDisposed();
1687 : :
1688 : 0 : if( impl_isForwardOnly() )
1689 : 0 : throw SQLException();
1690 : :
1691 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1692 : 0 : m_nRow = 1;
1693 : 0 : m_bAfterLast = sal_True;
1694 : 0 : }
1695 : :
1696 : : //virtual
1697 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1698 : : ::isAfterLast()
1699 : : throw( SQLException,
1700 : : RuntimeException )
1701 : : {
1702 : 0 : impl_EnsureNotDisposed();
1703 : :
1704 : 0 : ReacquireableGuard aGuard( m_aMutex );
1705 : 0 : if( !m_bAfterLast )
1706 : 0 : return sal_False;
1707 : 0 : if( m_nKnownCount )
1708 : 0 : return m_bAfterLast;
1709 : 0 : if( m_bFinalCount )
1710 : 0 : return sal_False;
1711 : :
1712 : 0 : if( !m_xResultSetOrigin.is() )
1713 : : {
1714 : : OSL_FAIL( "broadcaster was disposed already" );
1715 : 0 : return sal_False;
1716 : : }
1717 : 0 : aGuard.clear();
1718 : :
1719 : : //find out whethter the original resultset contains rows or not
1720 : 0 : m_xResultSetOrigin->afterLast();
1721 : :
1722 : 0 : aGuard.reacquire();
1723 : 0 : m_bAfterLastApplied = sal_True;
1724 : 0 : aGuard.clear();
1725 : :
1726 : 0 : return m_xResultSetOrigin->isAfterLast();
1727 : : }
1728 : :
1729 : : //virtual
1730 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1731 : : ::isBeforeFirst()
1732 : : throw( SQLException,
1733 : : RuntimeException )
1734 : : {
1735 : 0 : impl_EnsureNotDisposed();
1736 : :
1737 : 0 : ReacquireableGuard aGuard( m_aMutex );
1738 : 0 : if( m_bAfterLast )
1739 : 0 : return sal_False;
1740 : 0 : if( m_nRow )
1741 : 0 : return sal_False;
1742 : 0 : if( m_nKnownCount )
1743 : 0 : return !m_nRow;
1744 : 0 : if( m_bFinalCount )
1745 : 0 : return sal_False;
1746 : :
1747 : 0 : if( !m_xResultSetOrigin.is() )
1748 : : {
1749 : : OSL_FAIL( "broadcaster was disposed already" );
1750 : 0 : return sal_False;
1751 : : }
1752 : 0 : aGuard.clear();
1753 : :
1754 : : //find out whethter the original resultset contains rows or not
1755 : 0 : m_xResultSetOrigin->beforeFirst();
1756 : :
1757 : 0 : aGuard.reacquire();
1758 : 0 : m_bAfterLastApplied = sal_False;
1759 : 0 : m_nLastAppliedPos = 0;
1760 : 0 : aGuard.clear();
1761 : :
1762 : 0 : return m_xResultSetOrigin->isBeforeFirst();
1763 : : }
1764 : :
1765 : : //virtual
1766 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1767 : : ::isFirst()
1768 : : throw( SQLException,
1769 : : RuntimeException )
1770 : : {
1771 : 0 : impl_EnsureNotDisposed();
1772 : :
1773 : 0 : sal_Int32 nRow = 0;
1774 : 0 : Reference< XResultSet > xResultSetOrigin;
1775 : :
1776 : : {
1777 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1778 : 0 : if( m_bAfterLast )
1779 : 0 : return sal_False;
1780 : 0 : if( m_nRow != 1 )
1781 : 0 : return sal_False;
1782 : 0 : if( m_nKnownCount )
1783 : 0 : return m_nRow == 1;
1784 : 0 : if( m_bFinalCount )
1785 : 0 : return sal_False;
1786 : :
1787 : 0 : nRow = m_nRow;
1788 : 0 : xResultSetOrigin = m_xResultSetOrigin;
1789 : : }
1790 : :
1791 : : //need to ask origin
1792 : : {
1793 : 0 : if( applyPositionToOrigin( nRow ) )
1794 : 0 : return xResultSetOrigin->isFirst();
1795 : : else
1796 : 0 : return sal_False;
1797 : 0 : }
1798 : : }
1799 : :
1800 : : //virtual
1801 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1802 : : ::isLast()
1803 : : throw( SQLException,
1804 : : RuntimeException )
1805 : : {
1806 : 0 : impl_EnsureNotDisposed();
1807 : :
1808 : 0 : sal_Int32 nRow = 0;
1809 : 0 : Reference< XResultSet > xResultSetOrigin;
1810 : : {
1811 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1812 : 0 : if( m_bAfterLast )
1813 : 0 : return sal_False;
1814 : 0 : if( m_nRow < m_nKnownCount )
1815 : 0 : return sal_False;
1816 : 0 : if( m_bFinalCount )
1817 : 0 : return m_nKnownCount && m_nRow == m_nKnownCount;
1818 : :
1819 : 0 : nRow = m_nRow;
1820 : 0 : xResultSetOrigin = m_xResultSetOrigin;
1821 : : }
1822 : :
1823 : : //need to ask origin
1824 : : {
1825 : 0 : if( applyPositionToOrigin( nRow ) )
1826 : 0 : return xResultSetOrigin->isLast();
1827 : : else
1828 : 0 : return sal_False;
1829 : 0 : }
1830 : : }
1831 : :
1832 : :
1833 : : //virtual
1834 : 0 : sal_Int32 SAL_CALL CachedContentResultSet
1835 : : ::getRow()
1836 : : throw( SQLException,
1837 : : RuntimeException )
1838 : : {
1839 : 0 : impl_EnsureNotDisposed();
1840 : :
1841 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1842 : 0 : if( m_bAfterLast )
1843 : 0 : return 0;
1844 : 0 : return m_nRow;
1845 : : }
1846 : :
1847 : : //virtual
1848 : 0 : void SAL_CALL CachedContentResultSet
1849 : : ::refreshRow()
1850 : : throw( SQLException,
1851 : : RuntimeException )
1852 : : {
1853 : 0 : impl_EnsureNotDisposed();
1854 : :
1855 : : //the ContentResultSet is static and will not change
1856 : : //therefore we don't need to reload anything
1857 : 0 : }
1858 : :
1859 : : //virtual
1860 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1861 : : ::rowUpdated()
1862 : : throw( SQLException,
1863 : : RuntimeException )
1864 : : {
1865 : 0 : impl_EnsureNotDisposed();
1866 : :
1867 : : //the ContentResultSet is static and will not change
1868 : 0 : return sal_False;
1869 : : }
1870 : : //virtual
1871 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1872 : : ::rowInserted()
1873 : : throw( SQLException,
1874 : : RuntimeException )
1875 : : {
1876 : 0 : impl_EnsureNotDisposed();
1877 : :
1878 : : //the ContentResultSet is static and will not change
1879 : 0 : return sal_False;
1880 : : }
1881 : :
1882 : : //virtual
1883 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1884 : : ::rowDeleted()
1885 : : throw( SQLException,
1886 : : RuntimeException )
1887 : : {
1888 : 0 : impl_EnsureNotDisposed();
1889 : :
1890 : : //the ContentResultSet is static and will not change
1891 : 0 : return sal_False;
1892 : : }
1893 : :
1894 : : //virtual
1895 : 0 : Reference< XInterface > SAL_CALL CachedContentResultSet
1896 : : ::getStatement()
1897 : : throw( SQLException,
1898 : : RuntimeException )
1899 : : {
1900 : 0 : impl_EnsureNotDisposed();
1901 : : //@todo ?return anything
1902 : 0 : return Reference< XInterface >();
1903 : : }
1904 : :
1905 : : //-----------------------------------------------------------------
1906 : : // XRow methods. ( inherited )
1907 : : //-----------------------------------------------------------------
1908 : :
1909 : : //virtual
1910 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1911 : : ::wasNull()
1912 : : throw( SQLException,
1913 : : RuntimeException )
1914 : : {
1915 : 0 : impl_EnsureNotDisposed();
1916 : 0 : impl_init_xRowOrigin();
1917 : : {
1918 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
1919 : 0 : if( m_bLastReadWasFromCache )
1920 : 0 : return m_bLastCachedReadWasNull;
1921 : 0 : if( !m_xRowOrigin.is() )
1922 : : {
1923 : : OSL_FAIL( "broadcaster was disposed already" );
1924 : 0 : return sal_False;
1925 : 0 : }
1926 : : }
1927 : 0 : return m_xRowOrigin->wasNull();
1928 : : }
1929 : :
1930 : : //virtual
1931 : 0 : OUString SAL_CALL CachedContentResultSet
1932 : : ::getString( sal_Int32 columnIndex )
1933 : : throw( SQLException,
1934 : : RuntimeException )
1935 : : {
1936 : 0 : XROW_GETXXX( getString, OUString );
1937 : : }
1938 : :
1939 : : //virtual
1940 : 0 : sal_Bool SAL_CALL CachedContentResultSet
1941 : : ::getBoolean( sal_Int32 columnIndex )
1942 : : throw( SQLException,
1943 : : RuntimeException )
1944 : : {
1945 : 0 : XROW_GETXXX( getBoolean, sal_Bool );
1946 : : }
1947 : :
1948 : : //virtual
1949 : 0 : sal_Int8 SAL_CALL CachedContentResultSet
1950 : : ::getByte( sal_Int32 columnIndex )
1951 : : throw( SQLException,
1952 : : RuntimeException )
1953 : : {
1954 : 0 : XROW_GETXXX( getByte, sal_Int8 );
1955 : : }
1956 : :
1957 : : //virtual
1958 : 0 : sal_Int16 SAL_CALL CachedContentResultSet
1959 : : ::getShort( sal_Int32 columnIndex )
1960 : : throw( SQLException,
1961 : : RuntimeException )
1962 : : {
1963 : 0 : XROW_GETXXX( getShort, sal_Int16 );
1964 : : }
1965 : :
1966 : : //virtual
1967 : 0 : sal_Int32 SAL_CALL CachedContentResultSet
1968 : : ::getInt( sal_Int32 columnIndex )
1969 : : throw( SQLException,
1970 : : RuntimeException )
1971 : : {
1972 : 0 : XROW_GETXXX( getInt, sal_Int32 );
1973 : : }
1974 : :
1975 : : //virtual
1976 : 0 : sal_Int64 SAL_CALL CachedContentResultSet
1977 : : ::getLong( sal_Int32 columnIndex )
1978 : : throw( SQLException,
1979 : : RuntimeException )
1980 : : {
1981 : 0 : XROW_GETXXX( getLong, sal_Int64 );
1982 : : }
1983 : :
1984 : : //virtual
1985 : 0 : float SAL_CALL CachedContentResultSet
1986 : : ::getFloat( sal_Int32 columnIndex )
1987 : : throw( SQLException,
1988 : : RuntimeException )
1989 : : {
1990 : 0 : XROW_GETXXX( getFloat, float );
1991 : : }
1992 : :
1993 : : //virtual
1994 : 0 : double SAL_CALL CachedContentResultSet
1995 : : ::getDouble( sal_Int32 columnIndex )
1996 : : throw( SQLException,
1997 : : RuntimeException )
1998 : : {
1999 : 0 : XROW_GETXXX( getDouble, double );
2000 : : }
2001 : :
2002 : : //virtual
2003 : 0 : Sequence< sal_Int8 > SAL_CALL CachedContentResultSet
2004 : : ::getBytes( sal_Int32 columnIndex )
2005 : : throw( SQLException,
2006 : : RuntimeException )
2007 : : {
2008 : 0 : XROW_GETXXX( getBytes, Sequence< sal_Int8 > );
2009 : : }
2010 : :
2011 : : //virtual
2012 : 0 : Date SAL_CALL CachedContentResultSet
2013 : : ::getDate( sal_Int32 columnIndex )
2014 : : throw( SQLException,
2015 : : RuntimeException )
2016 : : {
2017 : 0 : XROW_GETXXX( getDate, Date );
2018 : : }
2019 : :
2020 : : //virtual
2021 : 0 : Time SAL_CALL CachedContentResultSet
2022 : : ::getTime( sal_Int32 columnIndex )
2023 : : throw( SQLException,
2024 : : RuntimeException )
2025 : : {
2026 : 0 : XROW_GETXXX( getTime, Time );
2027 : : }
2028 : :
2029 : : //virtual
2030 : 0 : DateTime SAL_CALL CachedContentResultSet
2031 : : ::getTimestamp( sal_Int32 columnIndex )
2032 : : throw( SQLException,
2033 : : RuntimeException )
2034 : : {
2035 : 0 : XROW_GETXXX( getTimestamp, DateTime );
2036 : : }
2037 : :
2038 : : //virtual
2039 : : Reference< com::sun::star::io::XInputStream >
2040 : 0 : SAL_CALL CachedContentResultSet
2041 : : ::getBinaryStream( sal_Int32 columnIndex )
2042 : : throw( SQLException,
2043 : : RuntimeException )
2044 : : {
2045 : 0 : XROW_GETXXX( getBinaryStream, Reference< com::sun::star::io::XInputStream > );
2046 : : }
2047 : :
2048 : : //virtual
2049 : : Reference< com::sun::star::io::XInputStream >
2050 : 0 : SAL_CALL CachedContentResultSet
2051 : : ::getCharacterStream( sal_Int32 columnIndex )
2052 : : throw( SQLException,
2053 : : RuntimeException )
2054 : : {
2055 : 0 : XROW_GETXXX( getCharacterStream, Reference< com::sun::star::io::XInputStream > );
2056 : : }
2057 : :
2058 : : //virtual
2059 : 0 : Any SAL_CALL CachedContentResultSet
2060 : : ::getObject( sal_Int32 columnIndex,
2061 : : const Reference<
2062 : : com::sun::star::container::XNameAccess >& typeMap )
2063 : : throw( SQLException,
2064 : : RuntimeException )
2065 : : {
2066 : : //if you change this macro please pay attention to
2067 : : //define XROW_GETXXX, where this is similar implemented
2068 : :
2069 : 0 : ReacquireableGuard aGuard( m_aMutex );
2070 : 0 : sal_Int32 nRow = m_nRow;
2071 : 0 : sal_Int32 nFetchSize = m_nFetchSize;
2072 : 0 : sal_Int32 nFetchDirection = m_nFetchDirection;
2073 : 0 : if( !m_aCache.hasRow( nRow ) )
2074 : : {
2075 : 0 : if( !m_aCache.hasCausedException( nRow ) )
2076 : : {
2077 : 0 : if( !m_xFetchProvider.is() )
2078 : : {
2079 : : OSL_FAIL( "broadcaster was disposed already" );
2080 : 0 : return Any();
2081 : : }
2082 : 0 : aGuard.clear();
2083 : :
2084 : 0 : impl_fetchData( nRow, nFetchSize, nFetchDirection );
2085 : : }
2086 : 0 : aGuard.reacquire();
2087 : 0 : if( !m_aCache.hasRow( nRow ) )
2088 : : {
2089 : 0 : m_bLastReadWasFromCache = sal_False;
2090 : 0 : aGuard.clear();
2091 : 0 : applyPositionToOrigin( nRow );
2092 : 0 : impl_init_xRowOrigin();
2093 : 0 : return m_xRowOrigin->getObject( columnIndex, typeMap );
2094 : : }
2095 : : }
2096 : : //@todo: pay attention to typeMap
2097 : 0 : const Any& rValue = m_aCache.getAny( nRow, columnIndex );
2098 : 0 : Any aRet;
2099 : 0 : m_bLastReadWasFromCache = sal_True;
2100 : 0 : m_bLastCachedReadWasNull = !( rValue >>= aRet );
2101 : 0 : return aRet;
2102 : : }
2103 : :
2104 : : //virtual
2105 : 0 : Reference< XRef > SAL_CALL CachedContentResultSet
2106 : : ::getRef( sal_Int32 columnIndex )
2107 : : throw( SQLException,
2108 : : RuntimeException )
2109 : : {
2110 : 0 : XROW_GETXXX( getRef, Reference< XRef > );
2111 : : }
2112 : :
2113 : : //virtual
2114 : 0 : Reference< XBlob > SAL_CALL CachedContentResultSet
2115 : : ::getBlob( sal_Int32 columnIndex )
2116 : : throw( SQLException,
2117 : : RuntimeException )
2118 : : {
2119 : 0 : XROW_GETXXX( getBlob, Reference< XBlob > );
2120 : : }
2121 : :
2122 : : //virtual
2123 : 0 : Reference< XClob > SAL_CALL CachedContentResultSet
2124 : : ::getClob( sal_Int32 columnIndex )
2125 : : throw( SQLException,
2126 : : RuntimeException )
2127 : : {
2128 : 0 : XROW_GETXXX( getClob, Reference< XClob > );
2129 : : }
2130 : :
2131 : : //virtual
2132 : 0 : Reference< XArray > SAL_CALL CachedContentResultSet
2133 : : ::getArray( sal_Int32 columnIndex )
2134 : : throw( SQLException,
2135 : : RuntimeException )
2136 : : {
2137 : 0 : XROW_GETXXX( getArray, Reference< XArray > );
2138 : : }
2139 : :
2140 : : //-----------------------------------------------------------------
2141 : : // Type Converter Support
2142 : : //-----------------------------------------------------------------
2143 : :
2144 : 0 : const Reference< XTypeConverter >& CachedContentResultSet::getTypeConverter()
2145 : : {
2146 : 0 : osl::Guard< osl::Mutex > aGuard( m_aMutex );
2147 : :
2148 : 0 : if ( !m_bTriedToGetTypeConverter && !m_xTypeConverter.is() )
2149 : : {
2150 : 0 : m_bTriedToGetTypeConverter = sal_True;
2151 : : m_xTypeConverter = Reference< XTypeConverter >(
2152 : 0 : m_xSMgr->createInstance(
2153 : 0 : OUString( "com.sun.star.script.Converter" ) ),
2154 : 0 : UNO_QUERY );
2155 : :
2156 : : OSL_ENSURE( m_xTypeConverter.is(),
2157 : : "PropertyValueSet::getTypeConverter() - "
2158 : : "Service 'com.sun.star.script.Converter' n/a!" );
2159 : : }
2160 : 0 : return m_xTypeConverter;
2161 : : }
2162 : :
2163 : : //--------------------------------------------------------------------------
2164 : : //--------------------------------------------------------------------------
2165 : : // class CachedContentResultSetFactory
2166 : : //--------------------------------------------------------------------------
2167 : : //--------------------------------------------------------------------------
2168 : :
2169 : 0 : CachedContentResultSetFactory::CachedContentResultSetFactory(
2170 : 0 : const Reference< XMultiServiceFactory > & rSMgr )
2171 : : {
2172 : 0 : m_xSMgr = rSMgr;
2173 : 0 : }
2174 : :
2175 : 0 : CachedContentResultSetFactory::~CachedContentResultSetFactory()
2176 : : {
2177 : 0 : }
2178 : :
2179 : : //--------------------------------------------------------------------------
2180 : : // CachedContentResultSetFactory XInterface methods.
2181 : : //--------------------------------------------------------------------------
2182 : :
2183 : 0 : XINTERFACE_IMPL_3( CachedContentResultSetFactory,
2184 : : XTypeProvider,
2185 : : XServiceInfo,
2186 : : XCachedContentResultSetFactory );
2187 : :
2188 : : //--------------------------------------------------------------------------
2189 : : // CachedContentResultSetFactory XTypeProvider methods.
2190 : : //--------------------------------------------------------------------------
2191 : :
2192 : 0 : XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory,
2193 : : XTypeProvider,
2194 : : XServiceInfo,
2195 : : XCachedContentResultSetFactory );
2196 : :
2197 : : //--------------------------------------------------------------------------
2198 : : // CachedContentResultSetFactory XServiceInfo methods.
2199 : : //--------------------------------------------------------------------------
2200 : :
2201 : 0 : XSERVICEINFO_IMPL_1( CachedContentResultSetFactory,
2202 : : OUString( "com.sun.star.comp.ucb.CachedContentResultSetFactory" ),
2203 : 0 : OUString( CACHED_CONTENT_RESULTSET_FACTORY_NAME ) );
2204 : :
2205 : : //--------------------------------------------------------------------------
2206 : : // Service factory implementation.
2207 : : //--------------------------------------------------------------------------
2208 : :
2209 : 0 : ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory );
2210 : :
2211 : : //--------------------------------------------------------------------------
2212 : : // CachedContentResultSetFactory XCachedContentResultSetFactory methods.
2213 : : //--------------------------------------------------------------------------
2214 : :
2215 : : //virtual
2216 : 0 : Reference< XResultSet > SAL_CALL CachedContentResultSetFactory
2217 : : ::createCachedContentResultSet(
2218 : : const Reference< XResultSet > & xSource,
2219 : : const Reference< XContentIdentifierMapping > & xMapping )
2220 : : throw( com::sun::star::uno::RuntimeException )
2221 : : {
2222 : 0 : Reference< XResultSet > xRet;
2223 : 0 : xRet = new CachedContentResultSet( m_xSMgr, xSource, xMapping );
2224 : 0 : return xRet;
2225 : 0 : }
2226 : :
2227 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|