Imported Upstream version 14.45.0
[platform/upstream/libzypp.git] / zypp / parser / yum / RepomdFileReader.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/parser/yum/RepomdFileReader.cc
10  * Implementation of repomd.xml file reader.
11  */
12 #include <iostream>
13
14 #include "zypp/base/String.h"
15 #include "zypp/base/Logger.h"
16
17 #include "zypp/Pathname.h"
18 #include "zypp/Date.h"
19 #include "zypp/CheckSum.h"
20 #include "zypp/parser/xml/Reader.h"
21
22 #include "zypp/parser/yum/RepomdFileReader.h"
23
24 #undef ZYPP_BASE_LOGGER_LOGGROUP
25 #define ZYPP_BASE_LOGGER_LOGGROUP "parser::yum"
26
27 using namespace std;
28 using namespace zypp::xml;
29 using zypp::repo::yum::ResourceType;
30
31 namespace zypp
32 {
33   namespace parser
34   {
35     namespace yum
36     {
37
38
39   ///////////////////////////////////////////////////////////////////////
40   //
41   //  CLASS NAME : RepomdFileReader::Impl
42   //
43   class RepomdFileReader::Impl : private base::NonCopyable
44   {
45   public:
46
47     /**
48      * Enumeration of repomd.xml tags.
49      * \see _tag
50      */
51     enum Tag
52     {
53       tag_NONE,
54       tag_Repomd,
55       tag_Data,
56       tag_Location,
57       tag_CheckSum,
58       tag_Timestamp,
59       tag_OpenCheckSum
60     };
61
62   public:
63     /**
64      * CTOR
65      *
66      * \see RepomdFileReader::RepomdFileReader(Pathname,ProcessResource)
67      */
68     Impl(const Pathname &repomd_file, const ProcessResource & callback);
69
70     /**
71      * Callback provided to the XML parser.
72      */
73     bool consumeNode( Reader & reader_r );
74
75
76   private:
77     /** Location of metadata file. */
78     OnMediaLocation _location;
79
80     /** Used to remember currently processed tag */
81     Tag _tag;
82
83     /** Type of metadata file. */
84     repo::yum::ResourceType _type;
85
86     /** Function for processing collected data. Passed-in through constructor. */
87     ProcessResource _callback;
88
89     /** Checksum of metadata file */
90     CheckSum _checksum;
91
92     /** Type of checksum of metadata file */
93     std::string _checksum_type;
94
95     /** Metadata file time-stamp. */
96     Date _timestamp;
97   };
98   ///////////////////////////////////////////////////////////////////////
99
100   RepomdFileReader::Impl::Impl(
101       const Pathname &repomd_file, const ProcessResource & callback)
102     :
103       _tag(tag_NONE), _type(ResourceType::NONE_e), _callback(callback)
104   {
105     Reader reader( repomd_file );
106     MIL << "Reading " << repomd_file << endl;
107     reader.foreachNode( bind( &RepomdFileReader::Impl::consumeNode, this, _1 ) );
108   }
109
110   // --------------------------------------------------------------------------
111
112   /*
113    * xpath and multiplicity of processed nodes are included in the code
114    * for convenience:
115    *
116    * // xpath: <xpath> (?|*|+)
117    *
118    * if multiplicity is ommited, then the node has multiplicity 'one'.
119    */
120
121   // --------------------------------------------------------------------------
122
123   bool RepomdFileReader::Impl::consumeNode( Reader & reader_r )
124   {
125     if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT )
126     {
127       // xpath: /repomd
128       if ( reader_r->name() == "repomd" )
129       {
130         _tag = tag_Repomd;
131         return true;
132       }
133
134       // xpath: /repomd/data (+)
135       if ( reader_r->name() == "data" )
136       {
137         _tag = tag_Data;
138         _type = ResourceType(reader_r->getAttribute("type").asString());
139         return true;
140       }
141
142       // xpath: /repomd/location
143       if ( reader_r->name() == "location" )
144       {
145         _tag = tag_Location;
146         _location.setLocation( reader_r->getAttribute("href").asString(), 1 );
147         // ignoring attribute xml:base
148         return true;
149       }
150
151       // xpath: /repomd/checksum
152       if ( reader_r->name() == "checksum" )
153       {
154         _tag = tag_CheckSum;
155         string checksum_type = reader_r->getAttribute("type").asString() ;
156         string checksum_vaue = reader_r.nodeText().asString();
157         _location.setChecksum( CheckSum( checksum_type, checksum_vaue ) );
158         return true;
159       }
160
161       // xpath: /repomd/timestamp
162       if ( reader_r->name() == "timestamp" )
163       {
164         // ignore it
165         return true;
166       }
167
168       //! \todo xpath: /repomd/open-checksum (?)
169     }
170
171     else if ( reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT )
172     {
173       // xpath: /repomd/data
174       if ( reader_r->name() == "data" )
175       {
176         if (_callback)
177           _callback( _location, _type );
178
179         return true;
180       }
181     }
182
183     return true;
184   }
185
186
187   ///////////////////////////////////////////////////////////////////
188   //
189   //  CLASS NAME : RepomdFileReader
190   //
191   ///////////////////////////////////////////////////////////////////
192
193   RepomdFileReader::RepomdFileReader(
194       const Pathname & repomd_file, const ProcessResource & callback)
195     :
196       _pimpl(new Impl(repomd_file, callback))
197   {}
198
199   RepomdFileReader::~RepomdFileReader()
200   {}
201
202
203     } // ns yum
204   } // ns parser
205 } // ns zypp
206
207 // vim: set ts=2 sts=2 sw=2 et ai: