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