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