- filtering of repos with non-matching repos moved to RepoManager
[platform/upstream/libzypp.git] / zypp / parser / RepoindexFileReader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/parser/RepoindexFileReader.cc
10  * Implementation of repoindex.xml file reader.
11  */
12 #include <iostream>
13
14 #include "zypp/base/String.h"
15 #include "zypp/base/Logger.h"
16 #include "zypp/base/Gettext.h"
17 #include "zypp/Pathname.h"
18
19 #include "zypp/parser/xml/Reader.h"
20 #include "zypp/parser/ParseException.h"
21
22 #include "zypp/RepoInfo.h"
23 #include "zypp/Target.h"
24 #include "zypp/ZYppFactory.h"
25
26 #include "zypp/parser/RepoindexFileReader.h"
27
28
29 #undef ZYPP_BASE_LOGGER_LOGGROUP
30 #define ZYPP_BASE_LOGGER_LOGGROUP "parser"
31
32 using namespace std;
33 using namespace zypp::xml;
34
35 namespace zypp
36 {
37   namespace parser
38   {
39
40
41   ///////////////////////////////////////////////////////////////////////
42   //
43   //  CLASS NAME : RepoindexFileReader::Impl
44   //
45   class RepoindexFileReader::Impl : private base::NonCopyable
46   {
47   public:
48     /**
49      * CTOR
50      *
51      * \see RepoindexFileReader::RepoindexFileReader(Pathname,ProcessResource)
52      */
53     Impl(const Pathname &repoindex_file, const ProcessResource & callback);
54
55     /**
56      * Callback provided to the XML parser.
57      */
58     bool consumeNode( Reader & reader_r );
59
60
61   private:
62     /** Function for processing collected data. Passed-in through constructor. */
63     ProcessResource _callback;
64     string _target_distro;
65   };
66   ///////////////////////////////////////////////////////////////////////
67
68   RepoindexFileReader::Impl::Impl(
69       const Pathname &repoindex_file, const ProcessResource & callback)
70     : _callback(callback)
71   {
72     Reader reader( repoindex_file );
73     MIL << "Reading " << repoindex_file << endl;
74     reader.foreachNode( bind( &RepoindexFileReader::Impl::consumeNode, this, _1 ) );
75   }
76
77   // --------------------------------------------------------------------------
78
79   /*
80    * xpath and multiplicity of processed nodes are included in the code
81    * for convenience:
82    *
83    * // xpath: <xpath> (?|*|+)
84    *
85    * if multiplicity is ommited, then the node has multiplicity 'one'.
86    */
87
88   // --------------------------------------------------------------------------
89
90   bool RepoindexFileReader::Impl::consumeNode( Reader & reader_r )
91   {
92     if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT )
93     {
94       // xpath: /repoindex
95       if ( reader_r->name() == "repoindex" )
96       {
97         return true;
98       }
99
100       // xpath: /repoindex/data (+)
101       if ( reader_r->name() == "repo" )
102       {
103         XmlString s;
104
105         RepoInfo info;
106
107         // url and/or path
108         string url_s;
109         s = reader_r->getAttribute("url");
110         if (s.get())
111           url_s = s.asString();
112         string path_s;
113         s = reader_r->getAttribute("path");
114         if (s.get())
115           path_s = s.asString();
116
117         if (url_s.empty() && path_s.empty())
118           throw ParseException(str::form(_("One or both of '%s' or '%s' attributes is required."), "url", "path"));
119         //! \todo FIXME this hardcodes the "/repo/" fragment - should not be if we want it to be usable by others!
120         else if (url_s.empty())
121           info.setPath(Pathname(string("/repo/") + path_s));
122         else if (path_s.empty())
123           info.setBaseUrl(Url(url_s));
124         else
125           info.setBaseUrl(Url(url_s + "/repo/" + path_s));
126
127         // required alias
128         info.setAlias(reader_r->getAttribute("alias").asString());
129
130         // optional type
131         s = reader_r->getAttribute("type");
132         if (s.get())
133           info.setType(repo::RepoType(s.asString()));
134
135         // optional name
136         s = reader_r->getAttribute("name");
137         if (s.get())
138           info.setName(s.asString());
139
140         // optional targetDistro
141         s = reader_r->getAttribute("distro_target");
142         if (s.get())
143           info.setTargetDistribution(s.asString());
144
145         DBG << info << endl;
146
147         // ignore the rest
148         _callback(info);
149         return true;
150       }
151     }
152
153     return true;
154   }
155
156
157   ///////////////////////////////////////////////////////////////////
158   //
159   //  CLASS NAME : RepoindexFileReader
160   //
161   ///////////////////////////////////////////////////////////////////
162
163   RepoindexFileReader::RepoindexFileReader(
164       const Pathname & repoindex_file, const ProcessResource & callback)
165     :
166       _pimpl(new Impl(repoindex_file, callback))
167   {}
168
169   RepoindexFileReader::~RepoindexFileReader()
170   {}
171
172
173   } // ns parser
174 } // ns zypp
175
176 // vim: set ts=2 sts=2 sw=2 et ai: