00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 00014 #include "zypp/base/String.h" 00015 #include "zypp/base/Logger.h" 00016 #include "zypp/base/Gettext.h" 00017 #include "zypp/Pathname.h" 00018 00019 #include "zypp/parser/xml/Reader.h" 00020 #include "zypp/parser/ParseException.h" 00021 00022 #include "zypp/RepoInfo.h" 00023 00024 #include "zypp/parser/RepoindexFileReader.h" 00025 00026 00027 #undef ZYPP_BASE_LOGGER_LOGGROUP 00028 #define ZYPP_BASE_LOGGER_LOGGROUP "parser" 00029 00030 using namespace std; 00031 using namespace zypp::xml; 00032 00033 namespace zypp 00034 { 00035 namespace parser 00036 { 00037 00038 00040 // 00041 // CLASS NAME : RepoindexFileReader::Impl 00042 // 00043 class RepoindexFileReader::Impl : private base::NonCopyable 00044 { 00045 public: 00051 Impl(const Pathname &repoindex_file, const ProcessResource & callback); 00052 00056 bool consumeNode( Reader & reader_r ); 00057 00058 00059 private: 00061 ProcessResource _callback; 00062 string _target_distro; 00063 }; 00065 00066 RepoindexFileReader::Impl::Impl( 00067 const Pathname &repoindex_file, const ProcessResource & callback) 00068 : _callback(callback) 00069 { 00070 Reader reader( repoindex_file ); 00071 MIL << "Reading " << repoindex_file << endl; 00072 reader.foreachNode( bind( &RepoindexFileReader::Impl::consumeNode, this, _1 ) ); 00073 } 00074 00075 // -------------------------------------------------------------------------- 00076 00077 /* 00078 * xpath and multiplicity of processed nodes are included in the code 00079 * for convenience: 00080 * 00081 * // xpath: <xpath> (?|*|+) 00082 * 00083 * if multiplicity is ommited, then the node has multiplicity 'one'. 00084 */ 00085 00086 // -------------------------------------------------------------------------- 00087 00088 bool RepoindexFileReader::Impl::consumeNode( Reader & reader_r ) 00089 { 00090 if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT ) 00091 { 00092 // xpath: /repoindex 00093 if ( reader_r->name() == "repoindex" ) 00094 { 00095 return true; 00096 } 00097 00098 // xpath: /repoindex/data (+) 00099 if ( reader_r->name() == "repo" ) 00100 { 00101 XmlString s; 00102 00103 RepoInfo info; 00104 00105 // url and/or path 00106 string url_s; 00107 s = reader_r->getAttribute("url"); 00108 if (s.get()) 00109 url_s = s.asString(); 00110 string path_s; 00111 s = reader_r->getAttribute("path"); 00112 if (s.get()) 00113 path_s = s.asString(); 00114 00115 if (url_s.empty() && path_s.empty()) 00116 throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path")); 00118 else if (url_s.empty()) 00119 info.setPath(Pathname(string("/repo/") + path_s)); 00120 else if (path_s.empty()) 00121 info.setBaseUrl(Url(url_s)); 00122 else 00123 info.setBaseUrl(Url(url_s + "/repo/" + path_s)); 00124 00125 // required alias 00126 s = reader_r->getAttribute("alias"); 00127 if (!s.get()) 00128 throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias")); 00129 info.setAlias(s.asString()); 00130 00131 // optional type 00132 s = reader_r->getAttribute("type"); 00133 if (s.get()) 00134 info.setType(repo::RepoType(s.asString())); 00135 00136 // optional name 00137 s = reader_r->getAttribute("name"); 00138 if (s.get()) 00139 info.setName(s.asString()); 00140 00141 // optional targetDistro 00142 s = reader_r->getAttribute("distro_target"); 00143 if (s.get()) 00144 info.setTargetDistribution(s.asString()); 00145 00146 DBG << info << endl; 00147 00148 // ignore the rest 00149 _callback(info); 00150 return true; 00151 } 00152 } 00153 00154 return true; 00155 } 00156 00157 00159 // 00160 // CLASS NAME : RepoindexFileReader 00161 // 00163 00164 RepoindexFileReader::RepoindexFileReader( 00165 const Pathname & repoindex_file, const ProcessResource & callback) 00166 : 00167 _pimpl(new Impl(repoindex_file, callback)) 00168 {} 00169 00170 RepoindexFileReader::~RepoindexFileReader() 00171 {} 00172 00173 00174 } // ns parser 00175 } // ns zypp 00176 00177 // vim: set ts=2 sts=2 sw=2 et ai: