95 lines
3.0 KiB
C++
95 lines
3.0 KiB
C++
|
#include "comdelvalidator.h"
|
||
|
|
||
|
namespace domain {
|
||
|
|
||
|
std::vector<ValidationError> ComdelValidator::validateSchema(Schema &schema, ValidationContext context) {
|
||
|
std::vector<ValidationError> errors;
|
||
|
|
||
|
context.instance = nullptr;
|
||
|
context.attribute = nullptr;
|
||
|
|
||
|
for(auto &inst: schema.instances) {
|
||
|
auto *instance = dynamic_cast<ComponentInstance*>(inst);
|
||
|
if(instance) {
|
||
|
auto result = validateComponent(instance, context);
|
||
|
errors.insert(errors.end(), result.begin(), result.end());
|
||
|
}
|
||
|
}
|
||
|
return errors;
|
||
|
}
|
||
|
|
||
|
std::vector<ValidationError> ComdelValidator::validateComponent(ComponentInstance *instance, ValidationContext context) {
|
||
|
std::vector<ValidationError> errors;
|
||
|
|
||
|
context.instance = instance;
|
||
|
context.attributes.clear();
|
||
|
|
||
|
for(auto &attribute: instance->attributes) {
|
||
|
context.attributes[attribute->name] = attribute->value;
|
||
|
}
|
||
|
|
||
|
for(auto &rule: instance->component.getRules()) {
|
||
|
auto result = validateRule(rule, context);
|
||
|
if(result) {
|
||
|
errors.push_back(*result);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(auto &attribute: instance->attributes) {
|
||
|
auto result = validateAttribute(attribute, context);
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
}
|