Line data Source code
1 : /*! 2 : * \file esys/repo/manifest/multifilexmlimpl_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/multifilexmlimpl.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 : MultiFileXMLImpl::MultiFileXMLImpl(MultiFileXML *self) 29 4 : : m_self(self) 30 : { 31 4 : } 32 : 33 4 : MultiFileXMLImpl::~MultiFileXMLImpl() = default; 34 : 35 1 : Result MultiFileXMLImpl::read(const std::string &path) 36 : { 37 1 : esysfile::xml::File xml_file; 38 : 39 1 : xml_file.set_root_node_name("esysrepo_multi"); 40 1 : int result = xml_file.read(path); 41 1 : if (result < 0) 42 : { 43 : // self()->add_error(result, "XML parsing failed."); 44 0 : return ESYSREPO_RESULT(ResultCode::MULTI_ERROR_PARSING_FILE, path); 45 : } 46 : 47 2 : if (self()->get_capture() == nullptr) 48 0 : self()->set_capture(std::make_shared<Capture>()); 49 : else 50 2 : self()->get_capture()->clear(); 51 : 52 2 : return read(xml_file.get_data()); 53 1 : } 54 : 55 3 : Result MultiFileXMLImpl::read(std::shared_ptr<esysfile::xml::Data> data) 56 : { 57 3 : Result result; 58 : 59 6 : for (auto el : data->get_elements()) 60 : { 61 3 : if (el->get_name() == "capture") 62 9 : result = read_capture(el); 63 : else 64 0 : result = ESYSREPO_RESULT(ResultCode::MULTI_ELEMENT_UNKNOWN, el->get_name()); 65 3 : if (result.error()) 66 : { 67 : // self()->add_error(result.get_result_code_int(), "Reading XML element failed : " + el->get_name()); 68 0 : return result; 69 : } 70 3 : } 71 3 : return ESYSREPO_RESULT(ResultCode::OK); 72 3 : } 73 : 74 3 : Result MultiFileXMLImpl::read_capture(std::shared_ptr<esysfile::xml::Element> el) 75 : { 76 3 : if (el->get_name() != "capture") return ESYSREPO_RESULT(ResultCode::INTERNAL_ERROR); 77 : 78 10 : for (auto repo_el : el->get_elements()) 79 : { 80 7 : if (repo_el->get_name() != "repository") 81 0 : return ESYSREPO_RESULT(ResultCode::MULTI_ELEMENT_UNKNOWN, el->get_name()); 82 : 83 7 : auto path_attr = repo_el->get_attr("path"); 84 7 : if (path_attr == nullptr) return ESYSREPO_RESULT(ResultCode::MULTI_REPOSITORY_WITHOUT_PATH); 85 : 86 7 : auto rev_attr = repo_el->get_attr("revision"); 87 7 : if (rev_attr == nullptr) return ESYSREPO_RESULT(ResultCode::MULTI_REPOSITORY_WITHOUT_REV); 88 : 89 7 : auto remote_name_attr = repo_el->get_attr("remote_name"); 90 7 : auto remote_url_attr = repo_el->get_attr("remote_url"); 91 : 92 7 : auto capture_item = std::make_shared<Capture::Item>(); 93 7 : capture_item->set_path(path_attr->get_value()); 94 7 : capture_item->set_revision(rev_attr->get_value()); 95 7 : if (remote_name_attr != nullptr) capture_item->set_remote_name(remote_name_attr->get_value()); 96 7 : if (remote_url_attr != nullptr) capture_item->set_remote_url(remote_url_attr->get_value()); 97 : 98 28 : self()->get_capture()->add_item(capture_item); 99 34 : } 100 : 101 3 : return ESYSREPO_RESULT(ResultCode::OK); 102 : } 103 : 104 2 : Result MultiFileXMLImpl::read(std::istream &is) 105 : { 106 2 : esysfile::xml::File xml_file; 107 : 108 2 : xml_file.set_root_node_name("esysrepo_multi"); 109 2 : int result = xml_file.read(is); 110 2 : if (result < 0) 111 : { 112 : // self()->add_error(result, "XML parsing failed."); 113 0 : return ESYSREPO_RESULT(ResultCode::MULTI_ERROR_PARSING_STREAM); 114 : } 115 : 116 4 : if (self()->get_capture() == nullptr) 117 0 : self()->set_capture(std::make_shared<Capture>()); 118 : else 119 4 : self()->get_capture()->clear(); 120 : 121 4 : return read(xml_file.get_data()); 122 2 : } 123 : 124 1 : Result MultiFileXMLImpl::write(const std::string &path) 125 : { 126 1 : Result result = write_xml(); 127 1 : if (result.error()) return ESYSREPO_RESULT(result); 128 : 129 1 : esysfile::xml::Writer writer; 130 : 131 1 : writer.set_indent(4); 132 2 : int result_int = writer.write(path, m_xml_data); 133 1 : if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int); 134 1 : return ESYSREPO_RESULT(ResultCode::OK); 135 1 : } 136 : 137 2 : Result MultiFileXMLImpl::write(std::ostream &os) 138 : { 139 2 : Result result = write_xml(); 140 2 : if (result.error()) return ESYSREPO_RESULT(result); 141 : 142 2 : esysfile::xml::Writer writer; 143 : 144 2 : writer.set_indent(4); 145 4 : int result_int = writer.write(os, m_xml_data); 146 2 : if (result_int < 0) return ESYSREPO_RESULT(ResultCode::RAW_INT_ERROR, result_int); 147 2 : return ESYSREPO_RESULT(ResultCode::OK); 148 2 : } 149 : 150 19 : MultiFileXML *MultiFileXMLImpl::self() 151 : { 152 19 : return m_self; 153 : } 154 : 155 3 : Result MultiFileXMLImpl::write(std::shared_ptr<esysfile::xml::Element> parent_el, std::shared_ptr<Capture> capture) 156 : { 157 3 : auto capture_el = std::make_shared<esysfile::xml::Element>(); 158 6 : parent_el->add_element(capture_el); 159 : 160 3 : capture_el->set_name("capture"); 161 : 162 10 : for (auto const &item : capture->get_items()) 163 : { 164 7 : auto repo_el = std::make_shared<esysfile::xml::Element>(); 165 14 : capture_el->add_element(repo_el); 166 : 167 7 : repo_el->set_name("repository"); 168 14 : if (!item->get_path().empty()) repo_el->add_attr("path", item->get_path()); 169 14 : if (!item->get_revision().empty()) repo_el->add_attr("revision", item->get_revision()); 170 10 : if (!item->get_remote_name().empty()) repo_el->add_attr("remote_name", item->get_remote_name()); 171 10 : if (!item->get_remote_url().empty()) repo_el->add_attr("remote_url", item->get_remote_url()); 172 7 : } 173 : 174 3 : return ESYSREPO_RESULT(ResultCode::OK); 175 3 : } 176 : 177 3 : Result MultiFileXMLImpl::write_xml() 178 : { 179 6 : if (self()->get_capture() == nullptr) return ESYSREPO_RESULT(ResultCode::MULTI_XML_CAPTURE_NULLPTR); 180 : 181 3 : m_xml_data = std::make_shared<esysfile::xml::Data>(); 182 3 : m_xml_data->set_root_node_name("esysrepo_multi"); 183 : 184 9 : auto result = write(m_xml_data, self()->get_capture()); 185 : 186 6 : return ESYSREPO_RESULT(result); 187 3 : } 188 : 189 : } // namespace esys::repo::manifest