QGIS API Documentation 3.99.0-Master (d270888f95f)
Loading...
Searching...
No Matches
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
20
21#include "qgsapplication.h"
22#include "qgslayertreelayer.h"
23#include "qgsvectorlayer.h"
24
25#include <QRegularExpression>
26#include <QString>
27
28using namespace Qt::StringLiterals;
29
31{
32 switch ( error )
33 {
35 return QObject::tr( "Encoding is not correctly set. A non 'System' encoding is required" );
37 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" );
39 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" );
41 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" );
43 return QObject::tr( "The project root name (either the project short name or project title) is already used by a layer or a group" );
45 return QObject::tr( "Use only maptip for HTML GetFeatureInfo response is enabled but the HTML maptip is empty" );
46 }
47 return QString();
48}
49
51template <class T>
52QString getShortName( T *node )
53{
54 const QString shortName = node->serverProperties()->shortName();
55 return shortName.isEmpty() ? node->name() : shortName;
56}
57
58void QgsProjectServerValidator::browseLayerTree( QgsLayerTreeGroup *treeGroup, QStringList &owsNames, QStringList &encodingMessages, QStringList &layerNames, QStringList &maptipTemplates )
59{
60 const QList< QgsLayerTreeNode * > treeGroupChildren = treeGroup->children();
61 for ( int i = 0; i < treeGroupChildren.size(); ++i )
62 {
63 QgsLayerTreeNode *treeNode = treeGroupChildren.at( i );
64 if ( treeNode->nodeType() == QgsLayerTreeNode::NodeGroup )
65 {
66 QgsLayerTreeGroup *treeGroupChild = static_cast<QgsLayerTreeGroup *>( treeNode );
67 owsNames << getShortName( treeGroupChild );
68 browseLayerTree( treeGroupChild, owsNames, encodingMessages, layerNames, maptipTemplates );
69 }
70 else
71 {
72 QgsLayerTreeLayer *treeLayer = static_cast<QgsLayerTreeLayer *>( treeNode );
73 QgsMapLayer *layer = treeLayer->layer();
74 if ( layer )
75 {
76 owsNames << getShortName( layer );
77 if ( layer->type() == Qgis::LayerType::Vector )
78 {
79 QgsVectorLayer *vl = static_cast<QgsVectorLayer *>( layer );
80 if ( vl->dataProvider() && vl->dataProvider()->encoding() == "System"_L1 )
81 encodingMessages << layer->name();
82 }
83 layerNames << treeLayer->name();
84 maptipTemplates << layer->mapTipTemplate();
85 }
86 }
87 }
88}
89
90bool QgsProjectServerValidator::isOnlyMaptipEnabled( QgsProject *project )
91{
92 return project->readBoolEntry(
93 u"WMSHTMLFeatureInfoUseOnlyMaptip"_s,
94 QString(),
95 false
96 );
97}
98
99bool QgsProjectServerValidator::validate( QgsProject *project, QList<QgsProjectServerValidator::ValidationResult> &results )
100{
101 results.clear();
102 bool result = true;
103
104 if ( !project )
105 return false;
106
107 if ( !project->layerTreeRoot() )
108 return false;
109
110 QStringList owsNames, encodingMessages, layerNames, maptipTemplates;
111 browseLayerTree( project->layerTreeRoot(), owsNames, encodingMessages, layerNames, maptipTemplates );
112
113 QStringList duplicateNames, regExpMessages;
114 const thread_local QRegularExpression snRegExp = QgsApplication::shortNameRegularExpression();
115 const auto constOwsNames = owsNames;
116 for ( const QString &name : constOwsNames )
117 {
118 if ( !snRegExp.match( name ).hasMatch() )
119 {
120 regExpMessages << name;
121 }
122
123 if ( duplicateNames.contains( name ) )
124 {
125 continue;
126 }
127
128 if ( owsNames.count( name ) > 1 )
129 {
130 duplicateNames << name;
131 }
132 }
133
134 if ( !duplicateNames.empty() )
135 {
136 result = false;
137 results << ValidationResult( QgsProjectServerValidator::DuplicatedNames, duplicateNames.join( ", "_L1 ) );
138 }
139
140 if ( !regExpMessages.empty() )
141 {
142 result = false;
143 results << ValidationResult( QgsProjectServerValidator::LayerShortName, regExpMessages.join( ", "_L1 ) );
144 }
145
146 if ( !encodingMessages.empty() )
147 {
148 result = false;
149 results << ValidationResult( QgsProjectServerValidator::LayerEncoding, encodingMessages.join( ", "_L1 ) );
150 }
151
152 // Determine the root layername
153 QString rootLayerName = project->readEntry( u"WMSRootName"_s, u"/"_s, "" );
154 if ( rootLayerName.isEmpty() && !project->title().isEmpty() )
155 {
156 rootLayerName = project->title();
157 }
158 if ( !rootLayerName.isEmpty() )
159 {
160 if ( owsNames.count( rootLayerName ) >= 1 )
161 {
162 result = false;
164 }
165
166 if ( !snRegExp.match( rootLayerName ).hasMatch() )
167 {
168 result = false;
170 }
171 }
172 if ( isOnlyMaptipEnabled( project ) )
173 {
174 QStringList emptyLayers;
175 for ( int i = 0; i < maptipTemplates.size(); ++i )
176 {
177 if ( maptipTemplates[i].trimmed().isEmpty() )
178 emptyLayers << layerNames[i];
179 }
180
181 if ( !emptyLayers.isEmpty() )
182 {
183 result = false;
184 QString details = emptyLayers.join( ", "_L1 ).toHtmlEscaped();
185 results << ValidationResult(
187 details );
188 }
189 }
190
191 return result;
192}
@ Vector
Vector layer.
Definition qgis.h:194
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 layer's name.
QgsMapLayer * layer() const
Returns the map layer associated with this node.
@ NodeGroup
Container of other groups and layers.
QList< QgsLayerTreeNode * > children()
Gets list of children of the node. Children are owned by the parent.
NodeType nodeType() const
Find out about type of the node. It is usually shorter to use convenience functions from QgsLayerTree...
QString name
Definition qgsmaplayer.h:87
Qgis::LayerType type
Definition qgsmaplayer.h:93
QString mapTipTemplate
Definition qgsmaplayer.h:96
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.
@ OnlyMaptipTrueButEmptyMaptip
Use only maptip for HTML GetFeatureInfo response is enabled but HTML maptip is empty.
@ 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:112
QString title
Definition qgsproject.h:115
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.
bool readBoolEntry(const QString &scope, const QString &key, bool def=false, bool *ok=nullptr) const
Reads a boolean from the specified scope and key.
QString encoding() const
Returns the encoding which is used for accessing data.
QgsVectorDataProvider * dataProvider() final
Returns the layer's data provider, it may be nullptr.
QString getShortName(T *node)
helper method to retrieve a layer or layer tree group short name
Contains the parameters describing a project validation failure.