| 30 | namespace OpenMS |
| 31 | { |
| 32 | bool ParamCWLFile::load(const std::string& filename, Param& param) |
| 33 | { |
| 34 | // discover the name of the first nesting Level |
| 35 | // this is expected to result in something like "ToolName:1:" |
| 36 | auto traces = param.begin().getTrace(); |
| 37 | std::string toolNamespace = traces.front().name + ":1:"; |
| 38 | |
| 39 | std::ifstream ifs {filename}; |
| 40 | if (!ifs.good()) |
| 41 | { |
| 42 | throw Exception::FileNotFound(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, filename); |
| 43 | } |
| 44 | try |
| 45 | { |
| 46 | json jsonNode = json::parse(std::ifstream {filename}); |
| 47 | if (!jsonNode.is_object()) |
| 48 | { |
| 49 | std::string msg = "Ignoring JSON file '" + filename + "' because of unexpected data type. Expecting a dictionary as root type."; |
| 50 | throw Exception::ParseError(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "", msg); |
| 51 | } |
| 52 | for (const auto& child : jsonNode.items()) |
| 53 | { |
| 54 | auto key = child.key(); |
| 55 | key = toolNamespace + replaceAll(key, "__", ":"); // This converts __ to ':', but ':' would also be an accepted delimiter |
| 56 | |
| 57 | auto node = child.value(); |
| 58 | if (node.is_null()) |
| 59 | { |
| 60 | continue; // No value given |
| 61 | } |
| 62 | if (!param.exists(key)) |
| 63 | { |
| 64 | OPENMS_LOG_ERROR << "Parameter " << key << " passed to '" << traces.front().name << "' is invalid. To prevent usage of wrong defaults, please update/fix the parameters!" << std::endl; |
| 65 | return false; |
| 66 | } |
| 67 | auto const& entry = param.getEntry(key); |
| 68 | auto value = entry.value; |
| 69 | if (entry.value.valueType() == ParamValue::ValueType::STRING_VALUE) |
| 70 | { |
| 71 | if ((entry.valid_strings.size() == 2 && entry.valid_strings[0] == "true" && entry.valid_strings[1] == "false") || |
| 72 | (entry.valid_strings.size() == 2 && entry.valid_strings[0] == "false" && entry.valid_strings[1] == "true")) |
| 73 | { |
| 74 | value = node.get<bool>() ? "true" : "false"; |
| 75 | } |
| 76 | else if (entry.tags.count("input file")) |
| 77 | { |
| 78 | // If this is an input file and 'is_executable' is set. this can be of 'class: File' or 'type: string' |
| 79 | if (entry.tags.count("is_executable")) |
| 80 | { |
| 81 | if (node.is_object()) |
| 82 | { |
| 83 | value = node["path"].get<std::string>(); |
| 84 | } |
| 85 | else |
| 86 | { |
| 87 | value = node.get<std::string>(); |
| 88 | } |
| 89 | } |