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