blob: 3023c542c1539502537cf1b662d206515906872f [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_dbaccess.hxx"
#include "DbAdminImpl.hxx"
#include "dsmeta.hxx"
#include <svl/poolitem.hxx>
#include <svl/itempool.hxx>
#include <svl/stritem.hxx>
#include <svl/intitem.hxx>
#include <svl/eitem.hxx>
#include "DriverSettings.hxx"
#include "IItemSetHelper.hxx"
#include "UITools.hxx"
#include "dbu_dlg.hrc"
#include "dbustrings.hrc"
#include "dsitems.hxx"
#include "dsnItem.hxx"
#include "moduledbu.hxx"
#include "optionalboolitem.hxx"
#include "propertysetitem.hxx"
#include "stringlistitem.hxx"
#include "OAuthenticationContinuation.hxx"
/** === begin UNO includes === **/
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/sdb/SQLContext.hpp>
#include <com/sun/star/sdbc/XDriver.hpp>
#include <com/sun/star/sdbc/XDriverAccess.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/task/XInteractionRequest.hpp>
#include <com/sun/star/ucb/XInteractionSupplyAuthentication2.hpp>
#include <com/sun/star/ucb/AuthenticationRequest.hpp>
/** === end UNO includes === **/
#include <comphelper/interaction.hxx>
#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/guarding.hxx>
#include <connectivity/DriversConfig.hxx>
#include <connectivity/dbexception.hxx>
#include <osl/file.hxx>
#include <svl/eitem.hxx>
#include <svl/intitem.hxx>
#include <svl/itempool.hxx>
#include <svl/poolitem.hxx>
#include <svl/stritem.hxx>
#include <tools/urlobj.hxx>
#include <tools/diagnose_ex.h>
#include <typelib/typedescription.hxx>
#include <vcl/svapp.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/waitobj.hxx>
#include <vos/mutex.hxx>
#include <algorithm>
#include <functional>
//.........................................................................
namespace dbaui
{
//.........................................................................
using namespace ::dbtools;
using namespace com::sun::star::uno;
using namespace com::sun::star;
using namespace com::sun::star::ucb;
using namespace com::sun::star::task;
using namespace com::sun::star::sdbc;
using namespace com::sun::star::sdb;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::util;
using namespace com::sun::star::container;
using namespace com::sun::star::frame;
//-------------------------------------------------------------------------
namespace
{
sal_Bool implCheckItemType( SfxItemSet& _rSet, const sal_uInt16 _nId, const TypeId _nExpectedItemType )
{
sal_Bool bCorrectType = sal_False;
SfxItemPool* pPool = _rSet.GetPool();
DBG_ASSERT( pPool, "implCheckItemType: invalid item pool!" );
if ( pPool )
{
const SfxPoolItem& rDefItem = pPool->GetDefaultItem( _nId );
bCorrectType = rDefItem.IsA( _nExpectedItemType );
}
return bCorrectType;
}
void lcl_putProperty(const Reference< XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const Any& _rValue)
{
try
{
if ( _rxSet.is() )
_rxSet->setPropertyValue(_rName, _rValue);
}
catch(Exception&)
{
#ifdef DBG_UTIL
::rtl::OString sMessage("ODbAdminDialog::implTranslateProperty: could not set the property ");
sMessage += ::rtl::OString(_rName.getStr(), _rName.getLength(), RTL_TEXTENCODING_ASCII_US);
sMessage += ::rtl::OString("!");
DBG_ERROR(sMessage.getStr());
#endif
}
}
String lcl_createHostWithPort(const SfxStringItem* _pHostName,const SfxInt32Item* _pPortNumber)
{
String sNewUrl;
if ( _pHostName && _pHostName->GetValue().Len() )
sNewUrl = _pHostName->GetValue();
if ( _pPortNumber )
{
sNewUrl += String::CreateFromAscii(":");
sNewUrl += String::CreateFromInt32(_pPortNumber->GetValue());
}
return sNewUrl;
}
}
//========================================================================
//= ODbDataSourceAdministrationHelper
//========================================================================
ODbDataSourceAdministrationHelper::ODbDataSourceAdministrationHelper(const Reference< XMultiServiceFactory >& _xORB,Window* _pParent,IItemSetHelper* _pItemSetHelper)
: m_xORB(_xORB)
, m_pParent(_pParent)
, m_pItemSetHelper(_pItemSetHelper)
{
/// initialize the property translation map
// direct properties of a data source
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_CONNECTURL, PROPERTY_URL));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_NAME, PROPERTY_NAME));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_USER, PROPERTY_USER));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_PASSWORD, PROPERTY_PASSWORD));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_PASSWORDREQUIRED, PROPERTY_ISPASSWORDREQUIRED));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_TABLEFILTER, PROPERTY_TABLEFILTER));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_READONLY, PROPERTY_ISREADONLY));
m_aDirectPropTranslator.insert(MapInt2String::value_type(DSID_SUPPRESSVERSIONCL, PROPERTY_SUPPRESSVERSIONCL));
// implicit properties, to be found in the direct property "Info"
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_JDBCDRIVERCLASS, INFO_JDBCDRIVERCLASS));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTFILEEXTENSION, INFO_TEXTFILEEXTENSION));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CHARSET, INFO_CHARSET));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTFILEHEADER, INFO_TEXTFILEHEADER));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_FIELDDELIMITER, INFO_FIELDDELIMITER));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_TEXTDELIMITER, INFO_TEXTDELIMITER));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DECIMALDELIMITER, INFO_DECIMALDELIMITER));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_THOUSANDSDELIMITER, INFO_THOUSANDSDELIMITER));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SHOWDELETEDROWS, INFO_SHOWDELETEDROWS));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ALLOWLONGTABLENAMES, INFO_ALLOWLONGTABLENAMES));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ADDITIONALOPTIONS, INFO_ADDITIONALOPTIONS));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SQL92CHECK, PROPERTY_ENABLESQL92CHECK));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AUTOINCREMENTVALUE, PROPERTY_AUTOINCREMENTCREATION));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AUTORETRIEVEVALUE, INFO_AUTORETRIEVEVALUE));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AUTORETRIEVEENABLED, INFO_AUTORETRIEVEENABLED));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_APPEND_TABLE_ALIAS, INFO_APPEND_TABLE_ALIAS));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_AS_BEFORE_CORRNAME, INFO_AS_BEFORE_CORRELATION_NAME ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CHECK_REQUIRED_FIELDS, INFO_FORMS_CHECK_REQUIRED_FIELDS ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ESCAPE_DATETIME, INFO_ESCAPE_DATETIME ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_PRIMARY_KEY_SUPPORT, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrimaryKeySupport" ) ) ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_PARAMETERNAMESUBST, INFO_PARAMETERNAMESUBST));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_IGNOREDRIVER_PRIV, INFO_IGNOREDRIVER_PRIV));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_BOOLEANCOMPARISON, PROPERTY_BOOLEANCOMPARISONMODE));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_ENABLEOUTERJOIN, PROPERTY_ENABLEOUTERJOIN));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CATALOG, PROPERTY_USECATALOGINSELECT));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_SCHEMA, PROPERTY_USESCHEMAINSELECT));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_INDEXAPPENDIX, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AddIndexAppendix"))));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DOSLINEENDS, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PreferDosLikeLineEnds" ) ) ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_SOCKET, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "LocalSocket" ) ) ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_NAMED_PIPE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "NamedPipe" ) ) ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_RESPECTRESULTSETTYPE, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "RespectDriverResultSetType" ) ) ) );
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_MAX_ROW_SCAN, ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MaxRowScan" ) ) ) );
// special settings for adabas
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_SHUTSERVICE, ::rtl::OUString::createFromAscii("ShutdownDatabase")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_DATAINC, ::rtl::OUString::createFromAscii("DataCacheSizeIncrement")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CACHESIZE, ::rtl::OUString::createFromAscii("DataCacheSize")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CTRLUSER, ::rtl::OUString::createFromAscii("ControlUser")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_CTRLPWD, ::rtl::OUString::createFromAscii("ControlPassword")));
// extra settings for odbc
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_USECATALOG, INFO_USECATALOG));
// extra settings for a ldap address book
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_BASEDN, INFO_CONN_LDAP_BASEDN));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_ROWCOUNT, INFO_CONN_LDAP_ROWCOUNT));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_CONN_LDAP_USESSL, ::rtl::OUString::createFromAscii("UseSSL")));
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_DOCUMENT_URL, PROPERTY_URL));
// oracle
m_aIndirectPropTranslator.insert(MapInt2String::value_type(DSID_IGNORECURRENCY, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("IgnoreCurrency"))));
try
{
m_xDatabaseContext = Reference< XNameAccess >(m_xORB->createInstance(SERVICE_SDB_DATABASECONTEXT), UNO_QUERY);
m_xDynamicContext.set(m_xDatabaseContext,UNO_QUERY);
}
catch(Exception&)
{
}
if ( !m_xDatabaseContext.is() )
{
ShowServiceNotAvailableError(_pParent->GetParent(), String(SERVICE_SDB_DATABASECONTEXT), sal_True);
}
DBG_ASSERT(m_xDynamicContext.is(), "ODbAdminDialog::ODbAdminDialog : no XNamingService interface !");
}
//-------------------------------------------------------------------------
sal_Bool ODbDataSourceAdministrationHelper::getCurrentSettings(Sequence< PropertyValue >& _rDriverParam)
{
DBG_ASSERT(m_pItemSetHelper->getOutputSet(), "ODbDataSourceAdministrationHelper::getCurrentSettings : not to be called without an example set!");
if (!m_pItemSetHelper->getOutputSet())
return sal_False;
::std::vector< PropertyValue > aReturn;
// collecting this in a vector because it has a push_back, in opposite to sequences
// user: DSID_USER -> "user"
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pUser, SfxStringItem, DSID_USER, sal_True);
if (pUser && pUser->GetValue().Len())
aReturn.push_back(
PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("user")), 0,
makeAny(::rtl::OUString(pUser->GetValue())), PropertyState_DIRECT_VALUE));
// check if the connection type requires a password
if (hasAuthentication(*m_pItemSetHelper->getOutputSet()))
{
// password: DSID_PASSWORD -> "password"
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPassword, SfxStringItem, DSID_PASSWORD, sal_True);
String sPassword = pPassword ? pPassword->GetValue() : String();
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPasswordRequired, SfxBoolItem, DSID_PASSWORDREQUIRED, sal_True);
// if the set does not contain a password, but the item set says it requires one, ask the user
if ((!pPassword || !pPassword->GetValue().Len()) && (pPasswordRequired && pPasswordRequired->GetValue()))
{
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pName, SfxStringItem, DSID_NAME, sal_True);
Reference< XModel > xModel( getDataSourceOrModel( m_xDatasource ), UNO_QUERY_THROW );
::comphelper::NamedValueCollection aArgs( xModel->getArgs() );
Reference< XInteractionHandler > xHandler( aArgs.getOrDefault( "InteractionHandler", Reference< XInteractionHandler >() ) );
if ( !xHandler.is() )
{
// instantiate the default SDB interaction handler
xHandler = Reference< XInteractionHandler >( m_xORB->createInstance( SERVICE_TASK_INTERACTION_HANDLER ), UNO_QUERY );
if ( !xHandler.is() )
ShowServiceNotAvailableError(m_pParent->GetParent(), String(SERVICE_TASK_INTERACTION_HANDLER), sal_True);
}
String sName = pName ? pName->GetValue() : String();
String sLoginRequest(ModuleRes(STR_ENTER_CONNECTION_PASSWORD));
::rtl::OUString sTemp = sName;
sName = ::dbaui::getStrippedDatabaseName(NULL,sTemp);
if ( sName.Len() )
sLoginRequest.SearchAndReplaceAscii("$name$", sName);
else
{
sLoginRequest.SearchAndReplaceAscii("\"$name$\"", String());
sLoginRequest.SearchAndReplaceAscii("$name$", String()); // just to be sure that in other languages the string will be deleted
}
// the request
AuthenticationRequest aRequest;
aRequest.ServerName = sName;
aRequest.Diagnostic = sLoginRequest;
aRequest.HasRealm = aRequest.HasAccount = sal_False;
// aRequest.Realm
aRequest.HasUserName = pUser != 0;
aRequest.UserName = pUser ? rtl::OUString(pUser->GetValue()) : ::rtl::OUString();
aRequest.HasPassword = sal_True;
//aRequest.Password
aRequest.HasAccount = sal_False;
// aRequest.Account
comphelper::OInteractionRequest* pRequest = new comphelper::OInteractionRequest(makeAny(aRequest));
uno::Reference< XInteractionRequest > xRequest(pRequest);
// build an interaction request
// two continuations (Ok and Cancel)
::rtl::Reference< comphelper::OInteractionAbort > pAbort = new comphelper::OInteractionAbort;
::rtl::Reference< dbaccess::OAuthenticationContinuation > pAuthenticate = new dbaccess::OAuthenticationContinuation;
pAuthenticate->setCanChangeUserName( sal_False );
pAuthenticate->setRememberPassword( RememberAuthentication_SESSION );
// some knittings
pRequest->addContinuation(pAbort.get());
pRequest->addContinuation(pAuthenticate.get());
// handle the request
try
{
::vos::OGuard aSolarGuard(Application::GetSolarMutex());
// release the mutex when calling the handler, it may need to lock the SolarMutex
xHandler->handle(xRequest);
}
catch(Exception&)
{
DBG_UNHANDLED_EXCEPTION();
}
if (!pAuthenticate->wasSelected())
return sal_False;
sPassword = pAuthenticate->getPassword();
if (pAuthenticate->getRememberPassword())
m_pItemSetHelper->getWriteOutputSet()->Put(SfxStringItem(DSID_PASSWORD, sPassword));
}
if (sPassword.Len())
aReturn.push_back(
PropertyValue( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("password")), 0,
makeAny(::rtl::OUString(sPassword)), PropertyState_DIRECT_VALUE));
}
if ( !aReturn.empty() )
_rDriverParam = Sequence< PropertyValue >(&(*aReturn.begin()), aReturn.size());
// append all the other stuff (charset etc.)
fillDatasourceInfo(*m_pItemSetHelper->getOutputSet(), _rDriverParam);
return sal_True;
}
//-------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::successfullyConnected()
{
DBG_ASSERT(m_pItemSetHelper->getOutputSet(), "ODbDataSourceAdministrationHelper::successfullyConnected: not to be called without an example set!");
if (!m_pItemSetHelper->getOutputSet())
return;
if (hasAuthentication(*m_pItemSetHelper->getOutputSet()))
{
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPassword, SfxStringItem, DSID_PASSWORD, sal_True);
if (pPassword && (0 != pPassword->GetValue().Len()))
{
::rtl::OUString sPassword = pPassword->GetValue();
Reference< XPropertySet > xCurrentDatasource = getCurrentDataSource();
lcl_putProperty(xCurrentDatasource,m_aDirectPropTranslator[DSID_PASSWORD], makeAny(sPassword));
}
}
}
//-------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::clearPassword()
{
if (m_pItemSetHelper->getWriteOutputSet())
m_pItemSetHelper->getWriteOutputSet()->ClearItem(DSID_PASSWORD);
}
// -----------------------------------------------------------------------------
::std::pair< Reference<XConnection>,sal_Bool> ODbDataSourceAdministrationHelper::createConnection()
{
::std::pair< Reference<XConnection>,sal_Bool> aRet;
aRet.second = sal_False;
Sequence< PropertyValue > aConnectionParams;
if ( getCurrentSettings(aConnectionParams) )
{
// the current DSN
// fill the table list with this connection information
SQLExceptionInfo aErrorInfo;
try
{
WaitObject aWaitCursor(m_pParent);
aRet.first = getDriver()->connect(getConnectionURL(), aConnectionParams);
aRet.second = sal_True;
}
catch (SQLContext& e) { aErrorInfo = SQLExceptionInfo(e); }
catch (SQLWarning& e) { aErrorInfo = SQLExceptionInfo(e); }
catch (SQLException& e) { aErrorInfo = SQLExceptionInfo(e); }
showError(aErrorInfo,m_pParent,getORB());
}
if ( aRet.first.is() )
successfullyConnected();// notify the admindlg to save the password
return aRet;
}
// -----------------------------------------------------------------------------
Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver()
{
return getDriver(getConnectionURL());
}
// -----------------------------------------------------------------------------
Reference< XDriver > ODbDataSourceAdministrationHelper::getDriver(const ::rtl::OUString& _sURL)
{
// get the global DriverManager
Reference< XDriverAccess > xDriverManager;
String sCurrentActionError = String(ModuleRes(STR_COULDNOTCREATE_DRIVERMANAGER));
// in case an error occures
sCurrentActionError.SearchAndReplaceAscii("#servicename#", (::rtl::OUString)SERVICE_SDBC_CONNECTIONPOOL);
try
{
xDriverManager = Reference< XDriverAccess >(getORB()->createInstance(SERVICE_SDBC_CONNECTIONPOOL), UNO_QUERY);
DBG_ASSERT(xDriverManager.is(), "ODbDataSourceAdministrationHelper::getDriver: could not instantiate the driver manager, or it does not provide the necessary interface!");
}
catch (Exception& e)
{
// wrap the exception into an SQLException
SQLException aSQLWrapper(e.Message, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, makeAny(aSQLWrapper));
}
if (!xDriverManager.is())
throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
Reference< XDriver > xDriver = xDriverManager->getDriverByURL(_sURL);
if (!xDriver.is())
{
sCurrentActionError = String(ModuleRes(STR_NOREGISTEREDDRIVER));
sCurrentActionError.SearchAndReplaceAscii("#connurl#", _sURL);
// will be caught and translated into an SQLContext exception
throw SQLException(sCurrentActionError, getORB(), ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("S1000")), 0, Any());
}
return xDriver;
}
// -----------------------------------------------------------------------------
Reference< XPropertySet > ODbDataSourceAdministrationHelper::getCurrentDataSource()
{
if ( !m_xDatasource.is() )
{
Reference<XInterface> xIn(m_aDataSourceOrName,UNO_QUERY);
if ( !xIn.is() )
{
::rtl::OUString sCurrentDatasource;
m_aDataSourceOrName >>= sCurrentDatasource;
OSL_ENSURE(sCurrentDatasource.getLength(),"No datasource name given!");
try
{
if ( m_xDatabaseContext.is() )
m_xDatasource.set(m_xDatabaseContext->getByName(sCurrentDatasource),UNO_QUERY);
xIn = m_xDatasource;
}
catch(const Exception&)
{
}
}
m_xModel.set(getDataSourceOrModel(xIn),UNO_QUERY);
if ( m_xModel.is() )
m_xDatasource.set(xIn,UNO_QUERY);
else
{
m_xDatasource.set(getDataSourceOrModel(xIn),UNO_QUERY);
m_xModel.set(xIn,UNO_QUERY);
}
}
DBG_ASSERT(m_xDatasource.is(), "ODbDataSourceAdministrationHelper::getCurrentDataSource: no data source!");
return m_xDatasource;
}
//-------------------------------------------------------------------------
::rtl::OUString ODbDataSourceAdministrationHelper::getDatasourceType( const SfxItemSet& _rSet )
{
SFX_ITEMSET_GET( _rSet, pConnectURL, SfxStringItem, DSID_CONNECTURL, sal_True );
DBG_ASSERT( pConnectURL , "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!" );
SFX_ITEMSET_GET(_rSet, pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
DBG_ASSERT(pTypeCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!");
::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
return pCollection->getType(pConnectURL->GetValue());
}
//-------------------------------------------------------------------------
sal_Bool ODbDataSourceAdministrationHelper::hasAuthentication(const SfxItemSet& _rSet) const
{
return DataSourceMetaData::getAuthentication( getDatasourceType( _rSet ) ) != AuthNone;
}
// -----------------------------------------------------------------------------
String ODbDataSourceAdministrationHelper::getConnectionURL() const
{
String sNewUrl;
::rtl::OUString eType = getDatasourceType(*m_pItemSetHelper->getOutputSet());
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
OSL_ENSURE(pUrlItem,"Connection URL is NULL. -> GPF!");
DBG_ASSERT(pTypeCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid items in the source set!");
::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
DBG_ASSERT(pCollection, "ODbDataSourceAdministrationHelper::getDatasourceType: invalid type collection!");
switch( pCollection->determineType(eType) )
{
case ::dbaccess::DST_DBASE:
case ::dbaccess::DST_FLAT:
case ::dbaccess::DST_CALC:
break;
case ::dbaccess::DST_ADABAS:
{
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
sNewUrl = lcl_createHostWithPort(pHostName,NULL);
String sUrl = pCollection->cutPrefix(pUrlItem->GetValue());
if ( sUrl.GetTokenCount(':') == 1 )
sNewUrl += String::CreateFromAscii(":");
sNewUrl += sUrl;
}
break;
case ::dbaccess::DST_MSACCESS:
case ::dbaccess::DST_MSACCESS_2007:
{
::rtl::OUString sFileName = pCollection->cutPrefix(pUrlItem->GetValue());
::rtl::OUString sNewFileName;
if ( ::osl::FileBase::getSystemPathFromFileURL( sFileName, sNewFileName ) == ::osl::FileBase::E_None )
{
sNewUrl += String(sNewFileName);
}
}
break;
case ::dbaccess::DST_MYSQL_NATIVE:
case ::dbaccess::DST_MYSQL_JDBC:
{
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPortNumber, SfxInt32Item, DSID_MYSQL_PORTNUMBER, sal_True);
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pDatabaseName, SfxStringItem, DSID_DATABASENAME, sal_True);
sNewUrl = lcl_createHostWithPort(pHostName,pPortNumber);
String sDatabaseName = pDatabaseName ? pDatabaseName->GetValue() : String();
if ( !sDatabaseName.Len() && pUrlItem )
sDatabaseName = pCollection->cutPrefix( pUrlItem->GetValue() );
// TODO: what's that? Why is the database name transported via the URL Item?
// Huh? Anybody there?
// OJ: It is needed when the connection properties are changed. There the URL is used for every type.
if ( sDatabaseName.Len() )
{
sNewUrl += String::CreateFromAscii("/");
sNewUrl += sDatabaseName;
}
}
break;
case ::dbaccess::DST_ORACLE_JDBC:
{
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPortNumber, SfxInt32Item, DSID_ORACLE_PORTNUMBER, sal_True);
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pDatabaseName, SfxStringItem, DSID_DATABASENAME, sal_True);
if ( pHostName && pHostName->GetValue().Len() )
{
sNewUrl = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("@"));
sNewUrl += lcl_createHostWithPort(pHostName,pPortNumber);
String sDatabaseName = pDatabaseName ? pDatabaseName->GetValue() : String();
if ( !sDatabaseName.Len() && pUrlItem )
sDatabaseName = pCollection->cutPrefix( pUrlItem->GetValue() );
if ( sDatabaseName.Len() )
{
sNewUrl += String::CreateFromAscii(":");
sNewUrl += sDatabaseName;
}
}
else
{ // here someone entered a JDBC url which looks like oracle, so we have to use the url property
}
}
break;
case ::dbaccess::DST_LDAP:
{
// SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pHostName, SfxStringItem, DSID_CONN_HOSTNAME, sal_True);
SFX_ITEMSET_GET(*m_pItemSetHelper->getOutputSet(), pPortNumber, SfxInt32Item, DSID_CONN_LDAP_PORTNUMBER, sal_True);
sNewUrl = pCollection->cutPrefix(pUrlItem->GetValue());
sNewUrl += lcl_createHostWithPort(NULL,pPortNumber);
}
break;
case ::dbaccess::DST_JDBC:
// run through
default:
break;
}
if ( sNewUrl.Len() )
{
String sUrl = pCollection->getPrefix(eType);
sUrl += sNewUrl;
sNewUrl = sUrl;
}
else
sNewUrl = pUrlItem->GetValue();
return sNewUrl;
}
//-------------------------------------------------------------------------
struct PropertyValueLess
{
bool operator() (const PropertyValue& x, const PropertyValue& y) const
{ return x.Name < y.Name ? true : false; } // construct prevents a MSVC6 warning
};
DECLARE_STL_SET( PropertyValue, PropertyValueLess, PropertyValueSet);
//........................................................................
void ODbDataSourceAdministrationHelper::translateProperties(const Reference< XPropertySet >& _rxSource, SfxItemSet& _rDest)
{
::rtl::OUString sNewConnectURL, sName, sUid, sPwd;
Sequence< ::rtl::OUString > aTableFitler;
if (_rxSource.is())
{
for ( ConstMapInt2StringIterator aDirect = m_aDirectPropTranslator.begin();
aDirect != m_aDirectPropTranslator.end();
++aDirect
)
{
// get the property value
Any aValue;
try
{
aValue = _rxSource->getPropertyValue(aDirect->second);
}
catch(Exception&)
{
#ifdef DBG_UTIL
::rtl::OString aMessage("ODbDataSourceAdministrationHelper::translateProperties: could not extract the property ");
aMessage += ::rtl::OString(aDirect->second.getStr(), aDirect->second.getLength(), RTL_TEXTENCODING_ASCII_US);
aMessage += ::rtl::OString("!");
DBG_ERROR(aMessage.getStr());
#endif
}
// transfer it into an item
implTranslateProperty(_rDest, aDirect->first, aValue);
}
// get the additional informations
Sequence< PropertyValue > aAdditionalInfo;
try
{
_rxSource->getPropertyValue(PROPERTY_INFO) >>= aAdditionalInfo;
}
catch(Exception&) { }
// collect the names of the additional settings
const PropertyValue* pAdditionalInfo = aAdditionalInfo.getConstArray();
PropertyValueSet aInfos;
for (sal_Int32 i=0; i<aAdditionalInfo.getLength(); ++i, ++pAdditionalInfo)
{
if (0 == pAdditionalInfo->Name.compareToAscii("JDBCDRV"))
{ // compatibility
PropertyValue aCompatibility(*pAdditionalInfo);
aCompatibility.Name = ::rtl::OUString::createFromAscii("JavaDriverClass");
aInfos.insert(aCompatibility);
}
else
aInfos.insert(*pAdditionalInfo);
}
// go through all known translations and check if we have such a setting
if ( !aInfos.empty() )
{
PropertyValue aSearchFor;
ConstMapInt2StringIterator aEnd = m_aIndirectPropTranslator.end();
for ( ConstMapInt2StringIterator aIndirect = m_aIndirectPropTranslator.begin();
aIndirect != aEnd;
++aIndirect)
{
aSearchFor.Name = aIndirect->second;
ConstPropertyValueSetIterator aInfoPos = aInfos.find(aSearchFor);
if (aInfos.end() != aInfoPos)
// the property is contained in the info sequence
// -> transfer it into an item
implTranslateProperty(_rDest, aIndirect->first, aInfoPos->Value);
}
}
convertUrl(_rDest);
}
try
{
_rDest.Put(OPropertySetItem(DSID_DATASOURCE_UNO, _rxSource));
Reference<XStorable> xStore(getDataSourceOrModel(_rxSource),UNO_QUERY);
_rDest.Put(SfxBoolItem(DSID_READONLY, !xStore.is() || xStore->isReadonly() ));
}
catch(Exception&)
{
OSL_ENSURE(0,"IsReadOnly throws an exception!");
}
}
//-------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::translateProperties(const SfxItemSet& _rSource, const Reference< XPropertySet >& _rxDest)
{
DBG_ASSERT(_rxDest.is(), "ODbDataSourceAdministrationHelper::translateProperties: invalid property set!");
if (!_rxDest.is())
return;
// the property set info
Reference< XPropertySetInfo > xInfo;
try { xInfo = _rxDest->getPropertySetInfo(); }
catch(Exception&) { }
const ::rtl::OUString sUrlProp(RTL_CONSTASCII_USTRINGPARAM("URL"));
// -----------------------------
// transfer the direct properties
for ( ConstMapInt2StringIterator aDirect = m_aDirectPropTranslator.begin();
aDirect != m_aDirectPropTranslator.end();
++aDirect
)
{
const SfxPoolItem* pCurrentItem = _rSource.GetItem((sal_uInt16)aDirect->first);
if (pCurrentItem)
{
sal_Int16 nAttributes = PropertyAttribute::READONLY;
if (xInfo.is())
{
try { nAttributes = xInfo->getPropertyByName(aDirect->second).Attributes; }
catch(Exception&) { }
}
if ((nAttributes & PropertyAttribute::READONLY) == 0)
{
if ( sUrlProp == aDirect->second )
{
Any aValue(makeAny(::rtl::OUString(getConnectionURL())));
// aValue <<= ::rtl::OUString();
lcl_putProperty(_rxDest, aDirect->second,aValue);
}
else
implTranslateProperty(_rxDest, aDirect->second, pCurrentItem);
}
}
}
// -------------------------------
// now for the indirect properties
Sequence< PropertyValue > aInfo;
// the original properties
try
{
_rxDest->getPropertyValue(PROPERTY_INFO) >>= aInfo;
}
catch(Exception&) { }
// overwrite and extend them
fillDatasourceInfo(_rSource, aInfo);
// and propagate the (newly composed) sequence to the set
lcl_putProperty(_rxDest,PROPERTY_INFO, makeAny(aInfo));
}
//-------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::fillDatasourceInfo(const SfxItemSet& _rSource, Sequence< ::com::sun::star::beans::PropertyValue >& _rInfo)
{
// within the current "Info" sequence, replace the ones we can examine from the item set
// (we don't just fill a completely new sequence with our own items, but we preserve any properties unknown to
// us)
// first determine which of all the items are relevant for the data source (depends on the connection url)
::rtl::OUString eType = getDatasourceType(_rSource);
::std::vector< sal_Int32> aDetailIds;
ODriversSettings::getSupportedIndirectSettings(eType,getORB(),aDetailIds);
// collect the translated property values for the relevant items
PropertyValueSet aRelevantSettings;
ConstMapInt2StringIterator aTranslation;
::std::vector< sal_Int32>::iterator aDetailsEnd = aDetailIds.end();
for (::std::vector< sal_Int32>::iterator aIter = aDetailIds.begin();aIter != aDetailsEnd ; ++aIter)
{
const SfxPoolItem* pCurrent = _rSource.GetItem((sal_uInt16)*aIter);
aTranslation = m_aIndirectPropTranslator.find(*aIter);
if ( pCurrent && (m_aIndirectPropTranslator.end() != aTranslation) )
{
if ( aTranslation->second == INFO_CHARSET )
{
::rtl::OUString sCharSet;
implTranslateProperty(pCurrent) >>= sCharSet;
if ( sCharSet.getLength() )
aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, makeAny(sCharSet), PropertyState_DIRECT_VALUE));
}
else
aRelevantSettings.insert(PropertyValue(aTranslation->second, 0, implTranslateProperty(pCurrent), PropertyState_DIRECT_VALUE));
}
}
// settings to preserve
MapInt2String aPreservedSettings;
// now aRelevantSettings contains all the property values relevant for the current data source type,
// check the original sequence if it already contains any of these values (which have to be overwritten, then)
PropertyValue* pInfo = _rInfo.getArray();
PropertyValue aSearchFor;
sal_Int32 nObsoleteSetting = -1;
sal_Int32 nCount = _rInfo.getLength();
for (sal_Int32 i = 0; i < nCount; ++i, ++pInfo)
{
aSearchFor.Name = pInfo->Name;
PropertyValueSetIterator aOverwrittenSetting = aRelevantSettings.find(aSearchFor);
if (aRelevantSettings.end() != aOverwrittenSetting)
{ // the setting was present in the original sequence, and it is to be overwritten -> replace it
if ( !::comphelper::compare(pInfo->Value,aOverwrittenSetting->Value) )
*pInfo = *aOverwrittenSetting;
aRelevantSettings.erase(aOverwrittenSetting);
}
else if (0 == pInfo->Name.compareToAscii("JDBCDRV"))
{ // this is a compatibility setting, remove it from the sequence (it's replaced by JavaDriverClass)
nObsoleteSetting = i;
}
else
aPreservedSettings[i] = pInfo->Name;
}
if (-1 != nObsoleteSetting)
::comphelper::removeElementAt(_rInfo, nObsoleteSetting);
if ( !aPreservedSettings.empty() )
{ // check if there are settings which
// * are known as indirect properties
// * but not relevant for the current data source type
// These settings have to be removed: If they're not relevant, we have no UI for changing them.
// 25.06.2001 - 88004/87182 - frank.schoenheit@sun.com
// for this, we need a string-controlled quick access to m_aIndirectPropTranslator
StringSet aIndirectProps;
::std::transform(m_aIndirectPropTranslator.begin(),
m_aIndirectPropTranslator.end(),
::std::insert_iterator<StringSet>(aIndirectProps,aIndirectProps.begin()),
::std::select2nd<MapInt2String::value_type>());
// now check the to-be-preserved props
::std::vector< sal_Int32 > aRemoveIndexes;
sal_Int32 nPositionCorrector = 0;
ConstMapInt2StringIterator aPreservedEnd = aPreservedSettings.end();
for ( ConstMapInt2StringIterator aPreserved = aPreservedSettings.begin();
aPreserved != aPreservedEnd;
++aPreserved
)
{
if (aIndirectProps.end() != aIndirectProps.find(aPreserved->second))
{
#ifdef DBG_UTIL
const ::rtl::OUString sName = aPreserved->second;
#endif
aRemoveIndexes.push_back(aPreserved->first - nPositionCorrector);
++nPositionCorrector;
}
}
// now finally remove all such props
::std::vector< sal_Int32 >::const_iterator aRemoveEnd = aRemoveIndexes.end();
for ( ::std::vector< sal_Int32 >::const_iterator aRemoveIndex = aRemoveIndexes.begin();
aRemoveIndex != aRemoveEnd;
++aRemoveIndex
)
::comphelper::removeElementAt(_rInfo, *aRemoveIndex);
#ifdef DBG_UTIL
const PropertyValue* pWhatsLeft = _rInfo.getConstArray();
const PropertyValue* pWhatsLeftEnd = pWhatsLeft + _rInfo.getLength();
for (; pWhatsLeft != pWhatsLeftEnd; ++pWhatsLeft)
{
::rtl::OUString sLookAtIt = pWhatsLeft->Name;
}
#endif
}
::connectivity::DriversConfig aDriverConfig(getORB());
const ::comphelper::NamedValueCollection& aProperties = aDriverConfig.getProperties(eType);
Sequence< Any> aTypeSettings;
aTypeSettings = aProperties.getOrDefault("TypeInfoSettings",aTypeSettings);
// here we have a special entry for types from oracle
if ( aTypeSettings.getLength() )
{
aRelevantSettings.insert(PropertyValue(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TypeInfoSettings")), 0, makeAny(aTypeSettings), PropertyState_DIRECT_VALUE));
}
// check which values are still left ('cause they were not present in the original sequence, but are to be set)
if ( !aRelevantSettings.empty() )
{
sal_Int32 nOldLength = _rInfo.getLength();
_rInfo.realloc(nOldLength + aRelevantSettings.size());
PropertyValue* pAppendValues = _rInfo.getArray() + nOldLength;
ConstPropertyValueSetIterator aRelevantEnd = aRelevantSettings.end();
for ( ConstPropertyValueSetIterator aLoop = aRelevantSettings.begin();
aLoop != aRelevantEnd;
++aLoop, ++pAppendValues
)
{
if ( aLoop->Name == INFO_CHARSET )
{
::rtl::OUString sCharSet;
aLoop->Value >>= sCharSet;
if ( sCharSet.getLength() )
*pAppendValues = *aLoop;
}
else
*pAppendValues = *aLoop;
}
}
}
//-------------------------------------------------------------------------
Any ODbDataSourceAdministrationHelper::implTranslateProperty(const SfxPoolItem* _pItem)
{
// translate the SfxPoolItem
Any aValue;
const SfxStringItem* pStringItem = PTR_CAST( SfxStringItem, _pItem );
const SfxBoolItem* pBoolItem = PTR_CAST( SfxBoolItem, _pItem );
const OptionalBoolItem* pOptBoolItem = PTR_CAST( OptionalBoolItem, _pItem );
const SfxInt32Item* pInt32Item = PTR_CAST( SfxInt32Item, _pItem );
const OStringListItem* pStringListItem = PTR_CAST( OStringListItem, _pItem );
if ( pStringItem )
{
aValue <<= ::rtl::OUString( pStringItem->GetValue().GetBuffer() );
}
else if ( pBoolItem )
{
aValue <<= pBoolItem->GetValue();
}
else if ( pOptBoolItem )
{
if ( !pOptBoolItem->HasValue() )
aValue.clear();
else
aValue <<= (sal_Bool)pOptBoolItem->GetValue();
}
else if ( pInt32Item )
{
aValue <<= pInt32Item->GetValue();
}
else if ( pStringListItem )
{
aValue <<= pStringListItem->getList();
}
else
{
DBG_ERROR("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported item type!");
return aValue;
}
return aValue;
}
//-------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::implTranslateProperty(const Reference< XPropertySet >& _rxSet, const ::rtl::OUString& _rName, const SfxPoolItem* _pItem)
{
Any aValue = implTranslateProperty(_pItem);
lcl_putProperty(_rxSet, _rName,aValue);
}
#ifdef DBG_UTIL
//-------------------------------------------------------------------------
::rtl::OString ODbDataSourceAdministrationHelper::translatePropertyId( sal_Int32 _nId )
{
::rtl::OUString aString;
MapInt2String::const_iterator aPos = m_aDirectPropTranslator.find( _nId );
if ( m_aDirectPropTranslator.end() != aPos )
{
aString = aPos->second;
}
else
{
MapInt2String::const_iterator indirectPos = m_aIndirectPropTranslator.find( _nId );
if ( m_aIndirectPropTranslator.end() != indirectPos )
aString = indirectPos->second;
}
::rtl::OString aReturn( aString.getStr(), aString.getLength(), RTL_TEXTENCODING_ASCII_US );
return aReturn;
}
#endif
//-------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::implTranslateProperty( SfxItemSet& _rSet, sal_Int32 _nId, const Any& _rValue )
{
switch ( _rValue.getValueType().getTypeClass() )
{
case TypeClass_STRING:
if ( implCheckItemType( _rSet, _nId, SfxStringItem::StaticType() ) )
{
::rtl::OUString sValue;
_rValue >>= sValue;
_rSet.Put(SfxStringItem(_nId, sValue.getStr()));
}
else {
DBG_ERROR(
( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
+= ::rtl::OString( translatePropertyId( _nId ) )
+= ::rtl::OString( " should be no string)!" )
).getStr()
);
}
break;
case TypeClass_BOOLEAN:
if ( implCheckItemType( _rSet, _nId, SfxBoolItem::StaticType() ) )
{
sal_Bool bVal = sal_False;
_rValue >>= bVal;
_rSet.Put(SfxBoolItem(_nId, bVal));
}
else if ( implCheckItemType( _rSet, _nId, OptionalBoolItem::StaticType() ) )
{
OptionalBoolItem aItem( _nId );
if ( _rValue.hasValue() )
{
sal_Bool bValue = sal_False;
_rValue >>= bValue;
aItem.SetValue( bValue );
}
else
aItem.ClearValue();
_rSet.Put( aItem );
}
else {
DBG_ERROR(
( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
+= ::rtl::OString( translatePropertyId( _nId ) )
+= ::rtl::OString( " should be no boolean)!" )
).getStr()
);
}
break;
case TypeClass_LONG:
if ( implCheckItemType( _rSet, _nId, SfxInt32Item::StaticType() ) )
{
sal_Int32 nValue = 0;
_rValue >>= nValue;
_rSet.Put( SfxInt32Item( _nId, nValue ) );
}
else {
DBG_ERROR(
( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
+= ::rtl::OString( translatePropertyId( _nId ) )
+= ::rtl::OString( " should be no int)!" )
).getStr()
);
}
break;
case TypeClass_SEQUENCE:
if ( implCheckItemType( _rSet, _nId, OStringListItem::StaticType() ) )
{
// determine the element type
TypeDescription aTD(_rValue.getValueType());
typelib_IndirectTypeDescription* pSequenceTD =
reinterpret_cast< typelib_IndirectTypeDescription* >(aTD.get());
DBG_ASSERT(pSequenceTD && pSequenceTD->pType, "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid sequence type!");
Type aElementType(pSequenceTD->pType);
switch (aElementType.getTypeClass())
{
case TypeClass_STRING:
{
Sequence< ::rtl::OUString > aStringList;
_rValue >>= aStringList;
_rSet.Put(OStringListItem(_nId, aStringList));
}
break;
default:
DBG_ERROR("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported property value type!");
}
}
else {
DBG_ERROR(
( ::rtl::OString( "ODbDataSourceAdministrationHelper::implTranslateProperty: invalid property value (" )
+= ::rtl::OString( translatePropertyId( _nId ) )
+= ::rtl::OString( " should be no string sequence)!" )
).getStr()
);
}
break;
case TypeClass_VOID:
_rSet.ClearItem(_nId);
break;
default:
DBG_ERROR("ODbDataSourceAdministrationHelper::implTranslateProperty: unsupported property value type!");
}
}
String ODbDataSourceAdministrationHelper::getDocumentUrl(SfxItemSet& _rDest)
{
SFX_ITEMSET_GET(_rDest, pUrlItem, SfxStringItem, DSID_DOCUMENT_URL, sal_True);
OSL_ENSURE(pUrlItem,"Document URL is NULL. -> GPF!");
return pUrlItem->GetValue();
}
// -----------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::convertUrl(SfxItemSet& _rDest)
{
::rtl::OUString eType = getDatasourceType(_rDest);
SFX_ITEMSET_GET(_rDest, pUrlItem, SfxStringItem, DSID_CONNECTURL, sal_True);
SFX_ITEMSET_GET(_rDest, pTypeCollection, DbuTypeCollectionItem, DSID_TYPECOLLECTION, sal_True);
OSL_ENSURE(pUrlItem,"Connection URL is NULL. -> GPF!");
DBG_ASSERT(pTypeCollection, "ODbAdminDialog::getDatasourceType: invalid items in the source set!");
::dbaccess::ODsnTypeCollection* pCollection = pTypeCollection->getCollection();
DBG_ASSERT(pCollection, "ODbAdminDialog::getDatasourceType: invalid type collection!");
sal_uInt16 nPortNumberId = 0;
sal_Int32 nPortNumber = -1;
String sNewHostName;
//String sUrl = pCollection->cutPrefix(pUrlItem->GetValue());
String sUrlPart;
pCollection->extractHostNamePort(pUrlItem->GetValue(),sUrlPart,sNewHostName,nPortNumber);
const ::dbaccess::DATASOURCE_TYPE eTy = pCollection->determineType(eType);
switch( eTy )
{
case ::dbaccess::DST_MYSQL_NATIVE:
case ::dbaccess::DST_MYSQL_JDBC:
nPortNumberId = DSID_MYSQL_PORTNUMBER;
break;
case ::dbaccess::DST_ORACLE_JDBC:
nPortNumberId = DSID_ORACLE_PORTNUMBER;
break;
case ::dbaccess::DST_LDAP:
nPortNumberId = DSID_CONN_LDAP_PORTNUMBER;
break;
default:
break;
}
if ( sUrlPart.Len() )
{
if ( eTy == ::dbaccess::DST_MYSQL_NATIVE )
{
_rDest.Put( SfxStringItem( DSID_DATABASENAME, sUrlPart ) );
}
else
{
String sNewUrl = pCollection->getPrefix(eType);
sNewUrl += sUrlPart;
_rDest.Put( SfxStringItem( DSID_CONNECTURL, sNewUrl ) );
}
}
if ( sNewHostName.Len() )
_rDest.Put(SfxStringItem(DSID_CONN_HOSTNAME, sNewHostName));
if ( nPortNumber != -1 && nPortNumberId != 0 )
_rDest.Put(SfxInt32Item(nPortNumberId, nPortNumber));
}
// -----------------------------------------------------------------------------
sal_Bool ODbDataSourceAdministrationHelper::saveChanges(const SfxItemSet& _rSource)
{
// put the remembered settings into the property set
Reference<XPropertySet> xDatasource = getCurrentDataSource();
if ( !xDatasource.is() )
return sal_False;
translateProperties(_rSource,xDatasource );
return sal_True;
}
// -----------------------------------------------------------------------------
void ODbDataSourceAdministrationHelper::setDataSourceOrName( const Any& _rDataSourceOrName )
{
DBG_ASSERT( !m_aDataSourceOrName.hasValue(), "ODbDataSourceAdministrationHelper::setDataSourceOrName: already have one!" );
// hmm. We could reset m_xDatasource/m_xModel, probably, and continue working
m_aDataSourceOrName = _rDataSourceOrName;
}
//=========================================================================
//= DbuTypeCollectionItem
//=========================================================================
TYPEINIT1(DbuTypeCollectionItem, SfxPoolItem);
//-------------------------------------------------------------------------
DbuTypeCollectionItem::DbuTypeCollectionItem(sal_Int16 _nWhich, ::dbaccess::ODsnTypeCollection* _pCollection)
:SfxPoolItem(_nWhich)
,m_pCollection(_pCollection)
{
}
//-------------------------------------------------------------------------
DbuTypeCollectionItem::DbuTypeCollectionItem(const DbuTypeCollectionItem& _rSource)
:SfxPoolItem(_rSource)
,m_pCollection(_rSource.getCollection())
{
}
//-------------------------------------------------------------------------
int DbuTypeCollectionItem::operator==(const SfxPoolItem& _rItem) const
{
DbuTypeCollectionItem* pCompare = PTR_CAST(DbuTypeCollectionItem, &_rItem);
return pCompare && (pCompare->getCollection() == getCollection());
}
//-------------------------------------------------------------------------
SfxPoolItem* DbuTypeCollectionItem::Clone(SfxItemPool* /*_pPool*/) const
{
return new DbuTypeCollectionItem(*this);
}
//.........................................................................
} // namespace dbaui
//.........................................................................