Line data Source code
1 : /*! 2 : * \file esys/repo/userconfigfileimpl.cpp 3 : * \brief 4 : * 5 : * \cond 6 : * __legal_b__ 7 : * 8 : * Copyright (c) 2023 Michel Gillet 9 : * Distributed under the MIT License. 10 : * (See accompanying file LICENSE.txt or 11 : * copy at https://opensource.org/licenses/MIT) 12 : * 13 : * __legal_e__ 14 : * \endcond 15 : * 16 : */ 17 : 18 : #include "esys/repo/esysrepo_prec.h" 19 : #include "esys/repo/userconfigfileimpl.h" 20 : 21 : #include <esysfile/xml/attr.h> 22 : #include <esysfile/xml/file.h> 23 : #include <esysfile/xml/writer.h> 24 : 25 : namespace esys::repo 26 : { 27 : 28 58 : UserConfigFileImpl::UserConfigFileImpl(UserConfigFile *self) 29 58 : : m_self(self) 30 : { 31 58 : } 32 : 33 58 : UserConfigFileImpl::~UserConfigFileImpl() = default; 34 : 35 58 : Result UserConfigFileImpl::read(const std::string &path) 36 : { 37 58 : esysfile::xml::File xml_file; 38 : 39 58 : xml_file.set_root_node_name("esysrepo_user_config"); 40 58 : int result = xml_file.read(path); 41 58 : if (result < 0) 42 : { 43 : // self()->add_error(result, "XML parsing failed."); 44 0 : return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ERROR_PARSING_FILE, path); 45 : } 46 : 47 116 : if (self()->get_config() == nullptr) 48 0 : self()->set_config(std::make_shared<UserConfig>()); 49 : else 50 116 : self()->get_config()->clear(); 51 : 52 116 : return read(xml_file.get_data()); 53 58 : } 54 : 55 0 : Result UserConfigFileImpl::write(const std::string &path) 56 : { 57 0 : Result result = write_xml(); 58 0 : if (result.error()) return ESYSREPO_RESULT(result); 59 : 60 0 : esysfile::xml::Writer writer; 61 : 62 0 : writer.set_indent(4); 63 0 : int result_int = writer.write(path, m_xml_data); 64 0 : if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int); 65 0 : return ESYSREPO_RESULT(ResultCode::OK); 66 0 : } 67 : 68 0 : Result UserConfigFileImpl::write_xml() 69 : { 70 0 : if (self()->get_config() == nullptr) return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_DATA_NULLPTR); 71 : 72 0 : m_xml_data = std::make_shared<esysfile::xml::Data>(); 73 0 : m_xml_data->set_root_node_name("esysrepo_user_config"); 74 : 75 0 : auto result = write(m_xml_data, self()->get_config()); 76 : 77 0 : return ESYSREPO_RESULT(result); 78 0 : } 79 : 80 0 : Result UserConfigFileImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, 81 : std::shared_ptr<UserConfig> user_config) 82 : { 83 0 : auto paths_el = std::make_shared<esysfile::xml::Element>(); 84 0 : parent_el->add_element(paths_el); 85 : 86 0 : paths_el->set_name("paths"); 87 : 88 0 : auto path_el = paths_el->add_element("path"); 89 0 : path_el->add_attr("name", "manifest_directories"); 90 0 : path_el->add_attr("value", user_config->get_manifest_directories_path()); 91 : 92 0 : path_el = paths_el->add_element("path"); 93 0 : path_el->add_attr("name", "temp"); 94 0 : path_el->add_attr("value", user_config->get_temp_path()); 95 : 96 0 : path_el = paths_el->add_element("path"); 97 0 : path_el->add_attr("name", "traces"); 98 0 : path_el->add_attr("value", user_config->get_traces_path()); 99 : 100 0 : if (user_config->get_manifest_directories() == nullptr) 101 : { 102 0 : auto manifest_directories = std::make_shared<manifest::Directories>(); 103 0 : manifest_directories->add_default_libesys(); 104 0 : user_config->set_manifest_directories(manifest_directories); 105 0 : } 106 : 107 0 : auto result = write(parent_el, user_config->get_manifest_directories()); 108 0 : return ESYSREPO_RESULT(result); 109 0 : } 110 : 111 0 : Result UserConfigFileImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, 112 : std::shared_ptr<manifest::Directories> manifest_directories) 113 : { 114 0 : auto mds_el = parent_el->add_element("manifest_directories"); 115 : 116 0 : for (auto md : manifest_directories->get_items()) 117 : { 118 0 : auto md_el = mds_el->add_element("manifest_directory"); 119 0 : md_el->add_attr("name", md->get_name()); 120 : 121 0 : auto urls_el = md_el->add_element("urls"); 122 0 : auto url_ssh_el = urls_el->add_element("url"); 123 0 : url_ssh_el->add_attr("type", "ssh"); 124 0 : url_ssh_el->add_attr("link", md->get_url_ssh()); 125 : 126 0 : auto url_https_el = urls_el->add_element("url"); 127 0 : url_https_el->add_attr("type", "https"); 128 0 : url_https_el->add_attr("link", md->get_url_https()); 129 0 : } 130 0 : return ESYSREPO_RESULT(ResultCode::OK); 131 0 : } 132 : 133 58 : Result UserConfigFileImpl::read(std::shared_ptr<esysfile::xml::Data> data) 134 : { 135 58 : Result result; 136 58 : auto user_config = self()->get_config(); 137 58 : if (user_config == nullptr) self()->set_config(std::make_shared<UserConfig>()); 138 : 139 174 : for (auto el : data->get_elements()) 140 : { 141 116 : if (el->get_name() == "paths") 142 174 : result = read_paths(el); 143 58 : else if (el->get_name() == "manifest_directories") 144 174 : result = read_manifest_directories(el); 145 : else 146 0 : result = ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ELEMENT_UNKNOWN, el->get_name()); 147 116 : if (result.error()) 148 : { 149 0 : return result; 150 : } 151 116 : } 152 58 : return ESYSREPO_RESULT(ResultCode::OK); 153 58 : } 154 : 155 58 : Result UserConfigFileImpl::read_manifest_directories(std::shared_ptr<esysfile::xml::Element> parent_el) 156 : { 157 58 : if (parent_el->get_name() != "manifest_directories") 158 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_ELEMENT_UNKNOWN, parent_el->get_name()); 159 : 160 122 : if (self()->get_config()->get_manifest_directories() == nullptr) 161 156 : self()->get_config()->set_manifest_directories(std::make_shared<manifest::Directories>()); 162 : 163 116 : for (auto md_el : parent_el->get_elements()) 164 : { 165 58 : if (md_el->get_name() != "manifest_directory") 166 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_ELEMENT_UNKNOWN, md_el->get_name()); 167 : 168 58 : auto attr_name = md_el->get_attr("name"); 169 58 : auto directories_item = std::make_shared<manifest::Directories::Item>(); 170 : 171 58 : directories_item->set_name(attr_name->get_value()); 172 : 173 58 : auto urls_el = md_el->get_element("urls"); 174 58 : if (urls_el == nullptr) return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_MISSING_ELEMENT, "urls"); 175 174 : for (auto url_el : urls_el->get_elements()) 176 : { 177 116 : if (url_el->get_name() != "url") 178 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_MISSING_ELEMENT, url_el->get_name()); 179 116 : auto attr_type = url_el->get_attr("type"); 180 116 : if (attr_type == nullptr) return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_MISSING_ATTR, "type"); 181 116 : auto attr_link = url_el->get_attr("link"); 182 116 : if (attr_link == nullptr) return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_MISSING_ATTR, "link"); 183 : 184 116 : if (attr_type->get_value() == "ssh") 185 58 : directories_item->set_url_ssh(attr_link->get_value()); 186 58 : else if (attr_type->get_value() == "https") 187 58 : directories_item->set_url_https(attr_link->get_value()); 188 : else 189 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_UNKNOWN_ATTR_VALUE, 190 : "type '" + attr_type->get_value() + "'"); 191 348 : } 192 290 : self()->get_config()->get_manifest_directories()->add_item(attr_name->get_value(), directories_item); 193 232 : } 194 58 : return ESYSREPO_RESULT(ResultCode::OK); 195 : } 196 : 197 58 : Result UserConfigFileImpl::read_paths(std::shared_ptr<esysfile::xml::Element> parent_el) 198 : { 199 58 : if (parent_el->get_name() != "paths") 200 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_ELEMENT_UNKNOWN, parent_el->get_name()); 201 : 202 232 : for (auto path_el : parent_el->get_elements()) 203 : { 204 174 : if (path_el->get_name() != "path") 205 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_ELEMENT_UNKNOWN, path_el->get_name()); 206 : 207 174 : auto attr_name = path_el->get_attr("name"); 208 174 : auto attr_link = path_el->get_attr("value"); 209 : 210 174 : if (attr_name == nullptr) return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_MISSING_ATTR, "name"); 211 174 : if (attr_link == nullptr) return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_MISSING_ATTR, "link"); 212 : 213 174 : if (attr_name->get_value() == "manifest_directories") 214 116 : self()->get_config()->set_manifest_directories_path(attr_link->get_value()); 215 116 : else if (attr_name->get_value() == "temp") 216 116 : self()->get_config()->set_temp_path(attr_link->get_value()); 217 58 : else if (attr_name->get_value() == "traces") 218 116 : self()->get_config()->set_traces_path(attr_link->get_value()); 219 : else 220 0 : return ESYSREPO_RESULT(ResultCode::USERCONFIG_XML_UNKNOWN_ATTR_VALUE, attr_name->get_value()); 221 522 : } 222 58 : return ESYSREPO_RESULT(ResultCode::OK); 223 : } 224 : 225 516 : UserConfigFile *UserConfigFileImpl::self() 226 : { 227 516 : return m_self; 228 : } 229 : 230 0 : const UserConfigFile *UserConfigFileImpl::self() const 231 : { 232 0 : return m_self; 233 : } 234 : 235 : } // namespace esys::repo