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