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