33 QString makeServiceKey(
const QString &name,
const QString &version )
35 return QString(
"%1_%2" ).arg( name, version );
45 bool isVersionGreater(
const QString &v1,
const QString &v2 )
47 QStringList l1 = v1.split(
'.' );
48 QStringList l2 = v2.split(
'.' );
49 QStringList::iterator it1 = l1.begin();
50 QStringList::iterator it2 = l2.begin();
52 while ( it1 != l1.end() && it2 != l2.end() )
57 int i1 = it1->toInt( &isint );
60 int i2 = it2->toInt( &isint );
61 if ( isint && i1 != i2 )
95 VersionTable::const_iterator v = mServiceVersions.constFind( name );
96 if ( v != mServiceVersions.constEnd() )
98 key = version.isEmpty() ? v->second : makeServiceKey( name, version );
99 ServiceTable::const_iterator it = mServices.constFind( key );
100 if ( it != mServices.constEnd() )
108 service = mServices[v->second].get();
120 QString name = service->
name();
121 QString version = service->
version();
124 QString key = makeServiceKey( name, version );
125 if ( mServices.constFind( key ) != mServices.constEnd() )
131 QgsMessageLog::logMessage( QStringLiteral(
"Adding service %1 %2" ).arg( name, version ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
132 mServices.insert( key, std::shared_ptr<QgsService>( service ) );
139 VersionTable::const_iterator v = mServiceVersions.constFind( name );
140 if ( v == mServiceVersions.constEnd() )
143 mServiceVersions.insert( name, VersionTable::mapped_type( version, key ) );
167 VersionTable::const_iterator v = mApiVersions.constFind( name );
168 if ( v != mApiVersions.constEnd() )
170 if ( version.isEmpty() )
173 ApiTable::iterator it = mApis.begin();
174 while ( it != mApis.end() )
176 if ( ( *it )->name() == name )
179 it = mApis.erase( it );
188 mApiVersions.remove( name );
192 const QString key = makeServiceKey( name, version );
193 ApiTable::iterator found = mApis.find( key );
194 if ( found != mApis.end() )
197 mApis.erase( found );
204 std::function < void (
const ApiTable::mapped_type & ) >
205 findGreaterVersion = [name, &maxVer](
const ApiTable::mapped_type & api )
207 if ( api->name() == name &&
208 ( maxVer.isEmpty() || isVersionGreater( api->version(), maxVer ) ) )
209 maxVer = api->version();
212 mApiVersions.remove( name );
214 std::for_each( mApis.constBegin(), mApis.constEnd(), findGreaterVersion );
215 if ( !maxVer.isEmpty() )
218 const QString key = makeServiceKey( name, maxVer );
219 mApiVersions.insert( name, VersionTable::mapped_type( version, key ) );
229 for (
const auto &api : mApis )
231 QgsMessageLog::logMessage( QStringLiteral(
"Trying URL path: '%1' for '%2'" ).arg( request.
url().path(), api->rootPath() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
232 if ( api->accept( request.
url() ) )
234 Q_ASSERT( !api->name().isEmpty() );
235 QgsMessageLog::logMessage( QStringLiteral(
"API %1 accepts the URL path '%2' " ).arg( api->name(), request.
url().path() ), QStringLiteral(
"Server" ), Qgis::MessageLevel::Info );
248 VersionTable::const_iterator v = mApiVersions.constFind( name );
249 if ( v != mApiVersions.constEnd() )
251 key = version.isEmpty() ? v->second : makeServiceKey( name, version );
252 ApiTable::const_iterator it = mApis.constFind( key );
253 if ( it != mApis.constEnd() )
261 api = mApis[v->second].get();
275 VersionTable::const_iterator v = mServiceVersions.constFind( name );
276 if ( v != mServiceVersions.constEnd() )
278 if ( version.isEmpty() )
281 ServiceTable::iterator it = mServices.begin();
282 while ( it != mServices.end() )
284 if ( ( *it )->name() == name )
287 it = mServices.erase( it );
296 mServiceVersions.remove( name );
300 QString key = makeServiceKey( name, version );
301 ServiceTable::iterator found = mServices.find( key );
302 if ( found != mServices.end() )
305 mServices.erase( found );
312 std::function < void (
const ServiceTable::mapped_type & ) >
313 findGreaterVersion = [name, &maxVer](
const ServiceTable::mapped_type & service )
315 if ( service->name() == name &&
316 ( maxVer.isEmpty() || isVersionGreater( service->version(), maxVer ) ) )
317 maxVer = service->version();
320 mServiceVersions.remove( name );
322 std::for_each( mServices.constBegin(), mServices.constEnd(), findGreaterVersion );
323 if ( !maxVer.isEmpty() )
326 QString key = makeServiceKey( name, maxVer );
327 mServiceVersions.insert( name, VersionTable::mapped_type( version, key ) );
337 mNativeLoader.
loadModules( nativeModulePath, *
this, serverIface );
343 mServiceVersions.clear();
352 const QString name = api->
name();
353 const QString version = api->
version();
356 const QString key = makeServiceKey( name, version );
357 if ( mApis.constFind( key ) != mApis.constEnd() )
363 QgsMessageLog::logMessage( QStringLiteral(
"Adding API %1 %2" ).arg( name, version ), QString(), Qgis::MessageLevel::Info );
364 mApis.insert( key, std::shared_ptr<QgsServerApi>( api ) );
371 VersionTable::const_iterator v = mApiVersions.constFind( name );
372 if ( v == mApiVersions.constEnd() )
375 mApiVersions.insert( name, VersionTable::mapped_type( version, key ) );
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Server generic API endpoint abstract base class.
virtual const QString version() const
Returns the version of the service.
virtual const QString name() const =0
Returns the API name.
QgsServerInterface Class defining interfaces exposed by QGIS Server and made available to plugins.
QgsServerRequest Class defining request interface passed to services QgsService::executeRequest() met...
void unloadModules()
Unload all modules.
void loadModules(const QString &modulePath, QgsServiceRegistry ®istrar, QgsServerInterface *serverIface=nullptr)
Load all modules from path.
void cleanUp()
Clean up registered service and unregister modules.
bool registerApi(QgsServerApi *api)
Registers the QgsServerApi api.
int unregisterService(const QString &name, const QString &version=QString())
Unregister service from its name and version.
int unregisterApi(const QString &name, const QString &version=QString())
Unregisters API from its name and version.
~QgsServiceRegistry()
Destructor.
QgsServerApi * apiForRequest(const QgsServerRequest &request) const
Searches the API register for an API matching the request and returns a (possibly NULL) pointer to it...
void init(const QString &nativeModulepath, QgsServerInterface *serverIface=nullptr)
Initialize registry, load modules and auto register services.
QgsService * getService(const QString &name, const QString &version=QString())
Retrieve a service from its name.
void registerService(QgsService *service)
Register a service by its name and version.
QgsServerApi * getApi(const QString &name, const QString &version=QString())
Retrieves an API from its name.
QgsService Class defining interfaces for QGIS server services.
virtual QString name() const =0
virtual QString version() const =0