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