LCOV - code coverage report
Current view: top level - libreoffice/ucb/source/cacher - cachedcontentresultset.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 845 0.0 %
Date: 2012-12-17 Functions: 0 117 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10