schema_editor/comdel/domain/comdelvalidator.cpp

92 lines
2.9 KiB
C++
Raw Normal View History

2022-04-10 12:23:18 +00:00
#include "comdelvalidator.h"
namespace domain {
std::vector<ValidationError> ComdelValidator::validateSchema(Schema &schema, ValidationContext context) {
std::vector<ValidationError> errors;
context.instance = nullptr;
context.attribute = nullptr;
2022-05-07 11:20:09 +00:00
for(auto &instance: schema.componentInstances) {
2022-05-07 12:19:43 +00:00
auto result = validateComponent(instance.get(), context);
2022-05-07 11:20:09 +00:00
errors.insert(errors.end(), result.begin(), result.end());
2022-04-10 12:23:18 +00:00
}
return errors;
}
2022-05-07 12:19:43 +00:00
std::vector<ValidationError> ComdelValidator::validateComponent(ComponentInstance* instance, ValidationContext context) {
2022-04-10 12:23:18 +00:00
std::vector<ValidationError> errors;
context.instance = instance;
context.attributes.clear();
for(auto &attribute: instance->attributes) {
2022-05-07 12:19:43 +00:00
context.attributes[attribute.name] = attribute.value;
2022-04-10 12:23:18 +00:00
}
for(auto &rule: instance->component.getRules()) {
auto result = validateRule(rule, context);
if(result) {
errors.push_back(*result);
}
}
for(auto &attribute: instance->attributes) {
2022-05-07 12:19:43 +00:00
auto result = validateAttribute(&attribute, context);
2022-04-10 12:23:18 +00:00
errors.insert(errors.end(), result.begin(), result.end());
}
return errors;
}
std::vector<ValidationError> ComdelValidator::validateAttribute(InstanceAttribute *attribute, ValidationContext context) {
std::vector<ValidationError> errors;
if(attribute->attribute.getPopup()) {
Popup popup = *attribute->attribute.getPopup();
context.attribute = attribute;
context.attributes = std::map<std::string, Value>{{attribute->name, attribute->value}};
for(auto &rule: popup.getRules()) {
auto result = validateRule(rule, context);
if(result) {
errors.push_back(*result);
}
}
}
return errors;
}
std::optional<ValidationError> ComdelValidator::validateRule(Rule rule, ValidationContext context) {
RuleContext ruleContext;
ruleContext.addressSpaces = context.addressSpaces;
ruleContext.attributes = context.attributes;
ruleContext.function = callbacks;
auto action = rule.evaluate(ruleContext);
if (action) {
std::string message = this->populateMessage(action->getMessage(), context);
return ValidationError{context.instance, context.attribute, action->getType(), message};
}
return nullopt;
}
std::string ComdelValidator::populateMessage(string source, ValidationContext context) {
for(auto &[key, value]: context.attributes) {
source = replacePlaceholder(source, key, value);
}
return source;
}
string ComdelValidator::replacePlaceholder(string source, string key, Value value) {
key = "{" + key + "}";
auto placeholderValue = value.string();
auto found = source.find(key);
while(found != string::npos) {
source.replace(found, key.length(), placeholderValue);
found = source.find(key);
}
return source;
}
}