|
|
@@ -18,19 +18,8 @@
|
|
|
"PatternLayout"
|
|
|
}
|
|
|
*/
|
|
|
+using namespace logging::property;
|
|
|
namespace logging {
|
|
|
- namespace {
|
|
|
- properties _property(std::map<std::string, properties> const& m) {
|
|
|
- return properties{properties::OBJECT, m, {}, {}};
|
|
|
- }
|
|
|
-// properties _list(std::vector<properties> const& l) {
|
|
|
-// return properties{properties::ARRAY, {}, l, {}};
|
|
|
-// }
|
|
|
- properties _value(std::string const& s) {
|
|
|
- return properties{properties::STRING, {}, {}, s};
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/*
|
|
|
* %d{%h:%M:%s.%_ms} [%t] %-5.5p %.36c - %m%n
|
|
|
*
|
|
|
@@ -46,45 +35,93 @@ namespace logging {
|
|
|
extern properties const DEFAULT_APPENDER_SCHEMA;
|
|
|
extern properties const DEFAULT_LOGGER_SCHEMA;
|
|
|
|
|
|
- static char const * const DEFAULT_PATTERN =
|
|
|
- "%d{%h:%M:%s.%_ms} [%t] %-5.5p %.36c - %m%n";
|
|
|
-
|
|
|
- properties const DEFAULT_APPENDER_SCHEMA{_property({
|
|
|
- {"appenders", _property({
|
|
|
- {"Console", _property({
|
|
|
- {"target", _value("SYSTEM_OUT")},
|
|
|
- {"PatternLayout", _property({
|
|
|
- {"pattern", _value(DEFAULT_PATTERN)}
|
|
|
+ properties const DEFAULT_APPENDER_SCHEMA{_obj({
|
|
|
+ {"appenders", _obj({
|
|
|
+ {"Console", _obj({
|
|
|
+ {"target", _v("SYSTEM_OUT")},
|
|
|
+ {"PatternLayout", _obj({
|
|
|
+ {"pattern", _v("%d{%h:%M:%s.%_ms} [%t] %-5.5p %.36c - %m%n")}
|
|
|
})}
|
|
|
})}
|
|
|
})}
|
|
|
})};
|
|
|
-
|
|
|
- properties const DEFAULT_LOGGER_SCHEMA{_property({
|
|
|
- {"loggers", _property({
|
|
|
- {"root", _property({
|
|
|
- {"level", _value("Error")},
|
|
|
- {"appenders", _property({
|
|
|
- {"ref", _value("Console")}
|
|
|
+
|
|
|
+ properties const DEFAULT_LOGGER_SCHEMA{_obj({
|
|
|
+ {"loggers", _obj({
|
|
|
+ {"root", _obj({
|
|
|
+ {"level", _v("Error")},
|
|
|
+ {"appenders", _obj({
|
|
|
+ {"ref", _v("Console")}
|
|
|
})}
|
|
|
})}
|
|
|
})}
|
|
|
})};
|
|
|
|
|
|
- properties::operator std::string const &() const {
|
|
|
- expects(type == STRING, invalid_property_type, "expected STRING");
|
|
|
- return value;
|
|
|
+ static properties mergeKey(std::string const & key,
|
|
|
+ properties const & defVal,
|
|
|
+ properties const & other) {
|
|
|
+ return other.contains(key) ? defVal.mergedWith(other[key]) : defVal;
|
|
|
+ }
|
|
|
+
|
|
|
+ properties properties::mergedWith(properties const & other) const {
|
|
|
+ if (data.is<object_t>()) {
|
|
|
+ properties out;
|
|
|
+ for (auto & pair : object()) {
|
|
|
+ auto & to = out.data.get<object_t>()[pair.first];
|
|
|
+ to = mergeKey(pair.first, pair.second, other);
|
|
|
+ }
|
|
|
+ return out;
|
|
|
+ } else {
|
|
|
+ return other.data.valid() ? other : *this;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ bool properties::contains(std::string const & key) const {
|
|
|
+ return data.is<object_t>() && object().count(key);
|
|
|
+ }
|
|
|
+
|
|
|
+ bool properties::contains(std::size_t idx) const {
|
|
|
+ return data.is<array_t>() && array().size() < idx;
|
|
|
+ }
|
|
|
+
|
|
|
+ object_t const & properties::object() const {
|
|
|
+ expects(data.is<object_t>(), invalid_property_type, "expected OBJECT");
|
|
|
+ return data.get<object_t>();
|
|
|
}
|
|
|
+
|
|
|
+ array_t const & properties::array() const {
|
|
|
+ expects(data.is<array_t>(), invalid_property_type, "expected ARRAY");
|
|
|
+ return data.get<array_t>();
|
|
|
+ }
|
|
|
+
|
|
|
+ properties const & properties::operator[](std::string const & key) const {
|
|
|
+ expects(data.is<object_t>(), invalid_property_type, "expected OBJECT");
|
|
|
+ expects(contains(key), missing_property, "Missing key: " + key);
|
|
|
+ return object().at(key);
|
|
|
+ }
|
|
|
+
|
|
|
properties const & properties::operator[](std::size_t idx) const {
|
|
|
- expects(type == ARRAY, invalid_property_type, "expected ARRAY");
|
|
|
- expects(idx < array.size(), missing_property,
|
|
|
+ expects(data.is<array_t>(), invalid_property_type, "expected ARRAY");
|
|
|
+ expects(contains(idx), missing_property,
|
|
|
"Out of bounds: " + std::to_string(idx));
|
|
|
- return array.at(idx);
|
|
|
+ return array().at(idx);
|
|
|
}
|
|
|
- properties const & properties::operator[](std::string const & key) const {
|
|
|
- expects(type == OBJECT, invalid_property_type, "expected OBJECT");
|
|
|
- expects(obj.find(key) != obj.end(), missing_property,
|
|
|
- "Missing key: " + key);
|
|
|
- return obj.at(key);
|
|
|
+
|
|
|
+ properties::operator std::string const &() const {
|
|
|
+ expects(data.is<std::string>(), invalid_property_type, "expected STRING");
|
|
|
+ return data.get<std::string>();
|
|
|
+ }
|
|
|
+
|
|
|
+ properties::operator int() const {
|
|
|
+ expects(data.is<int>(), invalid_property_type, "expected INT");
|
|
|
+ return data.get<int>();
|
|
|
}
|
|
|
+
|
|
|
+ properties::operator bool() const {
|
|
|
+ expects(data.is<bool>(), invalid_property_type, "expected BOOL");
|
|
|
+ return data.get<bool>();
|
|
|
+ }
|
|
|
+
|
|
|
+ std::string const & properties::str() const { return *this; }
|
|
|
+
|
|
|
}
|