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