| /************************************************************** |
| * |
| * 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_extensions.hxx" |
| |
| #include "abpresid.hrc" |
| #include "abptypes.hxx" |
| #include "componentmodule.hxx" |
| #include "datasourcehandling.hxx" |
| |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/container/XNameAccess.hpp> |
| #include <com/sun/star/frame/XStorable.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/lang/XMultiServiceFactory.hpp> |
| #include <com/sun/star/lang/XSingleServiceFactory.hpp> |
| #include <com/sun/star/sdb/SQLContext.hpp> |
| #include <com/sun/star/sdb/XCompletedConnection.hpp> |
| #include <com/sun/star/sdb/XDatabaseRegistrations.hpp> |
| #include <com/sun/star/sdb/XDocumentDataSource.hpp> |
| #include <com/sun/star/sdbc/XConnection.hpp> |
| #include <com/sun/star/sdbcx/XTablesSupplier.hpp> |
| #include <com/sun/star/task/XInteractionHandler.hpp> |
| #include <com/sun/star/uno/XNamingService.hpp> |
| |
| #include <comphelper/interaction.hxx> |
| #include <comphelper/componentcontext.hxx> |
| #include <tools/debug.hxx> |
| #include <tools/diagnose_ex.h> |
| #include <unotools/confignode.hxx> |
| #include <unotools/sharedunocomponent.hxx> |
| #include <vcl/stdtext.hxx> |
| |
| //......................................................................... |
| namespace abp |
| { |
| //......................................................................... |
| |
| using namespace ::utl; |
| using namespace ::comphelper; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::sdb; |
| using namespace ::com::sun::star::sdbc; |
| using namespace ::com::sun::star::task; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::sdbcx; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::frame; |
| |
| //===================================================================== |
| struct PackageAccessControl { }; |
| |
| //===================================================================== |
| //--------------------------------------------------------------------- |
| static Reference< XNameAccess > lcl_getDataSourceContext( const Reference< XMultiServiceFactory >& _rxORB ) SAL_THROW (( Exception )) |
| { |
| Reference< XNameAccess > xContext( _rxORB->createInstance( ::rtl::OUString::createFromAscii( "com.sun.star.sdb.DatabaseContext" ) ), UNO_QUERY ); |
| DBG_ASSERT(xContext.is(), "lcl_getDataSourceContext: could not access the data source context!"); |
| return xContext; |
| } |
| |
| //--------------------------------------------------------------------- |
| /// creates a new data source and inserts it into the context |
| static void lcl_implCreateAndInsert( |
| const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rName, |
| Reference< XPropertySet >& /* [out] */ _rxNewDataSource ) SAL_THROW (( ::com::sun::star::uno::Exception )) |
| { |
| //............................................................. |
| // get the data source context |
| Reference< XNameAccess > xContext = lcl_getDataSourceContext( _rxORB ); |
| |
| DBG_ASSERT( !xContext->hasByName( _rName ), "lcl_implCreateAndInsert: name already used!" ); |
| (void)_rName; |
| |
| //............................................................. |
| // create a new data source |
| Reference< XSingleServiceFactory > xFactory( xContext, UNO_QUERY ); |
| Reference< XPropertySet > xNewDataSource; |
| if (xFactory.is()) |
| xNewDataSource = Reference< XPropertySet >( xFactory->createInstance(), UNO_QUERY ); |
| DBG_ASSERT( xNewDataSource.is(), "lcl_implCreateAndInsert: could not create a new data source!" ); |
| |
| //............................................................. |
| // insert the data source into the context |
| Reference< XNamingService > xDynamicContext( xContext, UNO_QUERY ); |
| DBG_ASSERT( xDynamicContext.is(), "lcl_implCreateAndInsert: missing an interface on the context (XNamingService)!" ); |
| if (xDynamicContext.is()) |
| { |
| // xDynamicContext->registerObject( _rName, xNewDataSource ); |
| _rxNewDataSource = xNewDataSource; |
| } |
| } |
| |
| //--------------------------------------------------------------------- |
| /// creates and inserts a data source, and sets it's URL property to the string given |
| static ODataSource lcl_implCreateAndSetURL( |
| const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _rName, |
| const sal_Char* _pInitialAsciiURL ) SAL_THROW (( )) |
| { |
| ODataSource aReturn( _rxORB ); |
| try |
| { |
| // create the new data source |
| Reference< XPropertySet > xNewDataSource; |
| lcl_implCreateAndInsert( _rxORB, _rName, xNewDataSource ); |
| |
| //............................................................. |
| // set the URL property |
| if (xNewDataSource.is()) |
| { |
| xNewDataSource->setPropertyValue( |
| ::rtl::OUString::createFromAscii( "URL" ), |
| makeAny( ::rtl::OUString::createFromAscii( _pInitialAsciiURL ) ) |
| ); |
| } |
| |
| aReturn.setDataSource( xNewDataSource, _rName,PackageAccessControl() ); |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR( "lcl_implCreateAndSetURL: caught an exception while creating the data source!" ); |
| } |
| |
| return aReturn; |
| } |
| //--------------------------------------------------------------------- |
| void lcl_registerDataSource( |
| const Reference< XMultiServiceFactory >& _rxORB, const ::rtl::OUString& _sName, |
| const ::rtl::OUString& _sURL ) SAL_THROW (( ::com::sun::star::uno::Exception )) |
| { |
| OSL_ENSURE( _sName.getLength(), "lcl_registerDataSource: invalid name!" ); |
| OSL_ENSURE( _sURL.getLength(), "lcl_registerDataSource: invalid URL!" ); |
| try |
| { |
| |
| ::comphelper::ComponentContext aContext( _rxORB ); |
| Reference< XDatabaseRegistrations > xRegistrations( |
| aContext.createComponent( "com.sun.star.sdb.DatabaseContext" ), UNO_QUERY_THROW ); |
| |
| if ( xRegistrations->hasRegisteredDatabase( _sName ) ) |
| xRegistrations->changeDatabaseLocation( _sName, _sURL ); |
| else |
| xRegistrations->registerDatabaseLocation( _sName, _sURL ); |
| } |
| catch( const Exception& ) |
| { |
| DBG_UNHANDLED_EXCEPTION(); |
| } |
| } |
| |
| //===================================================================== |
| //= ODataSourceContextImpl |
| //===================================================================== |
| struct ODataSourceContextImpl |
| { |
| Reference< XMultiServiceFactory > xORB; |
| Reference< XNameAccess > xContext; /// the UNO data source context |
| StringBag aDataSourceNames; /// for quicker name checks (without the UNO overhead) |
| |
| ODataSourceContextImpl( const Reference< XMultiServiceFactory >& _rxORB ) : xORB( _rxORB ) { } |
| ODataSourceContextImpl( const ODataSourceContextImpl& _rSource ) |
| :xORB ( _rSource.xORB ) |
| ,xContext ( _rSource.xContext ) |
| { |
| } |
| }; |
| |
| //===================================================================== |
| //= ODataSourceContext |
| //===================================================================== |
| //--------------------------------------------------------------------- |
| ODataSourceContext::ODataSourceContext(const Reference< XMultiServiceFactory >& _rxORB) |
| :m_pImpl( new ODataSourceContextImpl( _rxORB ) ) |
| { |
| try |
| { |
| // create the UNO context |
| m_pImpl->xContext = lcl_getDataSourceContext( _rxORB ); |
| |
| if (m_pImpl->xContext.is()) |
| { |
| // collect the data source names |
| Sequence< ::rtl::OUString > aDSNames = m_pImpl->xContext->getElementNames(); |
| const ::rtl::OUString* pDSNames = aDSNames.getConstArray(); |
| const ::rtl::OUString* pDSNamesEnd = pDSNames + aDSNames.getLength(); |
| |
| for ( ;pDSNames != pDSNamesEnd; ++pDSNames ) |
| m_pImpl->aDataSourceNames.insert( *pDSNames ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "ODataSourceContext::ODataSourceContext: caught an exception!" ); |
| } |
| } |
| |
| //--------------------------------------------------------------------- |
| ::rtl::OUString& ODataSourceContext::disambiguate(::rtl::OUString& _rDataSourceName) |
| { |
| ::rtl::OUString sCheck( _rDataSourceName ); |
| ConstStringBagIterator aPos = m_pImpl->aDataSourceNames.find( sCheck ); |
| |
| sal_Int32 nPostFix = 1; |
| while ( ( m_pImpl->aDataSourceNames.end() != aPos ) && ( nPostFix < 65535 ) ) |
| { // there already is a data source with this name |
| sCheck = _rDataSourceName; |
| sCheck += ::rtl::OUString::valueOf( nPostFix++ ); |
| |
| aPos = m_pImpl->aDataSourceNames.find( sCheck ); |
| } |
| |
| _rDataSourceName = sCheck; |
| return _rDataSourceName; |
| } |
| |
| //--------------------------------------------------------------------- |
| void ODataSourceContext::getDataSourceNames( StringBag& _rNames ) const SAL_THROW (( )) |
| { |
| _rNames = m_pImpl->aDataSourceNames; |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewLDAP( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:ldap:" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewMORK( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:mozilla" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewThunderbird( const ::rtl::OUString& _rName ) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:thunderbird" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewEvolutionLdap( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:ldap" ); |
| } |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewEvolutionGroupwise( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:groupwise" ); |
| } |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewEvolution( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:evolution:local" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewKab( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:kab" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewMacab( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:macab" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewOutlook( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:outlook" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewOE( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:address:outlookexp" ); |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource ODataSourceContext::createNewDBase( const ::rtl::OUString& _rName) SAL_THROW (( )) |
| { |
| return lcl_implCreateAndSetURL( m_pImpl->xORB, _rName, "sdbc:dbase:" ); |
| } |
| |
| //===================================================================== |
| //= ODataSourceImpl |
| //===================================================================== |
| struct ODataSourceImpl |
| { |
| public: |
| Reference< XMultiServiceFactory > xORB; /// the service factory |
| Reference< XPropertySet > xDataSource; /// the UNO data source |
| ::utl::SharedUNOComponent< XConnection > |
| xConnection; |
| StringBag aTables; // the cached table names |
| ::rtl::OUString sName; |
| sal_Bool bTablesUpToDate; // table name cache up-to-date? |
| |
| ODataSourceImpl( const Reference< XMultiServiceFactory >& _rxORB ) |
| :xORB( _rxORB ) |
| ,bTablesUpToDate( sal_False ) |
| { |
| } |
| |
| ODataSourceImpl( const ODataSourceImpl& _rSource ); |
| }; |
| |
| //--------------------------------------------------------------------- |
| ODataSourceImpl::ODataSourceImpl( const ODataSourceImpl& _rSource ) |
| :xORB( _rSource.xORB ) |
| ,xDataSource( _rSource.xDataSource ) |
| ,xConnection( _rSource.xConnection ) |
| ,aTables( _rSource.aTables ) |
| ,sName( _rSource.sName ) |
| ,bTablesUpToDate( _rSource.bTablesUpToDate ) |
| { |
| } |
| |
| //===================================================================== |
| //= ODataSource |
| //===================================================================== |
| //--------------------------------------------------------------------- |
| ODataSource::ODataSource( const ODataSource& _rSource ) |
| :m_pImpl( NULL ) |
| { |
| *this = _rSource; |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource& ODataSource::operator=( const ODataSource& _rSource ) |
| { |
| delete m_pImpl; |
| m_pImpl = new ODataSourceImpl( *_rSource.m_pImpl ); |
| |
| return *this; |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource::ODataSource( const Reference< XMultiServiceFactory >& _rxORB ) |
| :m_pImpl(new ODataSourceImpl(_rxORB)) |
| { |
| } |
| |
| //--------------------------------------------------------------------- |
| ODataSource::~ODataSource( ) |
| { |
| delete m_pImpl; |
| } |
| |
| //--------------------------------------------------------------------- |
| void ODataSource::store() SAL_THROW (( )) |
| { |
| if (!isValid()) |
| // nothing to do |
| return; |
| try |
| { |
| Reference< XDocumentDataSource > xDocAccess( m_pImpl->xDataSource, UNO_QUERY ); |
| Reference< XStorable > xStorable; |
| if ( xDocAccess.is() ) |
| xStorable = xStorable.query( xDocAccess->getDatabaseDocument() ); |
| OSL_ENSURE( xStorable.is(),"DataSource is no XStorable!" ); |
| if ( xStorable.is() ) |
| xStorable->storeAsURL(m_pImpl->sName,Sequence<PropertyValue>()); |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR( "ODataSource::registerDataSource: caught an exception while creating the data source!" ); |
| } |
| } |
| //--------------------------------------------------------------------- |
| void ODataSource::registerDataSource( const ::rtl::OUString& _sRegisteredDataSourceName) SAL_THROW (( )) |
| { |
| if (!isValid()) |
| // nothing to do |
| return; |
| |
| try |
| { |
| // invalidate ourself |
| lcl_registerDataSource(m_pImpl->xORB,_sRegisteredDataSourceName,m_pImpl->sName); |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR( "ODataSource::registerDataSource: caught an exception while creating the data source!" ); |
| } |
| } |
| |
| //--------------------------------------------------------------------- |
| void ODataSource::setDataSource( const Reference< XPropertySet >& _rxDS,const ::rtl::OUString& _sName, PackageAccessControl ) |
| { |
| if (m_pImpl->xDataSource.get() == _rxDS.get()) |
| // nothing to do |
| return; |
| |
| if ( isConnected() ) |
| disconnect(); |
| |
| m_pImpl->sName = _sName; |
| m_pImpl->xDataSource = _rxDS; |
| } |
| |
| //--------------------------------------------------------------------- |
| void ODataSource::remove() SAL_THROW (( )) |
| { |
| if (!isValid()) |
| // nothing to do |
| return; |
| |
| try |
| { |
| // invalidate ourself |
| m_pImpl->xDataSource.clear(); |
| } |
| catch(const Exception&) |
| { |
| DBG_ERROR( "ODataSource::remove: caught an exception while creating the data source!" ); |
| } |
| } |
| |
| //--------------------------------------------------------------------- |
| sal_Bool ODataSource::rename( const ::rtl::OUString& _rName ) SAL_THROW (( )) |
| { |
| if (!isValid()) |
| // nothing to do |
| return sal_False; |
| |
| m_pImpl->sName = _rName; |
| return sal_True; |
| } |
| |
| //--------------------------------------------------------------------- |
| ::rtl::OUString ODataSource::getName() const SAL_THROW (( )) |
| { |
| if ( !isValid() ) |
| return ::rtl::OUString(); |
| return m_pImpl->sName; |
| } |
| |
| //--------------------------------------------------------------------- |
| bool ODataSource::hasTable( const ::rtl::OUString& _rTableName ) const |
| { |
| if ( !isConnected() ) |
| return false; |
| |
| const StringBag& aTables( getTableNames() ); |
| return aTables.find( _rTableName ) != aTables.end(); |
| } |
| |
| //--------------------------------------------------------------------- |
| const StringBag& ODataSource::getTableNames() const SAL_THROW (( )) |
| { |
| m_pImpl->aTables.clear(); |
| if ( !isConnected() ) |
| { |
| DBG_ERROR( "ODataSource::getTableNames: not connected!" ); |
| } |
| else |
| { |
| try |
| { |
| // get the tables container from the connection |
| Reference< XTablesSupplier > xSuppTables( m_pImpl->xConnection.getTyped(), UNO_QUERY ); |
| Reference< XNameAccess > xTables; |
| if ( xSuppTables.is( ) ) |
| xTables = xSuppTables->getTables(); |
| DBG_ASSERT( xTables.is(), "ODataSource::getTableNames: could not retrieve the tables container!" ); |
| |
| // get the names |
| Sequence< ::rtl::OUString > aTableNames; |
| if ( xTables.is( ) ) |
| aTableNames = xTables->getElementNames( ); |
| |
| // copy the names |
| const ::rtl::OUString* pTableNames = aTableNames.getConstArray(); |
| const ::rtl::OUString* pTableNamesEnd = pTableNames + aTableNames.getLength(); |
| for (;pTableNames < pTableNamesEnd; ++pTableNames) |
| m_pImpl->aTables.insert( *pTableNames ); |
| } |
| catch(const Exception&) |
| { |
| } |
| } |
| |
| // now the table cache is up-to-date |
| m_pImpl->bTablesUpToDate = sal_True; |
| return m_pImpl->aTables; |
| } |
| |
| //--------------------------------------------------------------------- |
| sal_Bool ODataSource::connect( Window* _pMessageParent ) SAL_THROW (( )) |
| { |
| if ( isConnected( ) ) |
| // nothing to do |
| return sal_True; |
| |
| // ................................................................ |
| // create the interaction handler (needed for authentication and error handling) |
| static ::rtl::OUString s_sInteractionHandlerServiceName = ::rtl::OUString::createFromAscii("com.sun.star.task.InteractionHandler"); |
| Reference< XInteractionHandler > xInteractions; |
| try |
| { |
| xInteractions = Reference< XInteractionHandler >( |
| m_pImpl->xORB->createInstance( s_sInteractionHandlerServiceName ), |
| UNO_QUERY |
| ); |
| } |
| catch(const Exception&) |
| { |
| } |
| |
| // ................................................................ |
| // failure to create the interaction handler is a serious issue ... |
| if (!xInteractions.is()) |
| { |
| if ( _pMessageParent ) |
| ShowServiceNotAvailableError( _pMessageParent, s_sInteractionHandlerServiceName, sal_True ); |
| return sal_False; |
| } |
| |
| // ................................................................ |
| // open the connection |
| Any aError; |
| Reference< XConnection > xConnection; |
| try |
| { |
| Reference< XCompletedConnection > xComplConn( m_pImpl->xDataSource, UNO_QUERY ); |
| DBG_ASSERT( xComplConn.is(), "ODataSource::connect: missing the XCompletedConnection interface on the data source!" ); |
| if ( xComplConn.is() ) |
| xConnection = xComplConn->connectWithCompletion( xInteractions ); |
| } |
| catch( const SQLContext& e ) { aError <<= e; } |
| catch( const SQLWarning& e ) { aError <<= e; } |
| catch( const SQLException& e ) { aError <<= e; } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "ODataSource::connect: caught a generic exception!" ); |
| } |
| |
| // ................................................................ |
| // handle errors |
| if ( aError.hasValue() && _pMessageParent ) |
| { |
| try |
| { |
| SQLException aException; |
| aError >>= aException; |
| if ( !aException.Message.getLength() ) |
| { |
| // prepend some context info |
| SQLContext aDetailedError; |
| aDetailedError.Message = String( ModuleRes( RID_STR_NOCONNECTION ) ); |
| aDetailedError.Details = String( ModuleRes( RID_STR_PLEASECHECKSETTINGS ) ); |
| aDetailedError.NextException = aError; |
| // handle (aka display) the new context info |
| xInteractions->handle( new OInteractionRequest( makeAny( aDetailedError ) ) ); |
| } |
| else |
| { |
| // handle (aka display) the original error |
| xInteractions->handle( new OInteractionRequest( makeAny( aException ) ) ); |
| } |
| } |
| catch( const Exception& ) |
| { |
| DBG_ERROR( "ODataSource::connect: caught an exception while trying to display the error!" ); |
| } |
| } |
| |
| if ( !xConnection.is() ) |
| return sal_False; |
| |
| // ................................................................ |
| // success |
| m_pImpl->xConnection.reset( xConnection ); |
| m_pImpl->aTables.clear(); |
| m_pImpl->bTablesUpToDate = sal_False; |
| |
| return sal_True; |
| } |
| |
| //--------------------------------------------------------------------- |
| void ODataSource::disconnect( ) SAL_THROW (( )) |
| { |
| m_pImpl->xConnection.clear(); |
| m_pImpl->aTables.clear(); |
| m_pImpl->bTablesUpToDate = sal_False; |
| } |
| |
| //--------------------------------------------------------------------- |
| sal_Bool ODataSource::isConnected( ) const SAL_THROW (( )) |
| { |
| return m_pImpl->xConnection.is(); |
| } |
| |
| //--------------------------------------------------------------------- |
| sal_Bool ODataSource::isValid() const SAL_THROW (( )) |
| { |
| return m_pImpl && m_pImpl->xDataSource.is(); |
| } |
| //--------------------------------------------------------------------- |
| Reference< XPropertySet > ODataSource::getDataSource() const SAL_THROW (( )) |
| { |
| return m_pImpl ? m_pImpl->xDataSource : Reference< XPropertySet >(); |
| } |
| |
| //......................................................................... |
| } // namespace abp |
| //......................................................................... |
| |