xref: /trunk/main/dbaccess/source/ui/dlg/DbAdminImpl.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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