"qt/git@code.ornl.gov:mantidproject/mantid.git" did not exist on "f38ee06bd4b7e7ddff90c1d94fd02c9035ccfdd1"
Newer
Older
Janik Zikovsky
committed
#include "MantidKernel/CompositeValidator.h"
#include <unordered_set>
Janik Zikovsky
committed
using namespace Mantid::Kernel;
namespace Mantid {
namespace Kernel {
/// Default constructor
CompositeValidator::CompositeValidator(const CompositeRelation &relation)
: IValidator(), m_children(), m_relation(relation) {}
/// Destructor
CompositeValidator::~CompositeValidator() { m_children.clear(); }
* The allowed values for the composite validator. This returns
* the intersection of the allowedValues for the child validators
* @return
*/
std::vector<std::string> CompositeValidator::allowedValues() const {
std::unordered_set<std::string> elem_unique;
std::unordered_multiset<std::string> elem_all;
// how many validators return non-empty list of allowed values
int n_combinations(0);
for (const auto &itr : m_children) {
std::vector<std::string> subs = itr->allowedValues();
if (subs.empty())
continue;
elem_unique.insert(subs.begin(), subs.end());
elem_all.insert(subs.begin(), subs.end());
n_combinations++;
}
// empty or single set of allowed values
if (n_combinations < 2)
return std::vector<std::string>(elem_unique.begin(), elem_unique.end());
// there is more then one combination and we have to identify its union;
for (const auto &its : elem_unique) {
auto im = elem_all.find(its);
for (const auto &im : elem_all) {
rez.insert(im);
}
return std::vector<std::string>(rez.begin(), rez.end());
}
/**
* Clone the validator
* @return A newly constructed validator object. Each child is also cloned
*/
Kernel::IValidator_sptr CompositeValidator::clone() const {
boost::shared_ptr<CompositeValidator> copy =
boost::make_shared<CompositeValidator>(m_relation);
for (const auto &itr : m_children) {
copy->add(itr->clone());
/** Adds a validator to the group of validators to check
* @param child :: A pointer to the validator to add
*/
void CompositeValidator::add(Kernel::IValidator_sptr child) {
m_children.push_back(child);
}
/** Checks the value of all child validators. Fails if any child fails.
* @param value :: The workspace to test
* @return A user level description of the first problem it finds otherwise ""
*/
std::string CompositeValidator::check(const boost::any &value) const {
switch (m_relation) {
case CompositeRelation::AND:
return checkAll(value);
case CompositeRelation::OR:
return checkAny(value);
default:
throw std::runtime_error("Unimplemented composite validator relation");
}
}
std::string CompositeValidator::checkAll(const boost::any &value) const {
const auto error = validator->check(value);
// exit on the first error, to avoid passing doing more tests on invalid
// objects that could fail
if (!error.empty())
return error;
}
// there were no errors
return "";
}
std::string CompositeValidator::checkAny(const boost::any &value) const {
std::stringstream errorStream;
// Lambda to check if a validator is valid. If it is not valid then
// capture its error message to a stream so we can potentially print it out
// to the user if required.
const auto checkIfValid =
[&errorStream, &value](const IValidator_sptr validator) {
const auto errorMessage = validator->check(value);
if (errorMessage.empty()) {
return true;
} else {
// capture error message to possibly later.
errorStream << errorMessage << "\n";
return false;
}
};
const auto valid =
std::any_of(m_children.begin(), m_children.end(), checkIfValid);
return buildErrorMessage(valid, errorStream.str());
}
/** Return a user friendly error message
*
* Returns empty string if no errors were found.
*
* @param valid :: whether all the validator succeded
* @param errors :: the combined list of errors from the child validators
* @return a user friendly message with all the child validator messages
* combined.
*/
std::string
CompositeValidator::buildErrorMessage(const bool valid,
const std::string &errors) const {
if (!valid) {
return "Invalid property. You must statisfy one of the following "
"conditions:\n" +
errors;
} else {
// there were no errors
return "";
}
}
Janik Zikovsky
committed
} // namespace Kernel