1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_dbaccess.hxx"
30 
31 #ifndef _DBAUI_DATASOURCECONNECTOR_HXX_
32 #include "datasourceconnector.hxx"
33 #endif
34 #ifndef _OSL_DIAGNOSE_H_
35 #include <osl/diagnose.h>
36 #endif
37 #ifndef DBACCESS_SHARED_DBUSTRINGS_HRC
38 #include "dbustrings.hrc"
39 #endif
40 #ifndef _COM_SUN_STAR_SDBC_XWARNINGSSUPPLIER_HPP_
41 #include <com/sun/star/sdbc/XWarningsSupplier.hpp>
42 #endif
43 #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #endif
46 #ifndef _COM_SUN_STAR_SDB_XCOMPLETEDCONNECTION_HPP_
47 #include <com/sun/star/sdb/XCompletedConnection.hpp>
48 #endif
49 #ifndef _COM_SUN_STAR_TASK_XINTERACTIONHANDLER_HPP_
50 #include <com/sun/star/task/XInteractionHandler.hpp>
51 #endif
52 #ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
53 #include <com/sun/star/frame/XModel.hpp>
54 #endif
55 #ifndef _COM_SUN_STAR_SDB_SQLCONTEXT_HPP_
56 #include <com/sun/star/sdb/SQLContext.hpp>
57 #endif
58 #ifndef _COM_SUN_STAR_SDBC_SQLWARNING_HPP_
59 #include <com/sun/star/sdbc/SQLWarning.hpp>
60 #endif
61 #ifndef _OSL_THREAD_H_
62 #include <osl/thread.h>
63 #endif
64 #ifndef _COMPHELPER_EXTRACT_HXX_
65 #include <comphelper/extract.hxx>
66 #endif
67 #ifndef COMPHELPER_NAMEDVALUECOLLECTION_HXX
68 #include <comphelper/namedvaluecollection.hxx>
69 #endif
70 #ifndef _DBHELPER_DBEXCEPTION_HXX_
71 #include <connectivity/dbexception.hxx>
72 #endif
73 #ifndef _COM_SUN_STAR_SDBC_XDATASOURCE_HPP_
74 #include <com/sun/star/sdbc/XDataSource.hpp>
75 #endif
76 #ifndef DBAUI_TOOLS_HXX
77 #include "UITools.hxx"
78 #endif
79 #ifndef _VCL_STDTEXT_HXX
80 #include <vcl/stdtext.hxx>
81 #endif
82 #ifndef _SV_BUTTON_HXX
83 #include <vcl/button.hxx>
84 #endif
85 #ifndef SVTOOLS_FILENOTATION_HXX
86 #include <svl/filenotation.hxx>
87 #endif
88 #ifndef TOOLS_DIAGNOSE_EX_H
89 #include <tools/diagnose_ex.h>
90 #endif
91 #ifndef _CPPUHELPER_EXC_HLP_HXX_
92 #include <cppuhelper/exc_hlp.hxx>
93 #endif
94 #ifndef _DBU_MISC_HRC_
95 #include "dbu_misc.hrc"
96 #endif
97 #include "moduledbu.hxx"
98 
99 //.........................................................................
100 namespace dbaui
101 {
102 //.........................................................................
103 
104 	using namespace ::com::sun::star::uno;
105 	using namespace ::com::sun::star::lang;
106 	using namespace ::com::sun::star::sdb;
107 	using namespace ::com::sun::star::sdbc;
108 	using namespace ::com::sun::star::task;
109 	using namespace ::com::sun::star::beans;
110 	using namespace ::com::sun::star::container;
111 	using namespace ::com::sun::star::frame;
112 	using namespace ::dbtools;
113     using ::svt::OFileNotation;
114 
115 	//=====================================================================
116 	//= ODatasourceConnector
117 	//=====================================================================
118 	//---------------------------------------------------------------------
119 	ODatasourceConnector::ODatasourceConnector(const Reference< XMultiServiceFactory >& _rxORB, Window* _pMessageParent)
120 		:m_pErrorMessageParent(_pMessageParent)
121 		,m_xORB(_rxORB)
122 	{
123 	}
124 
125 	//---------------------------------------------------------------------
126 	ODatasourceConnector::ODatasourceConnector( const Reference< XMultiServiceFactory >& _rxORB, Window* _pMessageParent,
127 		const ::rtl::OUString& _rContextInformation )
128 		:m_pErrorMessageParent(_pMessageParent)
129 		,m_xORB(_rxORB)
130 		,m_sContextInformation( _rContextInformation )
131 	{
132 	}
133 
134 	//---------------------------------------------------------------------
135     Reference< XConnection > ODatasourceConnector::connect( const ::rtl::OUString& _rDataSourceName,
136         ::dbtools::SQLExceptionInfo* _pErrorInfo ) const
137 	{
138 		Reference< XConnection > xConnection;
139 
140 		OSL_ENSURE(isValid(), "ODatasourceConnector::connect: invalid object!");
141 		if (!isValid())
142 			return xConnection;
143 
144 		// get the data source
145 		Reference< XDataSource > xDatasource(
146             getDataSourceByName( _rDataSourceName, m_pErrorMessageParent, m_xORB, _pErrorInfo ),
147             UNO_QUERY
148         );
149 
150         if ( xDatasource.is() )
151             xConnection = connect( xDatasource, _pErrorInfo );
152 		return xConnection;
153 	}
154 
155 	//---------------------------------------------------------------------
156 	Reference< XConnection > ODatasourceConnector::connect(const Reference< XDataSource>& _xDataSource,
157         ::dbtools::SQLExceptionInfo* _pErrorInfo ) const
158 	{
159 		Reference< XConnection > xConnection;
160 
161 		OSL_ENSURE( isValid() && _xDataSource.is(), "ODatasourceConnector::connect: invalid object or argument!" );
162 		if ( !isValid() || !_xDataSource.is() )
163 			return xConnection;
164 
165 		// get user/password
166 		::rtl::OUString sPassword, sUser;
167 		sal_Bool bPwdRequired = sal_False;
168 		Reference<XPropertySet> xProp(_xDataSource,UNO_QUERY);
169 		try
170 		{
171 			xProp->getPropertyValue(PROPERTY_PASSWORD) >>= sPassword;
172 			xProp->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED) >>= bPwdRequired;
173 			xProp->getPropertyValue(PROPERTY_USER) >>= sUser;
174 		}
175 		catch(Exception&)
176 		{
177             DBG_UNHANDLED_EXCEPTION();
178 		}
179 
180 		// try to connect
181 		SQLExceptionInfo aInfo;
182 		try
183 		{
184 			if (bPwdRequired && !sPassword.getLength())
185 			{	// password required, but empty -> connect using an interaction handler
186 				Reference< XCompletedConnection > xConnectionCompletion( _xDataSource, UNO_QUERY_THROW );
187 
188                 Reference< XModel > xModel( getDataSourceOrModel( _xDataSource ), UNO_QUERY_THROW );
189                 ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
190                 Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
191 
192                 if ( !xHandler.is() )
193                 {
194                     // instantiate the default SDB interaction handler
195                     xHandler = Reference< XInteractionHandler >( m_xORB->createInstance( SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
196                     if ( !xHandler.is() )
197                         ShowServiceNotAvailableError(m_pErrorMessageParent, (::rtl::OUString)SERVICE_TASK_INTERACTION_HANDLER, sal_True);
198                 }
199 
200                 if ( xHandler.is() )
201                 {
202 					xConnection = xConnectionCompletion->connectWithCompletion(xHandler);
203 				}
204 			}
205 			else
206 			{
207 				xConnection = _xDataSource->getConnection(sUser, sPassword);
208 			}
209 		}
210         catch( const SQLException& )
211         {
212             aInfo = ::cppu::getCaughtException();
213         }
214 		catch(const Exception&)
215         {
216             DBG_UNHANDLED_EXCEPTION();
217         }
218 
219         if ( !aInfo.isValid() )
220         {
221             // there was no error during connecting, but perhaps a warning?
222             Reference< XWarningsSupplier > xConnectionWarnings( xConnection, UNO_QUERY );
223             if ( xConnectionWarnings.is() )
224             {
225                 try
226                 {
227                     Any aWarnings( xConnectionWarnings->getWarnings() );
228                     if ( aWarnings.hasValue() )
229                     {
230                         String sMessage( ModuleRes( STR_WARNINGS_DURING_CONNECT ) );
231                         sMessage.SearchAndReplaceAscii( "$buttontext$", Button::GetStandardText( BUTTON_MORE ) );
232                         sMessage = OutputDevice::GetNonMnemonicString( sMessage );
233 
234                         SQLWarning aContext;
235                         aContext.Message = sMessage;
236                         aContext.NextException = aWarnings;
237                         aInfo = aContext;
238                     }
239                     xConnectionWarnings->clearWarnings();
240                 }
241                 catch( const Exception& )
242                 {
243             	    DBG_UNHANDLED_EXCEPTION();
244                 }
245             }
246         }
247         else
248         {
249 			if ( m_sContextInformation.getLength() )
250 			{
251                 SQLException aError;
252                 aError.Message = m_sContextInformation;
253 				aError.NextException = aInfo.get();
254 
255 				aInfo = aError;
256 			}
257         }
258 
259         // was there an error?
260         if ( aInfo.isValid() )
261         {
262             if ( _pErrorInfo )
263             {
264                 *_pErrorInfo = aInfo;
265             }
266             else
267             {
268 			    showError( aInfo, m_pErrorMessageParent, m_xORB );
269             }
270         }
271         return xConnection;
272 	}
273 
274 //.........................................................................
275 }	// namespace dbaui
276 //.........................................................................
277 
278