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

Generated by: LCOV version 1.10