Skip to content

Commit

Permalink
Server API: simplify contentTypes handling and allow overrides
Browse files Browse the repository at this point in the history
  • Loading branch information
elpaso committed Aug 20, 2019
1 parent dab7481 commit c9c2d3e
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 53 deletions.
2 changes: 1 addition & 1 deletion python/server/auto_generated/qgsserverogcapi.sip.in
Expand Up @@ -80,7 +80,7 @@ QgsServerOgcApi constructor

~QgsServerOgcApi();

virtual void executeRequest( const QgsServerApiContext &context ) const;
virtual void executeRequest( const QgsServerApiContext &context ) const throw( QgsServerApiBadRequestException ) /VirtualErrorHandler=serverapi_badrequest_exception_handler/;
%Docstring
Executes a request by passing the given ``context`` to the API handlers.
%End
Expand Down
20 changes: 11 additions & 9 deletions python/server/auto_generated/qgsserverogcapihandler.sip.in
Expand Up @@ -99,16 +99,11 @@ Tags
%Docstring
Returns the default response content type in case the client did not specifically
ask for any particular content type.
The default implementation returns the first content type returned by
contentTypes() or JSON if that list is empty.
%End


virtual QList<int> contentTypesInt() const /PyName=contentTypes/;
%Docstring
Returns the list of content types this handler can serve, default to JSON and HTML.
In case a specialized type (such as GEOJSON) is supported,
the generic type (such as JSON) should not be listed.
%End

virtual void handleRequest( const QgsServerApiContext &context ) const throw( QgsServerApiBadRequestException ) /VirtualErrorHandler=serverapi_badrequest_exception_handler/;
%Docstring
Handles the request within its ``context``
Expand Down Expand Up @@ -180,7 +175,7 @@ Returns an URL to self, to be used for links to the current resources and as a b
:param extension: optional file extension to add (the dot will be added automatically).
%End

const QString templatePath( const QgsServerApiContext &context ) const;
virtual const QString templatePath( const QgsServerApiContext &context ) const;
%Docstring
Returns the HTML template path for the handler in the given ``context``

Expand All @@ -190,7 +185,7 @@ e.g. for an API with root path "/wfs3" and an handler with operationId "collecti
will be apiResourcesDirectory() + "/ogc/templates/wfs3/collectionItems.html"
%End

const QString staticPath( const QgsServerApiContext &context ) const;
virtual const QString staticPath( const QgsServerApiContext &context ) const;
%Docstring
Returns the absolute path to the base directory where static resources for
this handler are stored in the given ``context``.
Expand Down Expand Up @@ -219,6 +214,13 @@ Returns a vector layer from the ``collectionId`` in the given ``context``



protected:

void setContentTypesInt( const QList<int> &contentTypes ) /PyName=setContentTypes/;
%Docstring
Set the content types to ``contentTypes``
%End


};

Expand Down
1 change: 0 additions & 1 deletion src/server/qgsserverogcapi.cpp
Expand Up @@ -70,7 +70,6 @@ void QgsServerOgcApi::executeRequest( const QgsServerApiContext &context ) const
{
// Get url
auto path { sanitizeUrl( context.request()->url() ).path() };
//path.truncate( context.apiRootPath().length() );
// Find matching handler
auto hasMatch { false };
for ( const auto &h : mHandlers )
Expand Down
2 changes: 1 addition & 1 deletion src/server/qgsserverogcapi.h
Expand Up @@ -101,7 +101,7 @@ class SERVER_EXPORT QgsServerOgcApi : public QgsServerApi
/**
* Executes a request by passing the given \a context to the API handlers.
*/
virtual void executeRequest( const QgsServerApiContext &context ) const override;
virtual void executeRequest( const QgsServerApiContext &context ) const override SIP_THROW( QgsServerApiBadRequestException ) SIP_VIRTUALERRORHANDLER( serverapi_badrequest_exception_handler );

/**
* Returns a map of contentType => mime type
Expand Down
33 changes: 20 additions & 13 deletions src/server/qgsserverogcapihandler.cpp
Expand Up @@ -66,9 +66,14 @@ QgsServerOgcApiHandler::~QgsServerOgcApiHandler()
//qDebug() << "handler destroyed";
}

QgsServerOgcApi::ContentType QgsServerOgcApiHandler::defaultContentType() const
{
return contentTypes().size() > 0 ? contentTypes().first() : QgsServerOgcApi::ContentType::JSON;
}

QList<QgsServerOgcApi::ContentType> QgsServerOgcApiHandler::contentTypes() const
{
return { QgsServerOgcApi::ContentType::JSON, QgsServerOgcApi::ContentType::HTML };
return mContentTypes;
}

void QgsServerOgcApiHandler::handleRequest( const QgsServerApiContext &context ) const
Expand All @@ -77,18 +82,6 @@ void QgsServerOgcApiHandler::handleRequest( const QgsServerApiContext &context )
throw QgsServerApiNotImplementedException( QStringLiteral( "Subclasses must implement handleRequest" ) );
}

QList<int> QgsServerOgcApiHandler::contentTypesInt() const
{
QList<int> ret;
const QList<QgsServerOgcApi::ContentType> constCt { contentTypes() };
for ( const QgsServerOgcApi::ContentType &t : constCt )
{
ret.push_back( static_cast<int>( t ) );
}
return ret;
}


QString QgsServerOgcApiHandler::contentTypeForAccept( const QString &accept ) const
{

Expand Down Expand Up @@ -519,3 +512,17 @@ json QgsServerOgcApiHandler::jsonTags() const
{
return QgsJsonUtils::jsonFromVariant( tags() );
}

void QgsServerOgcApiHandler::setContentTypesInt( const QList<int> &contentTypes )
{
mContentTypes.clear();
for ( const int &i : qgis::as_const( contentTypes ) )
{
mContentTypes.push_back( static_cast<QgsServerOgcApi::ContentType>( i ) );
}
}

void QgsServerOgcApiHandler::setContentTypes( const QList<QgsServerOgcApi::ContentType> &contentTypes )
{
mContentTypes = contentTypes;
}
35 changes: 24 additions & 11 deletions src/server/qgsserverogcapihandler.h
Expand Up @@ -108,23 +108,18 @@ class SERVER_EXPORT QgsServerOgcApiHandler
/**
* Returns the default response content type in case the client did not specifically
* ask for any particular content type.
* The default implementation returns the first content type returned by
* contentTypes() or JSON if that list is empty.
*/
virtual QgsServerOgcApi::ContentType defaultContentType() const { return QgsServerOgcApi::ContentType::JSON; }
virtual QgsServerOgcApi::ContentType defaultContentType() const;

/**
* Returns the list of content types this handler can serve, default to JSON and HTML.
* In case a specialized type (such as GEOJSON) is supported,
* the generic type (such as JSON) should not be listed.
* \note not available in Python bindings
*/
virtual QList<QgsServerOgcApi::ContentType> contentTypes() const SIP_SKIP;

/**
* Returns the list of content types this handler can serve, default to JSON and HTML.
* In case a specialized type (such as GEOJSON) is supported,
* the generic type (such as JSON) should not be listed.
*/
virtual QList<int> contentTypesInt() const SIP_PYNAME( contentTypes );
QList<QgsServerOgcApi::ContentType> contentTypes() const SIP_SKIP;

/**
* Handles the request within its \a context
Expand Down Expand Up @@ -293,14 +288,14 @@ class SERVER_EXPORT QgsServerOgcApiHandler
* e.g. for an API with root path "/wfs3" and an handler with operationId "collectionItems", the path
* will be apiResourcesDirectory() + "/ogc/templates/wfs3/collectionItems.html"
*/
const QString templatePath( const QgsServerApiContext &context ) const;
virtual const QString templatePath( const QgsServerApiContext &context ) const;

/**
* Returns the absolute path to the base directory where static resources for
* this handler are stored in the given \a context.
*
*/
const QString staticPath( const QgsServerApiContext &context ) const;
virtual const QString staticPath( const QgsServerApiContext &context ) const;

/**
* Returns the content type from the \a request.
Expand Down Expand Up @@ -339,6 +334,24 @@ class SERVER_EXPORT QgsServerOgcApiHandler
*/
json jsonTags( ) const SIP_SKIP;

protected:

/**
* Set the content types to \a contentTypes
*/
void setContentTypesInt( const QList<int> &contentTypes ) SIP_PYNAME( setContentTypes );

/**
* Set the content types to \a contentTypes
* \note not available in Python bindings
*/
void setContentTypes( const QList<QgsServerOgcApi::ContentType> &contentTypes ) SIP_SKIP;

private:

//! List of content types this handler can serve, first is the default
QList<QgsServerOgcApi::ContentType> mContentTypes = { QgsServerOgcApi::ContentType::JSON, QgsServerOgcApi::ContentType::HTML };


};

Expand Down
5 changes: 4 additions & 1 deletion src/server/services/wfs3/qgswfs3handlers.cpp
Expand Up @@ -35,6 +35,7 @@
QgsWfs3APIHandler::QgsWfs3APIHandler( const QgsServerOgcApi *api ):
mApi( api )
{
setContentTypes( { QgsServerOgcApi::ContentType::OPENAPI3, QgsServerOgcApi::ContentType::HTML } );
}

void QgsWfs3APIHandler::handleRequest( const QgsServerApiContext &context ) const
Expand Down Expand Up @@ -188,7 +189,6 @@ json QgsWfs3APIHandler::schema( const QgsServerApiContext &context ) const

QgsWfs3LandingPageHandler::QgsWfs3LandingPageHandler()
{

}

void QgsWfs3LandingPageHandler::handleRequest( const QgsServerApiContext &context ) const
Expand Down Expand Up @@ -620,6 +620,7 @@ json QgsWfs3DescribeCollectionHandler::schema( const QgsServerApiContext &contex

QgsWfs3CollectionsItemsHandler::QgsWfs3CollectionsItemsHandler()
{
setContentTypes( { QgsServerOgcApi::ContentType::GEOJSON, QgsServerOgcApi::ContentType::HTML } );
}

QList<QgsServerQueryStringParameter> QgsWfs3CollectionsItemsHandler::parameters( const QgsServerApiContext &context ) const
Expand Down Expand Up @@ -1053,6 +1054,7 @@ void QgsWfs3CollectionsItemsHandler::handleRequest( const QgsServerApiContext &c

QgsWfs3CollectionsFeatureHandler::QgsWfs3CollectionsFeatureHandler()
{
setContentTypes( { QgsServerOgcApi::ContentType::GEOJSON, QgsServerOgcApi::ContentType::HTML } );
}

void QgsWfs3CollectionsFeatureHandler::handleRequest( const QgsServerApiContext &context ) const
Expand Down Expand Up @@ -1171,6 +1173,7 @@ json QgsWfs3CollectionsFeatureHandler::schema( const QgsServerApiContext &contex

QgsWfs3StaticHandler::QgsWfs3StaticHandler()
{
setContentTypes( { QgsServerOgcApi::ContentType::HTML } );
}

void QgsWfs3StaticHandler::handleRequest( const QgsServerApiContext &context ) const
Expand Down
16 changes: 0 additions & 16 deletions src/server/services/wfs3/qgswfs3handlers.h
Expand Up @@ -39,9 +39,7 @@ class QgsWfs3APIHandler: public QgsServerOgcApiHandler
std::string description() const override { return "The formal documentation of this API according to the OpenAPI specification, version 3.0. I.e., this document."; }
std::string linkTitle() const override { return "API definition"; }
QStringList tags() const override { return { QStringLiteral( "Capabilities" ) }; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::OPENAPI3, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::service_desc; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::OPENAPI3; }
json schema( const QgsServerApiContext &context ) const override;

private:
Expand All @@ -67,9 +65,7 @@ class QgsWfs3StaticHandler: public QgsServerOgcApiHandler
std::string summary() const override { return "Serves static files"; }
std::string description() const override { return "Serves static files"; }
std::string linkTitle() const override { return "Serves static files"; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::data; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::HTML; }

};

Expand All @@ -96,9 +92,7 @@ class QgsWfs3LandingPageHandler: public QgsServerOgcApiHandler
"statements and the metadata about the feature data in this dataset.";
}
std::string linkTitle() const override { return "Landing page"; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::JSON, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::self; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::JSON; }
json schema( const QgsServerApiContext &context ) const override;
};

Expand All @@ -122,9 +116,7 @@ class QgsWfs3ConformanceHandler: public QgsServerOgcApiHandler
}
QStringList tags() const override { return { QStringLiteral( "Capabilities" ) }; }
std::string linkTitle() const override { return "WFS 3.0 conformance classes"; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::JSON, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::conformance; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::JSON; }
json schema( const QgsServerApiContext &context ) const override;
};

Expand Down Expand Up @@ -155,9 +147,7 @@ class QgsWfs3CollectionsHandler: public QgsServerOgcApiHandler
"statements and the metadata about the feature data in this dataset.";
}
std::string linkTitle() const override { return "Feature collections"; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::JSON, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::data; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::JSON; }
json schema( const QgsServerApiContext &context ) const override;
};

Expand All @@ -177,9 +167,7 @@ class QgsWfs3DescribeCollectionHandler: public QgsServerOgcApiHandler
std::string description() const override { return "Metadata about a feature collection."; }
std::string linkTitle() const override { return "Feature collection"; }
QStringList tags() const override { return { QStringLiteral( "Capabilities" ) }; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::JSON, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::data; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::JSON; }
json schema( const QgsServerApiContext &context ) const override;
};

Expand All @@ -205,9 +193,7 @@ class QgsWfs3CollectionsItemsHandler: public QgsServerOgcApiHandler
}
std::string linkTitle() const override { return "Retrieve the features of the collection"; }
QStringList tags() const override { return { QStringLiteral( "Features" ) }; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::GEOJSON, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::data; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::GEOJSON; }
QList<QgsServerQueryStringParameter> parameters( const QgsServerApiContext &context ) const override;
json schema( const QgsServerApiContext &context ) const override;

Expand All @@ -229,9 +215,7 @@ class QgsWfs3CollectionsFeatureHandler: public QgsServerOgcApiHandler
std::string summary() const override { return "Retrieve a single feature"; }
std::string linkTitle() const override { return "Retrieve a feature"; }
QStringList tags() const override { return { QStringLiteral( "Features" ) }; }
QList<QgsServerOgcApi::ContentType> contentTypes() const override { return { QgsServerOgcApi::ContentType::GEOJSON, QgsServerOgcApi::ContentType::HTML }; }
QgsServerOgcApi::Rel linkType() const override { return QgsServerOgcApi::Rel::data; }
QgsServerOgcApi::ContentType defaultContentType() const override { return QgsServerOgcApi::ContentType::GEOJSON; }
json schema( const QgsServerApiContext &context ) const override;
};

Expand Down

0 comments on commit c9c2d3e

Please sign in to comment.