LCOV - code coverage report
Current view: top level - core - qgsproviderregistry.cpp (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 147 433 33.9 %
Date: 2021-04-10 08:29:14 Functions: 0 0 -
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /***************************************************************************
       2                 :            :                     qgsproviderregistry.cpp  -  Singleton class for
       3                 :            :                     registering data providers.
       4                 :            :                              -------------------
       5                 :            :     begin                : Sat Jan 10 2004
       6                 :            :     copyright            : (C) 2004 by Gary E.Sherman
       7                 :            :     email                : sherman at mrcc.com
       8                 :            :  ***************************************************************************/
       9                 :            : 
      10                 :            : /***************************************************************************
      11                 :            :  *                                                                         *
      12                 :            :  *   This program is free software; you can redistribute it and/or modify  *
      13                 :            :  *   it under the terms of the GNU General Public License as published by  *
      14                 :            :  *   the Free Software Foundation; either version 2 of the License, or     *
      15                 :            :  *   (at your option) any later version.                                   *
      16                 :            :  *                                                                         *
      17                 :            :  ***************************************************************************/
      18                 :            : 
      19                 :            : #include "qgsproviderregistry.h"
      20                 :            : 
      21                 :            : #include <QString>
      22                 :            : #include <QDir>
      23                 :            : #include <QLibrary>
      24                 :            : 
      25                 :            : #include "qgis.h"
      26                 :            : #include "qgsdataprovider.h"
      27                 :            : #include "qgsdataitemprovider.h"
      28                 :            : #include "qgslogger.h"
      29                 :            : #include "qgsmessageoutput.h"
      30                 :            : #include "qgsmessagelog.h"
      31                 :            : #include "qgsprovidermetadata.h"
      32                 :            : #include "qgsvectorlayer.h"
      33                 :            : #include "qgsvectortileprovidermetadata.h"
      34                 :            : #include "qgsproject.h"
      35                 :            : #include "providers/memory/qgsmemoryprovider.h"
      36                 :            : #include "providers/gdal/qgsgdalprovider.h"
      37                 :            : #include "providers/ogr/qgsogrprovider.h"
      38                 :            : #include "providers/meshmemory/qgsmeshmemorydataprovider.h"
      39                 :            : 
      40                 :            : #ifdef HAVE_EPT
      41                 :            : #include "providers/ept/qgseptprovider.h"
      42                 :            : #endif
      43                 :            : 
      44                 :            : #include "qgsruntimeprofiler.h"
      45                 :            : #include "qgsfileutils.h"
      46                 :            : 
      47                 :            : #ifdef HAVE_STATIC_PROVIDERS
      48                 :            : #include "qgswmsprovider.h"
      49                 :            : #include "qgspostgresprovider.h"
      50                 :            : #endif
      51                 :            : 
      52                 :            : static QgsProviderRegistry *sInstance = nullptr;
      53                 :            : 
      54                 :        173 : QgsProviderRegistry *QgsProviderRegistry::instance( const QString &pluginPath )
      55                 :            : {
      56                 :        173 :   if ( !sInstance )
      57                 :            :   {
      58                 :          3 :     static QMutex sMutex;
      59                 :          3 :     QMutexLocker locker( &sMutex );
      60                 :          3 :     if ( !sInstance )
      61                 :            :     {
      62                 :          3 :       sInstance = new QgsProviderRegistry( pluginPath );
      63                 :          3 :     }
      64                 :          3 :   }
      65                 :        173 :   return sInstance;
      66                 :          0 : } // QgsProviderRegistry::instance
      67                 :            : 
      68                 :            : 
      69                 :            : /**
      70                 :            :  * Convenience function for finding any existing data providers that match "providerKey"
      71                 :            : 
      72                 :            :   Necessary because [] map operator will create a QgsProviderMetadata
      73                 :            :   instance.  Also you cannot use the map [] operator in const members for that
      74                 :            :   very reason.  So there needs to be a convenient way to find a data provider
      75                 :            :   without accidentally adding a null meta data item to the metadata map.
      76                 :            : */
      77                 :            : static
      78                 :        164 : QgsProviderMetadata *findMetadata_( const QgsProviderRegistry::Providers &metaData,
      79                 :            :                                     const QString &providerKey )
      80                 :            : {
      81                 :            :   // first do case-sensitive match
      82                 :            :   QgsProviderRegistry::Providers::const_iterator i =
      83                 :        164 :     metaData.find( providerKey );
      84                 :            : 
      85                 :        164 :   if ( i != metaData.end() )
      86                 :            :   {
      87                 :        164 :     return i->second;
      88                 :            :   }
      89                 :            : 
      90                 :            :   // fallback to case-insensitive match
      91                 :          0 :   for ( auto it = metaData.begin(); it != metaData.end(); ++it )
      92                 :            :   {
      93                 :          0 :     if ( providerKey.compare( it->first, Qt::CaseInsensitive ) == 0 )
      94                 :          0 :       return it->second;
      95                 :          0 :   }
      96                 :            : 
      97                 :          0 :   return nullptr;
      98                 :        164 : }
      99                 :            : 
     100                 :          3 : QgsProviderRegistry::QgsProviderRegistry( const QString &pluginPath )
     101                 :            : {
     102                 :            :   // At startup, examine the libs in the qgis/lib dir and store those that
     103                 :            :   // are a provider shared lib
     104                 :            :   // check all libs in the current plugin directory and get name and descriptions
     105                 :            :   //TODO figure out how to register and identify data source plugin for a specific
     106                 :            :   //TODO layer type
     107                 :            : #if 0
     108                 :            :   char **argv = qApp->argv();
     109                 :            :   QString appDir = argv[0];
     110                 :            :   int bin = appDir.findRev( "/bin", -1, false );
     111                 :            :   QString baseDir = appDir.left( bin );
     112                 :            :   QString mLibraryDirectory = baseDir + "/lib";
     113                 :            : #endif
     114                 :            : 
     115                 :          3 :   QgsScopedRuntimeProfile profile( QObject::tr( "Initialize data providers" ) );
     116                 :          3 :   mLibraryDirectory.setPath( pluginPath );
     117                 :          3 :   init();
     118                 :          3 : }
     119                 :            : 
     120                 :            : ///@cond PRIVATE
     121                 :          9 : class PdalUnusableUriHandlerInterface : public QgsProviderRegistry::UnusableUriHandlerInterface
     122                 :            : {
     123                 :            :   public:
     124                 :          0 :     bool matchesUri( const QString &uri ) const override
     125                 :            :     {
     126                 :          0 :       const QFileInfo fi( uri );
     127                 :          0 :       if ( fi.suffix().compare( QLatin1String( "las" ), Qt::CaseInsensitive ) == 0 || fi.suffix().compare( QLatin1String( "laz" ), Qt::CaseInsensitive ) == 0 )
     128                 :          0 :         return true;
     129                 :            : 
     130                 :          0 :       return false;
     131                 :          0 :     }
     132                 :            : 
     133                 :          0 :     QgsProviderRegistry::UnusableUriDetails details( const QString &uri ) const override
     134                 :            :     {
     135                 :          0 :       QgsProviderRegistry::UnusableUriDetails res = QgsProviderRegistry::UnusableUriDetails( uri,
     136                 :          0 :           QObject::tr( "LAS and LAZ files cannot be opened by this QGIS install." ),
     137                 :          0 :           QList<QgsMapLayerType>() << QgsMapLayerType::PointCloudLayer );
     138                 :            : 
     139                 :            : #ifdef Q_OS_WIN
     140                 :            :       res.detailedWarning = QObject::tr( "The installer used to install this version of QGIS does "
     141                 :            :                                          "not include the PDAL library required for opening LAS and LAZ point clouds. Please "
     142                 :            :                                          "obtain one of the alternative installers from https://qgis.org which has point "
     143                 :            :                                          "cloud support enabled." );
     144                 :            : #else
     145                 :          0 :       res.detailedWarning = QObject::tr( "This QGIS build does not include the PDAL library dependency required for opening LAS or LAZ point clouds." );
     146                 :            : #endif
     147                 :          0 :       return res;
     148                 :          0 :     }
     149                 :            : };
     150                 :            : ///@endcond
     151                 :            : 
     152                 :          3 : void QgsProviderRegistry::init()
     153                 :            : {
     154                 :            :   // add static providers
     155                 :            :   Q_NOWARN_DEPRECATED_PUSH
     156                 :            :   {
     157                 :          3 :     QgsScopedRuntimeProfile profile( QObject::tr( "Create memory layer provider" ) );
     158                 :          3 :     mProviders[ QgsMemoryProvider::providerKey() ] = new QgsProviderMetadata( QgsMemoryProvider::providerKey(), QgsMemoryProvider::providerDescription(), &QgsMemoryProvider::createProvider );
     159                 :          3 :   }
     160                 :            :   {
     161                 :          3 :     QgsScopedRuntimeProfile profile( QObject::tr( "Create mesh memory layer provider" ) );
     162                 :          3 :     mProviders[ QgsMeshMemoryDataProvider::providerKey() ] = new QgsProviderMetadata( QgsMeshMemoryDataProvider::providerKey(), QgsMeshMemoryDataProvider::providerDescription(), &QgsMeshMemoryDataProvider::createProvider );
     163                 :          3 :   }
     164                 :            :   Q_NOWARN_DEPRECATED_POP
     165                 :            :   {
     166                 :          3 :     QgsScopedRuntimeProfile profile( QObject::tr( "Create GDAL provider" ) );
     167                 :          3 :     mProviders[ QgsGdalProvider::providerKey() ] = new QgsGdalProviderMetadata();
     168                 :          3 :   }
     169                 :            :   {
     170                 :          3 :     QgsScopedRuntimeProfile profile( QObject::tr( "Create OGR provider" ) );
     171                 :          3 :     mProviders[ QgsOgrProvider::providerKey() ] = new QgsOgrProviderMetadata();
     172                 :          3 :   }
     173                 :            :   {
     174                 :          3 :     QgsScopedRuntimeProfile profile( QObject::tr( "Create vector tile provider" ) );
     175                 :          3 :     QgsProviderMetadata *vt = new QgsVectorTileProviderMetadata();
     176                 :          3 :     mProviders[ vt->key() ] = vt;
     177                 :          3 :   }
     178                 :            : #ifdef HAVE_EPT
     179                 :            :   {
     180                 :          3 :     QgsScopedRuntimeProfile profile( QObject::tr( "Create EPT point cloud provider" ) );
     181                 :          3 :     QgsProviderMetadata *pc = new QgsEptProviderMetadata();
     182                 :          3 :     mProviders[ pc->key() ] = pc;
     183                 :          3 :   }
     184                 :            : #endif
     185                 :            : 
     186                 :          3 :   registerUnusableUriHandler( new PdalUnusableUriHandlerInterface() );
     187                 :            : 
     188                 :            : #ifdef HAVE_STATIC_PROVIDERS
     189                 :            :   mProviders[ QgsWmsProvider::providerKey() ] = new QgsWmsProviderMetadata();
     190                 :            :   mProviders[ QgsPostgresProvider::providerKey() ] = new QgsPostgresProviderMetadata();
     191                 :            : #endif
     192                 :            : 
     193                 :            :   // add dynamic providers
     194                 :            : #ifdef HAVE_STATIC_PROVIDERS
     195                 :            :   QgsDebugMsg( QStringLiteral( "Forced only static providers" ) );
     196                 :            : #else
     197                 :            :   typedef QgsProviderMetadata *factory_function( );
     198                 :            : 
     199                 :          3 :   mLibraryDirectory.setSorting( QDir::Name | QDir::IgnoreCase );
     200                 :          3 :   mLibraryDirectory.setFilter( QDir::Files | QDir::NoSymLinks );
     201                 :            : 
     202                 :            : #if defined(Q_OS_WIN) || defined(__CYGWIN__)
     203                 :            :   mLibraryDirectory.setNameFilters( QStringList( "*.dll" ) );
     204                 :            : #elif defined(ANDROID)
     205                 :            :   mLibraryDirectory.setNameFilters( QStringList( "*provider*.so" ) );
     206                 :            : #else
     207                 :          6 :   mLibraryDirectory.setNameFilters( QStringList( QStringLiteral( "*.so" ) ) );
     208                 :            : #endif
     209                 :            : 
     210                 :          3 :   QgsDebugMsgLevel( QStringLiteral( "Checking %1 for provider plugins" ).arg( mLibraryDirectory.path() ), 2 );
     211                 :            : 
     212                 :          3 :   if ( mLibraryDirectory.count() == 0 )
     213                 :            :   {
     214                 :          3 :     QgsDebugMsg( QStringLiteral( "No dynamic QGIS data provider plugins found in:\n%1\n" ).arg( mLibraryDirectory.path() ) );
     215                 :          3 :   }
     216                 :            : 
     217                 :            :   // provider file regex pattern, only files matching the pattern are loaded if the variable is defined
     218                 :          3 :   QString filePattern = getenv( "QGIS_PROVIDER_FILE" );
     219                 :          3 :   QRegExp fileRegexp;
     220                 :          3 :   if ( !filePattern.isEmpty() )
     221                 :            :   {
     222                 :          0 :     fileRegexp.setPattern( filePattern );
     223                 :          0 :   }
     224                 :            : 
     225                 :            :   typedef std::vector<QgsProviderMetadata *> *multiple_factory_function();
     226                 :            : 
     227                 :          3 :   const auto constEntryInfoList = mLibraryDirectory.entryInfoList();
     228                 :          3 :   for ( const QFileInfo &fi : constEntryInfoList )
     229                 :            :   {
     230                 :          0 :     if ( !fileRegexp.isEmpty() )
     231                 :            :     {
     232                 :          0 :       if ( fileRegexp.indexIn( fi.fileName() ) == -1 )
     233                 :            :       {
     234                 :          0 :         QgsDebugMsg( "provider " + fi.fileName() + " skipped because doesn't match pattern " + filePattern );
     235                 :          0 :         continue;
     236                 :            :       }
     237                 :          0 :     }
     238                 :            : 
     239                 :            :     // Always skip authentication methods
     240                 :          0 :     if ( fi.fileName().contains( QStringLiteral( "authmethod" ), Qt::CaseSensitivity::CaseInsensitive ) )
     241                 :            :     {
     242                 :          0 :       continue;
     243                 :            :     }
     244                 :            : 
     245                 :          0 :     QgsScopedRuntimeProfile profile( QObject::tr( "Load %1" ).arg( fi.fileName() ) );
     246                 :          0 :     QLibrary myLib( fi.filePath() );
     247                 :          0 :     if ( !myLib.load() )
     248                 :            :     {
     249                 :          0 :       QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (lib not loadable): %2" ).arg( myLib.fileName(), myLib.errorString() ) );
     250                 :          0 :       continue;
     251                 :            :     }
     252                 :            : 
     253                 :          0 :     bool libraryLoaded { false };
     254                 :          0 :     QFunctionPointer func = myLib.resolve( QStringLiteral( "providerMetadataFactory" ).toLatin1().data() );
     255                 :          0 :     factory_function *function = reinterpret_cast< factory_function * >( cast_to_fptr( func ) );
     256                 :          0 :     if ( function )
     257                 :            :     {
     258                 :          0 :       QgsProviderMetadata *meta = function();
     259                 :          0 :       if ( meta )
     260                 :            :       {
     261                 :          0 :         if ( findMetadata_( mProviders, meta->key() ) )
     262                 :            :         {
     263                 :          0 :           QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->key() ) );
     264                 :          0 :           delete meta;
     265                 :          0 :           continue;
     266                 :            :         }
     267                 :            :         // add this provider to the provider map
     268                 :          0 :         mProviders[meta->key()] = meta;
     269                 :          0 :         libraryLoaded = true;
     270                 :          0 :       }
     271                 :          0 :     }
     272                 :            :     else
     273                 :            :     {
     274                 :          0 :       QFunctionPointer multi_func = myLib.resolve( QStringLiteral( "multipleProviderMetadataFactory" ).toLatin1().data() );
     275                 :          0 :       multiple_factory_function *multi_function = reinterpret_cast< multiple_factory_function * >( cast_to_fptr( multi_func ) );
     276                 :          0 :       if ( multi_function )
     277                 :            :       {
     278                 :          0 :         std::vector<QgsProviderMetadata *> *metadatas = multi_function();
     279                 :          0 :         for ( const auto meta : *metadatas )
     280                 :            :         {
     281                 :          0 :           if ( findMetadata_( mProviders, meta->key() ) )
     282                 :            :           {
     283                 :          0 :             QgsDebugMsg( QStringLiteral( "Checking %1: ...invalid (key %2 already registered)" ).arg( myLib.fileName() ).arg( meta->key() ) );
     284                 :          0 :             delete meta;
     285                 :          0 :             continue;
     286                 :            :           }
     287                 :            :           // add this provider to the provider map
     288                 :          0 :           mProviders[meta->key()] = meta;
     289                 :          0 :           libraryLoaded = true;
     290                 :            :         }
     291                 :          0 :         delete metadatas;
     292                 :          0 :       }
     293                 :            :     }
     294                 :            : 
     295                 :          0 :     if ( ! libraryLoaded )
     296                 :            :     {
     297                 :          0 :       QgsDebugMsgLevel( QStringLiteral( "Checking %1: ...invalid (no providerMetadataFactory method)" ).arg( myLib.fileName() ), 2 );
     298                 :          0 :     }
     299                 :          0 :   }
     300                 :            : 
     301                 :            : #endif
     302                 :          3 :   QgsDebugMsg( QStringLiteral( "Loaded %1 providers (%2) " ).arg( mProviders.size() ).arg( providerList().join( ';' ) ) );
     303                 :            : 
     304                 :          3 :   QStringList pointCloudWildcards;
     305                 :          3 :   QStringList pointCloudFilters;
     306                 :            : 
     307                 :            :   // now initialize all providers
     308                 :         21 :   for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
     309                 :            :   {
     310                 :         18 :     const QString &key = it->first;
     311                 :            : 
     312                 :         18 :     QgsScopedRuntimeProfile profile( QObject::tr( "Initialize %1" ).arg( key ) );
     313                 :            : 
     314                 :         18 :     QgsProviderMetadata *meta = it->second;
     315                 :            : 
     316                 :            :     // now get vector file filters, if any
     317                 :         18 :     QString fileVectorFilters = meta->filters( QgsProviderMetadata::FilterType::FilterVector );
     318                 :         18 :     if ( !fileVectorFilters.isEmpty() )
     319                 :            :     {
     320                 :          3 :       mVectorFileFilters += fileVectorFilters;
     321                 :          3 :       QgsDebugMsgLevel( QStringLiteral( "Checking %1: ...loaded OK (%2 file filters)" ).arg( key ).arg( fileVectorFilters.split( ";;" ).count() ), 2 );
     322                 :          3 :     }
     323                 :            : 
     324                 :            :     // now get raster file filters, if any
     325                 :         18 :     QString fileRasterFilters = meta->filters( QgsProviderMetadata::FilterType::FilterRaster );
     326                 :         18 :     if ( !fileRasterFilters.isEmpty() )
     327                 :            :     {
     328                 :          3 :       QgsDebugMsgLevel( "raster filters: " + fileRasterFilters, 2 );
     329                 :          3 :       mRasterFileFilters += fileRasterFilters;
     330                 :          3 :       QgsDebugMsgLevel( QStringLiteral( "Checking %1: ...loaded OK (%2 file filters)" ).arg( key ).arg( fileRasterFilters.split( ";;" ).count() ), 2 );
     331                 :          3 :     }
     332                 :            : 
     333                 :            :     // now get mesh file filters, if any
     334                 :         18 :     QString fileMeshFilters = meta->filters( QgsProviderMetadata::FilterType::FilterMesh );
     335                 :         18 :     if ( !fileMeshFilters.isEmpty() )
     336                 :            :     {
     337                 :          0 :       mMeshFileFilters += fileMeshFilters;
     338                 :          0 :       QgsDebugMsgLevel( QStringLiteral( "Checking %1: ...loaded OK (%2 file mesh filters)" ).arg( key ).arg( mMeshFileFilters.split( ";;" ).count() ), 2 );
     339                 :            : 
     340                 :          0 :     }
     341                 :            : 
     342                 :         18 :     QString fileMeshDatasetFilters = meta->filters( QgsProviderMetadata::FilterType::FilterMeshDataset );
     343                 :         18 :     if ( !fileMeshDatasetFilters.isEmpty() )
     344                 :            :     {
     345                 :          0 :       mMeshDatasetFileFilters += fileMeshDatasetFilters;
     346                 :          0 :       QgsDebugMsgLevel( QStringLiteral( "Checking %1: ...loaded OK (%2 file dataset filters)" ).arg( key ).arg( mMeshDatasetFileFilters.split( ";;" ).count() ), 2 );
     347                 :          0 :     }
     348                 :            : 
     349                 :            :     // now get point cloud file filters, if any
     350                 :         18 :     const QString filePointCloudFilters = meta->filters( QgsProviderMetadata::FilterType::FilterPointCloud );
     351                 :         18 :     if ( !filePointCloudFilters.isEmpty() )
     352                 :            :     {
     353                 :          3 :       QgsDebugMsgLevel( "point cloud filters: " + filePointCloudFilters, 2 );
     354                 :            : 
     355                 :            : #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
     356                 :            :       const QStringList filters = filePointCloudFilters.split( QStringLiteral( ";;" ), QString::SkipEmptyParts );
     357                 :            : #else
     358                 :          6 :       const QStringList filters = filePointCloudFilters.split( QStringLiteral( ";;" ), Qt::SkipEmptyParts );
     359                 :            : #endif
     360                 :          6 :       for ( const QString &filter : filters )
     361                 :            :       {
     362                 :          3 :         pointCloudFilters.append( filter );
     363                 :          3 :         pointCloudWildcards.append( QgsFileUtils::wildcardsFromFilter( filter ).split( ' ' ) );
     364                 :            :       }
     365                 :          3 :     }
     366                 :            : 
     367                 :            :     // call initProvider() - allows provider to register its services to QGIS
     368                 :         18 :     meta->initProvider();
     369                 :         18 :   }
     370                 :            : 
     371                 :          3 :   if ( !pointCloudFilters.empty() )
     372                 :            :   {
     373                 :          6 :     pointCloudFilters.insert( 0, QObject::tr( "All Supported Files" ) + QStringLiteral( " (%1)" ).arg( pointCloudWildcards.join( ' ' ) ) );
     374                 :          6 :     pointCloudFilters.insert( 1, QObject::tr( "All Files" ) + QStringLiteral( " (*.*)" ) );
     375                 :          3 :     mPointCloudFileFilters = pointCloudFilters.join( QLatin1String( ";;" ) );
     376                 :          3 :   }
     377                 :            : 
     378                 :            :   // load database drivers (only OGR)
     379                 :          3 :   mDatabaseDrivers = QgsOgrProviderUtils::databaseDrivers();
     380                 :            : 
     381                 :            :   // load directory drivers (only OGR)
     382                 :          3 :   mDirectoryDrivers =  QgsOgrProviderUtils::directoryDrivers();
     383                 :            : 
     384                 :            :   // load protocol drivers (only OGR)
     385                 :          3 :   mProtocolDrivers =  QgsOgrProviderUtils::protocolDrivers();
     386                 :          3 : } // QgsProviderRegistry ctor
     387                 :            : 
     388                 :            : 
     389                 :            : // typedef for the unload dataprovider function
     390                 :            : typedef void cleanupProviderFunction_t();
     391                 :            : 
     392                 :          3 : void QgsProviderRegistry::clean()
     393                 :            : {
     394                 :            :   // avoid recreating a new project just to clean it
     395                 :          3 :   if ( QgsProject::sProject )
     396                 :          0 :     QgsProject::instance()->removeAllMapLayers();
     397                 :            : 
     398                 :          3 :   Providers::const_iterator it = mProviders.begin();
     399                 :            : 
     400                 :         21 :   while ( it != mProviders.end() )
     401                 :            :   {
     402                 :         18 :     QgsDebugMsgLevel( QStringLiteral( "cleanup:%1" ).arg( it->first ), 5 );
     403                 :         18 :     it->second->cleanupProvider();
     404                 :         18 :     delete it->second;
     405                 :         18 :     ++it;
     406                 :            :   }
     407                 :          3 :   mProviders.clear();
     408                 :          3 : }
     409                 :            : 
     410                 :          3 : bool QgsProviderRegistry::exists()
     411                 :            : {
     412                 :          3 :   return static_cast< bool >( sInstance );
     413                 :            : }
     414                 :            : 
     415                 :          3 : QgsProviderRegistry::~QgsProviderRegistry()
     416                 :            : {
     417                 :          3 :   qDeleteAll( mUnusableUriHandlers );
     418                 :            : 
     419                 :          3 :   clean();
     420                 :          3 :   if ( sInstance == this )
     421                 :          3 :     sInstance = nullptr;
     422                 :          3 : }
     423                 :            : 
     424                 :          0 : QString QgsProviderRegistry::library( QString const &providerKey ) const
     425                 :            : {
     426                 :          0 :   QgsProviderMetadata *md = findMetadata_( mProviders, providerKey );
     427                 :            : 
     428                 :          0 :   if ( md )
     429                 :            :   {
     430                 :            :     Q_NOWARN_DEPRECATED_PUSH
     431                 :          0 :     return md->library();
     432                 :            :     Q_NOWARN_DEPRECATED_POP
     433                 :            :   }
     434                 :            : 
     435                 :          0 :   return QString();
     436                 :          0 : }
     437                 :            : 
     438                 :          0 : QString QgsProviderRegistry::pluginList( bool asHTML ) const
     439                 :            : {
     440                 :          0 :   Providers::const_iterator it = mProviders.begin();
     441                 :            : 
     442                 :          0 :   if ( mProviders.empty() )
     443                 :          0 :     return QObject::tr( "No data provider plugins are available. No vector layers can be loaded" );
     444                 :            : 
     445                 :          0 :   QString list;
     446                 :            : 
     447                 :          0 :   if ( asHTML )
     448                 :          0 :     list += QLatin1String( "<ol>" );
     449                 :            : 
     450                 :          0 :   while ( it != mProviders.end() )
     451                 :            :   {
     452                 :          0 :     if ( asHTML )
     453                 :          0 :       list += QLatin1String( "<li>" );
     454                 :            : 
     455                 :          0 :     list += it->second->description();
     456                 :            : 
     457                 :          0 :     if ( asHTML )
     458                 :          0 :       list += QLatin1String( "<br></li>" );
     459                 :            :     else
     460                 :          0 :       list += '\n';
     461                 :            : 
     462                 :          0 :     ++it;
     463                 :            :   }
     464                 :            : 
     465                 :          0 :   if ( asHTML )
     466                 :          0 :     list += QLatin1String( "</ol>" );
     467                 :            : 
     468                 :          0 :   return list;
     469                 :          0 : }
     470                 :            : 
     471                 :          0 : void QgsProviderRegistry::setLibraryDirectory( QDir const &path )
     472                 :            : {
     473                 :          0 :   mLibraryDirectory = path;
     474                 :          0 :   clean();
     475                 :          0 :   init();
     476                 :          0 : }
     477                 :            : 
     478                 :          0 : QDir QgsProviderRegistry::libraryDirectory() const
     479                 :            : {
     480                 :          0 :   return mLibraryDirectory;
     481                 :            : }
     482                 :            : 
     483                 :            : 
     484                 :            : /* Copied from QgsVectorLayer::setDataProvider
     485                 :            :  *  TODO: Make it work in the generic environment
     486                 :            :  *
     487                 :            :  *  TODO: Is this class really the best place to put a data provider loader?
     488                 :            :  *        It seems more sensible to provide the code in one place rather than
     489                 :            :  *        in qgsrasterlayer, qgsvectorlayer, serversourceselect, etc.
     490                 :            :  */
     491                 :         78 : QgsDataProvider *QgsProviderRegistry::createProvider( QString const &providerKey, QString const &dataSource,
     492                 :            :     const QgsDataProvider::ProviderOptions &options,
     493                 :            :     QgsDataProvider::ReadFlags flags )
     494                 :            : {
     495                 :            :   // XXX should I check for and possibly delete any pre-existing providers?
     496                 :            :   // XXX How often will that scenario occur?
     497                 :            : 
     498                 :         78 :   QgsProviderMetadata *metadata = findMetadata_( mProviders, providerKey );
     499                 :         78 :   if ( !metadata )
     500                 :            :   {
     501                 :          0 :     QgsMessageLog::logMessage( QObject::tr( "Invalid data provider %1" ).arg( providerKey ) );
     502                 :          0 :     return nullptr;
     503                 :            :   }
     504                 :            : 
     505                 :         78 :   return metadata->createProvider( dataSource, options, flags );
     506                 :         78 : }
     507                 :            : 
     508                 :          0 : int QgsProviderRegistry::providerCapabilities( const QString &providerKey ) const
     509                 :            : {
     510                 :          0 :   const QList< QgsDataItemProvider * > itemProviders = dataItemProviders( providerKey );
     511                 :          0 :   int ret = QgsDataProvider::NoDataCapabilities;
     512                 :            :   //concat flags
     513                 :          0 :   for ( const QgsDataItemProvider *itemProvider : itemProviders )
     514                 :            :   {
     515                 :          0 :     ret = ret | itemProvider->capabilities();
     516                 :            :   }
     517                 :          0 :   return ret;
     518                 :          0 : }
     519                 :            : 
     520                 :         64 : QVariantMap QgsProviderRegistry::decodeUri( const QString &providerKey, const QString &uri )
     521                 :            : {
     522                 :         64 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     523                 :         64 :   if ( meta )
     524                 :         64 :     return meta->decodeUri( uri );
     525                 :            :   else
     526                 :          0 :     return QVariantMap();
     527                 :         64 : }
     528                 :            : 
     529                 :          0 : QString QgsProviderRegistry::encodeUri( const QString &providerKey, const QVariantMap &parts )
     530                 :            : {
     531                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     532                 :          0 :   if ( meta )
     533                 :          0 :     return meta->encodeUri( parts );
     534                 :            :   else
     535                 :          0 :     return QString();
     536                 :          0 : }
     537                 :            : 
     538                 :          0 : QgsVectorLayerExporter::ExportError QgsProviderRegistry::createEmptyLayer( const QString &providerKey,
     539                 :            :     const QString &uri,
     540                 :            :     const QgsFields &fields,
     541                 :            :     QgsWkbTypes::Type wkbType,
     542                 :            :     const QgsCoordinateReferenceSystem &srs,
     543                 :            :     bool overwrite, QMap<int, int> &oldToNewAttrIdxMap,
     544                 :            :     QString &errorMessage,
     545                 :            :     const QMap<QString, QVariant> *options )
     546                 :            : {
     547                 :            :   QgsVectorLayerExporter::ExportError ret;
     548                 :            : 
     549                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     550                 :          0 :   if ( meta )
     551                 :          0 :     return meta->createEmptyLayer( uri, fields, wkbType, srs, overwrite, oldToNewAttrIdxMap, errorMessage, options );
     552                 :            :   else
     553                 :            :   {
     554                 :          0 :     ret = QgsVectorLayerExporter::ErrInvalidProvider;
     555                 :          0 :     errorMessage = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
     556                 :            :   }
     557                 :            : 
     558                 :          0 :   return ret;
     559                 :          0 : }
     560                 :            : 
     561                 :          0 : QgsRasterDataProvider *QgsProviderRegistry::createRasterDataProvider( const QString &providerKey, const QString &uri, const QString &format,
     562                 :            :     int nBands, Qgis::DataType type, int width, int height,
     563                 :            :     double *geoTransform, const QgsCoordinateReferenceSystem &crs,
     564                 :            :     const QStringList &createOptions )
     565                 :            : {
     566                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     567                 :          0 :   if ( meta )
     568                 :          0 :     return meta->createRasterDataProvider( uri, format, nBands, type, width, height, geoTransform, crs, createOptions );
     569                 :            :   else
     570                 :          0 :     return nullptr;
     571                 :          0 : }
     572                 :            : 
     573                 :          0 : QList<QPair<QString, QString> > QgsProviderRegistry::pyramidResamplingMethods( const QString &providerKey )
     574                 :            : {
     575                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     576                 :          0 :   if ( meta )
     577                 :          0 :     return meta->pyramidResamplingMethods();
     578                 :            :   else
     579                 :          0 :     return QList<QPair<QString, QString> >();
     580                 :          0 : }
     581                 :            : 
     582                 :         18 : QList<QgsDataItemProvider *> QgsProviderRegistry::dataItemProviders( const QString &providerKey ) const
     583                 :            : {
     584                 :         18 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     585                 :         18 :   if ( meta )
     586                 :         18 :     return meta->dataItemProviders();
     587                 :            :   else
     588                 :          0 :     return QList<QgsDataItemProvider *>();
     589                 :         18 : }
     590                 :            : 
     591                 :          0 : int QgsProviderRegistry::listStyles( const QString &providerKey, const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause )
     592                 :            : {
     593                 :          0 :   int res = -1;
     594                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     595                 :          0 :   if ( meta )
     596                 :            :   {
     597                 :          0 :     res = meta->listStyles( uri, ids, names, descriptions, errCause );
     598                 :          0 :   }
     599                 :            :   else
     600                 :            :   {
     601                 :          0 :     errCause = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
     602                 :            :   }
     603                 :          0 :   return res;
     604                 :          0 : }
     605                 :            : 
     606                 :          0 : QString QgsProviderRegistry::getStyleById( const QString &providerKey, const QString &uri, QString styleId, QString &errCause )
     607                 :            : {
     608                 :          0 :   QString ret;
     609                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     610                 :          0 :   if ( meta )
     611                 :            :   {
     612                 :          0 :     ret = meta->getStyleById( uri, styleId, errCause );
     613                 :          0 :   }
     614                 :            :   else
     615                 :            :   {
     616                 :          0 :     errCause = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
     617                 :            :   }
     618                 :          0 :   return ret;
     619                 :          0 : }
     620                 :            : 
     621                 :          0 : bool QgsProviderRegistry::deleteStyleById( const QString &providerKey, const QString &uri, QString styleId, QString &errCause )
     622                 :            : {
     623                 :          0 :   bool ret( false );
     624                 :            : 
     625                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     626                 :          0 :   if ( meta )
     627                 :          0 :     return meta->deleteStyleById( uri, styleId, errCause );
     628                 :            :   else
     629                 :            :   {
     630                 :          0 :     errCause = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
     631                 :            :   }
     632                 :          0 :   return ret;
     633                 :          0 : }
     634                 :            : 
     635                 :          0 : bool QgsProviderRegistry::saveStyle( const QString &providerKey, const QString &uri, const QString &qmlStyle,
     636                 :            :                                      const QString &sldStyle, const QString &styleName, const QString &styleDescription,
     637                 :            :                                      const QString &uiFileContent, bool useAsDefault, QString &errCause )
     638                 :            : {
     639                 :          0 :   bool ret( false );
     640                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     641                 :          0 :   if ( meta )
     642                 :          0 :     ret = meta->saveStyle( uri, qmlStyle, sldStyle, styleName, styleDescription,
     643                 :          0 :                            uiFileContent, useAsDefault, errCause );
     644                 :            :   else
     645                 :            :   {
     646                 :          0 :     errCause = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
     647                 :            :   }
     648                 :          0 :   return ret;
     649                 :          0 : }
     650                 :            : 
     651                 :          1 : QString QgsProviderRegistry::loadStyle( const QString &providerKey, const QString &uri, QString &errCause )
     652                 :            : {
     653                 :          1 :   QString ret;
     654                 :          1 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     655                 :          1 :   if ( meta )
     656                 :          1 :     ret = meta->loadStyle( uri, errCause );
     657                 :            :   else
     658                 :            :   {
     659                 :          0 :     errCause = QObject::tr( "Unable to load %1 provider" ).arg( providerKey );
     660                 :            :   }
     661                 :          1 :   return ret;
     662                 :          1 : }
     663                 :            : 
     664                 :          0 : bool QgsProviderRegistry::createDb( const QString &providerKey, const QString &dbPath, QString &errCause )
     665                 :            : {
     666                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     667                 :          0 :   if ( meta )
     668                 :          0 :     return meta->createDb( dbPath, errCause );
     669                 :            :   else
     670                 :            :   {
     671                 :          0 :     errCause = QStringLiteral( "Resolving createDb(...) failed" );
     672                 :          0 :     return false;
     673                 :            :   }
     674                 :          0 : }
     675                 :            : 
     676                 :          0 : QgsTransaction *QgsProviderRegistry::createTransaction( const QString &providerKey, const QString &connString )
     677                 :            : {
     678                 :          0 :   QgsProviderMetadata *meta = findMetadata_( mProviders, providerKey );
     679                 :          0 :   if ( meta )
     680                 :          0 :     return meta->createTransaction( connString );
     681                 :            :   else
     682                 :          0 :     return nullptr;
     683                 :          0 : }
     684                 :            : 
     685                 :          0 : QWidget *QgsProviderRegistry::createSelectionWidget( const QString &providerKey,
     686                 :            :     QWidget *parent, Qt::WindowFlags fl, QgsProviderRegistry::WidgetMode widgetMode )
     687                 :            : {
     688                 :          0 :   Q_UNUSED( providerKey );
     689                 :            :   Q_UNUSED( parent );
     690                 :            :   Q_UNUSED( fl );
     691                 :            :   Q_UNUSED( widgetMode );
     692                 :          0 :   QgsDebugMsg( "deprecated call - use QgsGui::sourceSelectProviderRegistry()->createDataSourceWidget() instead" );
     693                 :          0 :   return nullptr;
     694                 :            : }
     695                 :            : 
     696                 :          0 : QFunctionPointer QgsProviderRegistry::function( QString const &providerKey,
     697                 :            :     QString const &functionName )
     698                 :            : {
     699                 :            :   Q_NOWARN_DEPRECATED_PUSH
     700                 :          0 :   QString lib = library( providerKey );
     701                 :            :   Q_NOWARN_DEPRECATED_POP
     702                 :          0 :   if ( lib.isEmpty() )
     703                 :          0 :     return nullptr;
     704                 :            : 
     705                 :          0 :   QLibrary myLib( lib );
     706                 :            : 
     707                 :          0 :   QgsDebugMsg( "Library name is " + myLib.fileName() );
     708                 :            : 
     709                 :          0 :   if ( myLib.load() )
     710                 :            :   {
     711                 :          0 :     return myLib.resolve( functionName.toLatin1().data() );
     712                 :            :   }
     713                 :            :   else
     714                 :            :   {
     715                 :          0 :     QgsDebugMsg( "Cannot load library: " + myLib.errorString() );
     716                 :          0 :     return nullptr;
     717                 :            :   }
     718                 :          0 : }
     719                 :            : 
     720                 :          0 : QLibrary *QgsProviderRegistry::createProviderLibrary( QString const &providerKey ) const
     721                 :            : {
     722                 :            :   Q_NOWARN_DEPRECATED_PUSH
     723                 :          0 :   QString lib = library( providerKey );
     724                 :            :   Q_NOWARN_DEPRECATED_POP
     725                 :          0 :   if ( lib.isEmpty() )
     726                 :          0 :     return nullptr;
     727                 :            : 
     728                 :          0 :   std::unique_ptr< QLibrary > myLib( new QLibrary( lib ) );
     729                 :            : 
     730                 :          0 :   QgsDebugMsg( "Library name is " + myLib->fileName() );
     731                 :            : 
     732                 :          0 :   if ( myLib->load() )
     733                 :          0 :     return myLib.release();
     734                 :            : 
     735                 :          0 :   QgsDebugMsg( "Cannot load library: " + myLib->errorString() );
     736                 :            : 
     737                 :          0 :   return nullptr;
     738                 :          0 : }
     739                 :            : 
     740                 :          0 : void QgsProviderRegistry::registerGuis( QWidget * )
     741                 :            : {
     742                 :          0 :   QgsDebugMsg( "deprecated - use QgsGui::providerGuiRegistry() instead." );
     743                 :          0 : }
     744                 :            : 
     745                 :          0 : bool QgsProviderRegistry::registerProvider( QgsProviderMetadata *providerMetadata )
     746                 :            : {
     747                 :          0 :   if ( providerMetadata )
     748                 :            :   {
     749                 :          0 :     if ( mProviders.find( providerMetadata->key() ) == mProviders.end() )
     750                 :            :     {
     751                 :          0 :       mProviders[ providerMetadata->key() ] = providerMetadata;
     752                 :          0 :       return true;
     753                 :            :     }
     754                 :            :     else
     755                 :            :     {
     756                 :          0 :       QgsDebugMsgLevel( QStringLiteral( "Cannot register provider metadata: a provider with the same key (%1) was already registered!" ).arg( providerMetadata->key() ), 2 );
     757                 :            :     }
     758                 :          0 :   }
     759                 :            :   else
     760                 :            :   {
     761                 :          0 :     QgsDebugMsgLevel( QStringLiteral( "Trying to register a null metadata provider!" ), 2 );
     762                 :            :   }
     763                 :          0 :   return false;
     764                 :          0 : }
     765                 :            : 
     766                 :          0 : QString QgsProviderRegistry::fileVectorFilters() const
     767                 :            : {
     768                 :          0 :   return mVectorFileFilters;
     769                 :            : }
     770                 :            : 
     771                 :          0 : QString QgsProviderRegistry::fileRasterFilters() const
     772                 :            : {
     773                 :          0 :   return mRasterFileFilters;
     774                 :            : }
     775                 :            : 
     776                 :          0 : QString QgsProviderRegistry::fileMeshFilters() const
     777                 :            : {
     778                 :          0 :   return mMeshFileFilters;
     779                 :            : }
     780                 :            : 
     781                 :          0 : QString QgsProviderRegistry::fileMeshDatasetFilters() const
     782                 :            : {
     783                 :          0 :   return mMeshDatasetFileFilters;
     784                 :            : }
     785                 :            : 
     786                 :          0 : QString QgsProviderRegistry::filePointCloudFilters() const
     787                 :            : {
     788                 :          0 :   return mPointCloudFileFilters;
     789                 :            : }
     790                 :            : 
     791                 :          0 : QString QgsProviderRegistry::databaseDrivers() const
     792                 :            : {
     793                 :          0 :   return mDatabaseDrivers;
     794                 :            : }
     795                 :            : 
     796                 :          0 : QString QgsProviderRegistry::directoryDrivers() const
     797                 :            : {
     798                 :          0 :   return mDirectoryDrivers;
     799                 :            : }
     800                 :            : 
     801                 :          0 : QString QgsProviderRegistry::protocolDrivers() const
     802                 :            : {
     803                 :          0 :   return mProtocolDrivers;
     804                 :            : }
     805                 :            : 
     806                 :          3 : QStringList QgsProviderRegistry::providerList() const
     807                 :            : {
     808                 :          3 :   QStringList lst;
     809                 :         21 :   for ( Providers::const_iterator it = mProviders.begin(); it != mProviders.end(); ++it )
     810                 :            :   {
     811                 :         18 :     lst.append( it->first );
     812                 :         18 :   }
     813                 :          3 :   return lst;
     814                 :          3 : }
     815                 :            : 
     816                 :          3 : QgsProviderMetadata *QgsProviderRegistry::providerMetadata( const QString &providerKey ) const
     817                 :            : {
     818                 :          3 :   return findMetadata_( mProviders, providerKey );
     819                 :            : }
     820                 :            : 
     821                 :          0 : QList<QgsProviderRegistry::ProviderCandidateDetails> QgsProviderRegistry::preferredProvidersForUri( const QString &uri ) const
     822                 :            : {
     823                 :          0 :   QList< QgsProviderRegistry::ProviderCandidateDetails > res;
     824                 :          0 :   int maxPriority = 0;
     825                 :          0 :   for ( auto it = mProviders.begin(); it != mProviders.end(); ++it )
     826                 :            :   {
     827                 :          0 :     if ( !( it->second->capabilities() & QgsProviderMetadata::PriorityForUri ) )
     828                 :          0 :       continue;
     829                 :            : 
     830                 :          0 :     const int thisProviderPriority = it->second->priorityForUri( uri );
     831                 :          0 :     if ( thisProviderPriority == 0 )
     832                 :          0 :       continue;
     833                 :            : 
     834                 :          0 :     if ( thisProviderPriority > maxPriority )
     835                 :            :     {
     836                 :          0 :       res.clear();
     837                 :          0 :       maxPriority = thisProviderPriority;
     838                 :          0 :     }
     839                 :          0 :     if ( thisProviderPriority == maxPriority )
     840                 :            :     {
     841                 :          0 :       res.append( ProviderCandidateDetails( it->second, it->second->validLayerTypesForUri( uri ) ) );
     842                 :          0 :     }
     843                 :          0 :   }
     844                 :          0 :   return res;
     845                 :          0 : }
     846                 :            : 
     847                 :          3 : bool QgsProviderRegistry::registerUnusableUriHandler( QgsProviderRegistry::UnusableUriHandlerInterface *handler )
     848                 :            : {
     849                 :          3 :   mUnusableUriHandlers << handler;
     850                 :          3 :   return true;
     851                 :            : }
     852                 :            : 
     853                 :          0 : bool QgsProviderRegistry::handleUnusableUri( const QString &uri, UnusableUriDetails &details ) const
     854                 :            : {
     855                 :          0 :   for ( const QgsProviderRegistry::UnusableUriHandlerInterface *handler : mUnusableUriHandlers )
     856                 :            :   {
     857                 :          0 :     if ( handler->matchesUri( uri ) )
     858                 :            :     {
     859                 :          0 :       details = handler->details( uri );
     860                 :          0 :       return true;
     861                 :            :     }
     862                 :            :   }
     863                 :          0 :   return false;
     864                 :          0 : }
     865                 :            : 
     866                 :          0 : bool QgsProviderRegistry::shouldDeferUriForOtherProviders( const QString &uri, const QString &providerKey ) const
     867                 :            : {
     868                 :          0 :   const QList< ProviderCandidateDetails > providers = preferredProvidersForUri( uri );
     869                 :          0 :   if ( providers.empty() )
     870                 :          0 :     return false;
     871                 :            : 
     872                 :          0 :   for ( const ProviderCandidateDetails &provider : providers )
     873                 :            :   {
     874                 :          0 :     if ( provider.metadata()->key() == providerKey )
     875                 :          0 :       return false;
     876                 :            :   }
     877                 :          0 :   return true;
     878                 :          0 : }
     879                 :            : 
     880                 :          0 : bool QgsProviderRegistry::uriIsBlocklisted( const QString &uri ) const
     881                 :            : {
     882                 :          0 :   for ( auto it = mProviders.begin(); it != mProviders.end(); ++it )
     883                 :            :   {
     884                 :          0 :     if ( it->second->uriIsBlocklisted( uri ) )
     885                 :          0 :       return true;
     886                 :          0 :   }
     887                 :          0 :   return false;
     888                 :          0 : }

Generated by: LCOV version 1.14