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 { 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 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 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 //======================================================================== 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 374 void ODbDataSourceAdministrationHelper::clearPassword() 375 { 376 if (m_pItemSetHelper->getWriteOutputSet()) 377 m_pItemSetHelper->getWriteOutputSet()->ClearItem(DSID_PASSWORD); 378 } 379 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 408 Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver() 409 { 410 return getDriver(getConnectionURL()); 411 } 412 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 493 sal_Bool ODbDataSourceAdministrationHelper::hasAuthentication(const SfxItemSet& _rSet) const 494 { 495 return DataSourceMetaData::getAuthentication( getDatasourceType( _rSet ) ) != AuthNone; 496 } 497 // ----------------------------------------------------------------------------- 498 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 { 612 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 //........................................................................ 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 // ----------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 1187 DbuTypeCollectionItem::DbuTypeCollectionItem(sal_Int16 _nWhich, ::dbaccess::ODsnTypeCollection* _pCollection) 1188 :SfxPoolItem(_nWhich) 1189 ,m_pCollection(_pCollection) 1190 { 1191 } 1192 1193 //------------------------------------------------------------------------- 1194 DbuTypeCollectionItem::DbuTypeCollectionItem(const DbuTypeCollectionItem& _rSource) 1195 :SfxPoolItem(_rSource) 1196 ,m_pCollection(_rSource.getCollection()) 1197 { 1198 } 1199 1200 //------------------------------------------------------------------------- 1201 int DbuTypeCollectionItem::operator==(const SfxPoolItem& _rItem) const 1202 { 1203 DbuTypeCollectionItem* pCompare = PTR_CAST(DbuTypeCollectionItem, &_rItem); 1204 return pCompare && (pCompare->getCollection() == getCollection()); 1205 } 1206 1207 //------------------------------------------------------------------------- 1208 SfxPoolItem* DbuTypeCollectionItem::Clone(SfxItemPool* /*_pPool*/) const 1209 { 1210 return new DbuTypeCollectionItem(*this); 1211 } 1212 1213 //......................................................................... 1214 } // namespace dbaui 1215 //......................................................................... 1216