Imported Upstream version 16.4.1
[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     /** Ctro taking a ProcessResource2 callback */
64     Impl(const Pathname &repomd_file, const ProcessResource2 & callback )
65     : _callback( callback )
66     , _tag( tag_NONE )
67     , _type( ResourceType::NONE_e )
68     {
69       Reader reader( repomd_file );
70       MIL << "Reading " << repomd_file << endl;
71       reader.foreachNode( bind( &RepomdFileReader::Impl::consumeNode, this, _1 ) );
72     }
73    /** \overload Redirect an old ProcessResource callback */
74     Impl(const Pathname &repomd_file, const ProcessResource & callback)
75     : Impl( repomd_file, ProcessResource2( bind( callback, _1, _2 ) ) )
76     {}
77
78     /**
79      * Callback provided to the XML parser.
80      */
81     bool consumeNode( Reader & reader_r );
82
83
84   private:
85     /** Function for processing collected data. Passed-in through constructor. */
86     ProcessResource2 _callback;
87
88     /** Used to remember currently processed tag */
89     Tag _tag;
90
91     /** Type of metadata file (string) */
92     std::string _typeStr;
93
94     /** Type of metadata file as enum of well known repoinded.xml entries. */
95     repo::yum::ResourceType _type;
96
97     /** Location of metadata file. */
98     OnMediaLocation _location;
99   };
100   ///////////////////////////////////////////////////////////////////////
101
102   /*
103    * xpath and multiplicity of processed nodes are included in the code
104    * for convenience:
105    *
106    * // xpath: <xpath> (?|*|+)
107    *
108    * if multiplicity is ommited, then the node has multiplicity 'one'.
109    */
110
111   // --------------------------------------------------------------------------
112
113   bool RepomdFileReader::Impl::consumeNode( Reader & reader_r )
114   {
115     if ( reader_r->nodeType() == XML_READER_TYPE_ELEMENT )
116     {
117       // xpath: /repomd
118       if ( reader_r->name() == "repomd" )
119       {
120         _tag = tag_Repomd;
121         return true;
122       }
123
124       // xpath: /repomd/data (+)
125       if ( reader_r->name() == "data" )
126       {
127         _tag = tag_Data;
128         _typeStr = reader_r->getAttribute("type").asString();
129         _type = ResourceType(_typeStr);
130         return true;
131       }
132
133       // xpath: /repomd/location
134       if ( reader_r->name() == "location" )
135       {
136         _tag = tag_Location;
137         _location.setLocation( reader_r->getAttribute("href").asString(), 1 );
138         // ignoring attribute xml:base
139         return true;
140       }
141
142       // xpath: /repomd/checksum
143       if ( reader_r->name() == "checksum" )
144       {
145         _tag = tag_CheckSum;
146         string checksum_type = reader_r->getAttribute("type").asString() ;
147         string checksum_vaue = reader_r.nodeText().asString();
148         _location.setChecksum( CheckSum( checksum_type, checksum_vaue ) );
149         return true;
150       }
151
152       // xpath: /repomd/timestamp
153       if ( reader_r->name() == "timestamp" )
154       {
155         // ignore it
156         return true;
157       }
158
159       //! \todo xpath: /repomd/open-checksum (?)
160     }
161
162     else if ( reader_r->nodeType() == XML_READER_TYPE_END_ELEMENT )
163     {
164       // xpath: /repomd/data
165       if ( reader_r->name() == "data" )
166       {
167         if (_callback)
168           _callback( _location, _type, _typeStr );
169
170         return true;
171       }
172     }
173
174     return true;
175   }
176
177
178   ///////////////////////////////////////////////////////////////////
179   //
180   //  CLASS NAME : RepomdFileReader
181   //
182   ///////////////////////////////////////////////////////////////////
183
184   RepomdFileReader::RepomdFileReader( const Pathname & repomd_file, const ProcessResource & callback )
185   : _pimpl( new Impl(repomd_file, callback) )
186   {}
187
188   RepomdFileReader::RepomdFileReader( const Pathname & repomd_file, const ProcessResource2 & callback )
189   : _pimpl( new Impl(repomd_file, callback) )
190   {}
191
192   RepomdFileReader::~RepomdFileReader()
193   {}
194
195
196     } // ns yum
197   } // ns parser
198 } // ns zypp
199
200 // vim: set ts=2 sts=2 sw=2 et ai: