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