LCOV - code coverage report
Current view: top level - dbaccess/source/core/dataaccess - datasource.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 596 0.0 %
Date: 2014-04-14 Functions: 0 83 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "datasource.hxx"
      21             : #include "module_dba.hxx"
      22             : #include "userinformation.hxx"
      23             : #include "commandcontainer.hxx"
      24             : #include "dbastrings.hrc"
      25             : #include "core_resource.hxx"
      26             : #include "core_resource.hrc"
      27             : #include "connection.hxx"
      28             : #include "SharedConnection.hxx"
      29             : #include "databasedocument.hxx"
      30             : #include "OAuthenticationContinuation.hxx"
      31             : 
      32             : #include <com/sun/star/beans/NamedValue.hpp>
      33             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      34             : #include <com/sun/star/beans/PropertyState.hpp>
      35             : #include <com/sun/star/beans/XPropertyContainer.hpp>
      36             : #include <com/sun/star/document/XDocumentSubStorageSupplier.hpp>
      37             : #include <com/sun/star/document/XEventBroadcaster.hpp>
      38             : #include <com/sun/star/embed/XTransactedObject.hpp>
      39             : #include <com/sun/star/lang/DisposedException.hpp>
      40             : #include <com/sun/star/reflection/ProxyFactory.hpp>
      41             : #include <com/sun/star/sdb/DatabaseContext.hpp>
      42             : #include <com/sun/star/sdbc/ConnectionPool.hpp>
      43             : #include <com/sun/star/sdbc/XDriverAccess.hpp>
      44             : #include <com/sun/star/sdbc/XDriverManager.hpp>
      45             : #include <com/sun/star/sdbc/DriverManager.hpp>
      46             : #include <com/sun/star/sdbcx/XTablesSupplier.hpp>
      47             : #include <com/sun/star/ucb/AuthenticationRequest.hpp>
      48             : #include <com/sun/star/ucb/XInteractionSupplyAuthentication.hpp>
      49             : #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
      50             : #include <com/sun/star/view/XPrintable.hpp>
      51             : 
      52             : #include <comphelper/guarding.hxx>
      53             : #include <comphelper/interaction.hxx>
      54             : #include <comphelper/namedvaluecollection.hxx>
      55             : #include <comphelper/property.hxx>
      56             : #include <comphelper/seqstream.hxx>
      57             : #include <comphelper/sequence.hxx>
      58             : #include <cppuhelper/supportsservice.hxx>
      59             : #include <connectivity/dbexception.hxx>
      60             : #include <connectivity/dbtools.hxx>
      61             : #include <cppuhelper/typeprovider.hxx>
      62             : #include <tools/debug.hxx>
      63             : #include <tools/diagnose_ex.h>
      64             : #include <osl/diagnose.h>
      65             : #include <tools/urlobj.hxx>
      66             : #include <typelib/typedescription.hxx>
      67             : #include <unotools/confignode.hxx>
      68             : #include <unotools/sharedunocomponent.hxx>
      69             : #include <rtl/digest.h>
      70             : 
      71             : #include <algorithm>
      72             : #include <iterator>
      73             : #include <set>
      74             : 
      75             : using namespace ::com::sun::star::sdbc;
      76             : using namespace ::com::sun::star::sdbcx;
      77             : using namespace ::com::sun::star::sdb;
      78             : using namespace ::com::sun::star::beans;
      79             : using namespace ::com::sun::star::uno;
      80             : using namespace ::com::sun::star::lang;
      81             : using namespace ::com::sun::star::embed;
      82             : using namespace ::com::sun::star::container;
      83             : using namespace ::com::sun::star::util;
      84             : using namespace ::com::sun::star::io;
      85             : using namespace ::com::sun::star::task;
      86             : using namespace ::com::sun::star::ucb;
      87             : using namespace ::com::sun::star::frame;
      88             : using namespace ::com::sun::star::reflection;
      89             : using namespace ::cppu;
      90             : using namespace ::osl;
      91             : using namespace ::dbtools;
      92             : using namespace ::comphelper;
      93             : 
      94             : namespace dbaccess
      95             : {
      96             : 
      97             : // FlushNotificationAdapter
      98             : typedef ::cppu::WeakImplHelper1< XFlushListener > FlushNotificationAdapter_Base;
      99             : /** helper class which implements a XFlushListener, and forwards all
     100             :     notification events to another XFlushListener
     101             : 
     102             :     The speciality is that the foreign XFlushListener instance, to which
     103             :     the notifications are forwarded, is held weak.
     104             : 
     105             :     Thus, the class can be used with XFlushable instance which hold
     106             :     their listeners with a hard reference, if you simply do not *want*
     107             :     to be held hard-ref-wise.
     108             : */
     109             : class FlushNotificationAdapter : public FlushNotificationAdapter_Base
     110             : {
     111             : private:
     112             :     WeakReference< XFlushable >     m_aBroadcaster;
     113             :     WeakReference< XFlushListener > m_aListener;
     114             : 
     115             : public:
     116           0 :     static void installAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
     117             :     {
     118           0 :         Reference< XFlushListener > xAdapter( new FlushNotificationAdapter( _rxBroadcaster, _rxListener ) );
     119           0 :     }
     120             : 
     121             : protected:
     122             :     FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener );
     123             :     virtual ~FlushNotificationAdapter();
     124             : 
     125             :     void SAL_CALL impl_dispose( bool _bRevokeListener );
     126             : 
     127             : protected:
     128             :     // XFlushListener
     129             :     virtual void SAL_CALL flushed( const ::com::sun::star::lang::EventObject& rEvent ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     130             :     // XEventListener
     131             :     virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw (::com::sun::star::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     132             : };
     133             : 
     134           0 : FlushNotificationAdapter::FlushNotificationAdapter( const Reference< XFlushable >& _rxBroadcaster, const Reference< XFlushListener >& _rxListener )
     135             :     :m_aBroadcaster( _rxBroadcaster )
     136           0 :     ,m_aListener( _rxListener )
     137             : {
     138             :     OSL_ENSURE( _rxBroadcaster.is(), "FlushNotificationAdapter::FlushNotificationAdapter: invalid flushable!" );
     139             : 
     140           0 :     osl_atomic_increment( &m_refCount );
     141             :     {
     142           0 :         if ( _rxBroadcaster.is() )
     143           0 :             _rxBroadcaster->addFlushListener( this );
     144             :     }
     145           0 :     osl_atomic_decrement( &m_refCount );
     146             :     OSL_ENSURE( m_refCount == 1, "FlushNotificationAdapter::FlushNotificationAdapter: broadcaster isn't holding by hard ref!?" );
     147           0 : }
     148             : 
     149           0 : FlushNotificationAdapter::~FlushNotificationAdapter()
     150             : {
     151           0 : }
     152             : 
     153           0 : void SAL_CALL FlushNotificationAdapter::impl_dispose( bool _bRevokeListener )
     154             : {
     155           0 :     Reference< XFlushListener > xKeepAlive( this );
     156             : 
     157           0 :     if ( _bRevokeListener )
     158             :     {
     159           0 :         Reference< XFlushable > xFlushable( m_aBroadcaster );
     160           0 :         if ( xFlushable.is() )
     161           0 :             xFlushable->removeFlushListener( this );
     162             :     }
     163             : 
     164           0 :     m_aListener.clear();
     165           0 :     m_aBroadcaster.clear();
     166           0 : }
     167             : 
     168           0 : void SAL_CALL FlushNotificationAdapter::flushed( const EventObject& rEvent ) throw (RuntimeException, std::exception)
     169             : {
     170           0 :     Reference< XFlushListener > xListener( m_aListener );
     171           0 :     if ( xListener.is() )
     172           0 :         xListener->flushed( rEvent );
     173             :     else
     174           0 :         impl_dispose( true );
     175           0 : }
     176             : 
     177           0 : void SAL_CALL FlushNotificationAdapter::disposing( const EventObject& Source ) throw (RuntimeException, std::exception)
     178             : {
     179           0 :     Reference< XFlushListener > xListener( m_aListener );
     180           0 :     if ( xListener.is() )
     181           0 :         xListener->disposing( Source );
     182             : 
     183           0 :     impl_dispose( true );
     184           0 : }
     185             : 
     186           0 : OAuthenticationContinuation::OAuthenticationContinuation()
     187             :     :m_bRemberPassword(sal_True),   // TODO: a meaningful default
     188           0 :     m_bCanSetUserName(sal_True)
     189             : {
     190           0 : }
     191             : 
     192           0 : sal_Bool SAL_CALL OAuthenticationContinuation::canSetRealm(  ) throw(RuntimeException, std::exception)
     193             : {
     194           0 :     return sal_False;
     195             : }
     196             : 
     197           0 : void SAL_CALL OAuthenticationContinuation::setRealm( const OUString& /*Realm*/ ) throw(RuntimeException, std::exception)
     198             : {
     199             :     SAL_WARN("dbaccess","OAuthenticationContinuation::setRealm: not supported!");
     200           0 : }
     201             : 
     202           0 : sal_Bool SAL_CALL OAuthenticationContinuation::canSetUserName(  ) throw(RuntimeException, std::exception)
     203             : {
     204             :     // we always allow this, even if the database document is read-only. In this case,
     205             :     // it's simply that the user cannot store the new user name.
     206           0 :     return m_bCanSetUserName;
     207             : }
     208             : 
     209           0 : void SAL_CALL OAuthenticationContinuation::setUserName( const OUString& _rUser ) throw(RuntimeException, std::exception)
     210             : {
     211           0 :     m_sUser = _rUser;
     212           0 : }
     213             : 
     214           0 : sal_Bool SAL_CALL OAuthenticationContinuation::canSetPassword(  ) throw(RuntimeException, std::exception)
     215             : {
     216           0 :     return sal_True;
     217             : }
     218             : 
     219           0 : void SAL_CALL OAuthenticationContinuation::setPassword( const OUString& _rPassword ) throw(RuntimeException, std::exception)
     220             : {
     221           0 :     m_sPassword = _rPassword;
     222           0 : }
     223             : 
     224           0 : Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberPasswordModes( RememberAuthentication& _reDefault ) throw(RuntimeException, std::exception)
     225             : {
     226           0 :     Sequence< RememberAuthentication > aReturn(1);
     227           0 :     _reDefault = aReturn[0] = RememberAuthentication_SESSION;
     228           0 :     return aReturn;
     229             : }
     230             : 
     231           0 : void SAL_CALL OAuthenticationContinuation::setRememberPassword( RememberAuthentication _eRemember ) throw(RuntimeException, std::exception)
     232             : {
     233           0 :     m_bRemberPassword = (RememberAuthentication_NO != _eRemember);
     234           0 : }
     235             : 
     236           0 : sal_Bool SAL_CALL OAuthenticationContinuation::canSetAccount(  ) throw(RuntimeException, std::exception)
     237             : {
     238           0 :     return sal_False;
     239             : }
     240             : 
     241           0 : void SAL_CALL OAuthenticationContinuation::setAccount( const OUString& ) throw(RuntimeException, std::exception)
     242             : {
     243             :     SAL_WARN("dbaccess","OAuthenticationContinuation::setAccount: not supported!");
     244           0 : }
     245             : 
     246           0 : Sequence< RememberAuthentication > SAL_CALL OAuthenticationContinuation::getRememberAccountModes( RememberAuthentication& _reDefault ) throw(RuntimeException, std::exception)
     247             : {
     248           0 :     Sequence < RememberAuthentication > aReturn(1);
     249           0 :     aReturn[0] = RememberAuthentication_NO;
     250           0 :     _reDefault = RememberAuthentication_NO;
     251           0 :     return aReturn;
     252             : }
     253             : 
     254           0 : void SAL_CALL OAuthenticationContinuation::setRememberAccount( RememberAuthentication /*Remember*/ ) throw(RuntimeException, std::exception)
     255             : {
     256             :     SAL_WARN("dbaccess","OAuthenticationContinuation::setRememberAccount: not supported!");
     257           0 : }
     258             : 
     259             : /** The class OSharedConnectionManager implements a structure to share connections.
     260             :     It owns the master connections which will be disposed when the last connection proxy is gone.
     261             : */
     262             : typedef ::cppu::WeakImplHelper1< XEventListener > OConnectionHelper_BASE;
     263             : // need to hold the digest
     264             : struct TDigestHolder
     265             : {
     266             :     sal_uInt8 m_pBuffer[RTL_DIGEST_LENGTH_SHA1];
     267           0 :     TDigestHolder()
     268             :     {
     269           0 :         m_pBuffer[0] = 0;
     270           0 :     }
     271             : 
     272             : };
     273             : 
     274             : class OSharedConnectionManager : public OConnectionHelper_BASE
     275             : {
     276             : 
     277             :      // contains the currently used master connections
     278             :     typedef struct
     279           0 :     {
     280             :         Reference< XConnection >    xMasterConnection;
     281             :         oslInterlockedCount         nALiveCount;
     282           0 :     } TConnectionHolder;
     283             : 
     284             :     // the less-compare functor, used for the stl::map
     285             :     struct TDigestLess : public ::std::binary_function< TDigestHolder, TDigestHolder, bool>
     286             :     {
     287           0 :         bool operator() (const TDigestHolder& x, const TDigestHolder& y) const
     288             :         {
     289             :             sal_uInt32 i;
     290           0 :             for(i=0;i < RTL_DIGEST_LENGTH_SHA1 && (x.m_pBuffer[i] >= y.m_pBuffer[i]); ++i)
     291             :                 ;
     292           0 :             return i < RTL_DIGEST_LENGTH_SHA1;
     293             :         }
     294             :     };
     295             : 
     296             :     typedef ::std::map< TDigestHolder,TConnectionHolder,TDigestLess>        TConnectionMap;      // holds the master connections
     297             :     typedef ::std::map< Reference< XConnection >,TConnectionMap::iterator>  TSharedConnectionMap;// holds the shared connections
     298             : 
     299             :     ::osl::Mutex                m_aMutex;
     300             :     TConnectionMap              m_aConnections;         // remember the master connection in conjunction with the digest
     301             :     TSharedConnectionMap        m_aSharedConnection;    // the shared connections with conjunction with an iterator into the connections map
     302             :     Reference< XProxyFactory >  m_xProxyFactory;
     303             : 
     304             : protected:
     305             :     virtual ~OSharedConnectionManager();
     306             : 
     307             : public:
     308             :     OSharedConnectionManager(const Reference< XComponentContext >& _rxContext);
     309             : 
     310             :     void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException, std::exception) SAL_OVERRIDE;
     311             :     Reference<XConnection> getConnection(   const OUString& url,
     312             :                                             const OUString& user,
     313             :                                             const OUString& password,
     314             :                                             const Sequence< PropertyValue >& _aInfo,
     315             :                                             ODatabaseSource* _pDataSource);
     316             :     void addEventListener(const Reference<XConnection>& _rxConnection,TConnectionMap::iterator& _rIter);
     317             : };
     318             : 
     319           0 : OSharedConnectionManager::OSharedConnectionManager(const Reference< XComponentContext >& _rxContext)
     320             : {
     321           0 :     m_xProxyFactory.set( ProxyFactory::create( _rxContext ) );
     322           0 : }
     323             : 
     324           0 : OSharedConnectionManager::~OSharedConnectionManager()
     325             : {
     326           0 : }
     327             : 
     328           0 : void SAL_CALL OSharedConnectionManager::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException, std::exception)
     329             : {
     330           0 :     MutexGuard aGuard(m_aMutex);
     331           0 :     Reference<XConnection> xConnection(Source.Source,UNO_QUERY);
     332           0 :     TSharedConnectionMap::iterator aFind = m_aSharedConnection.find(xConnection);
     333           0 :     if ( m_aSharedConnection.end() != aFind )
     334             :     {
     335           0 :         osl_atomic_decrement(&aFind->second->second.nALiveCount);
     336           0 :         if ( !aFind->second->second.nALiveCount )
     337             :         {
     338           0 :             ::comphelper::disposeComponent(aFind->second->second.xMasterConnection);
     339           0 :             m_aConnections.erase(aFind->second);
     340             :         }
     341           0 :         m_aSharedConnection.erase(aFind);
     342           0 :     }
     343           0 : }
     344             : 
     345           0 : Reference<XConnection> OSharedConnectionManager::getConnection( const OUString& url,
     346             :                                         const OUString& user,
     347             :                                         const OUString& password,
     348             :                                         const Sequence< PropertyValue >& _aInfo,
     349             :                                         ODatabaseSource* _pDataSource)
     350             : {
     351           0 :     MutexGuard aGuard(m_aMutex);
     352           0 :     TConnectionMap::key_type nId;
     353           0 :     Sequence< PropertyValue > aInfoCopy(_aInfo);
     354           0 :     sal_Int32 nPos = aInfoCopy.getLength();
     355           0 :     aInfoCopy.realloc( nPos + 2 );
     356           0 :     aInfoCopy[nPos].Name      = "TableFilter";
     357           0 :     aInfoCopy[nPos++].Value <<= _pDataSource->m_pImpl->m_aTableFilter;
     358           0 :     aInfoCopy[nPos].Name      = "TableTypeFilter";
     359           0 :     aInfoCopy[nPos++].Value <<= _pDataSource->m_pImpl->m_aTableTypeFilter;
     360             : 
     361           0 :     OUString sUser = user;
     362           0 :     OUString sPassword = password;
     363           0 :     if ((sUser.isEmpty()) && (sPassword.isEmpty()) && (!_pDataSource->m_pImpl->m_sUser.isEmpty()))
     364             :     {   // ease the usage of this method. data source which are intended to have a user automatically
     365             :         // fill in the user/password combination if the caller of this method does not specify otherwise
     366           0 :         sUser = _pDataSource->m_pImpl->m_sUser;
     367           0 :         if (!_pDataSource->m_pImpl->m_aPassword.isEmpty())
     368           0 :             sPassword = _pDataSource->m_pImpl->m_aPassword;
     369             :     }
     370             : 
     371           0 :     ::connectivity::OConnectionWrapper::createUniqueId(url,aInfoCopy,nId.m_pBuffer,sUser,sPassword);
     372           0 :     TConnectionMap::iterator aIter = m_aConnections.find(nId);
     373             : 
     374           0 :     if ( m_aConnections.end() == aIter )
     375             :     {
     376           0 :         TConnectionHolder aHolder;
     377           0 :         aHolder.nALiveCount = 0; // will be incremented by addListener
     378           0 :         aHolder.xMasterConnection = _pDataSource->buildIsolatedConnection(user,password);
     379           0 :         aIter = m_aConnections.insert(TConnectionMap::value_type(nId,aHolder)).first;
     380             :     }
     381             : 
     382           0 :     Reference<XConnection> xRet;
     383           0 :     if ( aIter->second.xMasterConnection.is() )
     384             :     {
     385           0 :         Reference< XAggregation > xConProxy = m_xProxyFactory->createProxy(aIter->second.xMasterConnection.get());
     386           0 :         xRet = new OSharedConnection(xConProxy);
     387           0 :         m_aSharedConnection.insert(TSharedConnectionMap::value_type(xRet,aIter));
     388           0 :         addEventListener(xRet,aIter);
     389             :     }
     390             : 
     391           0 :     return xRet;
     392             : }
     393             : 
     394           0 : void OSharedConnectionManager::addEventListener(const Reference<XConnection>& _rxConnection,TConnectionMap::iterator& _rIter)
     395             : {
     396           0 :     Reference<XComponent> xComp(_rxConnection,UNO_QUERY);
     397           0 :     xComp->addEventListener(this);
     398             :     OSL_ENSURE( m_aConnections.end() != _rIter , "Iterator is end!");
     399           0 :     osl_atomic_increment(&_rIter->second.nALiveCount);
     400           0 : }
     401             : 
     402             : namespace
     403             : {
     404           0 :     Sequence< PropertyValue > lcl_filterDriverProperties( const Reference< XDriver >& _xDriver, const OUString& _sUrl,
     405             :         const Sequence< PropertyValue >& _rDataSourceSettings, const AsciiPropertyValue* _pKnownSettings )
     406             :     {
     407           0 :         if ( _xDriver.is() )
     408             :         {
     409           0 :             Sequence< DriverPropertyInfo > aDriverInfo(_xDriver->getPropertyInfo(_sUrl,_rDataSourceSettings));
     410             : 
     411           0 :             const PropertyValue* pDataSourceSetting = _rDataSourceSettings.getConstArray();
     412           0 :             const PropertyValue* pEnd = pDataSourceSetting + _rDataSourceSettings.getLength();
     413             : 
     414           0 :             ::std::vector< PropertyValue > aRet;
     415             : 
     416           0 :             for ( ; pDataSourceSetting != pEnd ; ++pDataSourceSetting )
     417             :             {
     418           0 :                 sal_Bool bAllowSetting = sal_False;
     419           0 :                 const AsciiPropertyValue* pSetting = _pKnownSettings;
     420           0 :                 for ( ; pSetting->AsciiName; ++pSetting )
     421             :                 {
     422           0 :                     if ( pDataSourceSetting->Name.equalsAscii( pSetting->AsciiName ) )
     423             :                     {   // the particular data source setting is known
     424             : 
     425           0 :                         const DriverPropertyInfo* pAllowedDriverSetting = aDriverInfo.getConstArray();
     426           0 :                         const DriverPropertyInfo* pDriverSettingsEnd = pAllowedDriverSetting + aDriverInfo.getLength();
     427           0 :                         for ( ; pAllowedDriverSetting != pDriverSettingsEnd; ++pAllowedDriverSetting )
     428             :                         {
     429           0 :                             if ( pAllowedDriverSetting->Name.equalsAscii( pSetting->AsciiName ) )
     430             :                             {   // the driver also allows this setting
     431           0 :                                 bAllowSetting = sal_True;
     432           0 :                                 break;
     433             :                             }
     434             :                         }
     435           0 :                         break;
     436             :                     }
     437             :                 }
     438           0 :                 if ( bAllowSetting || !pSetting->AsciiName )
     439             :                 {   // if the driver allows this particular setting, or if the setting is completely unknown,
     440             :                     // we pass it to the driver
     441           0 :                     aRet.push_back( *pDataSourceSetting );
     442             :                 }
     443             :             }
     444           0 :             if ( !aRet.empty() )
     445           0 :                 return Sequence< PropertyValue >(&(*aRet.begin()),aRet.size());
     446             :         }
     447           0 :         return Sequence< PropertyValue >();
     448             :     }
     449             : 
     450             :     typedef ::std::map< OUString, sal_Int32 > PropertyAttributeCache;
     451             : 
     452             :     struct IsDefaultAndNotRemoveable : public ::std::unary_function< PropertyValue, bool >
     453             :     {
     454             :     private:
     455             :         const PropertyAttributeCache& m_rAttribs;
     456             : 
     457             :     public:
     458           0 :         IsDefaultAndNotRemoveable( const PropertyAttributeCache& _rAttribs ) : m_rAttribs( _rAttribs ) { }
     459             : 
     460           0 :         bool operator()( const PropertyValue& _rProp )
     461             :         {
     462           0 :             if ( _rProp.State != PropertyState_DEFAULT_VALUE )
     463           0 :                 return false;
     464             : 
     465           0 :             bool bRemoveable = true;
     466             : 
     467           0 :             PropertyAttributeCache::const_iterator pos = m_rAttribs.find( _rProp.Name );
     468             :             OSL_ENSURE( pos != m_rAttribs.end(), "IsDefaultAndNotRemoveable: illegal property name!" );
     469           0 :             if ( pos != m_rAttribs.end() )
     470           0 :                 bRemoveable = ( ( pos->second & PropertyAttribute::REMOVABLE ) != 0 );
     471             : 
     472           0 :             return !bRemoveable;
     473             :         }
     474             :     };
     475             : }
     476             : 
     477             : // ODatabaseContext
     478             : 
     479           0 : extern "C" void SAL_CALL createRegistryInfo_ODatabaseSource()
     480             : {
     481           0 :     static ::dba::OAutoRegistration< ODatabaseSource > aAutoRegistration;
     482           0 : }
     483             : 
     484           0 : ODatabaseSource::ODatabaseSource(const ::rtl::Reference<ODatabaseModelImpl>& _pImpl)
     485             :             :ModelDependentComponent( _pImpl )
     486           0 :             ,ODatabaseSource_Base( getMutex() )
     487             :             ,OPropertySetHelper( ODatabaseSource_Base::rBHelper )
     488           0 :             ,m_aBookmarks( *this, getMutex() )
     489           0 :             ,m_aFlushListeners( getMutex() )
     490             : {
     491             :     // some kind of default
     492             :     SAL_INFO("dbaccess", "DS: ctor: " << std::hex << this << ": " << std::hex << m_pImpl.get() );
     493           0 : }
     494             : 
     495           0 : ODatabaseSource::~ODatabaseSource()
     496             : {
     497             :     SAL_INFO("dbaccess", "DS: dtor: " << std::hex << this << ": " << std::hex << m_pImpl.get() );
     498           0 :     if ( !ODatabaseSource_Base::rBHelper.bInDispose && !ODatabaseSource_Base::rBHelper.bDisposed )
     499             :     {
     500           0 :         acquire();
     501           0 :         dispose();
     502             :     }
     503           0 : }
     504             : 
     505           0 : void ODatabaseSource::setName( const Reference< XDocumentDataSource >& _rxDocument, const OUString& _rNewName, DBContextAccess )
     506             : {
     507             :     SAL_INFO("dbaccess", "ODatabaseSource::setName" );
     508           0 :     ODatabaseSource& rModelImpl = dynamic_cast< ODatabaseSource& >( *_rxDocument.get() );
     509             : 
     510           0 :     ::osl::MutexGuard aGuard( rModelImpl.m_aMutex );
     511           0 :     if ( rModelImpl.m_pImpl.is() )
     512           0 :         rModelImpl.m_pImpl->m_sName = _rNewName;
     513           0 : }
     514             : 
     515             : // com::sun::star::lang::XTypeProvider
     516           0 : Sequence< Type > ODatabaseSource::getTypes() throw (RuntimeException, std::exception)
     517             : {
     518             :     SAL_INFO("dbaccess", "ODatabaseSource::getTypes" );
     519           0 :     OTypeCollection aPropertyHelperTypes(   ::getCppuType( (const Reference< XFastPropertySet > *)0 ),
     520           0 :                                             ::getCppuType( (const Reference< XPropertySet > *)0 ),
     521           0 :                                             ::getCppuType( (const Reference< XMultiPropertySet > *)0 ));
     522             : 
     523             :     return ::comphelper::concatSequences(
     524             :         ODatabaseSource_Base::getTypes(),
     525             :         aPropertyHelperTypes.getTypes()
     526           0 :     );
     527             : }
     528             : 
     529           0 : Sequence< sal_Int8 > ODatabaseSource::getImplementationId() throw (RuntimeException, std::exception)
     530             : {
     531           0 :     return css::uno::Sequence<sal_Int8>();
     532             : }
     533             : 
     534             : // com::sun::star::uno::XInterface
     535           0 : Any ODatabaseSource::queryInterface( const Type & rType ) throw (RuntimeException, std::exception)
     536             : {
     537           0 :     Any aIface = ODatabaseSource_Base::queryInterface( rType );
     538           0 :     if ( !aIface.hasValue() )
     539           0 :         aIface = ::cppu::OPropertySetHelper::queryInterface( rType );
     540           0 :     return aIface;
     541             : }
     542             : 
     543           0 : void ODatabaseSource::acquire() throw ()
     544             : {
     545           0 :     ODatabaseSource_Base::acquire();
     546           0 : }
     547             : 
     548           0 : void ODatabaseSource::release() throw ()
     549             : {
     550           0 :     ODatabaseSource_Base::release();
     551           0 : }
     552             : 
     553           0 : void SAL_CALL ODatabaseSource::disposing( const ::com::sun::star::lang::EventObject& Source ) throw(RuntimeException, std::exception)
     554             : {
     555           0 :     if ( m_pImpl.is() )
     556           0 :         m_pImpl->disposing(Source);
     557           0 : }
     558             : 
     559             : // XServiceInfo
     560           0 : OUString ODatabaseSource::getImplementationName(  ) throw(RuntimeException, std::exception)
     561             : {
     562             :     SAL_INFO("dbaccess", "ODatabaseSource::getImplementationName" );
     563           0 :     return getImplementationName_static();
     564             : }
     565             : 
     566           0 : OUString ODatabaseSource::getImplementationName_static(  ) throw(RuntimeException)
     567             : {
     568             :     SAL_INFO("dbaccess", "ODatabaseSource::getImplementationName_static" );
     569           0 :     return OUString("com.sun.star.comp.dba.ODatabaseSource");
     570             : }
     571             : 
     572           0 : Sequence< OUString > ODatabaseSource::getSupportedServiceNames(  ) throw (RuntimeException, std::exception)
     573             : {
     574             :     SAL_INFO("dbaccess", "ODatabaseSource::getSupportedServiceNames" );
     575           0 :     return getSupportedServiceNames_static();
     576             : }
     577             : 
     578           0 : Reference< XInterface > ODatabaseSource::Create( const Reference< XComponentContext >& _rxContext )
     579             : {
     580             :     SAL_INFO("dbaccess", "ODatabaseSource::Create" );
     581           0 :     Reference< XDatabaseContext > xDBContext( DatabaseContext::create(_rxContext) );
     582           0 :     return xDBContext->createInstance();
     583             : }
     584             : 
     585           0 : Sequence< OUString > ODatabaseSource::getSupportedServiceNames_static(  ) throw (RuntimeException)
     586             : {
     587             :     SAL_INFO("dbaccess", "ODatabaseSource::getSupportedServiceNames_static" );
     588           0 :     Sequence< OUString > aSNS( 2 );
     589           0 :     aSNS[0] = SERVICE_SDB_DATASOURCE;
     590           0 :     aSNS[1] = "com.sun.star.sdb.DocumentDataSource";
     591           0 :     return aSNS;
     592             : }
     593             : 
     594           0 : sal_Bool ODatabaseSource::supportsService( const OUString& _rServiceName ) throw (RuntimeException, std::exception)
     595             : {
     596           0 :     return cppu::supportsService(this, _rServiceName);
     597             : }
     598             : 
     599             : // OComponentHelper
     600           0 : void ODatabaseSource::disposing()
     601             : {
     602             :     SAL_INFO("dbaccess", "DS: disp: " << std::hex << this << ", " << std::hex << m_pImpl.get() );
     603           0 :     ODatabaseSource_Base::WeakComponentImplHelperBase::disposing();
     604           0 :     OPropertySetHelper::disposing();
     605             : 
     606           0 :     EventObject aDisposeEvent(static_cast<XWeak*>(this));
     607           0 :     m_aFlushListeners.disposeAndClear( aDisposeEvent );
     608             : 
     609           0 :     ODatabaseDocument::clearObjectContainer(m_pImpl->m_xCommandDefinitions);
     610           0 :     ODatabaseDocument::clearObjectContainer(m_pImpl->m_xTableDefinitions);
     611           0 :     m_pImpl.clear();
     612           0 : }
     613             : 
     614           0 : Reference< XConnection > ODatabaseSource::buildLowLevelConnection(const OUString& _rUid, const OUString& _rPwd)
     615             : {
     616             :     SAL_INFO("dbaccess", "ODatabaseSource::buildLowLevelConnection" );
     617           0 :     Reference< XConnection > xReturn;
     618             : 
     619           0 :     Reference< XDriverManager > xManager;
     620             :     try {
     621           0 :         xManager.set( ConnectionPool::create( m_pImpl->m_aContext ), UNO_QUERY_THROW );
     622           0 :     } catch( const Exception& ) {  }
     623           0 :     if ( !xManager.is() )
     624             :         // no connection pool installed, fall back to driver manager
     625           0 :         xManager.set( DriverManager::create(m_pImpl->m_aContext ), UNO_QUERY_THROW );
     626             : 
     627           0 :     OUString sUser(_rUid);
     628           0 :     OUString sPwd(_rPwd);
     629           0 :     if ((sUser.isEmpty()) && (sPwd.isEmpty()) && (!m_pImpl->m_sUser.isEmpty()))
     630             :     {   // ease the usage of this method. data source which are intended to have a user automatically
     631             :         // fill in the user/password combination if the caller of this method does not specify otherwise
     632           0 :         sUser = m_pImpl->m_sUser;
     633           0 :         if (!m_pImpl->m_aPassword.isEmpty())
     634           0 :             sPwd = m_pImpl->m_aPassword;
     635             :     }
     636             : 
     637           0 :     sal_uInt16 nExceptionMessageId = RID_STR_COULDNOTCONNECT_UNSPECIFIED;
     638           0 :     if (xManager.is())
     639             :     {
     640           0 :         sal_Int32 nAdditionalArgs(0);
     641           0 :         if (!sUser.isEmpty()) ++nAdditionalArgs;
     642           0 :         if (!sPwd.isEmpty()) ++nAdditionalArgs;
     643             : 
     644           0 :         Sequence< PropertyValue > aUserPwd(nAdditionalArgs);
     645           0 :         sal_Int32 nArgPos = 0;
     646           0 :         if (!sUser.isEmpty())
     647             :         {
     648           0 :             aUserPwd[ nArgPos ].Name = "user";
     649           0 :             aUserPwd[ nArgPos ].Value <<= sUser;
     650           0 :             ++nArgPos;
     651             :         }
     652           0 :         if (!sPwd.isEmpty())
     653             :         {
     654           0 :             aUserPwd[ nArgPos ].Name = "password";
     655           0 :             aUserPwd[ nArgPos ].Value <<= sPwd;
     656             :         }
     657           0 :         Reference< XDriver > xDriver;
     658             :         try
     659             :         {
     660           0 :             Reference< XDriverAccess > xAccessDrivers( xManager, UNO_QUERY );
     661           0 :             if ( xAccessDrivers.is() )
     662           0 :                 xDriver = xAccessDrivers->getDriverByURL( m_pImpl->m_sConnectURL );
     663             :         }
     664           0 :         catch( const Exception& )
     665             :         {
     666             :             SAL_WARN("dbaccess",  "ODatabaseSource::buildLowLevelConnection: got a strange exception while analyzing the error!" );
     667             :         }
     668           0 :         if ( !xDriver.is() || !xDriver->acceptsURL( m_pImpl->m_sConnectURL ) )
     669             :         {
     670             :             // Nowadays, it's allowed for a driver to be registered for a given URL, but actually not to accept it.
     671             :             // This is because registration nowadays happens at compile time (by adding respective configuration data),
     672             :             // but acceptance is decided at runtime.
     673           0 :             nExceptionMessageId = RID_STR_COULDNOTCONNECT_NODRIVER;
     674             :         }
     675             :         else
     676             :         {
     677             :             Sequence< PropertyValue > aDriverInfo = lcl_filterDriverProperties(
     678             :                 xDriver,
     679           0 :                 m_pImpl->m_sConnectURL,
     680           0 :                 m_pImpl->m_xSettings->getPropertyValues(),
     681           0 :                 m_pImpl->getDefaultDataSourceSettings()
     682           0 :             );
     683             : 
     684           0 :             if ( m_pImpl->isEmbeddedDatabase() )
     685             :             {
     686           0 :                 sal_Int32 nCount = aDriverInfo.getLength();
     687           0 :                 aDriverInfo.realloc(nCount + 3 );
     688             : 
     689           0 :                 aDriverInfo[nCount].Name = "URL";
     690           0 :                 aDriverInfo[nCount++].Value <<= m_pImpl->getURL();
     691             : 
     692           0 :                 aDriverInfo[nCount].Name = "Storage";
     693           0 :                 Reference< css::document::XDocumentSubStorageSupplier> xDocSup( m_pImpl->getDocumentSubStorageSupplier() );
     694           0 :                 aDriverInfo[nCount++].Value <<= xDocSup->getDocumentSubStorage("database",ElementModes::READWRITE);
     695             : 
     696           0 :                 aDriverInfo[nCount].Name = "Document";
     697           0 :                 aDriverInfo[nCount++].Value <<= getDatabaseDocument();
     698             :             }
     699           0 :             if (nAdditionalArgs)
     700           0 :                 xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL, ::comphelper::concatSequences(aUserPwd,aDriverInfo));
     701             :             else
     702           0 :                 xReturn = xManager->getConnectionWithInfo(m_pImpl->m_sConnectURL,aDriverInfo);
     703             : 
     704           0 :             if ( m_pImpl->isEmbeddedDatabase() )
     705             :             {
     706             :                 // see ODatabaseSource::flushed for comment on why we register as FlushListener
     707             :                 // at the connection
     708           0 :                 Reference< XFlushable > xFlushable( xReturn, UNO_QUERY );
     709           0 :                 if ( xFlushable.is() )
     710           0 :                     FlushNotificationAdapter::installAdapter( xFlushable, this );
     711           0 :             }
     712           0 :         }
     713             :     }
     714             :     else
     715           0 :         nExceptionMessageId = RID_STR_COULDNOTLOAD_MANAGER;
     716             : 
     717           0 :     if ( !xReturn.is() )
     718             :     {
     719             :         OUString sMessage = DBACORE_RESSTRING( nExceptionMessageId )
     720           0 :             .replaceAll("$name$", m_pImpl->m_sConnectURL);
     721             : 
     722           0 :         SQLContext aContext;
     723           0 :         aContext.Message = DBACORE_RESSTRING(RID_STR_CONNECTION_REQUEST).
     724           0 :             replaceFirst("$name$", m_pImpl->m_sConnectURL);
     725             : 
     726           0 :         throwGenericSQLException( sMessage, static_cast< XDataSource* >( this ), makeAny( aContext ) );
     727             :     }
     728             : 
     729           0 :     return xReturn;
     730             : }
     731             : 
     732             : // OPropertySetHelper
     733           0 : Reference< XPropertySetInfo >  ODatabaseSource::getPropertySetInfo() throw (RuntimeException, std::exception)
     734             : {
     735             :     SAL_INFO("dbaccess", "ODatabaseSource::getPropertySetInfo" );
     736           0 :     return createPropertySetInfo( getInfoHelper() ) ;
     737             : }
     738             : 
     739             : // comphelper::OPropertyArrayUsageHelper
     740           0 : ::cppu::IPropertyArrayHelper* ODatabaseSource::createArrayHelper( ) const
     741             : {
     742             :     SAL_INFO("dbaccess", "ODatabaseSource::createArrayHelper" );
     743           0 :     BEGIN_PROPERTY_HELPER(13)
     744           0 :         DECL_PROP1(INFO,                        Sequence< PropertyValue >,  BOUND);
     745           0 :         DECL_PROP1_BOOL(ISPASSWORDREQUIRED,                                 BOUND);
     746           0 :         DECL_PROP1_BOOL(ISREADONLY,                                         READONLY);
     747           0 :         DECL_PROP1(LAYOUTINFORMATION,           Sequence< PropertyValue >,  BOUND);
     748           0 :         DECL_PROP1(NAME,                        OUString,            READONLY);
     749           0 :         DECL_PROP2_IFACE(NUMBERFORMATSSUPPLIER, XNumberFormatsSupplier,     READONLY, TRANSIENT);
     750           0 :         DECL_PROP1(PASSWORD,                    OUString,            TRANSIENT);
     751           0 :         DECL_PROP2_IFACE(SETTINGS,              XPropertySet,               BOUND, READONLY);
     752           0 :         DECL_PROP1_BOOL(SUPPRESSVERSIONCL,                                  BOUND);
     753           0 :         DECL_PROP1(TABLEFILTER,                 Sequence< OUString >,BOUND);
     754           0 :         DECL_PROP1(TABLETYPEFILTER,             Sequence< OUString >,BOUND);
     755           0 :         DECL_PROP1(URL,                         OUString,            BOUND);
     756           0 :         DECL_PROP1(USER,                        OUString,            BOUND);
     757           0 :     END_PROPERTY_HELPER();
     758             : }
     759             : 
     760             : // cppu::OPropertySetHelper
     761           0 : ::cppu::IPropertyArrayHelper& ODatabaseSource::getInfoHelper()
     762             : {
     763           0 :     return *getArrayHelper();
     764             : }
     765             : 
     766           0 : sal_Bool ODatabaseSource::convertFastPropertyValue(Any & rConvertedValue, Any & rOldValue, sal_Int32 nHandle, const Any& rValue ) throw( IllegalArgumentException  )
     767             : {
     768           0 :     sal_Bool bModified(sal_False);
     769           0 :     if ( m_pImpl.is() )
     770             :     {
     771           0 :         switch (nHandle)
     772             :         {
     773             :             case PROPERTY_ID_TABLEFILTER:
     774           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aTableFilter);
     775           0 :                 break;
     776             :             case PROPERTY_ID_TABLETYPEFILTER:
     777           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aTableTypeFilter);
     778           0 :                 break;
     779             :             case PROPERTY_ID_USER:
     780           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_sUser);
     781           0 :                 break;
     782             :             case PROPERTY_ID_PASSWORD:
     783           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aPassword);
     784           0 :                 break;
     785             :             case PROPERTY_ID_ISPASSWORDREQUIRED:
     786           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_bPasswordRequired);
     787           0 :                 break;
     788             :             case PROPERTY_ID_SUPPRESSVERSIONCL:
     789           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_bSuppressVersionColumns);
     790           0 :                 break;
     791             :             case PROPERTY_ID_LAYOUTINFORMATION:
     792           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_aLayoutInformation);
     793           0 :                 break;
     794             :             case PROPERTY_ID_URL:
     795             :             {
     796           0 :                 bModified = ::comphelper::tryPropertyValue(rConvertedValue, rOldValue, rValue, m_pImpl->m_sConnectURL);
     797           0 :             }   break;
     798             :             case PROPERTY_ID_INFO:
     799             :             {
     800           0 :                 Sequence<PropertyValue> aValues;
     801           0 :                 if (!(rValue >>= aValues))
     802           0 :                     throw IllegalArgumentException();
     803             : 
     804           0 :                 const PropertyValue* valueEnd = aValues.getConstArray() + aValues.getLength();
     805           0 :                 const PropertyValue* checkName = aValues.getConstArray();
     806           0 :                 for ( ;checkName != valueEnd; ++checkName )
     807             :                 {
     808           0 :                     if ( checkName->Name.isEmpty() )
     809           0 :                         throw IllegalArgumentException();
     810             :                 }
     811             : 
     812           0 :                 Sequence< PropertyValue > aSettings = m_pImpl->m_xSettings->getPropertyValues();
     813           0 :                 bModified = aSettings.getLength() != aValues.getLength();
     814           0 :                 if ( !bModified )
     815             :                 {
     816           0 :                     const PropertyValue* pInfoIter = aSettings.getConstArray();
     817           0 :                     const PropertyValue* checkValue = aValues.getConstArray();
     818           0 :                     for ( ;!bModified && checkValue != valueEnd ; ++checkValue,++pInfoIter)
     819             :                     {
     820           0 :                         bModified = checkValue->Name != pInfoIter->Name;
     821           0 :                         if ( !bModified )
     822             :                         {
     823           0 :                             bModified = !::comphelper::compare(checkValue->Value,pInfoIter->Value);
     824             :                         }
     825             :                     }
     826             :                 }
     827             : 
     828           0 :                 rConvertedValue = rValue;
     829           0 :                 rOldValue <<= aSettings;
     830             :             }
     831           0 :             break;
     832             :             default:
     833             :                 SAL_WARN("dbaccess", "ODatabaseSource::convertFastPropertyValue: unknown or readonly Property!" );
     834             :         }
     835             :     }
     836           0 :     return bModified;
     837             : }
     838             : 
     839             : namespace
     840             : {
     841             :     struct SelectPropertyName : public ::std::unary_function< PropertyValue, OUString >
     842             :     {
     843             :     public:
     844           0 :         const OUString& operator()( const PropertyValue& _lhs )
     845             :         {
     846           0 :             return _lhs.Name;
     847             :         }
     848             :     };
     849             : 
     850             :     /** sets a new set of property values for a given property bag instance
     851             : 
     852             :         The method takes a property bag, and a sequence of property values to set for this bag.
     853             :         Upon return, every property which is not part of the given sequence is
     854             :         <ul><li>removed from the bag, if it's a removable property</li>
     855             :             <li><em>or</em>reset to its default value, if it's not a removable property</li>
     856             :         </ul>.
     857             : 
     858             :         @param  _rxPropertyBag
     859             :             the property bag to operate on
     860             :         @param  _rAllNewPropertyValues
     861             :             the new property values to set for the bag
     862             :     */
     863           0 :     void lcl_setPropertyValues_resetOrRemoveOther( const Reference< XPropertyBag >& _rxPropertyBag, const Sequence< PropertyValue >& _rAllNewPropertyValues )
     864             :     {
     865             :         // sequences are ugly to operate on
     866             :         typedef ::std::set< OUString >   StringSet;
     867           0 :         StringSet aToBeSetPropertyNames;
     868             :         ::std::transform(
     869             :             _rAllNewPropertyValues.getConstArray(),
     870           0 :             _rAllNewPropertyValues.getConstArray() + _rAllNewPropertyValues.getLength(),
     871             :             ::std::insert_iterator< StringSet >( aToBeSetPropertyNames, aToBeSetPropertyNames.end() ),
     872             :             SelectPropertyName()
     873           0 :         );
     874             : 
     875             :         try
     876             :         {
     877             :             // obtain all properties currently known at the bag
     878           0 :             Reference< XPropertySetInfo > xPSI( _rxPropertyBag->getPropertySetInfo(), UNO_QUERY_THROW );
     879           0 :             Sequence< Property > aAllExistentProperties( xPSI->getProperties() );
     880             : 
     881           0 :             Reference< XPropertyState > xPropertyState( _rxPropertyBag, UNO_QUERY_THROW );
     882             : 
     883             :             // loop through them, and reset resp. default properties which are not to be set
     884           0 :             const Property* pExistentProperty( aAllExistentProperties.getConstArray() );
     885           0 :             const Property* pExistentPropertyEnd( aAllExistentProperties.getConstArray() + aAllExistentProperties.getLength() );
     886           0 :             for ( ; pExistentProperty != pExistentPropertyEnd; ++pExistentProperty )
     887             :             {
     888           0 :                 if ( aToBeSetPropertyNames.find( pExistentProperty->Name ) != aToBeSetPropertyNames.end() )
     889           0 :                     continue;
     890             : 
     891             :                 // this property is not to be set, but currently exists in the bag.
     892             :                 // -> Remove it, or reset it to the default.
     893           0 :                 if ( ( pExistentProperty->Attributes & PropertyAttribute::REMOVABLE ) != 0 )
     894           0 :                     _rxPropertyBag->removeProperty( pExistentProperty->Name );
     895             :                 else
     896           0 :                     xPropertyState->setPropertyToDefault( pExistentProperty->Name );
     897             :             }
     898             : 
     899             :             // finally, set the new property values
     900           0 :             _rxPropertyBag->setPropertyValues( _rAllNewPropertyValues );
     901             :         }
     902           0 :         catch( const Exception& )
     903             :         {
     904             :             DBG_UNHANDLED_EXCEPTION();
     905           0 :         }
     906           0 :     }
     907             : }
     908             : 
     909           0 : void ODatabaseSource::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw (Exception, std::exception)
     910             : {
     911             :     SAL_INFO("dbaccess", "ODatabaseSource::setFastPropertyValue_NoBroadcast" );
     912           0 :     if ( m_pImpl.is() )
     913             :     {
     914           0 :         switch(nHandle)
     915             :         {
     916             :             case PROPERTY_ID_TABLEFILTER:
     917           0 :                 rValue >>= m_pImpl->m_aTableFilter;
     918           0 :                 break;
     919             :             case PROPERTY_ID_TABLETYPEFILTER:
     920           0 :                 rValue >>= m_pImpl->m_aTableTypeFilter;
     921           0 :                 break;
     922             :             case PROPERTY_ID_USER:
     923           0 :                 rValue >>= m_pImpl->m_sUser;
     924             :                 // if the user name has changed, reset the password
     925           0 :                 m_pImpl->m_aPassword = OUString();
     926           0 :                 break;
     927             :             case PROPERTY_ID_PASSWORD:
     928           0 :                 rValue >>= m_pImpl->m_aPassword;
     929           0 :                 break;
     930             :             case PROPERTY_ID_ISPASSWORDREQUIRED:
     931           0 :                 m_pImpl->m_bPasswordRequired = any2bool(rValue);
     932           0 :                 break;
     933             :             case PROPERTY_ID_SUPPRESSVERSIONCL:
     934           0 :                 m_pImpl->m_bSuppressVersionColumns = any2bool(rValue);
     935           0 :                 break;
     936             :             case PROPERTY_ID_URL:
     937           0 :                 rValue >>= m_pImpl->m_sConnectURL;
     938           0 :                 break;
     939             :             case PROPERTY_ID_INFO:
     940             :             {
     941           0 :                 Sequence< PropertyValue > aInfo;
     942           0 :                 OSL_VERIFY( rValue >>= aInfo );
     943           0 :                 lcl_setPropertyValues_resetOrRemoveOther( m_pImpl->m_xSettings, aInfo );
     944             :             }
     945           0 :             break;
     946             :             case PROPERTY_ID_LAYOUTINFORMATION:
     947           0 :                 rValue >>= m_pImpl->m_aLayoutInformation;
     948           0 :                 break;
     949             :         }
     950           0 :         m_pImpl->setModified(sal_True);
     951             :     }
     952           0 : }
     953             : 
     954           0 : void ODatabaseSource::getFastPropertyValue( Any& rValue, sal_Int32 nHandle ) const
     955             : {
     956           0 :     if ( m_pImpl.is() )
     957             :     {
     958           0 :         switch (nHandle)
     959             :         {
     960             :             case PROPERTY_ID_TABLEFILTER:
     961           0 :                 rValue <<= m_pImpl->m_aTableFilter;
     962           0 :                 break;
     963             :             case PROPERTY_ID_TABLETYPEFILTER:
     964           0 :                 rValue <<= m_pImpl->m_aTableTypeFilter;
     965           0 :                 break;
     966             :             case PROPERTY_ID_USER:
     967           0 :                 rValue <<= m_pImpl->m_sUser;
     968           0 :                 break;
     969             :             case PROPERTY_ID_PASSWORD:
     970           0 :                 rValue <<= m_pImpl->m_aPassword;
     971           0 :                 break;
     972             :             case PROPERTY_ID_ISPASSWORDREQUIRED:
     973           0 :                 rValue <<= m_pImpl->m_bPasswordRequired;
     974           0 :                 break;
     975             :             case PROPERTY_ID_SUPPRESSVERSIONCL:
     976           0 :                 rValue <<= m_pImpl->m_bSuppressVersionColumns;
     977           0 :                 break;
     978             :             case PROPERTY_ID_ISREADONLY:
     979           0 :                 rValue <<= m_pImpl->m_bReadOnly;
     980           0 :                 break;
     981             :             case PROPERTY_ID_INFO:
     982             :             {
     983             :                 try
     984             :                 {
     985             :                     // collect the property attributes of all current settings
     986           0 :                     Reference< XPropertySet > xSettingsAsProps( m_pImpl->m_xSettings, UNO_QUERY_THROW );
     987           0 :                     Reference< XPropertySetInfo > xPST( xSettingsAsProps->getPropertySetInfo(), UNO_QUERY_THROW );
     988           0 :                     Sequence< Property > aSettings( xPST->getProperties() );
     989           0 :                     ::std::map< OUString, sal_Int32 > aPropertyAttributes;
     990           0 :                     for (   const Property* pSettings = aSettings.getConstArray();
     991           0 :                             pSettings != aSettings.getConstArray() + aSettings.getLength();
     992             :                             ++pSettings
     993             :                         )
     994             :                     {
     995           0 :                         aPropertyAttributes[ pSettings->Name ] = pSettings->Attributes;
     996             :                     }
     997             : 
     998             :                     // get all current settings with their values
     999           0 :                     Sequence< PropertyValue > aValues( m_pImpl->m_xSettings->getPropertyValues() );
    1000             : 
    1001             :                     // transform them so that only property values which fulfill certain
    1002             :                     // criteria survive
    1003           0 :                     Sequence< PropertyValue > aNonDefaultOrUserDefined( aValues.getLength() );
    1004             :                     const PropertyValue* pCopyEnd = ::std::remove_copy_if(
    1005             :                         aValues.getConstArray(),
    1006           0 :                         aValues.getConstArray() + aValues.getLength(),
    1007             :                         aNonDefaultOrUserDefined.getArray(),
    1008             :                         IsDefaultAndNotRemoveable( aPropertyAttributes )
    1009           0 :                     );
    1010           0 :                     aNonDefaultOrUserDefined.realloc( pCopyEnd - aNonDefaultOrUserDefined.getArray() );
    1011           0 :                     rValue <<= aNonDefaultOrUserDefined;
    1012             :                 }
    1013           0 :                 catch( const Exception& )
    1014             :                 {
    1015             :                     DBG_UNHANDLED_EXCEPTION();
    1016             :                 }
    1017             :             }
    1018           0 :             break;
    1019             :             case PROPERTY_ID_SETTINGS:
    1020           0 :                 rValue <<= m_pImpl->m_xSettings;
    1021           0 :                 break;
    1022             :             case PROPERTY_ID_URL:
    1023           0 :                 rValue <<= m_pImpl->m_sConnectURL;
    1024           0 :                 break;
    1025             :             case PROPERTY_ID_NUMBERFORMATSSUPPLIER:
    1026           0 :                 rValue <<= m_pImpl->getNumberFormatsSupplier();
    1027           0 :                 break;
    1028             :             case PROPERTY_ID_NAME:
    1029           0 :                 rValue <<= m_pImpl->m_sName;
    1030           0 :                 break;
    1031             :             case PROPERTY_ID_LAYOUTINFORMATION:
    1032           0 :                 rValue <<= m_pImpl->m_aLayoutInformation;
    1033           0 :                 break;
    1034             :             default:
    1035             :                 SAL_WARN("dbaccess","unknown Property");
    1036             :         }
    1037             :     }
    1038           0 : }
    1039             : 
    1040             : // XDataSource
    1041           0 : void ODatabaseSource::setLoginTimeout(sal_Int32 seconds) throw( SQLException, RuntimeException, std::exception )
    1042             : {
    1043             :     SAL_INFO("dbaccess", "ODatabaseSource::setLoginTimeout" );
    1044           0 :     ModelMethodGuard aGuard( *this );
    1045           0 :     m_pImpl->m_nLoginTimeout = seconds;
    1046           0 : }
    1047             : 
    1048           0 : sal_Int32 ODatabaseSource::getLoginTimeout(void) throw( SQLException, RuntimeException, std::exception )
    1049             : {
    1050             :     SAL_INFO("dbaccess", "ODatabaseSource::getLoginTimeout" );
    1051           0 :     ModelMethodGuard aGuard( *this );
    1052           0 :     return m_pImpl->m_nLoginTimeout;
    1053             : }
    1054             : 
    1055             : // XCompletedConnection
    1056           0 : Reference< XConnection > SAL_CALL ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException, std::exception)
    1057             : {
    1058             :     SAL_INFO("dbaccess", "ODatabaseSource::connectWithCompletion" );
    1059           0 :     return connectWithCompletion(_rxHandler,sal_False);
    1060             : }
    1061             : 
    1062           0 : Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, const OUString& password) throw( SQLException, RuntimeException, std::exception )
    1063             : {
    1064             :     SAL_INFO("dbaccess", "ODatabaseSource::getConnection" );
    1065           0 :     return getConnection(user,password,sal_False);
    1066             : }
    1067             : 
    1068           0 : Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnection( const OUString& user, const OUString& password ) throw(SQLException, RuntimeException, std::exception)
    1069             : {
    1070             :     SAL_INFO("dbaccess", "ODatabaseSource::getIsolatedConnection" );
    1071           0 :     return getConnection(user,password,sal_True);
    1072             : }
    1073             : 
    1074           0 : Reference< XConnection > SAL_CALL ODatabaseSource::getIsolatedConnectionWithCompletion( const Reference< XInteractionHandler >& _rxHandler ) throw(SQLException, RuntimeException, std::exception)
    1075             : {
    1076             :     SAL_INFO("dbaccess", "ODatabaseSource::getIsolatedConnectionWithCompletion" );
    1077           0 :     return connectWithCompletion(_rxHandler,sal_True);
    1078             : }
    1079             : 
    1080           0 : Reference< XConnection > SAL_CALL ODatabaseSource::connectWithCompletion( const Reference< XInteractionHandler >& _rxHandler,sal_Bool _bIsolated ) throw(SQLException, RuntimeException)
    1081             : {
    1082             :     SAL_INFO("dbaccess", "ODatabaseSource::connectWithCompletion" );
    1083           0 :     ModelMethodGuard aGuard( *this );
    1084             : 
    1085           0 :     if (!_rxHandler.is())
    1086             :     {
    1087             :         SAL_WARN("dbaccess","ODatabaseSource::connectWithCompletion: invalid interaction handler!");
    1088           0 :         return getConnection(m_pImpl->m_sUser, m_pImpl->m_aPassword,_bIsolated);
    1089             :     }
    1090             : 
    1091           0 :     OUString sUser(m_pImpl->m_sUser), sPassword(m_pImpl->m_aPassword);
    1092           0 :     sal_Bool bNewPasswordGiven = sal_False;
    1093             : 
    1094           0 :     if (m_pImpl->m_bPasswordRequired && sPassword.isEmpty())
    1095             :     {   // we need a password, but don't have one yet.
    1096             :         // -> ask the user
    1097             : 
    1098             :         // build an interaction request
    1099             :         // two continuations (Ok and Cancel)
    1100           0 :         OInteractionAbort* pAbort = new OInteractionAbort;
    1101           0 :         OAuthenticationContinuation* pAuthenticate = new OAuthenticationContinuation;
    1102             : 
    1103             :         // the name which should be referred in the login dialog
    1104           0 :         OUString sServerName( m_pImpl->m_sName );
    1105           0 :         INetURLObject aURLCheck( sServerName );
    1106           0 :         if ( aURLCheck.GetProtocol() != INET_PROT_NOT_VALID )
    1107           0 :             sServerName = aURLCheck.getBase( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_UNAMBIGUOUS );
    1108             : 
    1109             :         // the request
    1110           0 :         AuthenticationRequest aRequest;
    1111           0 :         aRequest.ServerName = sServerName;
    1112           0 :         aRequest.HasRealm = aRequest.HasAccount = sal_False;
    1113           0 :         aRequest.HasUserName = aRequest.HasPassword = sal_True;
    1114           0 :         aRequest.UserName = m_pImpl->m_sUser;
    1115           0 :         aRequest.Password = m_pImpl->m_sFailedPassword.isEmpty() ?  m_pImpl->m_aPassword : m_pImpl->m_sFailedPassword;
    1116           0 :         OInteractionRequest* pRequest = new OInteractionRequest(makeAny(aRequest));
    1117           0 :         Reference< XInteractionRequest > xRequest(pRequest);
    1118             :         // some knittings
    1119           0 :         pRequest->addContinuation(pAbort);
    1120           0 :         pRequest->addContinuation(pAuthenticate);
    1121             : 
    1122             :         // handle the request
    1123             :         try
    1124             :         {
    1125           0 :             MutexRelease aRelease( getMutex() );
    1126             :                 // release the mutex when calling the handler, it may need to lock the SolarMutex
    1127           0 :             _rxHandler->handle(xRequest);
    1128             :         }
    1129           0 :         catch(Exception&)
    1130             :         {
    1131             :             DBG_UNHANDLED_EXCEPTION();
    1132             :         }
    1133             : 
    1134           0 :         if (!pAuthenticate->wasSelected())
    1135           0 :             return Reference< XConnection >();
    1136             : 
    1137             :         // get the result
    1138           0 :         sUser = m_pImpl->m_sUser = pAuthenticate->getUser();
    1139           0 :         sPassword = pAuthenticate->getPassword();
    1140             : 
    1141           0 :         if (pAuthenticate->getRememberPassword())
    1142             :         {
    1143           0 :             m_pImpl->m_aPassword = pAuthenticate->getPassword();
    1144           0 :             bNewPasswordGiven = sal_True;
    1145             :         }
    1146           0 :         m_pImpl->m_sFailedPassword = OUString();
    1147             :     }
    1148             : 
    1149             :     try
    1150             :     {
    1151           0 :         return getConnection(sUser, sPassword,_bIsolated);
    1152             :     }
    1153           0 :     catch(Exception&)
    1154             :     {
    1155           0 :         if (bNewPasswordGiven)
    1156             :         {
    1157           0 :             m_pImpl->m_sFailedPassword = m_pImpl->m_aPassword;
    1158             :             // assume that we had an authentication problem. Without this we may, after an unsucessful connect, while
    1159             :             // the user gave us a password an the order to remember it, never allow an password input again (at least
    1160             :             // not without restarting the session)
    1161           0 :             m_pImpl->m_aPassword = OUString();
    1162             :         }
    1163           0 :         throw;
    1164           0 :     }
    1165             : }
    1166             : 
    1167           0 : Reference< XConnection > ODatabaseSource::buildIsolatedConnection(const OUString& user, const OUString& password)
    1168             : {
    1169             :     SAL_INFO("dbaccess", "ODatabaseSource::buildIsolatedConnection" );
    1170           0 :     Reference< XConnection > xConn;
    1171           0 :     Reference< XConnection > xSdbcConn = buildLowLevelConnection(user, password);
    1172             :     OSL_ENSURE( xSdbcConn.is(), "ODatabaseSource::buildIsolatedConnection: invalid return value of buildLowLevelConnection!" );
    1173             :     // buildLowLevelConnection is expected to always succeed
    1174           0 :     if ( xSdbcConn.is() )
    1175             :     {
    1176             :         // build a connection server and return it (no stubs)
    1177           0 :         xConn = new OConnection(*this, xSdbcConn, m_pImpl->m_aContext);
    1178             :     }
    1179           0 :     return xConn;
    1180             : }
    1181             : 
    1182           0 : Reference< XConnection > ODatabaseSource::getConnection(const OUString& user, const OUString& password,sal_Bool _bIsolated) throw( SQLException, RuntimeException )
    1183             : {
    1184             :     SAL_INFO("dbaccess", "ODatabaseSource::getConnection" );
    1185           0 :     ModelMethodGuard aGuard( *this );
    1186             : 
    1187           0 :     Reference< XConnection > xConn;
    1188           0 :     if ( _bIsolated )
    1189             :     {
    1190           0 :         xConn = buildIsolatedConnection(user,password);
    1191             :     }
    1192             :     else
    1193             :     { // create a new proxy for the connection
    1194           0 :         if ( !m_pImpl->m_xSharedConnectionManager.is() )
    1195             :         {
    1196           0 :             m_pImpl->m_pSharedConnectionManager = new OSharedConnectionManager( m_pImpl->m_aContext );
    1197           0 :             m_pImpl->m_xSharedConnectionManager = m_pImpl->m_pSharedConnectionManager;
    1198             :         }
    1199           0 :         xConn = m_pImpl->m_pSharedConnectionManager->getConnection(
    1200           0 :             m_pImpl->m_sConnectURL, user, password, m_pImpl->m_xSettings->getPropertyValues(), this );
    1201             :     }
    1202             : 
    1203           0 :     if ( xConn.is() )
    1204             :     {
    1205           0 :         Reference< XComponent> xComp(xConn,UNO_QUERY);
    1206           0 :         if ( xComp.is() )
    1207           0 :             xComp->addEventListener( static_cast< XContainerListener* >( this ) );
    1208           0 :         m_pImpl->m_aConnections.push_back(OWeakConnection(xConn));
    1209             :     }
    1210             : 
    1211           0 :     return xConn;
    1212             : }
    1213             : 
    1214           0 : Reference< XNameAccess > SAL_CALL ODatabaseSource::getBookmarks(  ) throw (RuntimeException, std::exception)
    1215             : {
    1216             :     SAL_INFO("dbaccess", "ODatabaseSource::getBookmarks" );
    1217           0 :     ModelMethodGuard aGuard( *this );
    1218           0 :     return static_cast< XNameContainer* >(&m_aBookmarks);
    1219             : }
    1220             : 
    1221           0 : Reference< XNameAccess > SAL_CALL ODatabaseSource::getQueryDefinitions( ) throw(RuntimeException, std::exception)
    1222             : {
    1223             :     SAL_INFO("dbaccess", "ODatabaseSource::getQueryDefinitions" );
    1224           0 :     ModelMethodGuard aGuard( *this );
    1225             : 
    1226           0 :     Reference< XNameAccess > xContainer = m_pImpl->m_xCommandDefinitions;
    1227           0 :     if ( !xContainer.is() )
    1228             :     {
    1229           0 :         Any aValue;
    1230           0 :         ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xMy(*this);
    1231           0 :         if ( dbtools::getDataSourceSetting(xMy,"CommandDefinitions",aValue) )
    1232             :         {
    1233           0 :             OUString sSupportService;
    1234           0 :             aValue >>= sSupportService;
    1235           0 :             if ( !sSupportService.isEmpty() )
    1236             :             {
    1237           0 :                 Sequence<Any> aArgs(1);
    1238           0 :                 aArgs[0] <<= NamedValue("DataSource",makeAny(xMy));
    1239           0 :                 xContainer.set( m_pImpl->m_aContext->getServiceManager()->createInstanceWithArgumentsAndContext(sSupportService, aArgs, m_pImpl->m_aContext), UNO_QUERY);
    1240           0 :             }
    1241             :         }
    1242           0 :         if ( !xContainer.is() )
    1243             :         {
    1244           0 :             TContentPtr& rContainerData( m_pImpl->getObjectContainer( ODatabaseModelImpl::E_QUERY ) );
    1245           0 :             xContainer = new OCommandContainer( m_pImpl->m_aContext, *this, rContainerData, sal_False );
    1246             :         }
    1247           0 :         m_pImpl->m_xCommandDefinitions = xContainer;
    1248             :     }
    1249           0 :     return xContainer;
    1250             : }
    1251             : 
    1252             : // XTablesSupplier
    1253           0 : Reference< XNameAccess >  ODatabaseSource::getTables() throw( RuntimeException, std::exception )
    1254             : {
    1255             :     SAL_INFO("dbaccess", "ODatabaseSource::getTables" );
    1256           0 :     ModelMethodGuard aGuard( *this );
    1257             : 
    1258           0 :     Reference< XNameAccess > xContainer = m_pImpl->m_xTableDefinitions;
    1259           0 :     if ( !xContainer.is() )
    1260             :     {
    1261           0 :         TContentPtr& rContainerData( m_pImpl->getObjectContainer( ODatabaseModelImpl::E_TABLE ) );
    1262           0 :         xContainer = new OCommandContainer( m_pImpl->m_aContext, *this, rContainerData, sal_True );
    1263           0 :         m_pImpl->m_xTableDefinitions = xContainer;
    1264             :     }
    1265           0 :     return xContainer;
    1266             : }
    1267             : 
    1268           0 : void SAL_CALL ODatabaseSource::flush(  ) throw (RuntimeException, std::exception)
    1269             : {
    1270             :     SAL_INFO("dbaccess", "ODatabaseSource::flush" );
    1271             :     try
    1272             :     {
    1273             :         // SYNCHRONIZED ->
    1274             :         {
    1275           0 :             ModelMethodGuard aGuard( *this );
    1276             : 
    1277             :             typedef ::utl::SharedUNOComponent< XModel, ::utl::CloseableComponent > SharedModel;
    1278           0 :             SharedModel xModel( m_pImpl->getModel_noCreate(), SharedModel::NoTakeOwnership );
    1279             : 
    1280           0 :             if ( !xModel.is() )
    1281           0 :                 xModel.reset( m_pImpl->createNewModel_deliverOwnership( false ), SharedModel::TakeOwnership );
    1282             : 
    1283           0 :             Reference< css::frame::XStorable> xStorable( xModel, UNO_QUERY_THROW );
    1284           0 :             xStorable->store();
    1285             :         }
    1286             :         // <- SYNCHRONIZED
    1287             : 
    1288           0 :         css::lang::EventObject aFlushedEvent(*this);
    1289           0 :         m_aFlushListeners.notifyEach( &XFlushListener::flushed, aFlushedEvent );
    1290             :     }
    1291           0 :     catch( const Exception& )
    1292             :     {
    1293             :         DBG_UNHANDLED_EXCEPTION();
    1294             :     }
    1295           0 : }
    1296             : 
    1297           0 : void SAL_CALL ODatabaseSource::flushed( const EventObject& /*rEvent*/ ) throw (RuntimeException, std::exception)
    1298             : {
    1299             :     SAL_INFO("dbaccess", "ODatabaseSource::flushed" );
    1300           0 :     ModelMethodGuard aGuard( *this );
    1301             : 
    1302             :     // Okay, this is some hack.
    1303             :     //
    1304             :     // In general, we have the problem that embedded databases write into their underlying storage, which
    1305             :     // logically is one of our sub storage, and practically is a temporary file maintained by the
    1306             :     // package implementation. As long as we did not commit this storage and our main storage,
    1307             :     // the changes made by the embedded database engine are not really reflected in the database document
    1308             :     // file. This is Bad (TM) for a "real" database application - imagine somebody entering some
    1309             :     // data, and then crashing: For a database application, you would expect that the data still is present
    1310             :     // when you connect to the database next time.
    1311             :     //
    1312             :     // Since this is a conceptual problem as long as we do use those ZIP packages (in fact, we *cannot*
    1313             :     // provide the desired functionality as long as we do not have a package format which allows O(1) writes),
    1314             :     // we cannot completely fix this. However, we can relax the problem by commiting more often - often
    1315             :     // enough so that data loss is more seldom, and seldom enough so that there's no noticable performance
    1316             :     // decrease.
    1317             :     //
    1318             :     // For this, we introduced a few places which XFlushable::flush their connections, and register as
    1319             :     // XFlushListener at the embedded connection (which needs to provide the XFlushable functionality).
    1320             :     // Then, when the connection is flushed, we commit both the database storage and our main storage.
    1321             :     //
    1322             :     // #i55274#
    1323             : 
    1324             :     OSL_ENSURE( m_pImpl->isEmbeddedDatabase(), "ODatabaseSource::flushed: no embedded database?!" );
    1325           0 :     sal_Bool bWasModified = m_pImpl->m_bModified;
    1326           0 :     m_pImpl->commitEmbeddedStorage();
    1327           0 :     m_pImpl->setModified( bWasModified );
    1328           0 : }
    1329             : 
    1330           0 : void SAL_CALL ODatabaseSource::addFlushListener( const Reference< ::com::sun::star::util::XFlushListener >& _xListener ) throw (RuntimeException, std::exception)
    1331             : {
    1332             :     SAL_INFO("dbaccess", "ODatabaseSource::addFlushListener" );
    1333           0 :     m_aFlushListeners.addInterface(_xListener);
    1334           0 : }
    1335             : 
    1336           0 : void SAL_CALL ODatabaseSource::removeFlushListener( const Reference< ::com::sun::star::util::XFlushListener >& _xListener ) throw (RuntimeException, std::exception)
    1337             : {
    1338             :     SAL_INFO("dbaccess", "ODatabaseSource::removeFlushListener" );
    1339           0 :     m_aFlushListeners.removeInterface(_xListener);
    1340           0 : }
    1341             : 
    1342           0 : void SAL_CALL ODatabaseSource::elementInserted( const ContainerEvent& /*Event*/ ) throw (RuntimeException, std::exception)
    1343             : {
    1344             :     SAL_INFO("dbaccess", "ODatabaseSource::elementInserted" );
    1345           0 :     ModelMethodGuard aGuard( *this );
    1346           0 :     if ( m_pImpl.is() )
    1347           0 :         m_pImpl->setModified(sal_True);
    1348           0 : }
    1349             : 
    1350           0 : void SAL_CALL ODatabaseSource::elementRemoved( const ContainerEvent& /*Event*/ ) throw (RuntimeException, std::exception)
    1351             : {
    1352             :     SAL_INFO("dbaccess", "ODatabaseSource::elementRemoved" );
    1353           0 :     ModelMethodGuard aGuard( *this );
    1354           0 :     if ( m_pImpl.is() )
    1355           0 :         m_pImpl->setModified(sal_True);
    1356           0 : }
    1357             : 
    1358           0 : void SAL_CALL ODatabaseSource::elementReplaced( const ContainerEvent& /*Event*/ ) throw (RuntimeException, std::exception)
    1359             : {
    1360             :     SAL_INFO("dbaccess", "ODatabaseSource::elementReplaced" );
    1361           0 :     ModelMethodGuard aGuard( *this );
    1362           0 :     if ( m_pImpl.is() )
    1363           0 :         m_pImpl->setModified(sal_True);
    1364           0 : }
    1365             : 
    1366             : // XDocumentDataSource
    1367           0 : Reference< XOfficeDatabaseDocument > SAL_CALL ODatabaseSource::getDatabaseDocument() throw (RuntimeException, std::exception)
    1368             : {
    1369             :     SAL_INFO("dbaccess", "ODatabaseSource::getDatabaseDocument" );
    1370           0 :     ModelMethodGuard aGuard( *this );
    1371             : 
    1372           0 :     Reference< XModel > xModel( m_pImpl->getModel_noCreate() );
    1373           0 :     if ( !xModel.is() )
    1374           0 :         xModel = m_pImpl->createNewModel_deliverOwnership( false );
    1375             : 
    1376           0 :     return Reference< XOfficeDatabaseDocument >( xModel, UNO_QUERY_THROW );
    1377             : }
    1378             : 
    1379           0 : Reference< XInterface > ODatabaseSource::getThis() const
    1380             : {
    1381             :     SAL_INFO("dbaccess", "ODatabaseSource::getThis" );
    1382           0 :     return *const_cast< ODatabaseSource* >( this );
    1383             : }
    1384             : 
    1385             : }   // namespace dbaccess
    1386             : 
    1387             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10