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 // enabled or disabled is controlled by the 00106 // reposToEnable/Disable list, unless the 00107 // enabled attribute is set 00108 info.setEnabled(false); 00109 00110 // Set some defaults that are not contained in the repo information 00111 info.setAutorefresh( true ); 00112 00113 // url and/or path 00114 string url_s; 00115 s = reader_r->getAttribute("url"); 00116 if (s.get()) 00117 url_s = s.asString(); 00118 string path_s; 00119 s = reader_r->getAttribute("path"); 00120 if (s.get()) 00121 path_s = s.asString(); 00122 00123 if (url_s.empty() && path_s.empty()) 00124 throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path")); 00126 else if (url_s.empty()) 00127 info.setPath(Pathname(string("/repo/") + path_s)); 00128 else if (path_s.empty()) 00129 info.setBaseUrl(Url(url_s)); 00130 else 00131 info.setBaseUrl(Url(url_s + "/repo/" + path_s)); 00132 00133 // required alias 00134 s = reader_r->getAttribute("alias"); 00135 if (!s.get()) 00136 throw ParseException(str::form(_("Required attribute '%s' is missing."), "alias")); 00137 info.setAlias(s.asString()); 00138 00139 // optional type 00140 s = reader_r->getAttribute("type"); 00141 if (s.get()) 00142 info.setType(repo::RepoType(s.asString())); 00143 00144 // optional name 00145 s = reader_r->getAttribute("name"); 00146 if (s.get()) 00147 info.setName(s.asString()); 00148 00149 // optional targetDistro 00150 s = reader_r->getAttribute("distro_target"); 00151 if (s.get()) 00152 info.setTargetDistribution(s.asString()); 00153 00154 // optional priority 00155 s = reader_r->getAttribute("priority"); 00156 if (s.get()) { 00157 info.setPriority(str::strtonum<unsigned>(s.asString())); 00158 } 00159 00160 // optional enabled 00161 s = reader_r->getAttribute("enabled"); 00162 if (s.get()) { 00163 info.setEnabled(str::strToTrue(s.asString())); 00164 } 00165 00166 DBG << info << endl; 00167 00168 // ignore the rest 00169 _callback(info); 00170 return true; 00171 } 00172 } 00173 00174 return true; 00175 } 00176 00177 00179 // 00180 // CLASS NAME : RepoindexFileReader 00181 // 00183 00184 RepoindexFileReader::RepoindexFileReader( 00185 const Pathname & repoindex_file, const ProcessResource & callback) 00186 : 00187 _pimpl(new Impl(repoindex_file, callback)) 00188 {} 00189 00190 RepoindexFileReader::~RepoindexFileReader() 00191 {} 00192 00193 00194 } // ns parser 00195 } // ns zypp 00196 00197 // vim: set ts=2 sts=2 sw=2 et ai: