RepoindexFileReader.cc

Go to the documentation of this file.
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:

doxygen