| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_ucb.hxx" |
| |
| #include <cachedcontentresultset.hxx> |
| #include <com/sun/star/sdbc/FetchDirection.hpp> |
| #include <com/sun/star/ucb/FetchError.hpp> |
| #include <com/sun/star/ucb/ResultSetException.hpp> |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/script/XTypeConverter.hpp> |
| #include <com/sun/star/sdbc/ResultSetType.hpp> |
| #include <rtl/ustring.hxx> |
| #include <osl/diagnose.h> |
| |
| using namespace com::sun::star::beans; |
| using namespace com::sun::star::lang; |
| using namespace com::sun::star::script; |
| using namespace com::sun::star::sdbc; |
| using namespace com::sun::star::ucb; |
| using namespace com::sun::star::uno; |
| using namespace com::sun::star::util; |
| using namespace cppu; |
| using namespace rtl; |
| |
| #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE 256 |
| #define COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION FetchDirection::FORWARD |
| |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| //define for getXXX methods of interface XRow |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| |
| //if you change this macro please pay attention to |
| //function ::getObject, where this is similar implemented |
| |
| #define XROW_GETXXX( getXXX, Type ) \ |
| impl_EnsureNotDisposed(); \ |
| ReacquireableGuard aGuard( m_aMutex ); \ |
| sal_Int32 nRow = m_nRow; \ |
| sal_Int32 nFetchSize = m_nFetchSize; \ |
| sal_Int32 nFetchDirection = m_nFetchDirection; \ |
| if( !m_aCache.hasRow( nRow ) ) \ |
| { \ |
| if( !m_aCache.hasCausedException( nRow ) ) \ |
| { \ |
| if( !m_xFetchProvider.is() ) \ |
| { \ |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \ |
| throw SQLException(); \ |
| } \ |
| aGuard.clear(); \ |
| if( impl_isForwardOnly() ) \ |
| applyPositionToOrigin( nRow ); \ |
| \ |
| impl_fetchData( nRow, nFetchSize, nFetchDirection ); \ |
| } \ |
| aGuard.reacquire(); \ |
| if( !m_aCache.hasRow( nRow ) ) \ |
| { \ |
| m_bLastReadWasFromCache = sal_False; \ |
| aGuard.clear(); \ |
| applyPositionToOrigin( nRow ); \ |
| impl_init_xRowOrigin(); \ |
| return m_xRowOrigin->getXXX( columnIndex ); \ |
| } \ |
| } \ |
| const Any& rValue = m_aCache.getAny( nRow, columnIndex );\ |
| Type aRet = Type(); \ |
| m_bLastReadWasFromCache = sal_True; \ |
| m_bLastCachedReadWasNull = !( rValue >>= aRet ); \ |
| /* Last chance. Try type converter service... */ \ |
| if ( m_bLastCachedReadWasNull && rValue.hasValue() ) \ |
| { \ |
| Reference< XTypeConverter > xConverter \ |
| = getTypeConverter(); \ |
| if ( xConverter.is() ) \ |
| { \ |
| try \ |
| { \ |
| Any aConvAny = xConverter->convertTo( \ |
| rValue, \ |
| getCppuType( static_cast< \ |
| const Type * >( 0 ) ) ); \ |
| m_bLastCachedReadWasNull = !( aConvAny >>= aRet ); \ |
| } \ |
| catch ( IllegalArgumentException ) \ |
| { \ |
| } \ |
| catch ( CannotConvertException ) \ |
| { \ |
| } \ |
| } \ |
| } \ |
| return aRet; |
| |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| // CCRS_Cache methoeds. |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| |
| CachedContentResultSet::CCRS_Cache::CCRS_Cache( |
| const Reference< XContentIdentifierMapping > & xMapping ) |
| : m_pResult( NULL ) |
| , m_xContentIdentifierMapping( xMapping ) |
| , m_pMappedReminder( NULL ) |
| { |
| } |
| |
| CachedContentResultSet::CCRS_Cache::~CCRS_Cache() |
| { |
| delete m_pResult; |
| } |
| |
| void SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::clear() |
| { |
| if( m_pResult ) |
| { |
| delete m_pResult; |
| m_pResult = NULL; |
| } |
| clearMappedReminder(); |
| } |
| |
| void SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::loadData( const FetchResult& rResult ) |
| { |
| clear(); |
| m_pResult = new FetchResult( rResult ); |
| } |
| |
| sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::hasRow( sal_Int32 row ) |
| { |
| if( !m_pResult ) |
| return sal_False; |
| long nStart = m_pResult->StartIndex; |
| long nEnd = nStart; |
| if( m_pResult->Orientation ) |
| nEnd += m_pResult->Rows.getLength() - 1; |
| else |
| nStart -= m_pResult->Rows.getLength() + 1; |
| |
| return nStart <= row && row <= nEnd; |
| } |
| |
| sal_Int32 SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getMaxRow() |
| { |
| if( !m_pResult ) |
| return 0; |
| long nEnd = m_pResult->StartIndex; |
| if( m_pResult->Orientation ) |
| return nEnd += m_pResult->Rows.getLength() - 1; |
| else |
| return nEnd; |
| } |
| |
| sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::hasKnownLast() |
| { |
| if( !m_pResult ) |
| return sal_False; |
| |
| if( ( m_pResult->FetchError & FetchError::ENDOFDATA ) |
| && m_pResult->Orientation |
| && m_pResult->Rows.getLength() ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::hasCausedException( sal_Int32 nRow ) |
| { |
| if( !m_pResult ) |
| return sal_False; |
| if( !( m_pResult->FetchError & FetchError::EXCEPTION ) ) |
| return sal_False; |
| |
| long nEnd = m_pResult->StartIndex; |
| if( m_pResult->Orientation ) |
| nEnd += m_pResult->Rows.getLength(); |
| |
| return nRow == nEnd+1; |
| } |
| |
| Any& SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getRowAny( sal_Int32 nRow ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| if( !nRow ) |
| throw SQLException(); |
| if( !m_pResult ) |
| throw SQLException(); |
| if( !hasRow( nRow ) ) |
| throw SQLException(); |
| |
| long nDiff = nRow - m_pResult->StartIndex; |
| if( nDiff < 0 ) |
| nDiff *= -1; |
| |
| return (m_pResult->Rows)[nDiff]; |
| } |
| |
| void SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::remindMapped( sal_Int32 nRow ) |
| { |
| //remind that this row was mapped |
| if( !m_pResult ) |
| return; |
| long nDiff = nRow - m_pResult->StartIndex; |
| if( nDiff < 0 ) |
| nDiff *= -1; |
| Sequence< sal_Bool >* pMappedReminder = getMappedReminder(); |
| if( nDiff < pMappedReminder->getLength() ) |
| (*pMappedReminder)[nDiff] = sal_True; |
| } |
| |
| sal_Bool SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::isRowMapped( sal_Int32 nRow ) |
| { |
| if( !m_pMappedReminder || !m_pResult ) |
| return sal_False; |
| long nDiff = nRow - m_pResult->StartIndex; |
| if( nDiff < 0 ) |
| nDiff *= -1; |
| if( nDiff < m_pMappedReminder->getLength() ) |
| return (*m_pMappedReminder)[nDiff]; |
| return sal_False; |
| } |
| |
| void SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::clearMappedReminder() |
| { |
| delete m_pMappedReminder; |
| m_pMappedReminder = NULL; |
| } |
| |
| Sequence< sal_Bool >* SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getMappedReminder() |
| { |
| if( !m_pMappedReminder ) |
| { |
| sal_Int32 nCount = m_pResult->Rows.getLength(); |
| m_pMappedReminder = new Sequence< sal_Bool >( nCount ); |
| for( ;nCount; nCount-- ) |
| (*m_pMappedReminder)[nCount] = sal_False; |
| } |
| return m_pMappedReminder; |
| } |
| |
| const Any& SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getAny( sal_Int32 nRow, sal_Int32 nColumnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| if( !nColumnIndex ) |
| throw SQLException(); |
| if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) ) |
| { |
| Any& rRow = getRowAny( nRow ); |
| Sequence< Any > aValue; |
| rRow >>= aValue; |
| if( m_xContentIdentifierMapping->mapRow( aValue ) ) |
| { |
| rRow <<= aValue; |
| remindMapped( nRow ); |
| } |
| else |
| m_xContentIdentifierMapping.clear(); |
| } |
| const Sequence< Any >& rRow = |
| (* reinterpret_cast< const Sequence< Any > * > |
| (getRowAny( nRow ).getValue() )); |
| |
| if( nColumnIndex > rRow.getLength() ) |
| throw SQLException(); |
| return rRow[nColumnIndex-1]; |
| } |
| |
| const rtl::OUString& SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getContentIdentifierString( sal_Int32 nRow ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| try |
| { |
| if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) ) |
| { |
| Any& rRow = getRowAny( nRow ); |
| rtl::OUString aValue; |
| rRow >>= aValue; |
| rRow <<= m_xContentIdentifierMapping->mapContentIdentifierString( aValue ); |
| remindMapped( nRow ); |
| } |
| return (* reinterpret_cast< const rtl::OUString * > |
| (getRowAny( nRow ).getValue() )); |
| } |
| catch( SQLException ) |
| { |
| throw RuntimeException(); |
| } |
| } |
| |
| const Reference< XContentIdentifier >& SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getContentIdentifier( sal_Int32 nRow ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| try |
| { |
| if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) ) |
| { |
| Any& rRow = getRowAny( nRow ); |
| Reference< XContentIdentifier > aValue; |
| rRow >>= aValue; |
| rRow <<= m_xContentIdentifierMapping->mapContentIdentifier( aValue ); |
| remindMapped( nRow ); |
| } |
| return (* reinterpret_cast< const Reference< XContentIdentifier > * > |
| (getRowAny( nRow ).getValue() )); |
| } |
| catch( SQLException ) |
| { |
| throw RuntimeException(); |
| } |
| } |
| |
| const Reference< XContent >& SAL_CALL CachedContentResultSet::CCRS_Cache |
| ::getContent( sal_Int32 nRow ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| try |
| { |
| if( m_xContentIdentifierMapping.is() && !isRowMapped( nRow ) ) |
| { |
| Any& rRow = getRowAny( nRow ); |
| Reference< XContent > aValue; |
| rRow >>= aValue; |
| rRow <<= m_xContentIdentifierMapping->mapContent( aValue ); |
| remindMapped( nRow ); |
| } |
| return (* reinterpret_cast< const Reference< XContent > * > |
| (getRowAny( nRow ).getValue() )); |
| } |
| catch( SQLException ) |
| { |
| throw RuntimeException(); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| // class CCRS_PropertySetInfo |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| |
| class CCRS_PropertySetInfo : |
| public cppu::OWeakObject, |
| public com::sun::star::lang::XTypeProvider, |
| public com::sun::star::beans::XPropertySetInfo |
| { |
| friend class CachedContentResultSet; |
| |
| //my Properties |
| Sequence< com::sun::star::beans::Property >* |
| m_pProperties; |
| |
| //some helping variables ( names for my special properties ) |
| static rtl::OUString m_aPropertyNameForCount; |
| static rtl::OUString m_aPropertyNameForFinalCount; |
| static rtl::OUString m_aPropertyNameForFetchSize; |
| static rtl::OUString m_aPropertyNameForFetchDirection; |
| |
| long m_nFetchSizePropertyHandle; |
| long m_nFetchDirectionPropertyHandle; |
| |
| private: |
| sal_Int32 SAL_CALL |
| impl_getRemainedHandle() const; |
| |
| sal_Bool SAL_CALL |
| impl_queryProperty( |
| const rtl::OUString& rName |
| , com::sun::star::beans::Property& rProp ) const; |
| sal_Int32 SAL_CALL |
| impl_getPos( const rtl::OUString& rName ) const; |
| |
| static sal_Bool SAL_CALL |
| impl_isMyPropertyName( const rtl::OUString& rName ); |
| |
| public: |
| CCRS_PropertySetInfo( Reference< |
| XPropertySetInfo > xPropertySetInfoOrigin ); |
| |
| virtual ~CCRS_PropertySetInfo(); |
| |
| // XInterface |
| XINTERFACE_DECL() |
| |
| // XTypeProvider |
| XTYPEPROVIDER_DECL() |
| |
| // XPropertySetInfo |
| virtual Sequence< com::sun::star::beans::Property > SAL_CALL |
| getProperties() |
| throw( RuntimeException ); |
| |
| virtual com::sun::star::beans::Property SAL_CALL |
| getPropertyByName( const rtl::OUString& aName ) |
| throw( com::sun::star::beans::UnknownPropertyException, RuntimeException ); |
| |
| virtual sal_Bool SAL_CALL |
| hasPropertyByName( const rtl::OUString& Name ) |
| throw( RuntimeException ); |
| }; |
| |
| OUString CCRS_PropertySetInfo::m_aPropertyNameForCount( OUString::createFromAscii( "RowCount" ) ); |
| OUString CCRS_PropertySetInfo::m_aPropertyNameForFinalCount( OUString::createFromAscii( "IsRowCountFinal" ) ); |
| OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) ); |
| OUString CCRS_PropertySetInfo::m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) ); |
| |
| CCRS_PropertySetInfo::CCRS_PropertySetInfo( |
| Reference< XPropertySetInfo > xInfo ) |
| : m_pProperties( NULL ) |
| , m_nFetchSizePropertyHandle( -1 ) |
| , m_nFetchDirectionPropertyHandle( -1 ) |
| { |
| //initialize list of properties: |
| |
| // it is required, that the received xInfo contains the two |
| // properties with names 'm_aPropertyNameForCount' and |
| // 'm_aPropertyNameForFinalCount' |
| |
| if( xInfo.is() ) |
| { |
| Sequence<Property> aProps = xInfo->getProperties(); |
| m_pProperties = new Sequence<Property> ( aProps ); |
| } |
| else |
| { |
| OSL_ENSURE( sal_False, "The received XPropertySetInfo doesn't contain required properties" ); |
| m_pProperties = new Sequence<Property>; |
| } |
| |
| //ensure, that we haven't got the Properties 'FetchSize' and 'Direction' twice: |
| sal_Int32 nFetchSize = impl_getPos( m_aPropertyNameForFetchSize ); |
| sal_Int32 nFetchDirection = impl_getPos( m_aPropertyNameForFetchDirection ); |
| sal_Int32 nDeleted = 0; |
| if( nFetchSize != -1 ) |
| nDeleted++; |
| if( nFetchDirection != -1 ) |
| nDeleted++; |
| |
| Sequence< Property >* pOrigProps = new Sequence<Property> ( *m_pProperties ); |
| sal_Int32 nOrigProps = pOrigProps->getLength(); |
| |
| m_pProperties->realloc( nOrigProps + 2 - nDeleted );//note that nDeleted is <= 2 |
| for( sal_Int32 n = 0, m = 0; n < nOrigProps; n++, m++ ) |
| { |
| if( n == nFetchSize || n == nFetchDirection ) |
| m--; |
| else |
| (*m_pProperties)[ m ] = (*pOrigProps)[ n ]; |
| } |
| { |
| Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted ]; |
| rMyProp.Name = m_aPropertyNameForFetchSize; |
| rMyProp.Type = getCppuType( static_cast< const sal_Int32 * >( 0 ) ); |
| rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT; |
| |
| if( nFetchSize != -1 ) |
| m_nFetchSizePropertyHandle = (*pOrigProps)[nFetchSize].Handle; |
| else |
| m_nFetchSizePropertyHandle = impl_getRemainedHandle(); |
| |
| rMyProp.Handle = m_nFetchSizePropertyHandle; |
| |
| } |
| { |
| Property& rMyProp = (*m_pProperties)[ nOrigProps - nDeleted + 1 ]; |
| rMyProp.Name = m_aPropertyNameForFetchDirection; |
| rMyProp.Type = getCppuType( static_cast< const sal_Bool * >( 0 ) ); |
| rMyProp.Attributes = PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT; |
| |
| if( nFetchSize != -1 ) |
| m_nFetchDirectionPropertyHandle = (*pOrigProps)[nFetchDirection].Handle; |
| else |
| m_nFetchDirectionPropertyHandle = impl_getRemainedHandle(); |
| |
| m_nFetchDirectionPropertyHandle = rMyProp.Handle; |
| } |
| delete pOrigProps; |
| } |
| |
| CCRS_PropertySetInfo::~CCRS_PropertySetInfo() |
| { |
| delete m_pProperties; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // XInterface methods. |
| //-------------------------------------------------------------------------- |
| //list all interfaces inclusive baseclasses of interfaces |
| XINTERFACE_IMPL_2( CCRS_PropertySetInfo |
| , XTypeProvider |
| , XPropertySetInfo |
| ); |
| |
| //-------------------------------------------------------------------------- |
| // XTypeProvider methods. |
| //-------------------------------------------------------------------------- |
| //list all interfaces exclusive baseclasses |
| XTYPEPROVIDER_IMPL_2( CCRS_PropertySetInfo |
| , XTypeProvider |
| , XPropertySetInfo |
| ); |
| //-------------------------------------------------------------------------- |
| // XPropertySetInfo methods. |
| //-------------------------------------------------------------------------- |
| //virtual |
| Sequence< Property > SAL_CALL CCRS_PropertySetInfo |
| ::getProperties() throw( RuntimeException ) |
| { |
| return *m_pProperties; |
| } |
| |
| //virtual |
| Property SAL_CALL CCRS_PropertySetInfo |
| ::getPropertyByName( const rtl::OUString& aName ) |
| throw( UnknownPropertyException, RuntimeException ) |
| { |
| if ( !aName.getLength() ) |
| throw UnknownPropertyException(); |
| |
| Property aProp; |
| if ( impl_queryProperty( aName, aProp ) ) |
| return aProp; |
| |
| throw UnknownPropertyException(); |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CCRS_PropertySetInfo |
| ::hasPropertyByName( const rtl::OUString& Name ) |
| throw( RuntimeException ) |
| { |
| return ( impl_getPos( Name ) != -1 ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // impl_ methods. |
| //-------------------------------------------------------------------------- |
| |
| sal_Int32 SAL_CALL CCRS_PropertySetInfo |
| ::impl_getPos( const OUString& rName ) const |
| { |
| for( sal_Int32 nN = m_pProperties->getLength(); nN--; ) |
| { |
| const Property& rMyProp = (*m_pProperties)[nN]; |
| if( rMyProp.Name == rName ) |
| return nN; |
| } |
| return -1; |
| } |
| |
| sal_Bool SAL_CALL CCRS_PropertySetInfo |
| ::impl_queryProperty( const OUString& rName, Property& rProp ) const |
| { |
| for( sal_Int32 nN = m_pProperties->getLength(); nN--; ) |
| { |
| const Property& rMyProp = (*m_pProperties)[nN]; |
| if( rMyProp.Name == rName ) |
| { |
| rProp.Name = rMyProp.Name; |
| rProp.Handle = rMyProp.Handle; |
| rProp.Type = rMyProp.Type; |
| rProp.Attributes = rMyProp.Attributes; |
| |
| return sal_True; |
| } |
| } |
| return sal_False; |
| } |
| |
| //static |
| sal_Bool SAL_CALL CCRS_PropertySetInfo |
| ::impl_isMyPropertyName( const OUString& rPropertyName ) |
| { |
| return ( rPropertyName == m_aPropertyNameForCount |
| || rPropertyName == m_aPropertyNameForFinalCount |
| || rPropertyName == m_aPropertyNameForFetchSize |
| || rPropertyName == m_aPropertyNameForFetchDirection ); |
| } |
| |
| sal_Int32 SAL_CALL CCRS_PropertySetInfo |
| ::impl_getRemainedHandle( ) const |
| { |
| sal_Int32 nHandle = 1; |
| |
| if( !m_pProperties ) |
| { |
| OSL_ENSURE( sal_False, "Properties not initialized yet" ); |
| return nHandle; |
| } |
| sal_Bool bFound = sal_True; |
| while( bFound ) |
| { |
| bFound = sal_False; |
| for( sal_Int32 nN = m_pProperties->getLength(); nN--; ) |
| { |
| if( nHandle == (*m_pProperties)[nN].Handle ) |
| { |
| bFound = sal_True; |
| nHandle++; |
| break; |
| } |
| } |
| } |
| return nHandle; |
| } |
| |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| // class CachedContentResultSet |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| |
| CachedContentResultSet::CachedContentResultSet( |
| const Reference< XMultiServiceFactory > & xSMgr |
| , const Reference< XResultSet > & xOrigin |
| , const Reference< XContentIdentifierMapping > & |
| xContentIdentifierMapping ) |
| : ContentResultSetWrapper( xOrigin ) |
| |
| , m_xSMgr( xSMgr ) |
| , m_xFetchProvider( NULL ) |
| , m_xFetchProviderForContentAccess( NULL ) |
| |
| , m_xMyPropertySetInfo( NULL ) |
| , m_pMyPropSetInfo( NULL ) |
| |
| , m_xContentIdentifierMapping( xContentIdentifierMapping ) |
| , m_nRow( 0 ) // Position is one-based. Zero means: before first element. |
| , m_bAfterLast( sal_False ) |
| , m_nLastAppliedPos( 0 ) |
| , m_bAfterLastApplied( sal_False ) |
| , m_nKnownCount( 0 ) |
| , m_bFinalCount( sal_False ) |
| , m_nFetchSize( |
| COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE ) |
| , m_nFetchDirection( |
| COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION ) |
| |
| , m_bLastReadWasFromCache( sal_False ) |
| , m_bLastCachedReadWasNull( sal_True ) |
| , m_aCache( m_xContentIdentifierMapping ) |
| , m_aCacheContentIdentifierString( m_xContentIdentifierMapping ) |
| , m_aCacheContentIdentifier( m_xContentIdentifierMapping ) |
| , m_aCacheContent( m_xContentIdentifierMapping ) |
| , m_bTriedToGetTypeConverter( sal_False ) |
| , m_xTypeConverter( NULL ) |
| { |
| m_xFetchProvider = Reference< XFetchProvider >( m_xResultSetOrigin, UNO_QUERY ); |
| OSL_ENSURE( m_xFetchProvider.is(), "interface XFetchProvider is required" ); |
| |
| m_xFetchProviderForContentAccess = Reference< XFetchProviderForContentAccess >( m_xResultSetOrigin, UNO_QUERY ); |
| OSL_ENSURE( m_xFetchProviderForContentAccess.is(), "interface XFetchProviderForContentAccess is required" ); |
| |
| impl_init(); |
| }; |
| |
| CachedContentResultSet::~CachedContentResultSet() |
| { |
| impl_deinit(); |
| //do not delete m_pMyPropSetInfo, cause it is hold via reference |
| }; |
| |
| //-------------------------------------------------------------------------- |
| // impl_ methods. |
| //-------------------------------------------------------------------------- |
| |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::applyPositionToOrigin( sal_Int32 nRow ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| //------------------------------------------------------------------------- |
| /** |
| @returns |
| <TRUE/> if the cursor is on a valid row; <FALSE/> if it is off |
| the result set. |
| */ |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| OSL_ENSURE( nRow >= 0, "only positive values supported" ); |
| if( !m_xResultSetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return sal_False; |
| } |
| // OSL_ENSURE( nRow <= m_nKnownCount, "don't step into regions you don't know with this method" ); |
| |
| sal_Int32 nLastAppliedPos = m_nLastAppliedPos; |
| sal_Bool bAfterLastApplied = m_bAfterLastApplied; |
| sal_Bool bAfterLast = m_bAfterLast; |
| sal_Int32 nForwardOnly = m_nForwardOnly; |
| |
| aGuard.clear(); |
| |
| if( bAfterLastApplied || nLastAppliedPos != nRow ) |
| { |
| if( nForwardOnly == 1 ) |
| { |
| if( bAfterLastApplied || bAfterLast || !nRow || nRow < nLastAppliedPos ) |
| throw SQLException(); |
| |
| sal_Int32 nN = nRow - nLastAppliedPos; |
| sal_Int32 nM; |
| for( nM = 0; nN--; nM++ ) |
| { |
| if( !m_xResultSetOrigin->next() ) |
| break; |
| } |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos += nM; |
| m_bAfterLastApplied = nRow != m_nLastAppliedPos; |
| return nRow == m_nLastAppliedPos; |
| } |
| |
| if( !nRow ) //absolute( 0 ) will throw exception |
| { |
| m_xResultSetOrigin->beforeFirst(); |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos = 0; |
| m_bAfterLastApplied = sal_False; |
| return sal_False; |
| } |
| try |
| { |
| //move absolute, if !nLastAppliedPos |
| //because move relative would throw exception |
| if( !nLastAppliedPos || bAfterLast || bAfterLastApplied ) |
| { |
| sal_Bool bValid = m_xResultSetOrigin->absolute( nRow ); |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos = nRow; |
| m_bAfterLastApplied = !bValid; |
| return bValid; |
| } |
| else |
| { |
| sal_Bool bValid = m_xResultSetOrigin->relative( nRow - nLastAppliedPos ); |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos += ( nRow - nLastAppliedPos ); |
| m_bAfterLastApplied = !bValid; |
| return bValid; |
| } |
| } |
| catch( SQLException& rEx ) |
| { |
| if( !bAfterLastApplied && !bAfterLast && nRow > nLastAppliedPos && impl_isForwardOnly() ) |
| { |
| sal_Int32 nN = nRow - nLastAppliedPos; |
| sal_Int32 nM; |
| for( nM = 0; nN--; nM++ ) |
| { |
| if( !m_xResultSetOrigin->next() ) |
| break; |
| } |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos += nM; |
| m_bAfterLastApplied = nRow != m_nLastAppliedPos; |
| } |
| else |
| throw rEx; |
| } |
| |
| return nRow == m_nLastAppliedPos; |
| } |
| return sal_True; |
| }; |
| |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| //define for fetching data |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| |
| #define FETCH_XXX( aCache, fetchInterface, fetchMethod ) \ |
| sal_Bool bDirection = !!( \ |
| nFetchDirection != FetchDirection::REVERSE ); \ |
| FetchResult aResult = \ |
| fetchInterface->fetchMethod( nRow, nFetchSize, bDirection ); \ |
| osl::ClearableGuard< osl::Mutex > aGuard2( m_aMutex ); \ |
| aCache.loadData( aResult ); \ |
| sal_Int32 nMax = aCache.getMaxRow(); \ |
| sal_Int32 nCurCount = m_nKnownCount; \ |
| sal_Bool bIsFinalCount = aCache.hasKnownLast(); \ |
| sal_Bool bCurIsFinalCount = m_bFinalCount; \ |
| aGuard2.clear(); \ |
| if( nMax > nCurCount ) \ |
| impl_changeRowCount( nCurCount, nMax ); \ |
| if( bIsFinalCount && !bCurIsFinalCount ) \ |
| impl_changeIsRowCountFinal( bCurIsFinalCount, bIsFinalCount ); |
| |
| void SAL_CALL CachedContentResultSet |
| ::impl_fetchData( sal_Int32 nRow |
| , sal_Int32 nFetchSize, sal_Int32 nFetchDirection ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| FETCH_XXX( m_aCache, m_xFetchProvider, fetch ); |
| } |
| |
| void SAL_CALL CachedContentResultSet |
| ::impl_changeRowCount( sal_Int32 nOld, sal_Int32 nNew ) |
| { |
| OSL_ENSURE( nNew > nOld, "RowCount only can grow" ); |
| if( nNew <= nOld ) |
| return; |
| |
| //create PropertyChangeEvent and set value |
| PropertyChangeEvent aEvt; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aEvt.Source = static_cast< XPropertySet * >( this ); |
| aEvt.Further = sal_False; |
| aEvt.OldValue <<= nOld; |
| aEvt.NewValue <<= nNew; |
| |
| m_nKnownCount = nNew; |
| } |
| |
| //send PropertyChangeEvent to listeners |
| impl_notifyPropertyChangeListeners( aEvt ); |
| } |
| |
| void SAL_CALL CachedContentResultSet |
| ::impl_changeIsRowCountFinal( sal_Bool bOld, sal_Bool bNew ) |
| { |
| OSL_ENSURE( !bOld && bNew, "This change is not allowed for IsRowCountFinal" ); |
| if( ! (!bOld && bNew ) ) |
| return; |
| |
| //create PropertyChangeEvent and set value |
| PropertyChangeEvent aEvt; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aEvt.Source = static_cast< XPropertySet * >( this ); |
| aEvt.Further = sal_False; |
| aEvt.OldValue <<= bOld; |
| aEvt.NewValue <<= bNew; |
| |
| m_bFinalCount = bNew; |
| } |
| |
| //send PropertyChangeEvent to listeners |
| impl_notifyPropertyChangeListeners( aEvt ); |
| } |
| |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::impl_isKnownValidPosition( sal_Int32 nRow ) |
| { |
| return m_nKnownCount && nRow |
| && nRow <= m_nKnownCount; |
| } |
| |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::impl_isKnownInvalidPosition( sal_Int32 nRow ) |
| { |
| if( !nRow ) |
| return sal_True; |
| if( !m_bFinalCount ) |
| return sal_False; |
| return nRow > m_nKnownCount; |
| } |
| |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::impl_initPropertySetInfo() |
| { |
| ContentResultSetWrapper::impl_initPropertySetInfo(); |
| |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( m_pMyPropSetInfo ) |
| return; |
| m_pMyPropSetInfo = new CCRS_PropertySetInfo( m_xPropertySetInfo ); |
| m_xMyPropertySetInfo = m_pMyPropSetInfo; |
| m_xPropertySetInfo = m_xMyPropertySetInfo; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // XInterface methods. ( inherited ) |
| //-------------------------------------------------------------------------- |
| XINTERFACE_COMMON_IMPL( CachedContentResultSet ) |
| |
| Any SAL_CALL CachedContentResultSet |
| ::queryInterface( const Type& rType ) |
| throw ( RuntimeException ) |
| { |
| //list all interfaces inclusive baseclasses of interfaces |
| |
| Any aRet = ContentResultSetWrapper::queryInterface( rType ); |
| if( aRet.hasValue() ) |
| return aRet; |
| |
| aRet = cppu::queryInterface( rType, |
| static_cast< XTypeProvider* >( this ), |
| static_cast< XServiceInfo* >( this ) ); |
| |
| return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // XTypeProvider methods. |
| //-------------------------------------------------------------------------- |
| //list all interfaces exclusive baseclasses |
| XTYPEPROVIDER_IMPL_11( CachedContentResultSet |
| , XTypeProvider |
| , XServiceInfo |
| , XComponent |
| , XCloseable |
| , XResultSetMetaDataSupplier |
| , XPropertySet |
| |
| , XPropertyChangeListener |
| , XVetoableChangeListener |
| |
| , XContentAccess |
| |
| , XResultSet |
| , XRow ); |
| |
| //-------------------------------------------------------------------------- |
| // XServiceInfo methods. |
| //-------------------------------------------------------------------------- |
| |
| XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSet, |
| OUString::createFromAscii( |
| "com.sun.star.comp.ucb.CachedContentResultSet" ), |
| OUString::createFromAscii( |
| CACHED_CONTENT_RESULTSET_SERVICE_NAME ) ); |
| |
| //-------------------------------------------------------------------------- |
| // XPropertySet methods. ( inherited ) |
| //-------------------------------------------------------------------------- |
| |
| // virtual |
| void SAL_CALL CachedContentResultSet |
| ::setPropertyValue( const OUString& aPropertyName, const Any& aValue ) |
| throw( UnknownPropertyException, |
| PropertyVetoException, |
| IllegalArgumentException, |
| WrappedTargetException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( !getPropertySetInfo().is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| throw UnknownPropertyException(); |
| } |
| |
| Property aProp = m_pMyPropSetInfo->getPropertyByName( aPropertyName ); |
| //throws UnknownPropertyException, if so |
| |
| if( aProp.Attributes & PropertyAttribute::READONLY ) |
| { |
| //It is assumed, that the properties |
| //'RowCount' and 'IsRowCountFinal' are readonly! |
| throw IllegalArgumentException(); |
| } |
| if( aProp.Name == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFetchDirection ) |
| { |
| //check value |
| sal_Int32 nNew; |
| if( !( aValue >>= nNew ) ) |
| { |
| throw IllegalArgumentException(); |
| } |
| |
| if( nNew == FetchDirection::UNKNOWN ) |
| { |
| nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_DIRECTION; |
| } |
| else if( !( nNew == FetchDirection::FORWARD |
| || nNew == FetchDirection::REVERSE ) ) |
| { |
| throw IllegalArgumentException(); |
| } |
| |
| //create PropertyChangeEvent and set value |
| PropertyChangeEvent aEvt; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aEvt.Source = static_cast< XPropertySet * >( this ); |
| aEvt.PropertyName = aPropertyName; |
| aEvt.Further = sal_False; |
| aEvt.PropertyHandle = m_pMyPropSetInfo-> |
| m_nFetchDirectionPropertyHandle; |
| aEvt.OldValue <<= m_nFetchDirection; |
| aEvt.NewValue <<= nNew; |
| |
| m_nFetchDirection = nNew; |
| } |
| |
| //send PropertyChangeEvent to listeners |
| impl_notifyPropertyChangeListeners( aEvt ); |
| } |
| else if( aProp.Name == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFetchSize ) |
| { |
| //check value |
| sal_Int32 nNew; |
| if( !( aValue >>= nNew ) ) |
| { |
| throw IllegalArgumentException(); |
| } |
| |
| if( nNew < 0 ) |
| { |
| nNew = COMSUNSTARUCBCCRS_DEFAULT_FETCH_SIZE; |
| } |
| |
| //create PropertyChangeEvent and set value |
| PropertyChangeEvent aEvt; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aEvt.Source = static_cast< XPropertySet * >( this ); |
| aEvt.PropertyName = aPropertyName; |
| aEvt.Further = sal_False; |
| aEvt.PropertyHandle = m_pMyPropSetInfo-> |
| m_nFetchSizePropertyHandle; |
| aEvt.OldValue <<= m_nFetchSize; |
| aEvt.NewValue <<= nNew; |
| |
| m_nFetchSize = nNew; |
| } |
| |
| //send PropertyChangeEvent to listeners |
| impl_notifyPropertyChangeListeners( aEvt ); |
| } |
| else |
| { |
| impl_init_xPropertySetOrigin(); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( !m_xPropertySetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return; |
| } |
| } |
| m_xPropertySetOrigin->setPropertyValue( aPropertyName, aValue ); |
| } |
| } |
| |
| //-------------------------------------------------------------------------- |
| // virtual |
| Any SAL_CALL CachedContentResultSet |
| ::getPropertyValue( const OUString& rPropertyName ) |
| throw( UnknownPropertyException, |
| WrappedTargetException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( !getPropertySetInfo().is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| throw UnknownPropertyException(); |
| } |
| |
| Property aProp = m_pMyPropSetInfo->getPropertyByName( rPropertyName ); |
| //throws UnknownPropertyException, if so |
| |
| Any aValue; |
| if( rPropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForCount ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aValue <<= m_nKnownCount; |
| } |
| else if( rPropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFinalCount ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aValue <<= m_bFinalCount; |
| } |
| else if( rPropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFetchSize ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aValue <<= m_nFetchSize; |
| } |
| else if( rPropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFetchDirection ) |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| aValue <<= m_nFetchDirection; |
| } |
| else |
| { |
| impl_init_xPropertySetOrigin(); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( !m_xPropertySetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| throw UnknownPropertyException(); |
| } |
| } |
| aValue = m_xPropertySetOrigin->getPropertyValue( rPropertyName ); |
| } |
| return aValue; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // own methods. ( inherited ) |
| //-------------------------------------------------------------------------- |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::impl_disposing( const EventObject& rEventObject ) |
| throw( RuntimeException ) |
| { |
| { |
| impl_EnsureNotDisposed(); |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| //release all references to the broadcaster: |
| m_xFetchProvider.clear(); |
| m_xFetchProviderForContentAccess.clear(); |
| } |
| ContentResultSetWrapper::impl_disposing( rEventObject ); |
| } |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::impl_propertyChange( const PropertyChangeEvent& rEvt ) |
| throw( RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| PropertyChangeEvent aEvt( rEvt ); |
| aEvt.Source = static_cast< XPropertySet * >( this ); |
| aEvt.Further = sal_False; |
| //--------- |
| |
| if( CCRS_PropertySetInfo |
| ::impl_isMyPropertyName( rEvt.PropertyName ) ) |
| { |
| //don't notify foreign events on fetchsize and fetchdirection |
| if( aEvt.PropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFetchSize |
| || aEvt.PropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFetchDirection ) |
| return; |
| |
| //adjust my props 'RowCount' and 'IsRowCountFinal' |
| if( aEvt.PropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForCount ) |
| {//RowCount changed |
| |
| //check value |
| sal_Int32 nNew = 0; |
| if( !( aEvt.NewValue >>= nNew ) ) |
| { |
| OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" ); |
| return; |
| } |
| |
| impl_changeRowCount( m_nKnownCount, nNew ); |
| } |
| else if( aEvt.PropertyName == CCRS_PropertySetInfo |
| ::m_aPropertyNameForFinalCount ) |
| {//IsRowCountFinal changed |
| |
| //check value |
| sal_Bool bNew = sal_False; |
| if( !( aEvt.NewValue >>= bNew ) ) |
| { |
| OSL_ENSURE( sal_False, "PropertyChangeEvent contains wrong data" ); |
| return; |
| } |
| impl_changeIsRowCountFinal( m_bFinalCount, bNew ); |
| } |
| return; |
| } |
| |
| //----------- |
| impl_notifyPropertyChangeListeners( aEvt ); |
| } |
| |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::impl_vetoableChange( const PropertyChangeEvent& rEvt ) |
| throw( PropertyVetoException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| //don't notify events on my properties, cause they are not vetoable |
| if( CCRS_PropertySetInfo |
| ::impl_isMyPropertyName( rEvt.PropertyName ) ) |
| { |
| return; |
| } |
| |
| |
| PropertyChangeEvent aEvt( rEvt ); |
| aEvt.Source = static_cast< XPropertySet * >( this ); |
| aEvt.Further = sal_False; |
| |
| impl_notifyVetoableChangeListeners( aEvt ); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // XContentAccess methods. ( inherited ) ( -- position dependent ) |
| //-------------------------------------------------------------------------- |
| |
| #define XCONTENTACCESS_queryXXX( queryXXX, XXX, TYPE ) \ |
| impl_EnsureNotDisposed(); \ |
| ReacquireableGuard aGuard( m_aMutex ); \ |
| sal_Int32 nRow = m_nRow; \ |
| sal_Int32 nFetchSize = m_nFetchSize; \ |
| sal_Int32 nFetchDirection = m_nFetchDirection; \ |
| if( !m_aCache##XXX.hasRow( nRow ) ) \ |
| { \ |
| if( !m_aCache##XXX.hasCausedException( nRow ) ) \ |
| { \ |
| if( !m_xFetchProviderForContentAccess.is() ) \ |
| { \ |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" );\ |
| throw RuntimeException(); \ |
| } \ |
| aGuard.clear(); \ |
| if( impl_isForwardOnly() ) \ |
| applyPositionToOrigin( nRow ); \ |
| \ |
| FETCH_XXX( m_aCache##XXX, m_xFetchProviderForContentAccess, fetch##XXX##s ); \ |
| } \ |
| aGuard.reacquire(); \ |
| if( !m_aCache##XXX.hasRow( nRow ) ) \ |
| { \ |
| aGuard.clear(); \ |
| applyPositionToOrigin( nRow ); \ |
| TYPE aRet = ContentResultSetWrapper::queryXXX(); \ |
| if( m_xContentIdentifierMapping.is() ) \ |
| return m_xContentIdentifierMapping->map##XXX( aRet );\ |
| return aRet; \ |
| } \ |
| } \ |
| return m_aCache##XXX.get##XXX( nRow ); |
| |
| //-------------------------------------------------------------------------- |
| // virtual |
| OUString SAL_CALL CachedContentResultSet |
| ::queryContentIdentifierString() |
| throw( RuntimeException ) |
| { |
| XCONTENTACCESS_queryXXX( queryContentIdentifierString, ContentIdentifierString, OUString ) |
| } |
| |
| //-------------------------------------------------------------------------- |
| // virtual |
| Reference< XContentIdentifier > SAL_CALL CachedContentResultSet |
| ::queryContentIdentifier() |
| throw( RuntimeException ) |
| { |
| XCONTENTACCESS_queryXXX( queryContentIdentifier, ContentIdentifier, Reference< XContentIdentifier > ) |
| } |
| |
| //-------------------------------------------------------------------------- |
| // virtual |
| Reference< XContent > SAL_CALL CachedContentResultSet |
| ::queryContent() |
| throw( RuntimeException ) |
| { |
| XCONTENTACCESS_queryXXX( queryContent, Content, Reference< XContent > ) |
| } |
| |
| //----------------------------------------------------------------- |
| // XResultSet methods. ( inherited ) |
| //----------------------------------------------------------------- |
| //virtual |
| |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::next() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| //after last |
| if( m_bAfterLast ) |
| return sal_False; |
| //last |
| aGuard.clear(); |
| if( isLast() ) |
| { |
| aGuard.reacquire(); |
| m_nRow++; |
| m_bAfterLast = sal_True; |
| return sal_False; |
| } |
| aGuard.reacquire(); |
| //known valid position |
| if( impl_isKnownValidPosition( m_nRow + 1 ) ) |
| { |
| m_nRow++; |
| return sal_True; |
| } |
| |
| //unknown position |
| sal_Int32 nRow = m_nRow; |
| aGuard.clear(); |
| |
| sal_Bool bValid = applyPositionToOrigin( nRow + 1 ); |
| |
| aGuard.reacquire(); |
| m_nRow = nRow + 1; |
| m_bAfterLast = !bValid; |
| return bValid; |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::previous() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| //before first ?: |
| if( !m_bAfterLast && !m_nRow ) |
| return sal_False; |
| //first ?: |
| if( !m_bAfterLast && m_nKnownCount && m_nRow == 1 ) |
| { |
| m_nRow--; |
| m_bAfterLast = sal_False; |
| return sal_False; |
| } |
| //known valid position ?: |
| if( impl_isKnownValidPosition( m_nRow - 1 ) ) |
| { |
| m_nRow--; |
| m_bAfterLast = sal_False; |
| return sal_True; |
| } |
| //unknown position: |
| sal_Int32 nRow = m_nRow; |
| aGuard.clear(); |
| |
| sal_Bool bValid = applyPositionToOrigin( nRow - 1 ); |
| |
| aGuard.reacquire(); |
| m_nRow = nRow - 1; |
| m_bAfterLast = sal_False; |
| return bValid; |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::absolute( sal_Int32 row ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( !row ) |
| throw SQLException(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| |
| if( !m_xResultSetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return sal_False; |
| } |
| if( row < 0 ) |
| { |
| if( m_bFinalCount ) |
| { |
| sal_Int32 nNewRow = m_nKnownCount + 1 + row; |
| sal_Bool bValid = sal_True; |
| if( nNewRow <= 0 ) |
| { |
| nNewRow = 0; |
| bValid = sal_False; |
| } |
| m_nRow = nNewRow; |
| m_bAfterLast = sal_False; |
| return bValid; |
| } |
| //unknown final count: |
| aGuard.clear(); |
| |
| // Solaris has problems catching or propagating derived exceptions |
| // when only the base class is known, so make ResultSetException |
| // (derived from SQLException) known here: |
| sal_Bool bValid; |
| try |
| { |
| bValid = m_xResultSetOrigin->absolute( row ); |
| } |
| catch (ResultSetException &) |
| { |
| throw; |
| } |
| |
| aGuard.reacquire(); |
| if( m_bFinalCount ) |
| { |
| sal_Int32 nNewRow = m_nKnownCount + 1 + row; |
| if( nNewRow < 0 ) |
| nNewRow = 0; |
| m_nLastAppliedPos = nNewRow; |
| m_nRow = nNewRow; |
| m_bAfterLastApplied = m_bAfterLast = sal_False; |
| return bValid; |
| } |
| aGuard.clear(); |
| |
| sal_Int32 nCurRow = m_xResultSetOrigin->getRow(); |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos = nCurRow; |
| m_nRow = nCurRow; |
| m_bAfterLast = sal_False; |
| return nCurRow != 0; |
| } |
| //row > 0: |
| if( m_bFinalCount ) |
| { |
| if( row > m_nKnownCount ) |
| { |
| m_nRow = m_nKnownCount + 1; |
| m_bAfterLast = sal_True; |
| return sal_False; |
| } |
| m_nRow = row; |
| m_bAfterLast = sal_False; |
| return sal_True; |
| } |
| //unknown new position: |
| aGuard.clear(); |
| |
| sal_Bool bValid = m_xResultSetOrigin->absolute( row ); |
| |
| aGuard.reacquire(); |
| if( m_bFinalCount ) |
| { |
| sal_Int32 nNewRow = row; |
| if( nNewRow > m_nKnownCount ) |
| { |
| nNewRow = m_nKnownCount + 1; |
| m_bAfterLastApplied = m_bAfterLast = sal_True; |
| } |
| else |
| m_bAfterLastApplied = m_bAfterLast = sal_False; |
| |
| m_nLastAppliedPos = nNewRow; |
| m_nRow = nNewRow; |
| return bValid; |
| } |
| aGuard.clear(); |
| |
| sal_Int32 nCurRow = m_xResultSetOrigin->getRow(); |
| sal_Bool bIsAfterLast = m_xResultSetOrigin->isAfterLast(); |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos = nCurRow; |
| m_nRow = nCurRow; |
| m_bAfterLastApplied = m_bAfterLast = bIsAfterLast; |
| return nCurRow && !bIsAfterLast; |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::relative( sal_Int32 rows ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| if( m_bAfterLast || impl_isKnownInvalidPosition( m_nRow ) ) |
| throw SQLException(); |
| |
| if( !rows ) |
| return sal_True; |
| |
| sal_Int32 nNewRow = m_nRow + rows; |
| if( nNewRow < 0 ) |
| nNewRow = 0; |
| |
| if( impl_isKnownValidPosition( nNewRow ) ) |
| { |
| m_nRow = nNewRow; |
| m_bAfterLast = sal_False; |
| return sal_True; |
| } |
| else |
| { |
| //known invalid new position: |
| if( nNewRow == 0 ) |
| { |
| m_bAfterLast = sal_False; |
| m_nRow = 0; |
| return sal_False; |
| } |
| if( m_bFinalCount && nNewRow > m_nKnownCount ) |
| { |
| m_bAfterLast = sal_True; |
| m_nRow = m_nKnownCount + 1; |
| return sal_False; |
| } |
| //unknown new position: |
| aGuard.clear(); |
| sal_Bool bValid = applyPositionToOrigin( nNewRow ); |
| |
| aGuard.reacquire(); |
| m_nRow = nNewRow; |
| m_bAfterLast = !bValid && nNewRow > 0; |
| return bValid; |
| } |
| } |
| |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::first() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| if( impl_isKnownValidPosition( 1 ) ) |
| { |
| m_nRow = 1; |
| m_bAfterLast = sal_False; |
| return sal_True; |
| } |
| if( impl_isKnownInvalidPosition( 1 ) ) |
| { |
| m_nRow = 1; |
| m_bAfterLast = sal_False; |
| return sal_False; |
| } |
| //unknown position |
| aGuard.clear(); |
| |
| sal_Bool bValid = applyPositionToOrigin( 1 ); |
| |
| aGuard.reacquire(); |
| m_nRow = 1; |
| m_bAfterLast = sal_False; |
| return bValid; |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::last() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| if( m_bFinalCount ) |
| { |
| m_nRow = m_nKnownCount; |
| m_bAfterLast = sal_False; |
| return m_nKnownCount != 0; |
| } |
| //unknown position |
| if( !m_xResultSetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return sal_False; |
| } |
| aGuard.clear(); |
| |
| sal_Bool bValid = m_xResultSetOrigin->last(); |
| |
| aGuard.reacquire(); |
| m_bAfterLastApplied = m_bAfterLast = sal_False; |
| if( m_bFinalCount ) |
| { |
| m_nLastAppliedPos = m_nKnownCount; |
| m_nRow = m_nKnownCount; |
| return bValid; |
| } |
| aGuard.clear(); |
| |
| sal_Int32 nCurRow = m_xResultSetOrigin->getRow(); |
| |
| aGuard.reacquire(); |
| m_nLastAppliedPos = nCurRow; |
| m_nRow = nCurRow; |
| OSL_ENSURE( nCurRow >= m_nKnownCount, "position of last row < known Count, that could not be" ); |
| m_nKnownCount = nCurRow; |
| m_bFinalCount = sal_True; |
| return nCurRow != 0; |
| } |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::beforeFirst() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_nRow = 0; |
| m_bAfterLast = sal_False; |
| } |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::afterLast() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| if( impl_isForwardOnly() ) |
| throw SQLException(); |
| |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| m_nRow = 1; |
| m_bAfterLast = sal_True; |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::isAfterLast() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| if( !m_bAfterLast ) |
| return sal_False; |
| if( m_nKnownCount ) |
| return m_bAfterLast; |
| if( m_bFinalCount ) |
| return sal_False; |
| |
| if( !m_xResultSetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return sal_False; |
| } |
| aGuard.clear(); |
| |
| //find out whethter the original resultset contains rows or not |
| m_xResultSetOrigin->afterLast(); |
| |
| aGuard.reacquire(); |
| m_bAfterLastApplied = sal_True; |
| aGuard.clear(); |
| |
| return m_xResultSetOrigin->isAfterLast(); |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::isBeforeFirst() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| if( m_bAfterLast ) |
| return sal_False; |
| if( m_nRow ) |
| return sal_False; |
| if( m_nKnownCount ) |
| return !m_nRow; |
| if( m_bFinalCount ) |
| return sal_False; |
| |
| if( !m_xResultSetOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return sal_False; |
| } |
| aGuard.clear(); |
| |
| //find out whethter the original resultset contains rows or not |
| m_xResultSetOrigin->beforeFirst(); |
| |
| aGuard.reacquire(); |
| m_bAfterLastApplied = sal_False; |
| m_nLastAppliedPos = 0; |
| aGuard.clear(); |
| |
| return m_xResultSetOrigin->isBeforeFirst(); |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::isFirst() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| sal_Int32 nRow = 0; |
| Reference< XResultSet > xResultSetOrigin; |
| |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( m_bAfterLast ) |
| return sal_False; |
| if( m_nRow != 1 ) |
| return sal_False; |
| if( m_nKnownCount ) |
| return m_nRow == 1; |
| if( m_bFinalCount ) |
| return sal_False; |
| |
| nRow = m_nRow; |
| xResultSetOrigin = m_xResultSetOrigin; |
| } |
| |
| //need to ask origin |
| { |
| if( applyPositionToOrigin( nRow ) ) |
| return xResultSetOrigin->isFirst(); |
| else |
| return sal_False; |
| } |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::isLast() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| sal_Int32 nRow = 0; |
| Reference< XResultSet > xResultSetOrigin; |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( m_bAfterLast ) |
| return sal_False; |
| if( m_nRow < m_nKnownCount ) |
| return sal_False; |
| if( m_bFinalCount ) |
| return m_nKnownCount && m_nRow == m_nKnownCount; |
| |
| nRow = m_nRow; |
| xResultSetOrigin = m_xResultSetOrigin; |
| } |
| |
| //need to ask origin |
| { |
| if( applyPositionToOrigin( nRow ) ) |
| return xResultSetOrigin->isLast(); |
| else |
| return sal_False; |
| } |
| } |
| |
| |
| //virtual |
| sal_Int32 SAL_CALL CachedContentResultSet |
| ::getRow() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( m_bAfterLast ) |
| return 0; |
| return m_nRow; |
| } |
| |
| //virtual |
| void SAL_CALL CachedContentResultSet |
| ::refreshRow() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| //the ContentResultSet is static and will not change |
| //therefore we don't need to reload anything |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::rowUpdated() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| //the ContentResultSet is static and will not change |
| return sal_False; |
| } |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::rowInserted() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| //the ContentResultSet is static and will not change |
| return sal_False; |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::rowDeleted() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| |
| //the ContentResultSet is static and will not change |
| return sal_False; |
| } |
| |
| //virtual |
| Reference< XInterface > SAL_CALL CachedContentResultSet |
| ::getStatement() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| //@todo ?return anything |
| return Reference< XInterface >(); |
| } |
| |
| //----------------------------------------------------------------- |
| // XRow methods. ( inherited ) |
| //----------------------------------------------------------------- |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::wasNull() |
| throw( SQLException, |
| RuntimeException ) |
| { |
| impl_EnsureNotDisposed(); |
| impl_init_xRowOrigin(); |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| if( m_bLastReadWasFromCache ) |
| return m_bLastCachedReadWasNull; |
| if( !m_xRowOrigin.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return sal_False; |
| } |
| } |
| return m_xRowOrigin->wasNull(); |
| } |
| |
| //virtual |
| rtl::OUString SAL_CALL CachedContentResultSet |
| ::getString( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getString, OUString ); |
| } |
| |
| //virtual |
| sal_Bool SAL_CALL CachedContentResultSet |
| ::getBoolean( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getBoolean, sal_Bool ); |
| } |
| |
| //virtual |
| sal_Int8 SAL_CALL CachedContentResultSet |
| ::getByte( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getByte, sal_Int8 ); |
| } |
| |
| //virtual |
| sal_Int16 SAL_CALL CachedContentResultSet |
| ::getShort( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getShort, sal_Int16 ); |
| } |
| |
| //virtual |
| sal_Int32 SAL_CALL CachedContentResultSet |
| ::getInt( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getInt, sal_Int32 ); |
| } |
| |
| //virtual |
| sal_Int64 SAL_CALL CachedContentResultSet |
| ::getLong( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getLong, sal_Int64 ); |
| } |
| |
| //virtual |
| float SAL_CALL CachedContentResultSet |
| ::getFloat( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getFloat, float ); |
| } |
| |
| //virtual |
| double SAL_CALL CachedContentResultSet |
| ::getDouble( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getDouble, double ); |
| } |
| |
| //virtual |
| Sequence< sal_Int8 > SAL_CALL CachedContentResultSet |
| ::getBytes( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getBytes, Sequence< sal_Int8 > ); |
| } |
| |
| //virtual |
| Date SAL_CALL CachedContentResultSet |
| ::getDate( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getDate, Date ); |
| } |
| |
| //virtual |
| Time SAL_CALL CachedContentResultSet |
| ::getTime( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getTime, Time ); |
| } |
| |
| //virtual |
| DateTime SAL_CALL CachedContentResultSet |
| ::getTimestamp( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getTimestamp, DateTime ); |
| } |
| |
| //virtual |
| Reference< com::sun::star::io::XInputStream > |
| SAL_CALL CachedContentResultSet |
| ::getBinaryStream( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getBinaryStream, Reference< com::sun::star::io::XInputStream > ); |
| } |
| |
| //virtual |
| Reference< com::sun::star::io::XInputStream > |
| SAL_CALL CachedContentResultSet |
| ::getCharacterStream( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getCharacterStream, Reference< com::sun::star::io::XInputStream > ); |
| } |
| |
| //virtual |
| Any SAL_CALL CachedContentResultSet |
| ::getObject( sal_Int32 columnIndex, |
| const Reference< |
| com::sun::star::container::XNameAccess >& typeMap ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| //if you change this macro please pay attention to |
| //define XROW_GETXXX, where this is similar implemented |
| |
| ReacquireableGuard aGuard( m_aMutex ); |
| sal_Int32 nRow = m_nRow; |
| sal_Int32 nFetchSize = m_nFetchSize; |
| sal_Int32 nFetchDirection = m_nFetchDirection; |
| if( !m_aCache.hasRow( nRow ) ) |
| { |
| if( !m_aCache.hasCausedException( nRow ) ) |
| { |
| if( !m_xFetchProvider.is() ) |
| { |
| OSL_ENSURE( sal_False, "broadcaster was disposed already" ); |
| return Any(); |
| } |
| aGuard.clear(); |
| |
| impl_fetchData( nRow, nFetchSize, nFetchDirection ); |
| } |
| aGuard.reacquire(); |
| if( !m_aCache.hasRow( nRow ) ) |
| { |
| m_bLastReadWasFromCache = sal_False; |
| aGuard.clear(); |
| applyPositionToOrigin( nRow ); |
| impl_init_xRowOrigin(); |
| return m_xRowOrigin->getObject( columnIndex, typeMap ); |
| } |
| } |
| //@todo: pay attention to typeMap |
| const Any& rValue = m_aCache.getAny( nRow, columnIndex ); |
| Any aRet; |
| m_bLastReadWasFromCache = sal_True; |
| m_bLastCachedReadWasNull = !( rValue >>= aRet ); |
| return aRet; |
| } |
| |
| //virtual |
| Reference< XRef > SAL_CALL CachedContentResultSet |
| ::getRef( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getRef, Reference< XRef > ); |
| } |
| |
| //virtual |
| Reference< XBlob > SAL_CALL CachedContentResultSet |
| ::getBlob( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getBlob, Reference< XBlob > ); |
| } |
| |
| //virtual |
| Reference< XClob > SAL_CALL CachedContentResultSet |
| ::getClob( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getClob, Reference< XClob > ); |
| } |
| |
| //virtual |
| Reference< XArray > SAL_CALL CachedContentResultSet |
| ::getArray( sal_Int32 columnIndex ) |
| throw( SQLException, |
| RuntimeException ) |
| { |
| XROW_GETXXX( getArray, Reference< XArray > ); |
| } |
| |
| //----------------------------------------------------------------- |
| // Type Converter Support |
| //----------------------------------------------------------------- |
| |
| const Reference< XTypeConverter >& CachedContentResultSet::getTypeConverter() |
| { |
| osl::Guard< osl::Mutex > aGuard( m_aMutex ); |
| |
| if ( !m_bTriedToGetTypeConverter && !m_xTypeConverter.is() ) |
| { |
| m_bTriedToGetTypeConverter = sal_True; |
| m_xTypeConverter = Reference< XTypeConverter >( |
| m_xSMgr->createInstance( |
| OUString::createFromAscii( |
| "com.sun.star.script.Converter" ) ), |
| UNO_QUERY ); |
| |
| OSL_ENSURE( m_xTypeConverter.is(), |
| "PropertyValueSet::getTypeConverter() - " |
| "Service 'com.sun.star.script.Converter' n/a!" ); |
| } |
| return m_xTypeConverter; |
| } |
| |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| // class CachedContentResultSetFactory |
| //-------------------------------------------------------------------------- |
| //-------------------------------------------------------------------------- |
| |
| CachedContentResultSetFactory::CachedContentResultSetFactory( |
| const Reference< XMultiServiceFactory > & rSMgr ) |
| { |
| m_xSMgr = rSMgr; |
| } |
| |
| CachedContentResultSetFactory::~CachedContentResultSetFactory() |
| { |
| } |
| |
| //-------------------------------------------------------------------------- |
| // CachedContentResultSetFactory XInterface methods. |
| //-------------------------------------------------------------------------- |
| |
| XINTERFACE_IMPL_3( CachedContentResultSetFactory, |
| XTypeProvider, |
| XServiceInfo, |
| XCachedContentResultSetFactory ); |
| |
| //-------------------------------------------------------------------------- |
| // CachedContentResultSetFactory XTypeProvider methods. |
| //-------------------------------------------------------------------------- |
| |
| XTYPEPROVIDER_IMPL_3( CachedContentResultSetFactory, |
| XTypeProvider, |
| XServiceInfo, |
| XCachedContentResultSetFactory ); |
| |
| //-------------------------------------------------------------------------- |
| // CachedContentResultSetFactory XServiceInfo methods. |
| //-------------------------------------------------------------------------- |
| |
| XSERVICEINFO_IMPL_1( CachedContentResultSetFactory, |
| OUString::createFromAscii( |
| "com.sun.star.comp.ucb.CachedContentResultSetFactory" ), |
| OUString::createFromAscii( |
| CACHED_CONTENT_RESULTSET_FACTORY_NAME ) ); |
| |
| //-------------------------------------------------------------------------- |
| // Service factory implementation. |
| //-------------------------------------------------------------------------- |
| |
| ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetFactory ); |
| |
| //-------------------------------------------------------------------------- |
| // CachedContentResultSetFactory XCachedContentResultSetFactory methods. |
| //-------------------------------------------------------------------------- |
| |
| //virtual |
| Reference< XResultSet > SAL_CALL CachedContentResultSetFactory |
| ::createCachedContentResultSet( |
| const Reference< XResultSet > & xSource, |
| const Reference< XContentIdentifierMapping > & xMapping ) |
| throw( com::sun::star::uno::RuntimeException ) |
| { |
| Reference< XResultSet > xRet; |
| xRet = new CachedContentResultSet( m_xSMgr, xSource, xMapping ); |
| return xRet; |
| } |
| |