LibreOffice Module dbaccess (master) 1
datasourceconnector.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <core_resource.hxx>
22#include <osl/diagnose.h>
23#include <com/sun/star/sdbc/XWarningsSupplier.hpp>
24#include <com/sun/star/beans/XPropertySet.hpp>
25#include <com/sun/star/sdb/XCompletedConnection.hpp>
26#include <com/sun/star/task/InteractionHandler.hpp>
27#include <com/sun/star/frame/XModel.hpp>
28#include <com/sun/star/sdbc/SQLWarning.hpp>
31#include <com/sun/star/sdbc/XDataSource.hpp>
32#include <UITools.hxx>
33#include <utility>
34#include <vcl/mnemonic.hxx>
35#include <vcl/outdev.hxx>
36#include <vcl/stdtext.hxx>
37#include <vcl/weld.hxx>
40#include <strings.hrc>
41#include <strings.hxx>
42
43namespace dbaui
44{
45
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::lang;
48 using namespace ::com::sun::star::sdb;
49 using namespace ::com::sun::star::sdbc;
50 using namespace ::com::sun::star::task;
51 using namespace ::com::sun::star::beans;
52 using namespace ::com::sun::star::container;
53 using namespace ::com::sun::star::frame;
54 using namespace ::dbtools;
55
56 // ODatasourceConnector
57 ODatasourceConnector::ODatasourceConnector(const Reference< XComponentContext >& _rxContext, weld::Window* _pMessageParent)
58 :m_pErrorMessageParent(_pMessageParent)
59 ,m_xContext(_rxContext)
60 {
61 }
62
63 ODatasourceConnector::ODatasourceConnector( const Reference< XComponentContext >& _rxContext, weld::Window* _pMessageParent,
64 OUString _sContextInformation )
65 :m_pErrorMessageParent(_pMessageParent)
66 ,m_xContext(_rxContext)
67 ,m_sContextInformation(std::move( _sContextInformation ))
68 {
69 }
70
71 Reference< XConnection > ODatasourceConnector::connect( const OUString& _rDataSourceName,
72 ::dbtools::SQLExceptionInfo* _pErrorInfo ) const
73 {
74 Reference< XConnection > xConnection;
75
76 OSL_ENSURE(isValid(), "ODatasourceConnector::connect: invalid object!");
77 if (!isValid())
78 return xConnection;
79
80 // get the data source
81 Reference< XDataSource > xDatasource =
82 getDataSourceByName( _rDataSourceName, m_pErrorMessageParent, m_xContext, _pErrorInfo );
83
84 if ( xDatasource.is() )
85 xConnection = connect( xDatasource, _pErrorInfo );
86 return xConnection;
87 }
88
89 Reference< XConnection > ODatasourceConnector::connect(const Reference< XDataSource>& _xDataSource,
90 ::dbtools::SQLExceptionInfo* _pErrorInfo ) const
91 {
92 Reference< XConnection > xConnection;
93
94 OSL_ENSURE( isValid() && _xDataSource.is(), "ODatasourceConnector::connect: invalid object or argument!" );
95 if ( !isValid() || !_xDataSource.is() )
96 return xConnection;
97
98 // get user/password
99 OUString sPassword, sUser;
100 bool bPwdRequired = false;
101 Reference<XPropertySet> xProp(_xDataSource,UNO_QUERY);
102 try
103 {
104 xProp->getPropertyValue(PROPERTY_PASSWORD) >>= sPassword;
105 xProp->getPropertyValue(PROPERTY_ISPASSWORDREQUIRED) >>= bPwdRequired;
106 xProp->getPropertyValue(PROPERTY_USER) >>= sUser;
107 }
108 catch(Exception&)
109 {
110 DBG_UNHANDLED_EXCEPTION("dbaccess");
111 }
112
113 // try to connect
114 SQLExceptionInfo aInfo;
115 try
116 {
117 if (bPwdRequired && sPassword.isEmpty())
118 { // password required, but empty -> connect using an interaction handler
119 Reference< XCompletedConnection > xConnectionCompletion( _xDataSource, UNO_QUERY_THROW );
120
121 Reference< XModel > xModel( getDataSourceOrModel( _xDataSource ), UNO_QUERY_THROW );
122 ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
123 Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
124
125 if ( !xHandler.is() )
126 {
127 // instantiate the default SDB interaction handler
128 xHandler = InteractionHandler::createWithParent(m_xContext, m_pErrorMessageParent ? m_pErrorMessageParent->GetXWindow() : nullptr);
129 }
130
131 xConnection = xConnectionCompletion->connectWithCompletion(xHandler);
132 }
133 else
134 {
135 xConnection = _xDataSource->getConnection(sUser, sPassword);
136 }
137 }
138 catch( const SQLException& )
139 {
140 aInfo = ::cppu::getCaughtException();
141 }
142 catch(const Exception&)
143 {
144 DBG_UNHANDLED_EXCEPTION("dbaccess");
145 }
146
147 if ( !aInfo.isValid() )
148 {
149 // there was no error during connecting, but perhaps a warning?
150 Reference< XWarningsSupplier > xConnectionWarnings( xConnection, UNO_QUERY );
151 if ( xConnectionWarnings.is() )
152 {
153 try
154 {
155 Any aWarnings( xConnectionWarnings->getWarnings() );
156 if ( aWarnings.hasValue() )
157 {
158 OUString sMessage( DBA_RES( STR_WARNINGS_DURING_CONNECT ) );
159 sMessage = sMessage.replaceFirst( "$buttontext$", GetStandardText( StandardButtonType::More ) );
161
162 SQLWarning aContext;
163 aContext.Message = sMessage;
164 aContext.NextException = aWarnings;
165 aInfo = aContext;
166 }
167 xConnectionWarnings->clearWarnings();
168 }
169 catch( const Exception& )
170 {
171 DBG_UNHANDLED_EXCEPTION("dbaccess");
172 }
173 }
174 }
175 else
176 {
177 if ( !m_sContextInformation.isEmpty() )
178 {
179 SQLException aError;
180 aError.Message = m_sContextInformation;
181 aError.NextException = aInfo.get();
182
183 aInfo = aError;
184 }
185 }
186
187 // was there an error?
188 if ( aInfo.isValid() )
189 {
190 if ( _pErrorInfo )
191 {
192 *_pErrorInfo = aInfo;
193 }
194 else
195 {
196 showError(aInfo, m_pErrorMessageParent ? m_pErrorMessageParent->GetXWindow() : nullptr, m_xContext);
197 }
198 }
199 return xConnection;
200 }
201
202} // namespace dbaui
203
204/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
ODatasourceConnector(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, weld::Window *_pMessageParent)
Reference< XComponentContext > m_xContext
#define DBA_RES(id)
#define DBG_UNHANDLED_EXCEPTION(...)
VCL_DLLPUBLIC OUString removeMnemonicFromString(OUString const &rStr, sal_Int32 &rMnemonicPos)
css::uno::Reference< css::sdbc::XDataSource > getDataSourceByName(const OUString &_rDataSourceName, weld::Window *_pErrorMessageParent, const css::uno::Reference< css::uno::XComponentContext > &_rxContext, ::dbtools::SQLExceptionInfo *_pErrorInfo)
retrieves a data source given by name or URL, and displays an error if this fails
css::uno::Reference< css::uno::XInterface > getDataSourceOrModel(const css::uno::Reference< css::uno::XInterface > &_xObject)
returns either the model when data source is given as parameter, or returns a data source when a mode...
void showError(const SQLExceptionInfo &_rInfo, const Reference< XWindow > &_xParent, const Reference< XComponentContext > &_rxContext)
OUString sMessage
Definition: sqlmessage.cxx:159
OUString VCL_DLLPUBLIC GetStandardText(StandardButtonType eButton)
constexpr OUStringLiteral PROPERTY_USER(u"User")
constexpr OUStringLiteral PROPERTY_PASSWORD(u"Password")
constexpr OUStringLiteral PROPERTY_ISPASSWORDREQUIRED(u"IsPasswordRequired")
Reference< XModel > xModel
the model of the sub component. Might be <NULL>