Mantid
Loading...
Searching...
No Matches
FileValidator.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
9#include <Poco/File.h>
10#include <Poco/Path.h>
11#include <boost/algorithm/string/case_conv.hpp>
12#include <fstream>
13#include <memory>
14#include <sstream>
15
16namespace Mantid::Kernel {
17
18namespace {
19// Initialize the static logger
20Logger g_log("FileValidator");
21} // namespace
22
28FileValidator::FileValidator(const std::vector<std::string> &extensions, bool testFileExists)
29 : TypedValidator<std::string>(), m_testExist(testFileExists) {
30 for (const auto &extension : extensions) {
31 const std::string ext = boost::to_lower_copy(extension);
32 if (std::find(m_extensions.begin(), m_extensions.end(), ext) == m_extensions.end()) {
33 m_extensions.emplace_back(ext);
34 }
35 }
36}
37
39std::vector<std::string> FileValidator::allowedValues() const { return m_extensions; }
40
45IValidator_sptr FileValidator::clone() const { return std::make_shared<FileValidator>(*this); }
46
52std::string FileValidator::checkValidity(const std::string &value) const {
53 // Check if the path is syntactically valid
54 if (!Poco::Path().tryParse(value)) {
55 return "Error in path syntax: \"" + value + "\".";
56 }
57
58 // Check the extension but just issue a warning if it is not one of the
59 // suggested values
60 if (!(value.empty())) {
61 if (!(this->endswith(value))) {
62 // Dropped from warning to debug level as it was printing out on every
63 // search of the archive, even when successful. re #5998
64 g_log.debug() << "Unrecognised extension in file \"" << value << "\"";
65 if (!this->m_extensions.empty()) {
66 g_log.debug() << " [ ";
67 for (const auto &extension : this->m_extensions)
68 g_log.debug() << extension << " ";
69 g_log.debug() << "]";
70 }
71 g_log.debug() << "\".\n";
72 }
73 }
74
75 // create a variable for the absolute path to be used in error messages
76 std::string abspath(value);
77 if (!value.empty()) {
78 Poco::Path path(value);
79 if (path.isAbsolute())
80 abspath = path.toString();
81 }
82
83 // If the file is required to exist check it is there
84 if (m_testExist && (value.empty() || !Poco::File(value).exists())) {
85 return "File \"" + abspath + "\" not found";
86 }
87
88 if (m_testExist && (Poco::File(value).exists())) {
89 std::ifstream in;
90 in.open(value.c_str());
91 if (!in) {
92 std::stringstream error;
93 error << "Failed to open " + value + ": " << strerror(errno);
94 return error.str();
95 }
96 }
97
98 // Otherwise we are okay, file extensions are just a suggestion so no
99 // validation on them is necessary
100 return "";
101}
102
108bool has_ending(const std::string &value, const std::string &ending) {
109 if (ending.empty()) // always match against an empty extension
110 return true;
111 if (value.length() < ending.length()) // filename is not long enough
112 return false;
113 int result = value.compare(value.length() - ending.length(), ending.length(), ending);
114 return (result == 0); // only care if it matches
115}
116
122bool FileValidator::endswith(const std::string &value) const {
123 if (m_extensions.empty()) // automatically match a lack of extensions
124 return true;
125 if ((m_extensions.size() == 1) && (m_extensions.begin()->empty()))
126 return true;
127
128 // create a lowercase copy of the filename
129 std::string value_copy(value);
130 std::transform(value_copy.begin(), value_copy.end(), value_copy.begin(), tolower);
131
132 // check for the ending
133 for (const auto &extension : m_extensions) {
134 if (has_ending(value, extension)) // original case
135 return true;
136 if (has_ending(value_copy, extension)) // lower case
137 return true;
138 }
139 return false;
140}
141
142} // namespace Mantid::Kernel
double value
The value of the point.
Definition: FitMW.cpp:51
double error
Definition: IndexPeaks.cpp:133
bool m_testExist
Flag indicating whether to test for existence of filename.
Definition: FileValidator.h:36
std::string checkValidity(const std::string &value) const override
If m_fullTest=true if checks that the files exists, otherwise just that path syntax looks valid.
bool endswith(const std::string &value) const
Checks the extension of a filename.
std::vector< std::string > m_extensions
The list of permitted extensions.
Definition: FileValidator.h:34
std::vector< std::string > allowedValues() const override
Returns the set of valid values.
IValidator_sptr clone() const override
Clone the validator.
FileValidator(const std::vector< std::string > &extensions=std::vector< std::string >(), bool testFileExists=true)
Constructor.
void debug(const std::string &msg)
Logs at debug level.
Definition: Logger.cpp:114
bool exists(::NeXus::File &file, const std::string &name)
Based on the current group in the file, does the named sub-entry exist?
bool has_ending(const std::string &value, const std::string &ending)
Confirm that the value string ends with then ending string.
std::shared_ptr< IValidator > IValidator_sptr
A shared_ptr to an IValidator.
Definition: IValidator.h:26
STL namespace.