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