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