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