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