Line data Source code
1 : /*! 2 : * \file esys/repo/manifest/directoryfilexmlimpl_manifest.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/manifest/directoryfilexmlimpl.h" 20 : 21 : #include <esysfile/xml/writer.h> 22 : #include <esysfile/xml/file.h> 23 : #include <esysfile/xml/attr.h> 24 : 25 : namespace esys::repo::manifest 26 : { 27 : 28 4 : DirectoryFileXMLImpl::DirectoryFileXMLImpl(DirectoryFileXML *self) 29 4 : : m_self(self) 30 : { 31 4 : } 32 : 33 4 : DirectoryFileXMLImpl::~DirectoryFileXMLImpl() = default; 34 : 35 3 : Result DirectoryFileXMLImpl::read(const std::string &path) 36 : { 37 3 : esysfile::xml::File xml_file; 38 : 39 3 : xml_file.set_root_node_name("esysrepo_manifest_dir"); 40 3 : int result = xml_file.read(path); 41 3 : 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 4 : if (self()->get_directory() == nullptr) 48 6 : self()->set_directory(std::make_shared<Directory>()); 49 : else 50 2 : self()->get_directory()->clear(); 51 : 52 6 : return read(xml_file.get_data()); 53 3 : } 54 : 55 4 : Result DirectoryFileXMLImpl::read(std::shared_ptr<esysfile::xml::Data> data) 56 : { 57 4 : Result result; 58 4 : auto directory = self()->get_directory(); 59 4 : auto name = data->get_attr("name"); 60 : 61 4 : if (name != nullptr) directory->set_name(name->get_value()); 62 : 63 8 : for (auto el : data->get_elements()) 64 : { 65 4 : if (el->get_name() == "projects") 66 12 : result = read_projects(el); 67 : else 68 0 : result = ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ELEMENT_UNKNOWN, el->get_name()); 69 4 : if (result.error()) 70 : { 71 0 : return result; 72 : } 73 4 : } 74 4 : return ESYSREPO_RESULT(ResultCode::OK); 75 8 : } 76 : 77 4 : Result DirectoryFileXMLImpl::read_projects(std::shared_ptr<esysfile::xml::Element> el) 78 : { 79 4 : if (el->get_name() != "projects") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 80 : 81 4 : auto directory = self()->get_directory(); 82 : 83 26 : for (auto project_el : el->get_elements()) 84 : { 85 22 : if (project_el->get_name() != "project") 86 0 : return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ELEMENT_UNKNOWN, el->get_name()); 87 : 88 22 : auto item = std::make_shared<Directory::Item>(); 89 22 : auto name_attr = project_el->get_attr("name"); 90 22 : item->set_name(name_attr->get_value()); 91 : 92 22 : auto urls_el = project_el->get_element("urls"); 93 : 94 66 : for (auto url_el : urls_el->get_elements()) 95 : { 96 44 : auto type_attr = url_el->get_attr("type"); 97 44 : if (type_attr == nullptr) return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_MISSING_ATTR, "type"); 98 : 99 44 : auto link_attr = url_el->get_attr("link"); 100 44 : if (link_attr == nullptr) return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_MISSING_ATTR, "link"); 101 : 102 44 : if (type_attr->get_value() == "ssh") 103 22 : item->set_url_ssh(link_attr->get_value()); 104 22 : else if (type_attr->get_value() == "https") 105 22 : item->set_url_https(link_attr->get_value()); 106 : else 107 : { 108 0 : return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_UNKNOWN_URL_TYPE, type_attr->get_value()); 109 : } 110 132 : } 111 : 112 66 : directory->add_item(item); 113 88 : } 114 : 115 4 : return ESYSREPO_RESULT(ResultCode::OK); 116 4 : } 117 : 118 1 : Result DirectoryFileXMLImpl::read(std::istream &is) 119 : { 120 1 : esysfile::xml::File xml_file; 121 : 122 1 : xml_file.set_root_node_name("esysrepo_manifest_dir"); 123 1 : int result = xml_file.read(is); 124 1 : if (result < 0) 125 : { 126 0 : return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_ERROR_PARSING_STREAM); 127 : } 128 : 129 2 : if (self()->get_directory() == nullptr) 130 0 : self()->set_directory(std::make_shared<Directory>()); 131 : else 132 2 : self()->get_directory()->clear(); 133 : 134 2 : return read(xml_file.get_data()); 135 1 : } 136 : 137 1 : Result DirectoryFileXMLImpl::write(const std::string &path) 138 : { 139 1 : Result result = write_xml(); 140 1 : if (result.error()) return ESYSREPO_RESULT(result); 141 : 142 1 : esysfile::xml::Writer writer; 143 : 144 1 : writer.set_indent(4); 145 2 : int result_int = writer.write(path, m_xml_data); 146 1 : if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int); 147 1 : return ESYSREPO_RESULT(ResultCode::OK); 148 1 : } 149 : 150 1 : Result DirectoryFileXMLImpl::write(std::ostream &os) 151 : { 152 1 : Result result = write_xml(); 153 1 : if (result.error()) return ESYSREPO_RESULT(result); 154 : 155 1 : esysfile::xml::Writer writer; 156 : 157 1 : writer.set_indent(4); 158 2 : int result_int = writer.write(os, m_xml_data); 159 1 : if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int); 160 1 : return ESYSREPO_RESULT(ResultCode::OK); 161 1 : } 162 : 163 22 : DirectoryFileXML *DirectoryFileXMLImpl::self() const 164 : { 165 22 : return m_self; 166 : } 167 : 168 2 : Result DirectoryFileXMLImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, 169 : std::shared_ptr<Directory> directory) 170 : { 171 2 : auto projects_el = std::make_shared<esysfile::xml::Element>(); 172 4 : parent_el->add_element(projects_el); 173 : 174 2 : projects_el->set_name("projects"); 175 : 176 12 : for (auto const &item : directory->get_items()) 177 : { 178 10 : auto project_el = std::make_shared<esysfile::xml::Element>(); 179 20 : projects_el->add_element(project_el); 180 : 181 10 : project_el->set_name("project"); 182 10 : project_el->add_attr("name", item->get_name()); 183 : 184 10 : auto urls_el = std::make_shared<esysfile::xml::Element>(); 185 20 : project_el->add_element(urls_el); 186 : 187 10 : urls_el->set_name("urls"); 188 : 189 10 : auto url_ssh_el = std::make_shared<esysfile::xml::Element>(); 190 20 : urls_el->add_element(url_ssh_el); 191 : 192 10 : url_ssh_el->set_name("url"); 193 10 : url_ssh_el->add_attr("type", "ssh"); 194 10 : url_ssh_el->add_attr("link", item->get_url_ssh()); 195 : 196 10 : if (!item->get_url_https().empty()) 197 : { 198 10 : auto url_https_el = std::make_shared<esysfile::xml::Element>(); 199 20 : urls_el->add_element(url_https_el); 200 : 201 10 : url_https_el->set_name("url"); 202 10 : url_https_el->add_attr("type", "https"); 203 20 : url_https_el->add_attr("link", item->get_url_https()); 204 10 : } 205 30 : } 206 : 207 2 : return ESYSREPO_RESULT(ResultCode::OK); 208 2 : } 209 : 210 2 : Result DirectoryFileXMLImpl::write_xml() 211 : { 212 4 : if (self()->get_directory() == nullptr) return ESYSREPO_RESULT(ResultCode::DIRECTORY_XML_DATA_NULLPTR); 213 : 214 2 : m_xml_data = std::make_shared<esysfile::xml::Data>(); 215 2 : m_xml_data->set_root_node_name("esysrepo_manifest_dir"); 216 2 : m_xml_data->set_root_attr_name(self()->get_directory()->get_name()); 217 : 218 6 : auto result = write(m_xml_data, self()->get_directory()); 219 : 220 4 : return ESYSREPO_RESULT(result); 221 2 : } 222 : 223 : } // namespace esys::repo::manifest