1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_dbui.hxx"
26
27 #include "DbAdminImpl.hxx"
28 #include "dsmeta.hxx"
29
30 #include <svl/poolitem.hxx>
31 #include <svl/itempool.hxx>
32 #include <svl/stritem.hxx>
33 #include <svl/intitem.hxx>
34 #include <svl/eitem.hxx>
35 #include "DriverSettings.hxx"
36 #include "IItemSetHelper.hxx"
37 #include "UITools.hxx"
38 #include "dbu_dlg.hrc"
39 #include "dbustrings.hrc"
40 #include "dsitems.hxx"
41 #include "dsnItem.hxx"
42 #include "moduledbu.hxx"
43 #include "optionalboolitem.hxx"
44 #include "propertysetitem.hxx"
45 #include "stringlistitem.hxx"
46 #include "OAuthenticationContinuation.hxx"
47
48 /** === begin UNO includes === **/
49 #include <com/sun/star/beans/PropertyAttribute.hpp>
50 #include <com/sun/star/frame/XStorable.hpp>
51 #include <com/sun/star/sdb/SQLContext.hpp>
52 #include <com/sun/star/sdbc/XDriver.hpp>
53 #include <com/sun/star/sdbc/XDriverAccess.hpp>
54 #include <com/sun/star/task/XInteractionHandler.hpp>
55 #include <com/sun/star/task/XInteractionRequest.hpp>
56 #include <com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp>
57 #include <com/sun/star/ucb/AuthenticationRequest.hpp>
58 /** === end UNO includes === **/
59
60 #include <comphelper/interaction.hxx>
61 #include <comphelper/property.hxx>
62 #include <comphelper/sequence.hxx>
63 #include <comphelper/guarding.hxx>
64 #include <connectivity/DriversConfig.hxx>
65 #include <connectivity/dbexception.hxx>
66 #include <osl/file.hxx>
67 #include <svl/eitem.hxx>
68 #include <svl/intitem.hxx>
69 #include <svl/itempool.hxx>
70 #include <svl/poolitem.hxx>
71 #include <svl/stritem.hxx>
72 #include <tools/urlobj.hxx>
73 #include <tools/diagnose_ex.h>
74 #include <typelib/typedescription.hxx>
75 #include <vcl/svapp.hxx>
76 #include <vcl/msgbox.hxx>
77 #include <vcl/stdtext.hxx>
78 #include <vcl/waitobj.hxx>
79 #include <vos/mutex.hxx>
80
81 #include <algorithm>
82 #include <functional>
83 #include <iterator>
84 //.........................................................................
85 namespace dbaui
86 {
87 //.........................................................................
88 using namespace ::dbtools;
89 using namespace com::sun::star::uno;
90 using namespace com::sun::star;
91 using namespace com::sun::star::ucb;
92 using namespace com::sun::star::task;
93 using namespace com::sun::star::sdbc;
94 using namespace com::sun::star::sdb;
95 using namespace com::sun::star::lang;
96 using namespace com::sun::star::beans;
97 using namespace com::sun::star::util;
98 using namespace com::sun::star::container;
99 using namespace com::sun::star::frame;
100
101 //-------------------------------------------------------------------------
102 namespace
103 {
implCheckItemType(SfxItemSet & _rSet,const sal_uInt16 _nId,const TypeId _nExpectedItemType)104 sal_Bool implCheckItemType( SfxItemSet& _rSet, const sal_uInt16 _nId, const TypeId _nExpectedItemType )
105 {
106 sal_Bool bCorrectType = sal_False;
107
108 SfxItemPool* pPool = _rSet.GetPool();
109 DBG_ASSERT( pPool, "implCheckItemType: invalid item pool!" );
110 if ( pPool )
111 {
112 const SfxPoolItem& rDefItem = pPool->GetDefaultItem( _nId );
113 bCorrectType = rDefItem.IsA( _nExpectedItemType );
114 }
115 return bCorrectType;
116 }
117
lcl_putProperty(const Reference<XPropertySet> & _rxSet,const::rtl::OUString & _rName,const Any & _rValue)118 void lcl_putProperty(const Reference< XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const Any& _rValue)
119 {
120 try
121 {
122 if ( _rxSet.is() )
123 _rxSet->setPropertyValue(_rName, _rValue);
124 }
125 catch(Exception&)
126 {
127 #ifdef DBG_UTIL
128 ::rtl::OString sMessage("ODbAdminDialog::implTranslateProperty: could not set the property ");
129 sMessage += ::rtl::OString(_rName.getStr(), _rName.getLength(), RTL_TEXTENCODING_ASCII_US);
130 sMessage += ::rtl::OString("!");
131 DBG_ERROR(sMessage.getStr());
132 #endif
133 }
134
135 }
136
lcl_createHostWithPort(const SfxStringItem * _pHostName,const SfxInt32Item * _pPortNumber)137 String lcl_createHostWithPort(const SfxStringItem* _pHostName,const SfxInt32Item* _pPortNumber)
138 {
139 String sNewUrl;
140
141 if ( _pHostName && _pHostName->GetValue().Len() )
142 sNewUrl = _pHostName->GetValue();
143
144 if ( _pPortNumber )
145 {
146 sNewUrl += String::CreateFromAscii(":");
147 sNewUrl += String::CreateFromInt32(_pPortNumber->GetValue());
148 }
149
150 return sNewUrl;
151 }
152 }
153
154 //========================================================================
155 //= ODbDataSourceAdministrationHelper
156 //========================================================================
ODbDataSourceAdministrationHelper(const Reference<XMultiServiceFactory> & _xORB,Window * _pParent,IItemSetHelper * _pItemSetHelper)157 ODbDataSourceAdministrationHelper::ODbDataSourceAdministrationHelper(const Reference< XMultiServiceFactory >& _xORB,Window* _pParent,IItemSetHelper* _pItemSetHelper)
158 : m_xORB(_xORB)
159 , m_pParent(_pParent)
160 , m_pItemSetHelper(_pItemSetHelper)
161 {
162 /// initialize the property translation map
163 // direct properties of a data source
164 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_CONNECTURL, PROPERTY_URL));
165 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_NAME, PROPERTY_NAME));
166 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_USER, PROPERTY_USER));
167 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_PASSWORD, PROPERTY_PASSWORD));
168 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_PASSWORDREQUIRED, PROPERTY_ISPASSWORDREQUIRED));
169 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_TABLEFILTER, PROPERTY_TABLEFILTER));
170 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_READONLY, PROPERTY_ISREADONLY));
171 m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_SUPPRESSVERSIONCL, PROPERTY_SUPPRESSVERSIONCL));
172
173 // implicit properties, to be found in the direct property "Info"
174 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_JDBCDRIVERCLASS, INFO_JDBCDRIVERCLASS));
175 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTFILEEXTENSION, INFO_TEXTFILEEXTENSION));
176 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CHARSET, INFO_CHARSET));
177 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTFILEHEADER, INFO_TEXTFILEHEADER));
178 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_FIELDDELIMITER, INFO_FIELDDELIMITER));
179 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTDELIMITER, INFO_TEXTDELIMITER));
180 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DECIMALDELIMITER, INFO_DECIMALDELIMITER));
181 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_THOUSANDSDELIMITER, INFO_THOUSANDSDELIMITER));
182 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SHOWDELETEDROWS, INFO_SHOWDELETEDROWS));
183 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ALLOWLONGTABLENAMES, INFO_ALLOWLONGTABLENAMES));
184 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ADDITIONALOPTIONS, INFO_ADDITIONALOPTIONS));
185 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SQL92CHECK, PROPERTY_ENABLESQL92CHECK));
186 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AUTOINCREMENTVALUE, PROPERTY_AUTOINCREMENTCREATION));
187 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AUTORETRIEVEVALUE, INFO_AUTORETRIEVEVALUE));
188 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AUTORETRIEVEENABLED, INFO_AUTORETRIEVEENABLED));
189 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_APPEND_TABLE_ALIAS, INFO_APPEND_TABLE_ALIAS));
190 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AS_BEFORE_CORRNAME, INFO_AS_BEFORE_CORRELATION_NAME ) );
191 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CHECK_REQUIRED_FIELDS, INFO_FORMS_CHECK_REQUIRED_FIELDS ) );
192 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ESCAPE_DATETIME, INFO_ESCAPE_DATETIME ) );
193 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_PRIMARY_KEY_SUPPORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrimaryKeySupport" ) ) ) );
194 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_PARAMETERNAMESUBST, INFO_PARAMETERNAMESUBST));
195 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_IGNOREDRIVER_PRIV, INFO_IGNOREDRIVER_PRIV));
196 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_BOOLEANCOMPARISON, PROPERTY_BOOLEANCOMPARISONMODE));
197 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ENABLEOUTERJOIN, PROPERTY_ENABLEOUTERJOIN));
198 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CATALOG, PROPERTY_USECATALOGINSELECT));
199 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SCHEMA, PROPERTY_USESCHEMAINSELECT));
200 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_INDEXAPPENDIX, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AddIndexAppendix"))));
201 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DOSLINEENDS, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PreferDosLikeLineEnds" ) ) ) );
202 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_SOCKET, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalSocket" ) ) ) );
203 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_NAMED_PIPE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NamedPipe" ) ) ) );
204 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_RESPECTRESULTSETTYPE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RespectDriverResultSetType" ) ) ) );
205 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_MAX_ROW_SCAN, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxRowScan" ) ) ) );
206
207 // special settings for adabas
208 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_SHUTSERVICE, ::rtl::OUString::createFromAscii("ShutdownDatabase")));
209 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_DATAINC, ::rtl::OUString::createFromAscii("DataCacheSizeIncrement")));
210 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CACHESIZE, ::rtl::OUString::createFromAscii("DataCacheSize")));
211 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CTRLUSER, ::rtl::OUString::createFromAscii("ControlUser")));
212 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CTRLPWD, ::rtl::OUString::createFromAscii("ControlPassword")));
213
214 // extra settings for odbc
215 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_USECATALOG, INFO_USECATALOG));
216 // extra settings for a ldap address book
217 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_BASEDN, INFO_CONN_LDAP_BASEDN));
218 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_ROWCOUNT, INFO_CONN_LDAP_ROWCOUNT));
219 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_USESSL, ::rtl::OUString::createFromAscii("UseSSL")));
220 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DOCUMENT_URL, PROPERTY_URL));
221
222 // oracle
223 m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_IGNORECURRENCY, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IgnoreCurrency"))));
224
225 try
226 {
227 m_xDatabaseContext = Reference< XNameAccess >(m_xORB->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY);
228 m_xDynamicContext.set(m_xDatabaseContext,UNO_QUERY);
229 }
230 catch(Exception&)
231 {
232 }
233
234 if ( !m_xDatabaseContext.is() )
235 {
236 ShowServiceNotAvailableError(_pParent->GetParent(), String(SERVICE_SDB_DATABASECONTEXT), sal_True);
237 }
238
239 DBG_ASSERT(m_xDynamicContext.is(), "ODbAdminDialog::ODbAdminDialog : no XNamingService interface !");
240 }
241 //-------------------------------------------------------------------------
getCurrentSettings(Sequence<PropertyValue> & _rDriverParam)242 sal_Bool ODbDataSourceAdministrationHelper::getCurrentSettings(Sequence< PropertyValue >& _rDriverParam)
243 {
244 DBG_ASSERT(m_pItemSetHelper->getOutputSet(), "ODbDataSourceAdministrationHelper::getCurrentSettings : not to be called without an example set!");
245 if (!m_pItemSetHelper->getOutputSet())
246 return sal_False;
247
248 ::std::vector< PropertyValue > aReturn;
249 // collecting this in a vector because it has a push_back, in opposite to sequences
250
251 // user: DSID_USER -> "user"
252 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pUser, SfxStringItem, DSID_USER, sal_True);
253 if (pUser && pUser->GetValue().Len())
254 aReturn.push_back(
255 PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")), 0,
256 makeAny(::rtl::OUString(pUser->GetValue())), PropertyState_DIRECT_VALUE));
257
258 // check if the connection type requires a password
259 if (hasAuthentication(*m_pItemSetHelper->getOutputSet()))
260 {
261 // password: DSID_PASSWORD -> "password"
262 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPassword, SfxStringItem, DSID_PASSWORD, sal_True);
263 String sPassword = pPassword ? pPassword->GetValue() : String();
264 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPasswordRequired, SfxBoolItem, DSID_PASSWORDREQUIRED, sal_True);
265 // if the set does not contain a password, but the item set says it requires one, ask the user
266 if ((!pPassword || !pPassword->GetValue().Len()) && (pPasswordRequired && pPasswordRequired->GetValue()))
267 {
268 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pName, SfxStringItem, DSID_NAME, sal_True);
269
270 Reference< XModel > xModel( getDataSourceOrModel( m_xDatasource ), UNO_QUERY_THROW );
271 ::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
272 Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
273
274 if ( !xHandler.is() )
275 {
276 // instantiate the default SDB interaction handler
277 xHandler = Reference< XInteractionHandler >( m_xORB->createInstance( SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
278 if ( !xHandler.is() )
279 ShowServiceNotAvailableError(m_pParent->GetParent(), String(SERVICE_TASK_INTERACTION_HANDLER), sal_True);
280 }
281
282 String sName = pName ? pName->GetValue() : String();
283 String sLoginRequest(ModuleRes(STR_ENTER_CONNECTION_PASSWORD));
284 ::rtl::OUString sTemp = sName;
285 sName = ::dbaui::getStrippedDatabaseName(NULL,sTemp);
286 if ( sName.Len() )
287 sLoginRequest.SearchAndReplaceAscii("$name$", sName);
288 else
289 {
290 sLoginRequest.SearchAndReplaceAscii("\"$name$\"", String());
291 sLoginRequest.SearchAndReplaceAscii("$name$", String()); // just to be sure that in other languages the string will be deleted
292 }
293
294 // the request
295 AuthenticationRequest aRequest;
296 aRequest.ServerName = sName;
297 aRequest.Diagnostic = sLoginRequest;
298 aRequest.HasRealm = aRequest.HasAccount = sal_False;
299 // aRequest.Realm
300 aRequest.HasUserName = pUser != 0;
301 aRequest.UserName = pUser ? rtl::OUString(pUser->GetValue()) : ::rtl::OUString();
302 aRequest.HasPassword = sal_True;
303 //aRequest.Password
304 aRequest.HasAccount = sal_False;
305 // aRequest.Account
306
307 comphelper::OInteractionRequest* pRequest = new comphelper::OInteractionRequest(makeAny(aRequest));
308 uno::Reference< XInteractionRequest > xRequest(pRequest);
309
310 // build an interaction request
311 // two continuations (Ok and Cancel)
312 ::rtl::Reference< comphelper::OInteractionAbort > pAbort = new comphelper::OInteractionAbort;
313 ::rtl::Reference< dbaccess::OAuthenticationContinuation > pAuthenticate = new dbaccess::OAuthenticationContinuation;
314 pAuthenticate->setCanChangeUserName( sal_False );
315 pAuthenticate->setRememberPassword( RememberAuthentication_SESSION );
316
317 // some knittings
318 pRequest->addContinuation(pAbort.get());
319 pRequest->addContinuation(pAuthenticate.get());
320
321 // handle the request
322 try
323 {
324 ::vos::OGuard aSolarGuard(Application::GetSolarMutex());
325 // release the mutex when calling the handler, it may need to lock the SolarMutex
326 xHandler->handle(xRequest);
327 }
328 catch(Exception&)
329 {
330 DBG_UNHANDLED_EXCEPTION();
331 }
332 if (!pAuthenticate->wasSelected())
333 return sal_False;
334
335 sPassword = pAuthenticate->getPassword();
336 if (pAuthenticate->getRememberPassword())
337 m_pItemSetHelper->getWriteOutputSet()->Put(SfxStringItem(DSID_PASSWORD, sPassword));
338 }
339
340 if (sPassword.Len())
341 aReturn.push_back(
342 PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("password")), 0,
343 makeAny(::rtl::OUString(sPassword)), PropertyState_DIRECT_VALUE));
344 }
345
346 if ( !aReturn.empty() )
347 _rDriverParam = Sequence< PropertyValue >(&(*aReturn.begin()), aReturn.size());
348
349 // append all the other stuff (charset etc.)
350 fillDatasourceInfo(*m_pItemSetHelper->getOutputSet(), _rDriverParam);
351
352 return sal_True;
353 }
354 //-------------------------------------------------------------------------
successfullyConnected()355 void ODbDataSourceAdministrationHelper::successfullyConnected()
356 {
357 DBG_ASSERT(m_pItemSetHelper->getOutputSet(), "ODbDataSourceAdministrationHelper::successfullyConnected: not to be called without an example set!");
358 if (!m_pItemSetHelper->getOutputSet())
359 return;
360
361 if (hasAuthentication(*m_pItemSetHelper->getOutputSet()))
362 {
363 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPassword, SfxStringItem, DSID_PASSWORD, sal_True);
364 if (pPassword && (0 != pPassword->GetValue().Len()))
365 {
366 ::rtl::OUString sPassword = pPassword->GetValue();
367
368 Reference< XPropertySet > xCurrentDatasource = getCurrentDataSource();
369 lcl_putProperty(xCurrentDatasource,m_aDirectPropTranslator[DSID_PASSWORD], makeAny(sPassword));
370 }
371 }
372 }
373 //-------------------------------------------------------------------------
clearPassword()374 void ODbDataSourceAdministrationHelper::clearPassword()
375 {
376 if (m_pItemSetHelper->getWriteOutputSet())
377 m_pItemSetHelper->getWriteOutputSet()->ClearItem(DSID_PASSWORD);
378 }
379 // -----------------------------------------------------------------------------
createConnection()380 ::std::pair< Reference<XConnection>,sal_Bool> ODbDataSourceAdministrationHelper::createConnection()
381 {
382 ::std::pair< Reference<XConnection>,sal_Bool> aRet;
383 aRet.second = sal_False;
384 Sequence< PropertyValue > aConnectionParams;
385 if ( getCurrentSettings(aConnectionParams) )
386 {
387 // the current DSN
388 // fill the table list with this connection information
389 SQLExceptionInfo aErrorInfo;
390 try
391 {
392 WaitObject aWaitCursor(m_pParent);
393 aRet.first = getDriver()->connect(getConnectionURL(), aConnectionParams);
394 aRet.second = sal_True;
395 }
396 catch (SQLContext& e) { aErrorInfo = SQLExceptionInfo(e); }
397 catch (SQLWarning& e) { aErrorInfo = SQLExceptionInfo(e); }
398 catch (SQLException& e) { aErrorInfo = SQLExceptionInfo(e); }
399
400 showError(aErrorInfo,m_pParent,getORB());
401 }
402 if ( aRet.first.is() )
403 successfullyConnected();// notify the admindlg to save the password
404
405 return aRet;
406 }
407 // -----------------------------------------------------------------------------
getDriver()408 Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver()
409 {
410 return getDriver(getConnectionURL());
411 }
412 // -----------------------------------------------------------------------------
getDriver(const::rtl::OUString & _sURL)413 Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver(const ::rtl::OUString& _sURL)
414 {
415 // get the global DriverManager
416 Reference< XDriverAccess > xDriverManager;
417 String sCurrentActionError = String(ModuleRes(STR_COULDNOTCREATE_DRIVERMANAGER));
418 // in case an error occurs
419 sCurrentActionError.SearchAndReplaceAscii("#servicename#", (::rtl::OUString)SERVICE_SDBC_CONNECTIONPOOL);
420 try
421 {
422 xDriverManager = Reference< XDriverAccess >(getORB()->createInstance(SERVICE_SDBC_CONNECTIONPOOL), UNO_QUERY);
423 DBG_ASSERT(xDriverManager.is(), "ODbDataSourceAdministrationHelper::getDriver: could not instantiate the driver manager, or it does not provide the necessary interface!");
424 }
425 catch (Exception& e)
426 {
427 // wrap the exception into an SQLException
428 SQLException aSQLWrapper(e.Message, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
429 throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, makeAny(aSQLWrapper));
430 }
431 if (!xDriverManager.is())
432 throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
433
434
435 Reference< XDriver > xDriver = xDriverManager->getDriverByURL(_sURL);
436 if (!xDriver.is())
437 {
438 sCurrentActionError = String(ModuleRes(STR_NOREGISTEREDDRIVER));
439 sCurrentActionError.SearchAndReplaceAscii("#connurl#", _sURL);
440 // will be caught and translated into an SQLContext exception
441 throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
442 }
443 return xDriver;
444 }
445
446 // -----------------------------------------------------------------------------
getCurrentDataSource()447 Reference< XPropertySet > ODbDataSourceAdministrationHelper::getCurrentDataSource()
448 {
449 if ( !m_xDatasource.is() )
450 {
451 Reference<XInterface> xIn(m_aDataSourceOrName,UNO_QUERY);
452 if ( !xIn.is() )
453 {
454 ::rtl::OUString sCurrentDatasource;
455 m_aDataSourceOrName >>= sCurrentDatasource;
456 OSL_ENSURE(sCurrentDatasource.getLength(),"No datasource name given!");
457 try
458 {
459 if ( m_xDatabaseContext.is() )
460 m_xDatasource.set(m_xDatabaseContext->getByName(sCurrentDatasource),UNO_QUERY);
461 xIn = m_xDatasource;
462 }
463 catch(const Exception&)
464 {
465 }
466 }
467 m_xModel.set(getDataSourceOrModel(xIn),UNO_QUERY);
468 if ( m_xModel.is() )
469 m_xDatasource.set(xIn,UNO_QUERY);
470 else
471 {
472 m_xDatasource.set(getDataSourceOrModel(xIn),UNO_QUERY);
473 m_xModel.set(xIn,UNO_QUERY);
474 }
475 }
476
477
478 DBG_ASSERT(m_xDatasource.is(), "ODbDataSourceAdministrationHelper::getCurrentDataSource: no data source!");
479 return m_xDatasource;
480 }
481 //-------------------------------------------------------------------------
getDatasourceType(const SfxItemSet & _rSet)482 ::rtl::OUString ODbDataSourceAdministrationHelper::getDatasourceType( const SfxItemSet& _rSet )
483 {
484 SFX_ITEMSET_GET( _rSet, pConnectURL, SfxStringItem, DSID_CONNECTURL, sal_True );
485 DBG_ASSERT( pConnectURL , "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!" );
486 SFX_ITEMSET_GET(_rSet, pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
487 DBG_ASSERT(pTypeCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!");
488 ::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
489 return pCollection->getType(pConnectURL->GetValue());
490 }
491
492 //-------------------------------------------------------------------------
hasAuthentication(const SfxItemSet & _rSet) const493 sal_Bool ODbDataSourceAdministrationHelper::hasAuthentication(const SfxItemSet& _rSet) const
494 {
495 return DataSourceMetaData::getAuthentication( getDatasourceType( _rSet ) ) != AuthNone;
496 }
497 // -----------------------------------------------------------------------------
getConnectionURL() const498 String ODbDataSourceAdministrationHelper::getConnectionURL() const
499 {
500 String sNewUrl;
501
502 ::rtl::OUString eType = getDatasourceType(*m_pItemSetHelper->getOutputSet());
503
504 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
505 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
506
507 OSL_ENSURE(pUrlItem,"Connection URL is NULL. -> GPF!");
508 DBG_ASSERT(pTypeCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!");
509 ::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
510 DBG_ASSERT(pCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid type collection!");
511
512 switch( pCollection->determineType(eType) )
513 {
514 case ::dbaccess::DST_DBASE:
515 case ::dbaccess::DST_FLAT:
516 case ::dbaccess::DST_CALC:
517 break;
518 case ::dbaccess::DST_ADABAS:
519 {
520 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
521 sNewUrl = lcl_createHostWithPort(pHostName,NULL);
522 String sUrl = pCollection->cutPrefix(pUrlItem->GetValue());
523 if ( sUrl.GetTokenCount(':') == 1 )
524 sNewUrl += String::CreateFromAscii(":");
525
526 sNewUrl += sUrl;
527 }
528 break;
529 case ::dbaccess::DST_MSACCESS:
530 case ::dbaccess::DST_MSACCESS_2007:
531 {
532 ::rtl::OUString sFileName = pCollection->cutPrefix(pUrlItem->GetValue());
533 ::rtl::OUString sNewFileName;
534 if ( ::osl::FileBase::getSystemPathFromFileURL( sFileName, sNewFileName ) == ::osl::FileBase::E_None )
535 {
536 sNewUrl += String(sNewFileName);
537 }
538 }
539 break;
540 case ::dbaccess::DST_MYSQL_NATIVE:
541 case ::dbaccess::DST_MYSQL_JDBC:
542 {
543 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
544 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPortNumber, SfxInt32Item, DSID_MYSQL_PORTNUMBER, sal_True);
545 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pDatabaseName, SfxStringItem, DSID_DATABASENAME, sal_True);
546 sNewUrl = lcl_createHostWithPort(pHostName,pPortNumber);
547 String sDatabaseName = pDatabaseName ? pDatabaseName->GetValue() : String();
548 if ( !sDatabaseName.Len() && pUrlItem )
549 sDatabaseName = pCollection->cutPrefix( pUrlItem->GetValue() );
550 // TODO: what's that? Why is the database name transported via the URL Item?
551 // Huh? Anybody there?
552 // OJ: It is needed when the connection properties are changed. There the URL is used for every type.
553
554 if ( sDatabaseName.Len() )
555 {
556 sNewUrl += String::CreateFromAscii("/");
557 sNewUrl += sDatabaseName;
558 }
559 }
560 break;
561 case ::dbaccess::DST_ORACLE_JDBC:
562 {
563 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
564 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPortNumber, SfxInt32Item, DSID_ORACLE_PORTNUMBER, sal_True);
565 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pDatabaseName, SfxStringItem, DSID_DATABASENAME, sal_True);
566 if ( pHostName && pHostName->GetValue().Len() )
567 {
568 sNewUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("@"));
569 sNewUrl += lcl_createHostWithPort(pHostName,pPortNumber);
570 String sDatabaseName = pDatabaseName ? pDatabaseName->GetValue() : String();
571 if ( !sDatabaseName.Len() && pUrlItem )
572 sDatabaseName = pCollection->cutPrefix( pUrlItem->GetValue() );
573 if ( sDatabaseName.Len() )
574 {
575 sNewUrl += String::CreateFromAscii(":");
576 sNewUrl += sDatabaseName;
577 }
578 }
579 else
580 { // here someone entered a JDBC url which looks like oracle, so we have to use the url property
581
582 }
583 }
584 break;
585 case ::dbaccess::DST_LDAP:
586 {
587 // SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
588 SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPortNumber, SfxInt32Item, DSID_CONN_LDAP_PORTNUMBER, sal_True);
589 sNewUrl = pCollection->cutPrefix(pUrlItem->GetValue());
590 sNewUrl += lcl_createHostWithPort(NULL,pPortNumber);
591 }
592 break;
593 case ::dbaccess::DST_JDBC:
594 // run through
595 default:
596 break;
597 }
598 if ( sNewUrl.Len() )
599 {
600 String sUrl = pCollection->getPrefix(eType);
601 sUrl += sNewUrl;
602 sNewUrl = sUrl;
603 }
604 else
605 sNewUrl = pUrlItem->GetValue();
606
607 return sNewUrl;
608 }
609 //-------------------------------------------------------------------------
610 struct PropertyValueLess
611 {
operator ()dbaui::PropertyValueLess612 bool operator() (const PropertyValue& x, const PropertyValue& y) const
613 { return x.Name < y.Name ? true : false; } // construct prevents a MSVC6 warning
614 };
615 DECLARE_STL_SET( PropertyValue, PropertyValueLess, PropertyValueSet);
616
617 //........................................................................
translateProperties(const Reference<XPropertySet> & _rxSource,SfxItemSet & _rDest)618 void ODbDataSourceAdministrationHelper::translateProperties(const Reference< XPropertySet >& _rxSource, SfxItemSet& _rDest)
619 {
620 ::rtl::OUString sNewConnectURL, sName, sUid, sPwd;
621 Sequence< ::rtl::OUString > aTableFitler;
622
623 if (_rxSource.is())
624 {
625 for ( ConstMapInt2StringIterator aDirect = m_aDirectPropTranslator.begin();
626 aDirect != m_aDirectPropTranslator.end();
627 ++aDirect
628 )
629 {
630 // get the property value
631 Any aValue;
632 try
633 {
634 aValue = _rxSource->getPropertyValue(aDirect->second);
635 }
636 catch(Exception&)
637 {
638 #ifdef DBG_UTIL
639 ::rtl::OString aMessage("ODbDataSourceAdministrationHelper::translateProperties: could not extract the property ");
640 aMessage += ::rtl::OString(aDirect->second.getStr(), aDirect->second.getLength(), RTL_TEXTENCODING_ASCII_US);
641 aMessage += ::rtl::OString("!");
642 DBG_ERROR(aMessage.getStr());
643 #endif
644 }
645 // transfer it into an item
646 implTranslateProperty(_rDest, aDirect->first, aValue);
647 }
648
649 // get the additional informations
650 Sequence< PropertyValue > aAdditionalInfo;
651 try
652 {
653 _rxSource->getPropertyValue(PROPERTY_INFO) >>= aAdditionalInfo;
654 }
655 catch(Exception&) { }
656
657 // collect the names of the additional settings
658 const PropertyValue* pAdditionalInfo = aAdditionalInfo.getConstArray();
659 PropertyValueSet aInfos;
660 for (sal_Int32 i=0; i<aAdditionalInfo.getLength(); ++i, ++pAdditionalInfo)
661 {
662 if (0 == pAdditionalInfo->Name.compareToAscii("JDBCDRV"))
663 { // compatibility
664 PropertyValue aCompatibility(*pAdditionalInfo);
665 aCompatibility.Name = ::rtl::OUString::createFromAscii("JavaDriverClass");
666 aInfos.insert(aCompatibility);
667 }
668 else
669 aInfos.insert(*pAdditionalInfo);
670 }
671
672 // go through all known translations and check if we have such a setting
673 if ( !aInfos.empty() )
674 {
675 PropertyValue aSearchFor;
676 ConstMapInt2StringIterator aEnd = m_aIndirectPropTranslator.end();
677 for ( ConstMapInt2StringIterator aIndirect = m_aIndirectPropTranslator.begin();
678 aIndirect != aEnd;
679 ++aIndirect)
680 {
681 aSearchFor.Name = aIndirect->second;
682 ConstPropertyValueSetIterator aInfoPos = aInfos.find(aSearchFor);
683 if (aInfos.end() != aInfoPos)
684 // the property is contained in the info sequence
685 // -> transfer it into an item
686 implTranslateProperty(_rDest, aIndirect->first, aInfoPos->Value);
687 }
688 }
689
690 convertUrl(_rDest);
691 }
692
693 try
694 {
695 _rDest.Put(OPropertySetItem(DSID_DATASOURCE_UNO, _rxSource));
696 Reference<XStorable> xStore(getDataSourceOrModel(_rxSource),UNO_QUERY);
697 _rDest.Put(SfxBoolItem(DSID_READONLY, !xStore.is() || xStore->isReadonly() ));
698 }
699 catch(Exception&)
700 {
701 OSL_ENSURE(0,"IsReadOnly throws an exception!");
702 }
703 }
704
705 //-------------------------------------------------------------------------
translateProperties(const SfxItemSet & _rSource,const Reference<XPropertySet> & _rxDest)706 void ODbDataSourceAdministrationHelper::translateProperties(const SfxItemSet& _rSource, const Reference< XPropertySet >& _rxDest)
707 {
708 DBG_ASSERT(_rxDest.is(), "ODbDataSourceAdministrationHelper::translateProperties: invalid property set!");
709 if (!_rxDest.is())
710 return;
711
712 // the property set info
713 Reference< XPropertySetInfo > xInfo;
714 try { xInfo = _rxDest->getPropertySetInfo(); }
715 catch(Exception&) { }
716
717 const ::rtl::OUString sUrlProp(RTL_CONSTASCII_USTRINGPARAM("URL"));
718 // -----------------------------
719 // transfer the direct properties
720 for ( ConstMapInt2StringIterator aDirect = m_aDirectPropTranslator.begin();
721 aDirect != m_aDirectPropTranslator.end();
722 ++aDirect
723 )
724 {
725 const SfxPoolItem* pCurrentItem = _rSource.GetItem((sal_uInt16)aDirect->first);
726 if (pCurrentItem)
727 {
728 sal_Int16 nAttributes = PropertyAttribute::READONLY;
729 if (xInfo.is())
730 {
731 try { nAttributes = xInfo->getPropertyByName(aDirect->second).Attributes; }
732 catch(Exception&) { }
733 }
734 if ((nAttributes & PropertyAttribute::READONLY) == 0)
735 {
736 if ( sUrlProp == aDirect->second )
737 {
738 Any aValue(makeAny(::rtl::OUString(getConnectionURL())));
739 // aValue <<= ::rtl::OUString();
740 lcl_putProperty(_rxDest, aDirect->second,aValue);
741 }
742 else
743 implTranslateProperty(_rxDest, aDirect->second, pCurrentItem);
744 }
745 }
746 }
747
748 // -------------------------------
749 // now for the indirect properties
750
751 Sequence< PropertyValue > aInfo;
752 // the original properties
753 try
754 {
755 _rxDest->getPropertyValue(PROPERTY_INFO) >>= aInfo;
756 }
757 catch(Exception&) { }
758
759 // overwrite and extend them
760 fillDatasourceInfo(_rSource, aInfo);
761 // and propagate the (newly composed) sequence to the set
762 lcl_putProperty(_rxDest,PROPERTY_INFO, makeAny(aInfo));
763 }
764
765
766 //-------------------------------------------------------------------------
fillDatasourceInfo(const SfxItemSet & _rSource,Sequence<::com::sun::star::beans::PropertyValue> & _rInfo)767 void ODbDataSourceAdministrationHelper::fillDatasourceInfo(const SfxItemSet& _rSource, Sequence< ::com::sun::star::beans::PropertyValue >& _rInfo)
768 {
769 // within the current "Info" sequence, replace the ones we can examine from the item set
770 // (we don't just fill a completely new sequence with our own items, but we preserve any properties unknown to
771 // us)
772
773 // first determine which of all the items are relevant for the data source (depends on the connection url)
774 ::rtl::OUString eType = getDatasourceType(_rSource);
775 ::std::vector< sal_Int32> aDetailIds;
776 ODriversSettings::getSupportedIndirectSettings(eType,getORB(),aDetailIds);
777
778 // collect the translated property values for the relevant items
779 PropertyValueSet aRelevantSettings;
780 ConstMapInt2StringIterator aTranslation;
781 ::std::vector< sal_Int32>::iterator aDetailsEnd = aDetailIds.end();
782 for (::std::vector< sal_Int32>::iterator aIter = aDetailIds.begin();aIter != aDetailsEnd ; ++aIter)
783 {
784 const SfxPoolItem* pCurrent = _rSource.GetItem((sal_uInt16)*aIter);
785 aTranslation = m_aIndirectPropTranslator.find(*aIter);
786 if ( pCurrent && (m_aIndirectPropTranslator.end() != aTranslation) )
787 {
788 if ( aTranslation->second == INFO_CHARSET )
789 {
790 ::rtl::OUString sCharSet;
791 implTranslateProperty(pCurrent) >>= sCharSet;
792 if ( sCharSet.getLength() )
793 aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, makeAny(sCharSet), PropertyState_DIRECT_VALUE));
794 }
795 else
796 aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, implTranslateProperty(pCurrent), PropertyState_DIRECT_VALUE));
797 }
798 }
799
800 // settings to preserve
801 MapInt2String aPreservedSettings;
802
803 // now aRelevantSettings contains all the property values relevant for the current data source type,
804 // check the original sequence if it already contains any of these values (which have to be overwritten, then)
805 PropertyValue* pInfo = _rInfo.getArray();
806 PropertyValue aSearchFor;
807 sal_Int32 nObsoleteSetting = -1;
808 sal_Int32 nCount = _rInfo.getLength();
809 for (sal_Int32 i = 0; i < nCount; ++i, ++pInfo)
810 {
811 aSearchFor.Name = pInfo->Name;
812 PropertyValueSetIterator aOverwrittenSetting = aRelevantSettings.find(aSearchFor);
813 if (aRelevantSettings.end() != aOverwrittenSetting)
814 { // the setting was present in the original sequence, and it is to be overwritten -> replace it
815 if ( !::comphelper::compare(pInfo->Value,aOverwrittenSetting->Value) )
816 *pInfo = *aOverwrittenSetting;
817 aRelevantSettings.erase(aOverwrittenSetting);
818 }
819 else if (0 == pInfo->Name.compareToAscii("JDBCDRV"))
820 { // this is a compatibility setting, remove it from the sequence (it's replaced by JavaDriverClass)
821 nObsoleteSetting = i;
822 }
823 else
824 aPreservedSettings[i] = pInfo->Name;
825 }
826 if (-1 != nObsoleteSetting)
827 ::comphelper::removeElementAt(_rInfo, nObsoleteSetting);
828
829 if ( !aPreservedSettings.empty() )
830 { // check if there are settings which
831 // * are known as indirect properties
832 // * but not relevant for the current data source type
833 // These settings have to be removed: If they're not relevant, we have no UI for changing them.
834 // 25.06.2001 - 88004/87182 - frank.schoenheit@sun.com
835
836 // for this, we need a string-controlled quick access to m_aIndirectPropTranslator
837 StringSet aIndirectProps;
838 ::std::transform(m_aIndirectPropTranslator.begin(),
839 m_aIndirectPropTranslator.end(),
840 ::std::insert_iterator<StringSet>(aIndirectProps,aIndirectProps.begin()),
841 ::std::select2nd<MapInt2String::value_type>());
842
843 // now check the to-be-preserved props
844 ::std::vector< sal_Int32 > aRemoveIndexes;
845 sal_Int32 nPositionCorrector = 0;
846 ConstMapInt2StringIterator aPreservedEnd = aPreservedSettings.end();
847 for ( ConstMapInt2StringIterator aPreserved = aPreservedSettings.begin();
848 aPreserved != aPreservedEnd;
849 ++aPreserved
850 )
851 {
852 if (aIndirectProps.end() != aIndirectProps.find(aPreserved->second))
853 {
854 #ifdef DBG_UTIL
855 const ::rtl::OUString sName = aPreserved->second;
856 #endif
857 aRemoveIndexes.push_back(aPreserved->first - nPositionCorrector);
858 ++nPositionCorrector;
859 }
860 }
861 // now finally remove all such props
862 ::std::vector< sal_Int32 >::const_iterator aRemoveEnd = aRemoveIndexes.end();
863 for ( ::std::vector< sal_Int32 >::const_iterator aRemoveIndex = aRemoveIndexes.begin();
864 aRemoveIndex != aRemoveEnd;
865 ++aRemoveIndex
866 )
867 ::comphelper::removeElementAt(_rInfo, *aRemoveIndex);
868 #ifdef DBG_UTIL
869 const PropertyValue* pWhatsLeft = _rInfo.getConstArray();
870 const PropertyValue* pWhatsLeftEnd = pWhatsLeft + _rInfo.getLength();
871 for (; pWhatsLeft != pWhatsLeftEnd; ++pWhatsLeft)
872 {
873 ::rtl::OUString sLookAtIt = pWhatsLeft->Name;
874 }
875 #endif
876 }
877
878 ::connectivity::DriversConfig aDriverConfig(getORB());
879 const ::comphelper::NamedValueCollection& aProperties = aDriverConfig.getProperties(eType);
880 Sequence< Any> aTypeSettings;
881 aTypeSettings = aProperties.getOrDefault("TypeInfoSettings",aTypeSettings);
882 // here we have a special entry for types from oracle
883 if ( aTypeSettings.getLength() )
884 {
885 aRelevantSettings.insert(PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeInfoSettings")), 0, makeAny(aTypeSettings), PropertyState_DIRECT_VALUE));
886 }
887
888 // check which values are still left ('cause they were not present in the original sequence, but are to be set)
889 if ( !aRelevantSettings.empty() )
890 {
891 sal_Int32 nOldLength = _rInfo.getLength();
892 _rInfo.realloc(nOldLength + aRelevantSettings.size());
893 PropertyValue* pAppendValues = _rInfo.getArray() + nOldLength;
894 ConstPropertyValueSetIterator aRelevantEnd = aRelevantSettings.end();
895 for ( ConstPropertyValueSetIterator aLoop = aRelevantSettings.begin();
896 aLoop != aRelevantEnd;
897 ++aLoop, ++pAppendValues
898 )
899 {
900 if ( aLoop->Name == INFO_CHARSET )
901 {
902 ::rtl::OUString sCharSet;
903 aLoop->Value >>= sCharSet;
904 if ( sCharSet.getLength() )
905 *pAppendValues = *aLoop;
906 }
907 else
908 *pAppendValues = *aLoop;
909 }
910 }
911 }
912 //-------------------------------------------------------------------------
implTranslateProperty(const SfxPoolItem * _pItem)913 Any ODbDataSourceAdministrationHelper::implTranslateProperty(const SfxPoolItem* _pItem)
914 {
915 // translate the SfxPoolItem
916 Any aValue;
917
918 const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, _pItem );
919 const SfxBoolItem* pBoolItem = PTR_CAST( SfxBoolItem, _pItem );
920 const OptionalBoolItem* pOptBoolItem = PTR_CAST( OptionalBoolItem, _pItem );
921 const SfxInt32Item* pInt32Item = PTR_CAST( SfxInt32Item, _pItem );
922 const OStringListItem* pStringListItem = PTR_CAST( OStringListItem, _pItem );
923
924 if ( pStringItem )
925 {
926 aValue <<= ::rtl::OUString( pStringItem->GetValue().GetBuffer() );
927 }
928 else if ( pBoolItem )
929 {
930 aValue <<= pBoolItem->GetValue();
931 }
932 else if ( pOptBoolItem )
933 {
934 if ( !pOptBoolItem->HasValue() )
935 aValue.clear();
936 else
937 aValue <<= (sal_Bool)pOptBoolItem->GetValue();
938 }
939 else if ( pInt32Item )
940 {
941 aValue <<= pInt32Item->GetValue();
942 }
943 else if ( pStringListItem )
944 {
945 aValue <<= pStringListItem->getList();
946 }
947 else
948 {
949 DBG_ERROR("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported item type!");
950 return aValue;
951 }
952
953 return aValue;
954 }
955 //-------------------------------------------------------------------------
implTranslateProperty(const Reference<XPropertySet> & _rxSet,const::rtl::OUString & _rName,const SfxPoolItem * _pItem)956 void ODbDataSourceAdministrationHelper::implTranslateProperty(const Reference< XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const SfxPoolItem* _pItem)
957 {
958 Any aValue = implTranslateProperty(_pItem);
959 lcl_putProperty(_rxSet, _rName,aValue);
960 }
961 #ifdef DBG_UTIL
962 //-------------------------------------------------------------------------
translatePropertyId(sal_Int32 _nId)963 ::rtl::OString ODbDataSourceAdministrationHelper::translatePropertyId( sal_Int32 _nId )
964 {
965 ::rtl::OUString aString;
966
967 MapInt2String::const_iterator aPos = m_aDirectPropTranslator.find( _nId );
968 if ( m_aDirectPropTranslator.end() != aPos )
969 {
970 aString = aPos->second;
971 }
972 else
973 {
974 MapInt2String::const_iterator indirectPos = m_aIndirectPropTranslator.find( _nId );
975 if ( m_aIndirectPropTranslator.end() != indirectPos )
976 aString = indirectPos->second;
977 }
978
979 ::rtl::OString aReturn( aString.getStr(), aString.getLength(), RTL_TEXTENCODING_ASCII_US );
980 return aReturn;
981 }
982 #endif
983
984 //-------------------------------------------------------------------------
implTranslateProperty(SfxItemSet & _rSet,sal_Int32 _nId,const Any & _rValue)985 void ODbDataSourceAdministrationHelper::implTranslateProperty( SfxItemSet& _rSet, sal_Int32 _nId, const Any& _rValue )
986 {
987 switch ( _rValue.getValueType().getTypeClass() )
988 {
989 case TypeClass_STRING:
990 if ( implCheckItemType( _rSet, _nId, SfxStringItem::StaticType() ) )
991 {
992 ::rtl::OUString sValue;
993 _rValue >>= sValue;
994 _rSet.Put(SfxStringItem(_nId, sValue.getStr()));
995 }
996 else {
997 DBG_ERROR(
998 ( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
999 += ::rtl::OString( translatePropertyId( _nId ) )
1000 += ::rtl::OString( " should be no string)!" )
1001 ).getStr()
1002 );
1003 }
1004 break;
1005
1006 case TypeClass_BOOLEAN:
1007 if ( implCheckItemType( _rSet, _nId, SfxBoolItem::StaticType() ) )
1008 {
1009 sal_Bool bVal = sal_False;
1010 _rValue >>= bVal;
1011 _rSet.Put(SfxBoolItem(_nId, bVal));
1012 }
1013 else if ( implCheckItemType( _rSet, _nId, OptionalBoolItem::StaticType() ) )
1014 {
1015 OptionalBoolItem aItem( _nId );
1016 if ( _rValue.hasValue() )
1017 {
1018 sal_Bool bValue = sal_False;
1019 _rValue >>= bValue;
1020 aItem.SetValue( bValue );
1021 }
1022 else
1023 aItem.ClearValue();
1024 _rSet.Put( aItem );
1025 }
1026 else {
1027 DBG_ERROR(
1028 ( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
1029 += ::rtl::OString( translatePropertyId( _nId ) )
1030 += ::rtl::OString( " should be no boolean)!" )
1031 ).getStr()
1032 );
1033 }
1034 break;
1035
1036 case TypeClass_LONG:
1037 if ( implCheckItemType( _rSet, _nId, SfxInt32Item::StaticType() ) )
1038 {
1039 sal_Int32 nValue = 0;
1040 _rValue >>= nValue;
1041 _rSet.Put( SfxInt32Item( _nId, nValue ) );
1042 }
1043 else {
1044 DBG_ERROR(
1045 ( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
1046 += ::rtl::OString( translatePropertyId( _nId ) )
1047 += ::rtl::OString( " should be no int)!" )
1048 ).getStr()
1049 );
1050 }
1051 break;
1052
1053 case TypeClass_SEQUENCE:
1054 if ( implCheckItemType( _rSet, _nId, OStringListItem::StaticType() ) )
1055 {
1056 // determine the element type
1057 TypeDescription aTD(_rValue.getValueType());
1058 typelib_IndirectTypeDescription* pSequenceTD =
1059 reinterpret_cast< typelib_IndirectTypeDescription* >(aTD.get());
1060 DBG_ASSERT(pSequenceTD && pSequenceTD->pType, "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid sequence type!");
1061
1062 Type aElementType(pSequenceTD->pType);
1063 switch (aElementType.getTypeClass())
1064 {
1065 case TypeClass_STRING:
1066 {
1067 Sequence< ::rtl::OUString > aStringList;
1068 _rValue >>= aStringList;
1069 _rSet.Put(OStringListItem(_nId, aStringList));
1070 }
1071 break;
1072 default:
1073 DBG_ERROR("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported property value type!");
1074 }
1075 }
1076 else {
1077 DBG_ERROR(
1078 ( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
1079 += ::rtl::OString( translatePropertyId( _nId ) )
1080 += ::rtl::OString( " should be no string sequence)!" )
1081 ).getStr()
1082 );
1083 }
1084 break;
1085
1086 case TypeClass_VOID:
1087 _rSet.ClearItem(_nId);
1088 break;
1089
1090 default:
1091 DBG_ERROR("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported property value type!");
1092 }
1093 }
1094
1095
getDocumentUrl(SfxItemSet & _rDest)1096 String ODbDataSourceAdministrationHelper::getDocumentUrl(SfxItemSet& _rDest)
1097 {
1098 SFX_ITEMSET_GET(_rDest, pUrlItem, SfxStringItem, DSID_DOCUMENT_URL, sal_True);
1099 OSL_ENSURE(pUrlItem,"Document URL is NULL. -> GPF!");
1100 return pUrlItem->GetValue();
1101 }
1102
1103
1104 // -----------------------------------------------------------------------------
convertUrl(SfxItemSet & _rDest)1105 void ODbDataSourceAdministrationHelper::convertUrl(SfxItemSet& _rDest)
1106 {
1107 ::rtl::OUString eType = getDatasourceType(_rDest);
1108
1109 SFX_ITEMSET_GET(_rDest, pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
1110 SFX_ITEMSET_GET(_rDest, pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
1111
1112 OSL_ENSURE(pUrlItem,"Connection URL is NULL. -> GPF!");
1113 DBG_ASSERT(pTypeCollection, "ODbAdminDialog::getDatasourceType: invalid items in the source set!");
1114 ::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
1115 DBG_ASSERT(pCollection, "ODbAdminDialog::getDatasourceType: invalid type collection!");
1116
1117 sal_uInt16 nPortNumberId = 0;
1118 sal_Int32 nPortNumber = -1;
1119 String sNewHostName;
1120 //String sUrl = pCollection->cutPrefix(pUrlItem->GetValue());
1121 String sUrlPart;
1122
1123 pCollection->extractHostNamePort(pUrlItem->GetValue(),sUrlPart,sNewHostName,nPortNumber);
1124 const ::dbaccess::DATASOURCE_TYPE eTy = pCollection->determineType(eType);
1125
1126 switch( eTy )
1127 {
1128 case ::dbaccess::DST_MYSQL_NATIVE:
1129 case ::dbaccess::DST_MYSQL_JDBC:
1130 nPortNumberId = DSID_MYSQL_PORTNUMBER;
1131 break;
1132 case ::dbaccess::DST_ORACLE_JDBC:
1133 nPortNumberId = DSID_ORACLE_PORTNUMBER;
1134 break;
1135 case ::dbaccess::DST_LDAP:
1136 nPortNumberId = DSID_CONN_LDAP_PORTNUMBER;
1137 break;
1138 default:
1139 break;
1140 }
1141
1142 if ( sUrlPart.Len() )
1143 {
1144 if ( eTy == ::dbaccess::DST_MYSQL_NATIVE )
1145 {
1146 _rDest.Put( SfxStringItem( DSID_DATABASENAME, sUrlPart ) );
1147 }
1148 else
1149 {
1150 String sNewUrl = pCollection->getPrefix(eType);
1151 sNewUrl += sUrlPart;
1152 _rDest.Put( SfxStringItem( DSID_CONNECTURL, sNewUrl ) );
1153 }
1154 }
1155
1156 if ( sNewHostName.Len() )
1157 _rDest.Put(SfxStringItem(DSID_CONN_HOSTNAME, sNewHostName));
1158
1159 if ( nPortNumber != -1 && nPortNumberId != 0 )
1160 _rDest.Put(SfxInt32Item(nPortNumberId, nPortNumber));
1161
1162 }
1163 // -----------------------------------------------------------------------------
saveChanges(const SfxItemSet & _rSource)1164 sal_Bool ODbDataSourceAdministrationHelper::saveChanges(const SfxItemSet& _rSource)
1165 {
1166 // put the remembered settings into the property set
1167 Reference<XPropertySet> xDatasource = getCurrentDataSource();
1168 if ( !xDatasource.is() )
1169 return sal_False;
1170
1171 translateProperties(_rSource,xDatasource );
1172
1173 return sal_True;
1174 }
1175 // -----------------------------------------------------------------------------
setDataSourceOrName(const Any & _rDataSourceOrName)1176 void ODbDataSourceAdministrationHelper::setDataSourceOrName( const Any& _rDataSourceOrName )
1177 {
1178 DBG_ASSERT( !m_aDataSourceOrName.hasValue(), "ODbDataSourceAdministrationHelper::setDataSourceOrName: already have one!" );
1179 // hmm. We could reset m_xDatasource/m_xModel, probably, and continue working
1180 m_aDataSourceOrName = _rDataSourceOrName;
1181 }
1182 //=========================================================================
1183 //= DbuTypeCollectionItem
1184 //=========================================================================
1185 TYPEINIT1(DbuTypeCollectionItem, SfxPoolItem);
1186 //-------------------------------------------------------------------------
DbuTypeCollectionItem(sal_Int16 _nWhich,::dbaccess::ODsnTypeCollection * _pCollection)1187 DbuTypeCollectionItem::DbuTypeCollectionItem(sal_Int16 _nWhich, ::dbaccess::ODsnTypeCollection* _pCollection)
1188 :SfxPoolItem(_nWhich)
1189 ,m_pCollection(_pCollection)
1190 {
1191 }
1192
1193 //-------------------------------------------------------------------------
DbuTypeCollectionItem(const DbuTypeCollectionItem & _rSource)1194 DbuTypeCollectionItem::DbuTypeCollectionItem(const DbuTypeCollectionItem& _rSource)
1195 :SfxPoolItem(_rSource)
1196 ,m_pCollection(_rSource.getCollection())
1197 {
1198 }
1199
1200 //-------------------------------------------------------------------------
operator ==(const SfxPoolItem & _rItem) const1201 int DbuTypeCollectionItem::operator==(const SfxPoolItem& _rItem) const
1202 {
1203 DbuTypeCollectionItem* pCompare = PTR_CAST(DbuTypeCollectionItem, &_rItem);
1204 return pCompare && (pCompare->getCollection() == getCollection());
1205 }
1206
1207 //-------------------------------------------------------------------------
Clone(SfxItemPool *) const1208 SfxPoolItem* DbuTypeCollectionItem::Clone(SfxItemPool* /*_pPool*/) const
1209 {
1210 return new DbuTypeCollectionItem(*this);
1211 }
1212
1213 //.........................................................................
1214 } // namespace dbaui
1215 //.........................................................................
1216