QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsconfigcache.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsconfigcache.cpp
3  ------------------
4  begin : July 24th, 2010
5  copyright : (C) 2010 by Marco Hugentobler
6  email : marco dot hugentobler at sourcepole dot ch
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 #include "qgsconfigcache.h"
19 #include "qgsmessagelog.h"
20 #include "qgsserverexception.h"
21 #include "qgsstorebadlayerinfo.h"
22 #include "qgsserverprojectutils.h"
23 
24 #include <QFile>
25 
27 {
28  static QgsConfigCache *sInstance = nullptr;
29 
30  if ( !sInstance )
31  sInstance = new QgsConfigCache();
32 
33  return sInstance;
34 }
35 
36 QgsConfigCache::QgsConfigCache()
37 {
38  QObject::connect( &mFileSystemWatcher, &QFileSystemWatcher::fileChanged, this, &QgsConfigCache::removeChangedEntry );
39 }
40 
41 
42 const QgsProject *QgsConfigCache::project( const QString &path, QgsServerSettings *settings )
43 {
44  if ( ! mProjectCache[ path ] )
45  {
46  std::unique_ptr<QgsProject> prj( new QgsProject() );
47  QgsStoreBadLayerInfo *badLayerHandler = new QgsStoreBadLayerInfo();
48  prj->setBadLayerHandler( badLayerHandler );
49  if ( prj->read( path ) )
50  {
51  if ( !badLayerHandler->badLayers().isEmpty() )
52  {
53  // if bad layers are not restricted layers so service failed
54  QStringList unrestrictedBadLayers;
55  // test bad layers through restrictedlayers
56  const QStringList badLayerIds = badLayerHandler->badLayers();
57  const QMap<QString, QString> badLayerNames = badLayerHandler->badLayerNames();
58  const QStringList resctrictedLayers = QgsServerProjectUtils::wmsRestrictedLayers( *prj );
59  for ( const QString &badLayerId : badLayerIds )
60  {
61  // if this bad layer is in restricted layers
62  // it doesn't need to be added to unrestricted bad layers
63  if ( badLayerNames.contains( badLayerId ) &&
64  resctrictedLayers.contains( badLayerNames.value( badLayerId ) ) )
65  {
66  continue;
67  }
68  unrestrictedBadLayers.append( badLayerId );
69  }
70  if ( !unrestrictedBadLayers.isEmpty() )
71  {
72  // This is a critical error unless QGIS_SERVER_IGNORE_BAD_LAYERS is set to TRUE
73  if ( ! settings || ! settings->ignoreBadLayers() )
74  {
76  QStringLiteral( "Error, Layer(s) %1 not valid in project %2" ).arg( unrestrictedBadLayers.join( QStringLiteral( ", " ) ), path ),
77  QStringLiteral( "Server" ), Qgis::Critical );
78  throw QgsServerException( QStringLiteral( "Layer(s) not valid" ) );
79  }
80  else
81  {
83  QStringLiteral( "Warning, Layer(s) %1 not valid in project %2" ).arg( unrestrictedBadLayers.join( QStringLiteral( ", " ) ), path ),
84  QStringLiteral( "Server" ), Qgis::Warning );
85  }
86  }
87  }
88  mProjectCache.insert( path, prj.release() );
89  mFileSystemWatcher.addPath( path );
90  }
91  else
92  {
94  QStringLiteral( "Error when loading project file '%1': %2 " ).arg( path, prj->error() ),
95  QStringLiteral( "Server" ), Qgis::Critical );
96  }
97  }
98  QgsProject::setInstance( mProjectCache[ path ] );
99  return mProjectCache[ path ];
100 
101 }
102 
103 QDomDocument *QgsConfigCache::xmlDocument( const QString &filePath )
104 {
105  //first open file
106  QFile configFile( filePath );
107  if ( !configFile.exists() )
108  {
109  QgsMessageLog::logMessage( "Error, configuration file '" + filePath + "' does not exist", QStringLiteral( "Server" ), Qgis::Critical );
110  return nullptr;
111  }
112 
113  if ( !configFile.open( QIODevice::ReadOnly ) )
114  {
115  QgsMessageLog::logMessage( "Error, cannot open configuration file '" + filePath + "'", QStringLiteral( "Server" ), Qgis::Critical );
116  return nullptr;
117  }
118 
119  // first get cache
120  QDomDocument *xmlDoc = mXmlDocumentCache.object( filePath );
121  if ( !xmlDoc )
122  {
123  //then create xml document
124  xmlDoc = new QDomDocument();
125  QString errorMsg;
126  int line, column;
127  if ( !xmlDoc->setContent( &configFile, true, &errorMsg, &line, &column ) )
128  {
129  QgsMessageLog::logMessage( "Error parsing file '" + filePath +
130  QStringLiteral( "': parse error %1 at row %2, column %3" ).arg( errorMsg ).arg( line ).arg( column ), QStringLiteral( "Server" ), Qgis::Critical );
131  delete xmlDoc;
132  return nullptr;
133  }
134  mXmlDocumentCache.insert( filePath, xmlDoc );
135  mFileSystemWatcher.addPath( filePath );
136  xmlDoc = mXmlDocumentCache.object( filePath );
137  Q_ASSERT( xmlDoc );
138  }
139  return xmlDoc;
140 }
141 
142 void QgsConfigCache::removeChangedEntry( const QString &path )
143 {
144  mProjectCache.remove( path );
145 
146  //xml document must be removed last, as other config cache destructors may require it
147  mXmlDocumentCache.remove( path );
148 
149  mFileSystemWatcher.removePath( path );
150 }
151 
152 
153 void QgsConfigCache::removeEntry( const QString &path )
154 {
155  removeChangedEntry( path );
156 }
QgsStoreBadLayerInfo::badLayerNames
QMap< QString, QString > badLayerNames() const
Returns names of bad layers with ids.
Definition: qgsstorebadlayerinfo.h:69
QgsConfigCache::removeEntry
void removeEntry(const QString &path)
Removes an entry from cache.
Definition: qgsconfigcache.cpp:153
QgsConfigCache
Cache for server configuration.
Definition: qgsconfigcache.h:38
qgsconfigcache.h
Qgis::Warning
@ Warning
Definition: qgis.h:104
QgsConfigCache::instance
static QgsConfigCache * instance()
Returns the current instance.
Definition: qgsconfigcache.cpp:26
qgsserverprojectutils.h
qgsstorebadlayerinfo.h
QgsStoreBadLayerInfo::badLayers
QStringList badLayers() const
badLayers
Definition: qgsstorebadlayerinfo.h:63
QgsProject
Definition: qgsproject.h:92
QgsServerSettings
Provides a way to retrieve settings by prioritizing according to environment variables,...
Definition: qgsserversettings.h:82
QgsServerProjectUtils::wmsRestrictedLayers
SERVER_EXPORT QStringList wmsRestrictedLayers(const QgsProject &project)
Returns the restricted layer name list.
Definition: qgsserverprojectutils.cpp:311
QgsServerSettings::ignoreBadLayers
bool ignoreBadLayers() const
Returns true if the bad layers are ignored and false when the presence of a bad layers invalidates th...
Definition: qgsserversettings.cpp:433
QgsServerException
Exception base class for server exceptions.
Definition: qgsserverexception.h:42
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
Qgis::Critical
@ Critical
Definition: qgis.h:105
QgsConfigCache::project
const QgsProject * project(const QString &path, QgsServerSettings *settings=nullptr)
If the project is not cached yet, then the project is read from the path.
Definition: qgsconfigcache.cpp:42
QgsStoreBadLayerInfo
Definition: qgsstorebadlayerinfo.h:31
qgsserverexception.h
qgsmessagelog.h