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