Implement support for . in modify_attribute

fixes #9852
This commit is contained in:
Michael Friedrich 2015-08-17 14:55:51 +02:00
parent 428be72bab
commit 13b5acec90
1 changed files with 51 additions and 7 deletions

View File

@ -36,6 +36,8 @@
#include "config/configitem.hpp" #include "config/configitem.hpp"
#include <fstream> #include <fstream>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/exception/errinfo_api_function.hpp> #include <boost/exception/errinfo_api_function.hpp>
#include <boost/exception/errinfo_errno.hpp> #include <boost/exception/errinfo_errno.hpp>
#include <boost/exception/errinfo_file_name.hpp> #include <boost/exception/errinfo_file_name.hpp>
@ -119,28 +121,69 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value)
bool updated_original_attributes = false; bool updated_original_attributes = false;
Type::Ptr type = GetReflectionType(); Type::Ptr type = GetReflectionType();
int fid = type->GetFieldId(attr);
std::vector<String> tokens;
boost::algorithm::split(tokens, attr, boost::is_any_of("."));
String fieldName = tokens[0];
int fid = type->GetFieldId(fieldName);
Field field = type->GetFieldInfo(fid); Field field = type->GetFieldInfo(fid);
Value oldValue = GetField(fid);
if (field.Attributes & FAConfig) { if (field.Attributes & FAConfig) {
if (!original_attributes) { if (!original_attributes) {
original_attributes = new Dictionary(); original_attributes = new Dictionary();
SetOriginalAttributes(original_attributes, true); SetOriginalAttributes(original_attributes, true);
} }
Value attrVal = GetField(fid);
if (!original_attributes->Contains(attr)) { if (!original_attributes->Contains(attr)) {
updated_original_attributes = true; updated_original_attributes = true;
original_attributes->Set(attr, attrVal); original_attributes->Set(attr, oldValue);
} }
} }
ModAttrValidationUtils utils; Value newValue;
ValidateField(fid, value, utils);
//TODO: vars.os if (tokens.size() > 1) {
SetField(fid, value); newValue = oldValue.Clone();
Value current = newValue;
if (current.IsEmpty()) {
current = new Dictionary();
newValue = current;
}
for (std::vector<String>::size_type i = 1; i < tokens.size() - 1; i++) {
if (!current.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Value must be a dictionary."));
Dictionary::Ptr dict = current;
const String& key = tokens[i];
if (!dict->Contains(key)) {
current = new Dictionary();
dict->Set(key, current);
} else {
current = dict->Get(key);
}
}
if (!current.IsObjectType<Dictionary>())
BOOST_THROW_EXCEPTION(std::invalid_argument("Value must be a dictionary."));
Dictionary::Ptr dict = current;
const String& key = tokens[tokens.size() - 1];
dict->Set(key, value);
} else
newValue = value;
ModAttrValidationUtils utils;
ValidateField(fid, newValue, utils);
SetField(fid, newValue);
if (updated_original_attributes) if (updated_original_attributes)
NotifyOriginalAttributes(); NotifyOriginalAttributes();
@ -148,6 +191,7 @@ void ConfigObject::ModifyAttribute(const String& attr, const Value& value)
void ConfigObject::RestoreAttribute(const String& attr) void ConfigObject::RestoreAttribute(const String& attr)
{ {
//TODO-MA: vars.os
Dictionary::Ptr original_attributes = GetOriginalAttributes(); Dictionary::Ptr original_attributes = GetOriginalAttributes();
if (!original_attributes || !original_attributes->Contains(attr)) if (!original_attributes || !original_attributes->Contains(attr))