Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
move the QGIS Server validator from the project properties to its own…
… class
  • Loading branch information
Gustry committed Apr 22, 2020
1 parent a270618 commit 471979a
Show file tree
Hide file tree
Showing 9 changed files with 413 additions and 87 deletions.
80 changes: 80 additions & 0 deletions python/core/auto_generated/qgsprojectservervalidator.sip.in
@@ -0,0 +1,80 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsprojectservervalidator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/





class QgsProjectServerValidator
{
%Docstring
Project server validator.

.. versionadded:: 3.14
%End

%TypeHeaderCode
#include "qgsprojectservervalidator.h"
%End
public:

QgsProjectServerValidator();
%Docstring
Constructor for QgsProjectServerValidator.
%End

enum ValidationError
{
DuplicatedNames,
ShortNames,
Encoding
};

static QString displayValidationError( QgsProjectServerValidator::ValidationError error );
%Docstring
Returns a human readable string for a given error.

:param error: the error.

:return: the human readable error.
%End

struct ValidationResult
{

ValidationResult( const QgsProjectServerValidator::ValidationError error, const QVariant &identifier );
%Docstring
Constructor for ValidationResult.
%End

QgsProjectServerValidator::ValidationError error;

QVariant identifier;
};

static bool validate( QgsProject *project, QList< QgsProjectServerValidator::ValidationResult > &results /Out/ );
%Docstring
Validates a project to avoid some problems on QGIS Server, and returns ``True`` if it's considered valid.
If validation fails, the ``results`` list will be filled with a list of
items describing why the validation failed and what needs to be rectified

:param project: input project to check

:return: - bool
- results: results of the validation
%End

};

/************************************************************************
* This file has been generated automatically from *
* *
* src/core/qgsprojectservervalidator.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
1 change: 1 addition & 0 deletions python/core/core_auto.sip
Expand Up @@ -154,6 +154,7 @@
%Include auto_generated/qgsprojectdisplaysettings.sip
%Include auto_generated/qgsprojectfiletransform.sip
%Include auto_generated/qgsprojectproperty.sip
%Include auto_generated/qgsprojectservervalidator.sip
%Include auto_generated/qgsprojectstorage.sip
%Include auto_generated/qgsprojectstorageregistry.sip
%Include auto_generated/qgsprojecttimesettings.sip
Expand Down
101 changes: 16 additions & 85 deletions src/app/qgsprojectproperties.cpp
Expand Up @@ -63,6 +63,7 @@
#include "qgsmessagelog.h"
#include "qgslayercapabilitiesmodel.h"
#include "qgsexpressioncontextutils.h"
#include "qgsprojectservervalidator.h"
#include "qgsprojectstorage.h"
#include "qgsprojectstorageregistry.h"
#include "qgsprojectviewsettings.h"
Expand Down Expand Up @@ -1907,60 +1908,28 @@ void QgsProjectProperties::pbnWCSLayersDeselectAll_clicked()

void QgsProjectProperties::pbnLaunchOWSChecker_clicked()
{
QString myStyle = QgsApplication::reportStyleSheet();
teOWSChecker->clear();
teOWSChecker->document()->setDefaultStyleSheet( myStyle );
teOWSChecker->setHtml( "<h1>" + tr( "Start checking QGIS Server" ) + "</h1>" );

QStringList owsNames, encodingMessages;
checkOWS( QgisApp::instance()->layerTreeView()->layerTreeModel()->rootGroup(), owsNames, encodingMessages );

QStringList duplicateNames, regExpMessages;
QRegExp snRegExp = QgsApplication::shortNameRegExp();
const auto constOwsNames = owsNames;
for ( const QString &name : constOwsNames )
{
if ( !snRegExp.exactMatch( name ) )
regExpMessages << tr( "Use short name for \"%1\"" ).arg( name );
if ( duplicateNames.contains( name ) )
continue;
if ( owsNames.count( name ) > 1 )
duplicateNames << name;
}
QList<QgsProjectServerValidator::ValidationResult> validationResults;
bool results = QgsProjectServerValidator::validate( QgsProject::instance(), validationResults );

if ( !duplicateNames.empty() )
{
QString nameMessage = "<h1>" + tr( "Some layers and groups have the same name or short name" ) + "</h1>";
nameMessage += "<h2>" + tr( "Duplicate names:" ) + "</h2>";
nameMessage += duplicateNames.join( QStringLiteral( "</li><li>" ) ) + "</li></ul>";
teOWSChecker->setHtml( teOWSChecker->toHtml() + nameMessage );
}
else
QString errors;
if ( !results )
{
teOWSChecker->setHtml( teOWSChecker->toHtml() + "<h1>" + tr( "All names and short names of layer and group are unique" ) + "</h1>" );
}

if ( !regExpMessages.empty() )
{
QString encodingMessage = "<h1>" + tr( "Some layer short names have to be updated:" ) + "</h1><ul><li>" + regExpMessages.join( QStringLiteral( "</li><li>" ) ) + "</li></ul>";
teOWSChecker->setHtml( teOWSChecker->toHtml() + encodingMessage );
}
else
{
teOWSChecker->setHtml( teOWSChecker->toHtml() + "<h1>" + tr( "All layer short names are well formed" ) + "</h1>" );
}

if ( !encodingMessages.empty() )
{
QString encodingMessage = "<h1>" + tr( "Some layer encodings are not set:" ) + "</h1><ul><li>" + encodingMessages.join( QStringLiteral( "</li><li>" ) ) + "</li></ul>";
teOWSChecker->setHtml( teOWSChecker->toHtml() + encodingMessage );
for ( const QgsProjectServerValidator::ValidationResult &result : qgis::as_const( validationResults ) )
{
errors += QLatin1String( "<b>" ) % QgsProjectServerValidator::displayValidationError( result.error ) % QLatin1String( " :</b> " );
errors += result.identifier.toString();
}
}
else
{
teOWSChecker->setHtml( teOWSChecker->toHtml() + "<h1>" + tr( "All layer encodings are set" ) + "</h1>" );
errors += QString( tr( "Ok, it seems valid." ) );
}

teOWSChecker->setHtml( teOWSChecker->toHtml() + "<h1>" + tr( "Start checking QGIS Server" ) + "</h1>" );
QString myStyle = QgsApplication::reportStyleSheet();
myStyle.append( QStringLiteral( "body { margin: 10px; }\n " ) );
teOWSChecker->clear();
teOWSChecker->document()->setDefaultStyleSheet( myStyle );
teOWSChecker->setHtml( errors );
}

void QgsProjectProperties::pbnAddScale_clicked()
Expand Down Expand Up @@ -2323,44 +2292,6 @@ void QgsProjectProperties::addWmtsGrid( const QString &crsStr )
twWmtsGrids->blockSignals( false );
}

void QgsProjectProperties::checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages )
{
QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children();
for ( int i = 0; i < treeGroupChildren.size(); ++i )
{
QgsLayerTreeNode *treeNode = treeGroupChildren.at( i );
if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
{
QgsLayerTreeGroup *treeGroupChild = static_cast<QgsLayerTreeGroup *>( treeNode );
QString shortName = treeGroupChild->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
if ( shortName.isEmpty() )
owsNames << treeGroupChild->name();
else
owsNames << shortName;
checkOWS( treeGroupChild, owsNames, encodingMessages );
}
else
{
QgsLayerTreeLayer *treeLayer = static_cast<QgsLayerTreeLayer *>( treeNode );
QgsMapLayer *l = treeLayer->layer();
if ( l )
{
QString shortName = l->shortName();
if ( shortName.isEmpty() )
owsNames << l->name();
else
owsNames << shortName;
if ( l->type() == QgsMapLayerType::VectorLayer )
{
QgsVectorLayer *vl = static_cast<QgsVectorLayer *>( l );
if ( vl->dataProvider()->encoding() == QLatin1String( "System" ) )
encodingMessages << tr( "Update layer \"%1\" encoding" ).arg( l->name() );
}
}
}
}
}

void QgsProjectProperties::populateEllipsoidList()
{
//
Expand Down
2 changes: 0 additions & 2 deletions src/app/qgsprojectproperties.h
Expand Up @@ -251,8 +251,6 @@ class APP_EXPORT QgsProjectProperties : public QgsOptionsDialogBase, private Ui:
void populateWmtsTree( const QgsLayerTreeGroup *treeGroup, QgsTreeWidgetItem *treeItem );
//! add WMTS Grid definition based on CRS
void addWmtsGrid( const QString &crsStr );
//! Check OWS configuration
void checkOWS( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages );

//! Populates list with ellipsoids from Sqlite3 db
void populateEllipsoidList();
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -349,6 +349,7 @@ SET(QGIS_CORE_SRCS
qgssnappingconfig.cpp
qgsprojectdisplaysettings.cpp
qgsprojectproperty.cpp
qgsprojectservervalidator.cpp
qgsprojectstorage.cpp
qgsprojectstorageregistry.cpp
qgsprojecttimesettings.cpp
Expand Down Expand Up @@ -896,6 +897,7 @@ SET(QGIS_CORE_HDRS
qgsprojectdisplaysettings.h
qgsprojectfiletransform.h
qgsprojectproperty.h
qgsprojectservervalidator.h
qgsprojectstorage.h
qgsprojectstorageregistry.h
qgsprojecttimesettings.h
Expand Down
132 changes: 132 additions & 0 deletions src/core/qgsprojectservervalidator.cpp
@@ -0,0 +1,132 @@
/***************************************************************************
qgsprojectservervalidator.cpp
---------------------------
begin : March 2020
copyright : (C) 2020 by Etienne Trimaille
email : etienne dot trimaille at gmail dot com
***************************************************************************/

/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/


#include "qgsapplication.h"
#include "qgslayertreelayer.h"
#include "qgsprojectservervalidator.h"
#include "qgsvectorlayer.h"


QString QgsProjectServerValidator::displayValidationError( QgsProjectServerValidator::ValidationError error )
{
switch ( error )
{
case QgsProjectServerValidator::Encoding:
return QObject::tr( "Encoding is not set properly. A non 'System' encoding is required" );
case QgsProjectServerValidator::ShortNames:
return QObject::tr( "Layer short name is not valid. It must start with an unaccented alphabetical letter, followed by any alphanumeric letters, dot, dash or underscore" );
case QgsProjectServerValidator::DuplicatedNames:
return QObject::tr( "One or more layers or groups have the same name or short name. Both the 'name' and 'short name' for layers and groups needs to be unique" );
}
return QString();
}

void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages )
{
QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children();
for ( int i = 0; i < treeGroupChildren.size(); ++i )
{
QgsLayerTreeNode *treeNode = treeGroupChildren.at( i );
if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
{
QgsLayerTreeGroup *treeGroupChild = static_cast<QgsLayerTreeGroup *>( treeNode );
QString shortName = treeGroupChild->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
if ( shortName.isEmpty() )
owsNames << treeGroupChild->name();
else
owsNames << shortName;
browseLayerTree( treeGroupChild, owsNames, encodingMessages );
}
else
{
QgsLayerTreeLayer *treeLayer = static_cast<QgsLayerTreeLayer *>( treeNode );
QgsMapLayer *layer = treeLayer->layer();
if ( layer )
{
QString shortName = layer->shortName();
if ( shortName.isEmpty() )
owsNames << layer->name();
else
owsNames << shortName;

if ( layer->type() == QgsMapLayerType::VectorLayer )
{
QgsVectorLayer *vl = static_cast<QgsVectorLayer *>( layer );
if ( vl->dataProvider()->encoding() == QLatin1String( "System" ) )
encodingMessages << layer->name();
}
}
}
}
}

bool QgsProjectServerValidator::validate( QgsProject *project, QList<QgsProjectServerValidator::ValidationResult> &results )
{
results.clear();
bool result = true;

if ( !project )
return false;

if ( !project->layerTreeRoot() )
return false;

QStringList owsNames, encodingMessages;
browseLayerTree( project->layerTreeRoot(), owsNames, encodingMessages );

QStringList duplicateNames, regExpMessages;
QRegExp snRegExp = QgsApplication::shortNameRegExp();
const auto constOwsNames = owsNames;
for ( const QString &name : constOwsNames )
{
if ( !snRegExp.exactMatch( name ) )
{
regExpMessages << name;
}

if ( duplicateNames.contains( name ) )
{
continue;
}

if ( owsNames.count( name ) > 1 )
{
duplicateNames << name;
}
}

if ( !duplicateNames.empty() )
{
result = false;
results << ValidationResult( QgsProjectServerValidator::DuplicatedNames, duplicateNames.join( QStringLiteral( ", " ) ) );
}

if ( !regExpMessages.empty() )
{
result = false;
results << ValidationResult( QgsProjectServerValidator::ShortNames, regExpMessages.join( QStringLiteral( ", " ) ) );
}

if ( !encodingMessages.empty() )
{
result = false;
results << ValidationResult( QgsProjectServerValidator::Encoding, encodingMessages.join( QStringLiteral( ", " ) ) );
}

return result;
}

0 comments on commit 471979a

Please sign in to comment.