/**************************************************************
 * 
 * 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_dbui.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
//.........................................................................



