diff options
Diffstat (limited to 'ucb/source/cacher/cachedcontentresultsetstub.cxx')
-rw-r--r-- | ucb/source/cacher/cachedcontentresultsetstub.cxx | 634 |
1 files changed, 634 insertions, 0 deletions
diff --git a/ucb/source/cacher/cachedcontentresultsetstub.cxx b/ucb/source/cacher/cachedcontentresultsetstub.cxx new file mode 100644 index 000000000000..baedfa0824af --- /dev/null +++ b/ucb/source/cacher/cachedcontentresultsetstub.cxx @@ -0,0 +1,634 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: cachedcontentresultsetstub.cxx,v $ + * $Revision: 1.11 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_ucb.hxx" + +#include <cachedcontentresultsetstub.hxx> +#include <com/sun/star/sdbc/FetchDirection.hpp> +#include <com/sun/star/ucb/FetchError.hpp> +#include <osl/diagnose.h> + +using namespace com::sun::star::beans; +using namespace com::sun::star::lang; +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; + +CachedContentResultSetStub::CachedContentResultSetStub( Reference< XResultSet > xOrigin ) + : ContentResultSetWrapper( xOrigin ) + , m_nColumnCount( 0 ) + , m_bColumnCountCached( sal_False ) + , m_bNeedToPropagateFetchSize( sal_True ) + , m_bFirstFetchSizePropagationDone( sal_False ) + , m_nLastFetchSize( 1 )//this value is not important at all + , m_bLastFetchDirection( sal_True )//this value is not important at all + , m_aPropertyNameForFetchSize( OUString::createFromAscii( "FetchSize" ) ) + , m_aPropertyNameForFetchDirection( OUString::createFromAscii( "FetchDirection" ) ) +{ + impl_init(); +} + +CachedContentResultSetStub::~CachedContentResultSetStub() +{ + impl_deinit(); +} + +//-------------------------------------------------------------------------- +// XInterface methods. +//-------------------------------------------------------------------------- +XINTERFACE_COMMON_IMPL( CachedContentResultSetStub ) + +Any SAL_CALL CachedContentResultSetStub + ::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 ) + , static_cast< XFetchProvider* >( this ) + , static_cast< XFetchProviderForContentAccess* >( this ) + ); + + return aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ); +} + +//-------------------------------------------------------------------------- +// own methods. ( inherited ) +//-------------------------------------------------------------------------- + +//virtual +void SAL_CALL CachedContentResultSetStub + ::impl_propertyChange( const PropertyChangeEvent& rEvt ) + throw( RuntimeException ) +{ + impl_EnsureNotDisposed(); + + //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet + //because it will ignore them anyway and we can save this remote calls + if( rEvt.PropertyName == m_aPropertyNameForFetchSize + || rEvt.PropertyName == m_aPropertyNameForFetchDirection ) + return; + + PropertyChangeEvent aEvt( rEvt ); + aEvt.Source = static_cast< XPropertySet * >( this ); + aEvt.Further = sal_False; + + impl_notifyPropertyChangeListeners( aEvt ); +} + + +//virtual +void SAL_CALL CachedContentResultSetStub + ::impl_vetoableChange( const PropertyChangeEvent& rEvt ) + throw( PropertyVetoException, + RuntimeException ) +{ + impl_EnsureNotDisposed(); + + //don't notify events on fetchsize and fetchdirection to the above CachedContentResultSet + //because it will ignore them anyway and we can save this remote calls + if( rEvt.PropertyName == m_aPropertyNameForFetchSize + || rEvt.PropertyName == m_aPropertyNameForFetchDirection ) + return; + + PropertyChangeEvent aEvt( rEvt ); + aEvt.Source = static_cast< XPropertySet * >( this ); + aEvt.Further = sal_False; + + impl_notifyVetoableChangeListeners( aEvt ); +} + +//-------------------------------------------------------------------------- +// XTypeProvider methods. +//-------------------------------------------------------------------------- + +XTYPEPROVIDER_COMMON_IMPL( CachedContentResultSetStub ) +//list all interfaces exclusive baseclasses +Sequence< Type > SAL_CALL CachedContentResultSetStub + ::getTypes() + throw( RuntimeException ) +{ + static Sequence< Type >* pTypes = NULL; + if( !pTypes ) + { + osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() ); + if( !pTypes ) + { + pTypes = new Sequence< Type >(13); + (*pTypes)[0] = CPPU_TYPE_REF( XTypeProvider ); + (*pTypes)[1] = CPPU_TYPE_REF( XServiceInfo ); + (*pTypes)[2] = CPPU_TYPE_REF( XComponent ); + (*pTypes)[3] = CPPU_TYPE_REF( XCloseable ); + (*pTypes)[4] = CPPU_TYPE_REF( XResultSetMetaDataSupplier ); + (*pTypes)[5] = CPPU_TYPE_REF( XPropertySet ); + (*pTypes)[6] = CPPU_TYPE_REF( XPropertyChangeListener ); + (*pTypes)[7] = CPPU_TYPE_REF( XVetoableChangeListener ); + (*pTypes)[8] = CPPU_TYPE_REF( XResultSet ); + (*pTypes)[9] = CPPU_TYPE_REF( XContentAccess ); + (*pTypes)[10] = CPPU_TYPE_REF( XRow ); + (*pTypes)[11] = CPPU_TYPE_REF( XFetchProvider ); + (*pTypes)[12] = CPPU_TYPE_REF( XFetchProviderForContentAccess ); + } + } + return *pTypes; + /* + static cppu::OTypeCollection * pCollection = 0; + if (!pCollection) + { + osl::MutexGuard aGuard(osl::Mutex::getGlobalMutex()); + if (!pCollection) + { + static cppu::OTypeCollection + aTheCollection( + getCppuType( + static_cast< Reference< XTypeProvider > + const * >( + 0)), + getCppuType( + static_cast< Reference< XServiceInfo > + const * >( + 0)), + getCppuType( + static_cast< Reference< XComponent > + const * >( + 0)), + getCppuType( + static_cast< Reference< XCloseable > + const * >( + 0)), + getCppuType( + static_cast< Reference< XResultSetMetaDataSupplier > + const * >( + 0)), + getCppuType( + static_cast< Reference< XPropertySet > + const * >( + 0)), + getCppuType( + static_cast< Reference< XPropertyChangeListener > + const * >( + 0)), + getCppuType( + static_cast< Reference< XVetoableChangeListener > + const * >( + 0)), + getCppuType( + static_cast< Reference< XResultSet > + const * >( + 0)), + getCppuType( + static_cast< Reference< XContentAccess > + const * >( + 0)), + getCppuType( + static_cast< Reference< XRow > + const * >( + 0)), + getCppuType( + static_cast< Reference< XFetchProvider > + const * >( + 0)), + getCppuType( + static_cast< Reference< XFetchProviderForContentAccess > + const * >( + 0)) + ); + pCollection = &aTheCollection; + } + } + return pCollection->getTypes(); + */ +} + +//-------------------------------------------------------------------------- +// XServiceInfo methods. +//-------------------------------------------------------------------------- + +XSERVICEINFO_NOFACTORY_IMPL_1( CachedContentResultSetStub, + OUString::createFromAscii( + "com.sun.star.comp.ucb.CachedContentResultSetStub" ), + OUString::createFromAscii( + CACHED_CRS_STUB_SERVICE_NAME ) ); + +//----------------------------------------------------------------- +// XFetchProvider methods. +//----------------------------------------------------------------- + +#define FETCH_XXX( impl_loadRow, loadInterface ) \ +impl_EnsureNotDisposed(); \ +if( !m_xResultSetOrigin.is() ) \ +{ \ + OSL_ENSURE( sal_False, "broadcaster was disposed already" ); \ + throw RuntimeException(); \ +} \ +impl_propagateFetchSizeAndDirection( nRowCount, bDirection ); \ +FetchResult aRet; \ +aRet.StartIndex = nRowStartPosition; \ +aRet.Orientation = bDirection; \ +aRet.FetchError = FetchError::SUCCESS; /*ENDOFDATA, EXCEPTION*/ \ +sal_Int32 nOldOriginal_Pos = m_xResultSetOrigin->getRow(); \ +if( impl_isForwardOnly() ) \ +{ \ + if( nOldOriginal_Pos != nRowStartPosition ) \ + { \ + /*@todo*/ \ + aRet.FetchError = FetchError::EXCEPTION; \ + return aRet; \ + } \ + if( nRowCount != 1 ) \ + aRet.FetchError = FetchError::EXCEPTION; \ + \ + aRet.Rows.realloc( 1 ); \ + \ + try \ + { \ + impl_loadRow( aRet.Rows[0], loadInterface ); \ + } \ + catch( SQLException& ) \ + { \ + aRet.Rows.realloc( 0 ); \ + aRet.FetchError = FetchError::EXCEPTION; \ + return aRet; \ + } \ + return aRet; \ +} \ +aRet.Rows.realloc( nRowCount ); \ +sal_Bool bOldOriginal_AfterLast = sal_False; \ +if( !nOldOriginal_Pos ) \ + bOldOriginal_AfterLast = m_xResultSetOrigin->isAfterLast(); \ +sal_Int32 nN = 1; \ +sal_Bool bValidNewPos = sal_False; \ +try \ +{ \ + try \ + { \ + /*if( nOldOriginal_Pos != nRowStartPosition )*/ \ + bValidNewPos = m_xResultSetOrigin->absolute( nRowStartPosition ); \ + } \ + catch( SQLException& ) \ + { \ + aRet.Rows.realloc( 0 ); \ + aRet.FetchError = FetchError::EXCEPTION; \ + return aRet; \ + } \ + if( !bValidNewPos ) \ + { \ + aRet.Rows.realloc( 0 ); \ + aRet.FetchError = FetchError::EXCEPTION; \ + \ + /*restore old position*/ \ + if( nOldOriginal_Pos ) \ + m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \ + else if( bOldOriginal_AfterLast ) \ + m_xResultSetOrigin->afterLast(); \ + else \ + m_xResultSetOrigin->beforeFirst(); \ + \ + return aRet; \ + } \ + for( ; nN <= nRowCount; ) \ + { \ + impl_loadRow( aRet.Rows[nN-1], loadInterface ); \ + nN++; \ + if( nN <= nRowCount ) \ + { \ + if( bDirection ) \ + { \ + if( !m_xResultSetOrigin->next() ) \ + { \ + aRet.Rows.realloc( nN-1 ); \ + aRet.FetchError = FetchError::ENDOFDATA; \ + break; \ + } \ + } \ + else \ + { \ + if( !m_xResultSetOrigin->previous() ) \ + { \ + aRet.Rows.realloc( nN-1 ); \ + aRet.FetchError = FetchError::ENDOFDATA; \ + break; \ + } \ + } \ + } \ + } \ +} \ +catch( SQLException& ) \ +{ \ + aRet.Rows.realloc( nN-1 ); \ + aRet.FetchError = FetchError::EXCEPTION; \ +} \ +/*restore old position*/ \ +if( nOldOriginal_Pos ) \ + m_xResultSetOrigin->absolute( nOldOriginal_Pos ); \ +else if( bOldOriginal_AfterLast ) \ + m_xResultSetOrigin->afterLast(); \ +else \ + m_xResultSetOrigin->beforeFirst(); \ +return aRet; + +FetchResult SAL_CALL CachedContentResultSetStub + ::fetch( sal_Int32 nRowStartPosition + , sal_Int32 nRowCount, sal_Bool bDirection ) + throw( RuntimeException ) +{ + impl_init_xRowOrigin(); + FETCH_XXX( impl_getCurrentRowContent, m_xRowOrigin ); +} + +sal_Int32 SAL_CALL CachedContentResultSetStub + ::impl_getColumnCount() +{ + sal_Int32 nCount; + sal_Bool bCached; + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + nCount = m_nColumnCount; + bCached = m_bColumnCountCached; + } + if( !bCached ) + { + try + { + Reference< XResultSetMetaData > xMetaData = getMetaData(); + if( xMetaData.is() ) + nCount = xMetaData->getColumnCount(); + } + catch( SQLException& ) + { + OSL_ENSURE( sal_False, "couldn't determine the column count" ); + nCount = 0; + } + } + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + m_nColumnCount = nCount; + m_bColumnCountCached = sal_True; + return m_nColumnCount; +} + +void SAL_CALL CachedContentResultSetStub + ::impl_getCurrentRowContent( Any& rRowContent + , Reference< XRow > xRow ) + throw ( SQLException, RuntimeException ) +{ + sal_Int32 nCount = impl_getColumnCount(); + + Sequence< Any > aContent( nCount ); + for( sal_Int32 nN = 1; nN <= nCount; nN++ ) + { + aContent[nN-1] = xRow->getObject( nN, NULL ); + } + + rRowContent <<= aContent; +} + +void SAL_CALL CachedContentResultSetStub + ::impl_propagateFetchSizeAndDirection( sal_Int32 nFetchSize, sal_Bool bFetchDirection ) + throw ( RuntimeException ) +{ + //this is done only for the case, that there is another CachedContentResultSet in the chain of underlying ResulSets + + //we do not propagate the property 'FetchSize' or 'FetchDirection' via 'setPropertyValue' from the above CachedContentResultSet to save remote calls + + //if the underlying ResultSet has a property FetchSize and FetchDirection, + //we will set these properties, if the new given parameters are different from the last ones + + if( !m_bNeedToPropagateFetchSize ) + return; + + sal_Bool bNeedAction; + sal_Int32 nLastSize; + sal_Bool bLastDirection; + sal_Bool bFirstPropagationDone; + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + bNeedAction = m_bNeedToPropagateFetchSize; + nLastSize = m_nLastFetchSize; + bLastDirection = m_bLastFetchDirection; + bFirstPropagationDone = m_bFirstFetchSizePropagationDone; + } + if( bNeedAction ) + { + if( nLastSize == nFetchSize + && bLastDirection == bFetchDirection + && bFirstPropagationDone == sal_True ) + return; + + if(!bFirstPropagationDone) + { + //check wether the properties 'FetchSize' and 'FetchDirection' do exist + + Reference< XPropertySetInfo > xPropertySetInfo = getPropertySetInfo(); + sal_Bool bHasSize = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchSize ); + sal_Bool bHasDirection = xPropertySetInfo->hasPropertyByName( m_aPropertyNameForFetchDirection ); + + if(!bHasSize || !bHasDirection) + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + m_bNeedToPropagateFetchSize = sal_False; + return; + } + } + + sal_Bool bSetSize = ( nLastSize !=nFetchSize ) || !bFirstPropagationDone; + sal_Bool bSetDirection = ( bLastDirection !=bFetchDirection ) || !bFirstPropagationDone; + + { + osl::Guard< osl::Mutex > aGuard( m_aMutex ); + m_bFirstFetchSizePropagationDone = sal_True; + m_nLastFetchSize = nFetchSize; + m_bLastFetchDirection = bFetchDirection; + } + + if( bSetSize ) + { + Any aValue; + aValue <<= nFetchSize; + try + { + setPropertyValue( m_aPropertyNameForFetchSize, aValue ); + } + catch( com::sun::star::uno::Exception& ) {} + } + if( bSetDirection ) + { + sal_Int32 nFetchDirection = FetchDirection::FORWARD; + if( !bFetchDirection ) + nFetchDirection = FetchDirection::REVERSE; + Any aValue; + aValue <<= nFetchDirection; + try + { + setPropertyValue( m_aPropertyNameForFetchDirection, aValue ); + } + catch( com::sun::star::uno::Exception& ) {} + } + + } +} + +//----------------------------------------------------------------- +// XFetchProviderForContentAccess methods. +//----------------------------------------------------------------- + +void SAL_CALL CachedContentResultSetStub + ::impl_getCurrentContentIdentifierString( Any& rAny + , Reference< XContentAccess > xContentAccess ) + throw ( RuntimeException ) +{ + rAny <<= xContentAccess->queryContentIdentifierString(); +} + +void SAL_CALL CachedContentResultSetStub + ::impl_getCurrentContentIdentifier( Any& rAny + , Reference< XContentAccess > xContentAccess ) + throw ( RuntimeException ) +{ + rAny <<= xContentAccess->queryContentIdentifier(); +} + +void SAL_CALL CachedContentResultSetStub + ::impl_getCurrentContent( Any& rAny + , Reference< XContentAccess > xContentAccess ) + throw ( RuntimeException ) +{ + rAny <<= xContentAccess->queryContent(); +} + +//virtual +FetchResult SAL_CALL CachedContentResultSetStub + ::fetchContentIdentifierStrings( sal_Int32 nRowStartPosition + , sal_Int32 nRowCount, sal_Bool bDirection ) + throw( com::sun::star::uno::RuntimeException ) +{ + impl_init_xContentAccessOrigin(); + FETCH_XXX( impl_getCurrentContentIdentifierString, m_xContentAccessOrigin ); +} + +//virtual +FetchResult SAL_CALL CachedContentResultSetStub + ::fetchContentIdentifiers( sal_Int32 nRowStartPosition + , sal_Int32 nRowCount, sal_Bool bDirection ) + throw( com::sun::star::uno::RuntimeException ) +{ + impl_init_xContentAccessOrigin(); + FETCH_XXX( impl_getCurrentContentIdentifier, m_xContentAccessOrigin ); +} + +//virtual +FetchResult SAL_CALL CachedContentResultSetStub + ::fetchContents( sal_Int32 nRowStartPosition + , sal_Int32 nRowCount, sal_Bool bDirection ) + throw( com::sun::star::uno::RuntimeException ) +{ + impl_init_xContentAccessOrigin(); + FETCH_XXX( impl_getCurrentContent, m_xContentAccessOrigin ); +} + +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- +// class CachedContentResultSetStubFactory +//-------------------------------------------------------------------------- +//-------------------------------------------------------------------------- + +CachedContentResultSetStubFactory::CachedContentResultSetStubFactory( + const Reference< XMultiServiceFactory > & rSMgr ) +{ + m_xSMgr = rSMgr; +} + +CachedContentResultSetStubFactory::~CachedContentResultSetStubFactory() +{ +} + +//-------------------------------------------------------------------------- +// CachedContentResultSetStubFactory XInterface methods. +//-------------------------------------------------------------------------- + +XINTERFACE_IMPL_3( CachedContentResultSetStubFactory, + XTypeProvider, + XServiceInfo, + XCachedContentResultSetStubFactory ); + +//-------------------------------------------------------------------------- +// CachedContentResultSetStubFactory XTypeProvider methods. +//-------------------------------------------------------------------------- + +XTYPEPROVIDER_IMPL_3( CachedContentResultSetStubFactory, + XTypeProvider, + XServiceInfo, + XCachedContentResultSetStubFactory ); + +//-------------------------------------------------------------------------- +// CachedContentResultSetStubFactory XServiceInfo methods. +//-------------------------------------------------------------------------- + +XSERVICEINFO_IMPL_1( CachedContentResultSetStubFactory, + OUString::createFromAscii( + "com.sun.star.comp.ucb.CachedContentResultSetStubFactory" ), + OUString::createFromAscii( + CACHED_CRS_STUB_FACTORY_NAME ) ); + +//-------------------------------------------------------------------------- +// Service factory implementation. +//-------------------------------------------------------------------------- + +ONE_INSTANCE_SERVICE_FACTORY_IMPL( CachedContentResultSetStubFactory ); + +//-------------------------------------------------------------------------- +// CachedContentResultSetStubFactory XCachedContentResultSetStubFactory methods. +//-------------------------------------------------------------------------- + + //virtual +Reference< XResultSet > SAL_CALL CachedContentResultSetStubFactory + ::createCachedContentResultSetStub( + const Reference< XResultSet > & xSource ) + throw( RuntimeException ) +{ + if( xSource.is() ) + { + Reference< XResultSet > xRet; + xRet = new CachedContentResultSetStub( xSource ); + return xRet; + } + return NULL; +} + + |