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