QGIS API Documentation 3.37.0-Master (fdefdf9c27f)
qgsprojectservervalidator.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprojectservervalidator.cpp
3 ---------------------------
4 begin : March 2020
5 copyright : (C) 2020 by Etienne Trimaille
6 email : etienne dot trimaille at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18
19#include "qgsapplication.h"
20#include "qgslayertreelayer.h"
22#include "qgsvectorlayer.h"
23
24#include <QRegularExpression>
25
27{
28 switch ( error )
29 {
31 return QObject::tr( "Encoding is not correctly set. A non 'System' encoding is required" );
33 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" );
35 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 must be unique" );
37 return QObject::tr( "The project root name (either the project short name or project title) is not valid. It must start with an unaccented alphabetical letter, followed by any alphanumeric letters, dot, dash or underscore" );
39 return QObject::tr( "The project root name (either the project short name or project title) is already used by a layer or a group" );
40 }
41 return QString();
42}
43
44void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages )
45{
46 const QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children();
47 for ( int i = 0; i < treeGroupChildren.size(); ++i )
48 {
49 QgsLayerTreeNode *treeNode = treeGroupChildren.at( i );
50 if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
51 {
52 QgsLayerTreeGroup *treeGroupChild = static_cast<QgsLayerTreeGroup *>( treeNode );
53 const QString shortName = treeGroupChild->customProperty( QStringLiteral( "wmsShortName" ) ).toString();
54 if ( shortName.isEmpty() )
55 owsNames << treeGroupChild->name();
56 else
57 owsNames << shortName;
58 browseLayerTree( treeGroupChild, owsNames, encodingMessages );
59 }
60 else
61 {
62 QgsLayerTreeLayer *treeLayer = static_cast<QgsLayerTreeLayer *>( treeNode );
63 QgsMapLayer *layer = treeLayer->layer();
64 if ( layer )
65 {
66 const QString shortName = layer->shortName();
67 if ( shortName.isEmpty() )
68 owsNames << layer->name();
69 else
70 owsNames << shortName;
71
72 if ( layer->type() == Qgis::LayerType::Vector )
73 {
74 QgsVectorLayer *vl = static_cast<QgsVectorLayer *>( layer );
75 if ( vl->dataProvider() && vl->dataProvider()->encoding() == QLatin1String( "System" ) )
76 encodingMessages << layer->name();
77 }
78 }
79 }
80 }
81}
82
83bool QgsProjectServerValidator::validate( QgsProject *project, QList<QgsProjectServerValidator::ValidationResult> &results )
84{
85 results.clear();
86 bool result = true;
87
88 if ( !project )
89 return false;
90
91 if ( !project->layerTreeRoot() )
92 return false;
93
94 QStringList owsNames, encodingMessages;
95 browseLayerTree( project->layerTreeRoot(), owsNames, encodingMessages );
96
97 QStringList duplicateNames, regExpMessages;
98 const thread_local QRegularExpression snRegExp = QgsApplication::shortNameRegularExpression();
99 const auto constOwsNames = owsNames;
100 for ( const QString &name : constOwsNames )
101 {
102 if ( !snRegExp.match( name ).hasMatch() )
103 {
104 regExpMessages << name;
105 }
106
107 if ( duplicateNames.contains( name ) )
108 {
109 continue;
110 }
111
112 if ( owsNames.count( name ) > 1 )
113 {
114 duplicateNames << name;
115 }
116 }
117
118 if ( !duplicateNames.empty() )
119 {
120 result = false;
121 results << ValidationResult( QgsProjectServerValidator::DuplicatedNames, duplicateNames.join( QLatin1String( ", " ) ) );
122 }
123
124 if ( !regExpMessages.empty() )
125 {
126 result = false;
127 results << ValidationResult( QgsProjectServerValidator::LayerShortName, regExpMessages.join( QLatin1String( ", " ) ) );
128 }
129
130 if ( !encodingMessages.empty() )
131 {
132 result = false;
133 results << ValidationResult( QgsProjectServerValidator::LayerEncoding, encodingMessages.join( QLatin1String( ", " ) ) );
134 }
135
136 // Determine the root layername
137 QString rootLayerName = project->readEntry( QStringLiteral( "WMSRootName" ), QStringLiteral( "/" ), "" );
138 if ( rootLayerName.isEmpty() && !project->title().isEmpty() )
139 {
140 rootLayerName = project->title();
141 }
142 if ( !rootLayerName.isEmpty() )
143 {
144 if ( owsNames.count( rootLayerName ) >= 1 )
145 {
146 result = false;
148 }
149
150 if ( !snRegExp.match( rootLayerName ).hasMatch() )
151 {
152 result = false;
154 }
155 }
156
157 return result;
158}
@ Vector
Vector layer.
static QRegularExpression shortNameRegularExpression()
Returns the short name regular expression for line edit validator.
Layer tree group node serves as a container for layers and further groups.
QString name() const override
Returns the group's name.
Layer tree node points to a map layer.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
This class is a base class for nodes in a layer tree.
@ NodeGroup
Container of other groups and layers.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer. Properties are stored in a map and saved in project file.
NodeType nodeType() const
Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree...
Base class for all map layer types.
Definition: qgsmaplayer.h:75
QString name
Definition: qgsmaplayer.h:78
Qgis::LayerType type
Definition: qgsmaplayer.h:82
QString shortName() const
Returns the short name of the layer used by QGIS Server to identify the layer.
static QString displayValidationError(QgsProjectServerValidator::ValidationError error)
Returns a human readable string for a given error.
ValidationError
Errors that might be raised by the validation process.
@ LayerEncoding
Encoding is not correctly set on a vector layer.
@ ProjectRootNameConflict
The project root name is already used by a layer or a group.
@ ProjectShortName
The project short name is not valid.
@ DuplicatedNames
A duplicated layer/group name in the layer tree.
@ LayerShortName
Layer/group short name is not valid.
static bool validate(QgsProject *project, QList< QgsProjectServerValidator::ValidationResult > &results)
Validates a project to detect problems on QGIS Server, and returns true if it's considered valid.
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:107
QString title() const
Returns the project's title.
Definition: qgsproject.cpp:506
QString readEntry(const QString &scope, const QString &key, const QString &def=QString(), bool *ok=nullptr) const
Reads a string from the specified scope and key.
QgsLayerTree * layerTreeRoot() const
Returns pointer to the root (invisible) node of the project's layer tree.
QString encoding() const
Returns the encoding which is used for accessing data.
Represents a vector layer which manages a vector based data sets.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
Contains the parameters describing a project validation failure.