1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <dsntypes.hxx>
21 #include <unotools/confignode.hxx>
22 #include <osl/diagnose.h>
23 #include <svtools/miscopt.hxx>
24 #include <tools/wldcrd.hxx>
25 #include <osl/file.hxx>
26 #include <stringconstants.hxx>
27 #include <comphelper/documentconstants.hxx>
28 #include <comphelper/string.hxx>
29 
30 namespace dbaccess
31 {
32 
33     using namespace ::com::sun::star;
34     using namespace ::com::sun::star::uno;
35     using namespace ::com::sun::star::beans;
36     using namespace ::com::sun::star::lang;
37 
38     namespace
39     {
lcl_extractHostAndPort(const OUString & _sUrl,OUString & _sHostname,sal_Int32 & _nPortNumber)40         void lcl_extractHostAndPort(const OUString& _sUrl,OUString& _sHostname,sal_Int32& _nPortNumber)
41         {
42             if ( comphelper::string::getTokenCount(_sUrl, ':') >= 2 )
43             {
44                 sal_Int32 nPos {0};
45                 _sHostname   = _sUrl.getToken(0, ':', nPos);
46                 _nPortNumber = _sUrl.getToken(0, ':', nPos).toInt32();
47             }
48         }
49     }
50 // ODsnTypeCollection
ODsnTypeCollection(const css::uno::Reference<css::uno::XComponentContext> & _xContext)51 ODsnTypeCollection::ODsnTypeCollection(const css::uno::Reference< css::uno::XComponentContext >& _xContext)
52 :m_aDriverConfig(_xContext)
53 #if OSL_DEBUG_LEVEL > 0
54 ,m_nLivingIterators(0)
55 #endif
56 {
57     const uno::Sequence< OUString > aURLs = m_aDriverConfig.getURLs();
58     const OUString* pIter = aURLs.getConstArray();
59     const OUString* pEnd = pIter + aURLs.getLength();
60     for(;pIter != pEnd;++pIter )
61     {
62         m_aDsnPrefixes.push_back(*pIter);
63         m_aDsnTypesDisplayNames.push_back(m_aDriverConfig.getDriverTypeDisplayName(*pIter));
64     }
65 
66     OSL_ENSURE(m_aDsnTypesDisplayNames.size() == m_aDsnPrefixes.size(),
67         "ODsnTypeCollection::ODsnTypeCollection : invalid resources !");
68 }
69 
~ODsnTypeCollection()70 ODsnTypeCollection::~ODsnTypeCollection()
71 {
72 #if OSL_DEBUG_LEVEL > 0
73     OSL_ENSURE(0 == m_nLivingIterators, "ODsnTypeCollection::~ODsnTypeCollection : there are still living iterator objects!");
74 #endif
75 }
76 
getTypeDisplayName(const OUString & _sURL) const77 OUString ODsnTypeCollection::getTypeDisplayName(const OUString& _sURL) const
78 {
79     return m_aDriverConfig.getDriverTypeDisplayName(_sURL);
80 }
81 
cutPrefix(const OUString & _sURL) const82 OUString ODsnTypeCollection::cutPrefix(const OUString& _sURL) const
83 {
84     OUString sRet;
85     OUString sOldPattern;
86 
87     // on Windows or with gen rendering, the urls may begin with an ~
88     const OUString& sCleanURL = comphelper::string::stripStart(_sURL, '~');
89 
90     for (auto const& dsnPrefix : m_aDsnPrefixes)
91     {
92         WildCard aWildCard(dsnPrefix);
93         if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(sCleanURL) )
94         {
95             // This relies on the fact that all patterns are of the form
96             //   foo*
97             // that is, the very concept of "prefix" applies.
98             OUString prefix(comphelper::string::stripEnd(dsnPrefix, '*'));
99             OSL_ENSURE(prefix.getLength() <= sCleanURL.getLength(), "How can A match B when A shorter than B?");
100             sRet = sCleanURL.copy(prefix.getLength());
101             sOldPattern = dsnPrefix;
102         }
103     }
104 
105     return sRet;
106 }
107 
getPrefix(const OUString & _sURL) const108 OUString ODsnTypeCollection::getPrefix(const OUString& _sURL) const
109 {
110     OUString sRet;
111     OUString sOldPattern;
112     for (auto const& dsnPrefix : m_aDsnPrefixes)
113     {
114         WildCard aWildCard(dsnPrefix);
115         if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) )
116         {
117             // This relies on the fact that all patterns are of the form
118             //   foo*
119             // that is, the very concept of "prefix" applies.
120             sRet = comphelper::string::stripEnd(dsnPrefix, '*');
121             OSL_ENSURE(sRet.getLength() <= _sURL.getLength(), "How can A match B when A shorter than B?");
122             sOldPattern = dsnPrefix;
123         }
124     }
125 
126     return sRet;
127 }
128 
hasDriver(const sal_Char * _pAsciiPattern) const129 bool ODsnTypeCollection::hasDriver( const sal_Char* _pAsciiPattern ) const
130 {
131     OUString sPrefix( getPrefix( OUString::createFromAscii( _pAsciiPattern ) ) );
132     return !sPrefix.isEmpty();
133 }
134 
isConnectionUrlRequired(const OUString & _sURL) const135 bool ODsnTypeCollection::isConnectionUrlRequired(const OUString& _sURL) const
136 {
137     OUString sRet;
138     OUString sOldPattern;
139     for (auto const& dsnPrefix : m_aDsnPrefixes)
140     {
141         WildCard aWildCard(dsnPrefix);
142         if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) )
143         {
144             sRet = dsnPrefix;
145             sOldPattern = dsnPrefix;
146         }
147     }
148     return !sRet.isEmpty() && sRet[sRet.getLength()-1] == '*';
149 }
150 
getMediaType(const OUString & _sURL) const151 OUString ODsnTypeCollection::getMediaType(const OUString& _sURL) const
152 {
153     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL);
154     return aFeatures.getOrDefault("MediaType",OUString());
155 }
156 
getDatasourcePrefixFromMediaType(const OUString & _sMediaType,const OUString & _sExtension)157 OUString ODsnTypeCollection::getDatasourcePrefixFromMediaType(const OUString& _sMediaType,const OUString& _sExtension)
158 {
159     OUString sURL, sFallbackURL;
160     const uno::Sequence< OUString > aURLs = m_aDriverConfig.getURLs();
161     const OUString* pIter = aURLs.getConstArray();
162     const OUString* pEnd = pIter + aURLs.getLength();
163     for(;pIter != pEnd;++pIter )
164     {
165         const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(*pIter);
166         if ( aFeatures.getOrDefault("MediaType",OUString()) == _sMediaType )
167         {
168             const OUString sFileExtension = aFeatures.getOrDefault("Extension",OUString());
169             if ( _sExtension == sFileExtension )
170             {
171                 sURL = *pIter;
172                 break;
173             }
174             if ( sFileExtension.isEmpty() && !_sExtension.isEmpty() )
175                 sFallbackURL = *pIter;
176         }
177     }
178 
179     if ( sURL.isEmpty() && !sFallbackURL.isEmpty() )
180         sURL = sFallbackURL;
181 
182     sURL = comphelper::string::stripEnd(sURL, '*');
183     return sURL;
184 }
185 
isShowPropertiesEnabled(const OUString & _sURL)186 bool ODsnTypeCollection::isShowPropertiesEnabled( const OUString& _sURL )
187 {
188     return !(   _sURL.startsWithIgnoreAsciiCase("sdbc:embedded:hsqldb")
189             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:embedded:firebird")
190             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:outlook")
191             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:outlookexp")
192             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:mozilla:")
193             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:kab")
194             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:evolution:local")
195             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:evolution:groupwise")
196             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:evolution:ldap")
197             ||  _sURL.startsWithIgnoreAsciiCase("sdbc:address:macab")  );
198 }
199 
extractHostNamePort(const OUString & _rDsn,OUString & _sDatabaseName,OUString & _rsHostname,sal_Int32 & _nPortNumber) const200 void ODsnTypeCollection::extractHostNamePort(const OUString& _rDsn,OUString& _sDatabaseName,OUString& _rsHostname,sal_Int32& _nPortNumber) const
201 {
202     OUString sUrl = cutPrefix(_rDsn);
203     if ( _rDsn.startsWithIgnoreAsciiCase("jdbc:oracle:thin:") )
204     {
205         lcl_extractHostAndPort(sUrl,_rsHostname,_nPortNumber);
206         const sal_Int32 nUrlTokens {comphelper::string::getTokenCount(sUrl, ':')};
207         if ( _rsHostname.isEmpty() && nUrlTokens == 2 )
208         {
209             _nPortNumber = -1;
210             _rsHostname = sUrl.getToken(0,':');
211         }
212         if ( !_rsHostname.isEmpty() )
213             _rsHostname = _rsHostname.copy(_rsHostname.lastIndexOf('@')+1);
214         _sDatabaseName = sUrl.copy(sUrl.lastIndexOf(':')+1);
215     }
216     else if ( _rDsn.startsWithIgnoreAsciiCase("sdbc:address:ldap:") )
217     {
218         lcl_extractHostAndPort(sUrl,_sDatabaseName,_nPortNumber);
219     }
220     else if ( _rDsn.startsWithIgnoreAsciiCase("sdbc:mysql:mysqlc:")
221               || _rDsn.startsWithIgnoreAsciiCase("sdbc:mysql:jdbc:") )
222     {
223         lcl_extractHostAndPort(sUrl,_rsHostname,_nPortNumber);
224 
225         const sal_Int32 nUrlTokens {comphelper::string::getTokenCount(sUrl, '/')};
226         if ( _nPortNumber == -1 && _rsHostname.isEmpty() && nUrlTokens == 2 )
227             _rsHostname = sUrl.getToken(0,'/');
228         _sDatabaseName = sUrl.copy(sUrl.lastIndexOf('/')+1);
229     }
230     else if ( _rDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:Provider=Microsoft.ACE.OLEDB.12.0;DATA SOURCE=")
231            || _rDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:PROVIDER=Microsoft.Jet.OLEDB.4.0;DATA SOURCE=") )
232     {
233         OUString sNewFileName;
234         if ( ::osl::FileBase::getFileURLFromSystemPath( sUrl, sNewFileName ) == ::osl::FileBase::E_None )
235         {
236             _sDatabaseName = sNewFileName;
237         }
238     }
239 }
240 
getJavaDriverClass(const OUString & _sURL) const241 OUString ODsnTypeCollection::getJavaDriverClass(const OUString& _sURL) const
242 {
243     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getProperties(_sURL);
244     return aFeatures.getOrDefault("JavaDriverClass",OUString());
245 }
246 
isFileSystemBased(const OUString & _sURL) const247 bool ODsnTypeCollection::isFileSystemBased(const OUString& _sURL) const
248 {
249     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL);
250     return aFeatures.getOrDefault("FileSystemBased",false);
251 }
252 
supportsTableCreation(const OUString & _sURL) const253 bool ODsnTypeCollection::supportsTableCreation(const OUString& _sURL) const
254 {
255     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL);
256     return aFeatures.getOrDefault("SupportsTableCreation",false);
257 }
258 
supportsColumnDescription(const OUString & _sURL) const259 bool ODsnTypeCollection::supportsColumnDescription(const OUString& _sURL) const
260 {
261     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL);
262     return aFeatures.getOrDefault("SupportsColumnDescription",false);
263 }
264 
supportsBrowsing(const OUString & _sURL) const265 bool ODsnTypeCollection::supportsBrowsing(const OUString& _sURL) const
266 {
267     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL);
268     return aFeatures.getOrDefault("SupportsBrowsing",false);
269 }
270 
supportsDBCreation(const OUString & _sURL) const271 bool ODsnTypeCollection::supportsDBCreation(const OUString& _sURL) const
272 {
273     const ::comphelper::NamedValueCollection& aFeatures = m_aDriverConfig.getMetaData(_sURL);
274     return aFeatures.getOrDefault("SupportsDBCreation",false);
275 }
276 
getDefaultDBSettings(const OUString & _sURL) const277 Sequence<PropertyValue> ODsnTypeCollection::getDefaultDBSettings( const OUString& _sURL ) const
278 {
279     const ::comphelper::NamedValueCollection& aProperties = m_aDriverConfig.getProperties(_sURL);
280     return aProperties.getPropertyValues();
281 }
282 
isEmbeddedDatabase(const OUString & _sURL)283 bool ODsnTypeCollection::isEmbeddedDatabase( const OUString& _sURL )
284 {
285     return _sURL.startsWith( "sdbc:embedded:" );
286 }
287 
getEmbeddedDatabase()288 OUString ODsnTypeCollection::getEmbeddedDatabase()
289 {
290     SvtMiscOptions aMiscOptions;
291     if (aMiscOptions.IsExperimentalMode())
292         return "sdbc:embedded:firebird";
293     else
294         return "sdbc:embedded:hsqldb";
295 }
296 
297 
determineType(const OUString & _rDsn) const298 DATASOURCE_TYPE ODsnTypeCollection::determineType(const OUString& _rDsn) const
299 {
300     OUString sDsn(comphelper::string::stripEnd(_rDsn, '*'));
301     sal_Int32 nSeparator = sDsn.indexOf(u':');
302     if (-1 == nSeparator)
303     {
304         if (!sDsn.isEmpty())
305         {
306             // there should be at least one such separator
307             OSL_FAIL("ODsnTypeCollection::implDetermineType : missing the colon !");
308         }
309 
310         return DST_UNKNOWN;
311     }
312 
313     // find first :
314     if (sDsn.startsWithIgnoreAsciiCase("jdbc:oracle:thin:"))
315         return DST_ORACLE_JDBC;
316 
317     if (sDsn.startsWithIgnoreAsciiCase("jdbc:"))
318         return DST_JDBC;
319 
320     if (sDsn.equalsIgnoreAsciiCase("sdbc:embedded:hsqldb"))
321         return DST_EMBEDDED_HSQLDB;
322 
323     if (sDsn.equalsIgnoreAsciiCase("sdbc:embedded:firebird"))
324         return DST_EMBEDDED_FIREBIRD;
325 
326     // find second :
327     nSeparator = sDsn.indexOf(u':', nSeparator + 1);
328     if (-1 == nSeparator)
329     {
330         // at the moment only jdbc is allowed to have just one separator
331         OSL_FAIL("ODsnTypeCollection::implDetermineType : missing the second colon !");
332         return DST_UNKNOWN;
333     }
334 
335     if (sDsn.startsWithIgnoreAsciiCase("sdbc:ado:"))
336     {
337         if (sDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:"))
338         {
339             if (sDsn.startsWithIgnoreAsciiCase("sdbc:ado:access:Provider=Microsoft.ACE.OLEDB.12.0;"))
340                 return DST_MSACCESS_2007;
341             else
342                 return DST_MSACCESS;
343         }
344         return DST_ADO;
345     }
346 
347     struct KnownPrefix
348     {
349         const OUString          sPrefix;
350         const DATASOURCE_TYPE   eType;
351         const bool              bMatchComplete;
352 
353         KnownPrefix( const OUString &_s, const DATASOURCE_TYPE _t, const bool _m )
354             :sPrefix( _s )
355             ,eType ( _t )
356             ,bMatchComplete( _m )
357         {
358         }
359 
360         bool match( const OUString &url) const
361         {
362             if(bMatchComplete)
363             {
364                 return url.equalsIgnoreAsciiCase(sPrefix);
365             }
366             else
367             {
368                 return url.startsWithIgnoreAsciiCase(sPrefix);
369             }
370         }
371     };
372     const KnownPrefix aKnowPrefixes[] =
373     {
374         KnownPrefix( "sdbc:calc:",          DST_CALC,               false ),
375         KnownPrefix( "sdbc:writer:",        DST_WRITER,             false ),
376         KnownPrefix( "sdbc:flat:",          DST_FLAT,               false ),
377         KnownPrefix( "sdbc:odbc:",          DST_ODBC,               false ),
378         KnownPrefix( "sdbc:dbase:",         DST_DBASE,              false ),
379         KnownPrefix( "sdbc:firebird:",      DST_FIREBIRD,           false ),
380         KnownPrefix( "sdbc:mysql:odbc:",    DST_MYSQL_ODBC,         false ),
381         KnownPrefix( "sdbc:mysql:jdbc:",    DST_MYSQL_JDBC,         false ),
382         KnownPrefix( "sdbc:mysql:mysqlc:",  DST_MYSQL_NATIVE,       false ),
383         KnownPrefix( "sdbc:mysqlc:",        DST_MYSQL_NATIVE_DIRECT,false ),
384         KnownPrefix( "sdbc:postgresql:",    DST_POSTGRES           ,false ),
385 
386         KnownPrefix( "sdbc:address:mozilla:",           DST_MOZILLA,            true ),
387         KnownPrefix( "sdbc:address:thunderbird:",       DST_THUNDERBIRD,        true ),
388         KnownPrefix( "sdbc:address:ldap:",              DST_LDAP,               true ),
389         KnownPrefix( "sdbc:address:outlook",            DST_OUTLOOK,            true ),
390         KnownPrefix( "sdbc:address:outlookexp",         DST_OUTLOOKEXP,         true ),
391         KnownPrefix( "sdbc:address:evolution:ldap",     DST_EVOLUTION_LDAP,     true ),
392         KnownPrefix( "sdbc:address:evolution:groupwise",DST_EVOLUTION_GROUPWISE,true ),
393         KnownPrefix( "sdbc:address:evolution:local",    DST_EVOLUTION,          true ),
394         KnownPrefix( "sdbc:address:kab",                DST_KAB,                true ),
395         KnownPrefix( "sdbc:address:macab",              DST_MACAB,              true )
396     };
397 
398     for (const auto & aKnowPrefixe : aKnowPrefixes)
399     {
400         if( aKnowPrefixe.match(sDsn) )
401         {
402             return aKnowPrefixe.eType;
403         }
404     }
405 
406     return DST_UNKNOWN;
407 }
408 
fillPageIds(const OUString & _sURL,std::vector<sal_Int16> & _rOutPathIds) const409 void ODsnTypeCollection::fillPageIds(const OUString& _sURL,std::vector<sal_Int16>& _rOutPathIds) const
410 {
411     DATASOURCE_TYPE eType = determineType(_sURL);
412     switch(eType)
413     {
414         case DST_ADO:
415             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_ADO);
416             break;
417         case DST_DBASE:
418             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_DBASE);
419             break;
420         case DST_FLAT:
421             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_TEXT);
422             break;
423         case DST_CALC:
424         case DST_WRITER:
425             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_DOCUMENT_OR_SPREADSHEET);
426             break;
427         case DST_ODBC:
428             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_ODBC);
429             break;
430         case DST_JDBC:
431             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_JDBC);
432             break;
433         case DST_MYSQL_ODBC:
434             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_INTRO);
435             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_ODBC);
436             break;
437         case DST_MYSQL_JDBC:
438             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_INTRO);
439             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_JDBC);
440             break;
441         case DST_MYSQL_NATIVE:
442             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_INTRO);
443             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MYSQL_NATIVE);
444             break;
445         case DST_ORACLE_JDBC:
446             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_ORACLE);
447             break;
448         case DST_LDAP:
449             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_LDAP);
450             break;
451         case DST_MSACCESS:
452         case DST_MSACCESS_2007:
453             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_MSACCESS);
454             break;
455         case DST_OUTLOOKEXP:
456         case DST_OUTLOOK:
457         case DST_MOZILLA:
458         case DST_THUNDERBIRD:
459         case DST_EVOLUTION:
460         case DST_EVOLUTION_GROUPWISE:
461         case DST_EVOLUTION_LDAP:
462         case DST_KAB:
463         case DST_MACAB:
464         case DST_EMBEDDED_HSQLDB:
465         case DST_EMBEDDED_FIREBIRD:
466             break;
467         default:
468             _rOutPathIds.push_back(PAGE_DBSETUPWIZARD_USERDEFINED);
469             break;
470     }
471 }
472 
getType(const OUString & _sURL) const473 OUString ODsnTypeCollection::getType(const OUString& _sURL) const
474 {
475     OUString sOldPattern;
476     for (auto const& dsnPrefix : m_aDsnPrefixes)
477     {
478         WildCard aWildCard(dsnPrefix);
479         if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) )
480         {
481             sOldPattern = dsnPrefix;
482         }
483     }
484     return sOldPattern;
485 }
486 
getIndexOf(const OUString & _sURL) const487 sal_Int32 ODsnTypeCollection::getIndexOf(const OUString& _sURL) const
488 {
489     sal_Int32 nRet = -1;
490     OUString sOldPattern;
491     sal_Int32 i = 0;
492     for (auto const& dsnPrefix : m_aDsnPrefixes)
493     {
494         WildCard aWildCard(dsnPrefix);
495         if ( sOldPattern.getLength() < dsnPrefix.getLength() && aWildCard.Matches(_sURL) )
496         {
497             nRet = i;
498             sOldPattern = dsnPrefix;
499         }
500         ++i;
501     }
502 
503     return nRet;
504 }
505 
size() const506 sal_Int32 ODsnTypeCollection::size() const
507 {
508     return m_aDsnPrefixes.size();
509 }
510 
511 // ODsnTypeCollection::TypeIterator
TypeIterator(const ODsnTypeCollection * _pContainer,sal_Int32 _nInitialPos)512 ODsnTypeCollection::TypeIterator::TypeIterator(const ODsnTypeCollection* _pContainer, sal_Int32 _nInitialPos)
513     :m_pContainer(_pContainer)
514     ,m_nPosition(_nInitialPos)
515 {
516     OSL_ENSURE(m_pContainer, "ODsnTypeCollection::TypeIterator::TypeIterator : invalid container!");
517 #if OSL_DEBUG_LEVEL > 0
518     ++const_cast<ODsnTypeCollection*>(m_pContainer)->m_nLivingIterators;
519 #endif
520 }
521 
TypeIterator(const TypeIterator & _rSource)522 ODsnTypeCollection::TypeIterator::TypeIterator(const TypeIterator& _rSource)
523     :m_pContainer(_rSource.m_pContainer)
524     ,m_nPosition(_rSource.m_nPosition)
525 {
526 #if OSL_DEBUG_LEVEL > 0
527     ++const_cast<ODsnTypeCollection*>(m_pContainer)->m_nLivingIterators;
528 #endif
529 }
530 
~TypeIterator()531 ODsnTypeCollection::TypeIterator::~TypeIterator()
532 {
533 #if OSL_DEBUG_LEVEL > 0
534     --const_cast<ODsnTypeCollection*>(m_pContainer)->m_nLivingIterators;
535 #endif
536 }
537 
getDisplayName() const538 OUString const & ODsnTypeCollection::TypeIterator::getDisplayName() const
539 {
540     OSL_ENSURE(m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnTypesDisplayNames.size()), "ODsnTypeCollection::TypeIterator::getDisplayName : invalid position!");
541     return m_pContainer->m_aDsnTypesDisplayNames[m_nPosition];
542 }
543 
getURLPrefix() const544 OUString const & ODsnTypeCollection::TypeIterator::getURLPrefix() const
545 {
546     OSL_ENSURE(m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnPrefixes.size()), "ODsnTypeCollection::TypeIterator::getDisplayName : invalid position!");
547     return m_pContainer->m_aDsnPrefixes[m_nPosition];
548 }
549 
operator ++()550 const ODsnTypeCollection::TypeIterator& ODsnTypeCollection::TypeIterator::operator++()
551 {
552     OSL_ENSURE(m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnTypesDisplayNames.size()), "ODsnTypeCollection::TypeIterator::operator++ : invalid position!");
553     if (m_nPosition < static_cast<sal_Int32>(m_pContainer->m_aDsnTypesDisplayNames.size()))
554         ++m_nPosition;
555     return *this;
556 }
557 
operator ==(const ODsnTypeCollection::TypeIterator & lhs,const ODsnTypeCollection::TypeIterator & rhs)558 bool operator==(const ODsnTypeCollection::TypeIterator& lhs, const ODsnTypeCollection::TypeIterator& rhs)
559 {
560     return (lhs.m_pContainer == rhs.m_pContainer) && (lhs.m_nPosition == rhs.m_nPosition);
561 }
562 
563 }   // namespace dbaccess
564 
565 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
566