1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/parser/ProductFileReader.cc
13 #include "zypp/base/Logger.h"
14 #include "zypp/base/Exception.h"
15 #include "zypp/base/Functional.h"
17 #include "zypp/PathInfo.h"
19 #include "zypp/parser/ProductFileReader.h"
20 #include "zypp/parser/xml/ParseDef.h"
21 #include "zypp/parser/xml/ParseDefConsume.h"
22 #include "zypp/parser/xml/Reader.h"
26 ///////////////////////////////////////////////////////////////////
28 { /////////////////////////////////////////////////////////////////
29 ///////////////////////////////////////////////////////////////////
31 { /////////////////////////////////////////////////////////////////
33 /////////////////////////////////////////////////////////////////
35 // class ProductFileData::Upgrade
37 /////////////////////////////////////////////////////////////////
39 struct ProductFileData::Upgrade::Impl
43 std::string _repository;
45 DefaultIntegral<bool,false> _notify;
49 ProductFileData::Upgrade::Upgrade( Impl * allocated_r )
50 : _pimpl( allocated_r ? allocated_r : new Impl )
53 std::string ProductFileData::Upgrade::name() const { return _pimpl->_name; }
54 std::string ProductFileData::Upgrade::summary() const { return _pimpl->_summary; }
55 std::string ProductFileData::Upgrade::repository() const { return _pimpl->_repository; }
56 std::string ProductFileData::Upgrade::product() const { return _pimpl->_product; }
57 bool ProductFileData::Upgrade::notify() const { return _pimpl->_notify; }
58 std::string ProductFileData::Upgrade::status() const { return _pimpl->_status; }
60 /////////////////////////////////////////////////////////////////
62 // class ProductFileData
64 /////////////////////////////////////////////////////////////////
66 struct ProductFileData::Impl
73 std::string _shortName;
76 std::string _productline;
77 std::string _registerTarget;
78 std::string _registerRelease;
80 std::string _updaterepokey;
85 ProductFileData::ProductFileData( Impl * allocated_r )
86 : _pimpl( allocated_r ? allocated_r : new Impl )
89 IdString ProductFileData::vendor() const { return _pimpl->_vendor; }
90 IdString ProductFileData::name() const { return _pimpl->_name; }
91 Edition ProductFileData::edition() const { return _pimpl->_edition; }
92 Arch ProductFileData::arch() const { return _pimpl->_arch; }
94 std::string ProductFileData::shortName() const { return _pimpl->_shortName; }
95 std::string ProductFileData::summary() const { return _pimpl->_summary; }
97 std::string ProductFileData::productline() const { return _pimpl->_productline; }
98 std::string ProductFileData::registerTarget() const { return _pimpl->_registerTarget; }
99 std::string ProductFileData::registerRelease() const { return _pimpl->_registerRelease; }
101 std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; }
103 const ProductFileData::Upgrades & ProductFileData::upgrades() const { return _pimpl->_upgrades; }
105 std::ostream & operator<<( std::ostream & str, const ProductFileData & obj )
107 str << str::form( "|product|%s|%s|%s|%s|",
109 obj.edition().c_str(),
111 obj.vendor().c_str() );
112 if ( ! obj.upgrades().empty() )
114 for_( it, obj.upgrades().begin(), obj.upgrades().end() )
115 str << endl << " " << *it;
120 std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj )
122 str << str::form( "|upgrade|%s|%s|%s|%s|%s|",
124 obj.repository().c_str(),
125 obj.product().c_str(),
126 obj.status().c_str(),
127 (obj.notify() ? "notify" : "noNotify") );
130 /////////////////////////////////////////////////////////////////
132 // class ProductFileReader
134 /////////////////////////////////////////////////////////////////
136 struct ProductNode : public xml::ParseDef
138 ProductNode( ProductFileData::Impl & pdata_r )
139 : ParseDef( "product", MANDTAORY )
143 ("vendor", OPTIONAL, xml::parseDefAssign( _pdata._vendor ) )
144 ("name", MANDTAORY, xml::parseDefAssign( _pdata._name ) )
145 ("version", MANDTAORY, xml::parseDefAssign( _version ) )
146 ("release", MANDTAORY, xml::parseDefAssign( _release ) )
147 ("arch", MANDTAORY, xml::parseDefAssign( _pdata._arch ) )
148 ("shortsummary", OPTIONAL, xml::parseDefAssign( _pdata._shortName ) )
149 ("summary", MULTIPLE_OPTIONAL, xml::parseDefAssign( _ttext )( "lang", _tlocale )
150 >>bind( &ProductNode::doneLocalizedDefault, this, _1, boost::ref(_pdata._summary) ))
151 ("productline", OPTIONAL, xml::parseDefAssign( _pdata._productline ) )
152 ("register", OPTIONAL)
153 ("updaterepokey", OPTIONAL, xml::parseDefAssign( _pdata._updaterepokey ) )
154 ("upgrades", OPTIONAL)
158 ("target", OPTIONAL, xml::parseDefAssign( _pdata._registerTarget ) )
159 ("release", OPTIONAL, xml::parseDefAssign( _pdata._registerRelease ) )
163 ("upgrade", MULTIPLE_OPTIONAL, xml::parseDefAssign()
164 >> bind( &ProductNode::doneUpgrade, this, _1 ))
167 (*this)["upgrades"]["upgrade"]
168 ("name", OPTIONAL, xml::parseDefAssign( _upgrade._name ) )
169 ("summary", OPTIONAL, xml::parseDefAssign( _upgrade._summary ) )
170 ("repository", OPTIONAL, xml::parseDefAssign( _upgrade._repository ) )
171 ("product", OPTIONAL, xml::parseDefAssign( _upgrade._product ) )
172 ("notify", OPTIONAL, xml::parseDefAssign( _upgrade._notify ) )
173 ("status", OPTIONAL, xml::parseDefAssign( _upgrade._status ) )
176 // </product> callback to build edition.
177 setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) );
178 // xml::ParseDef::_debug = true;
181 /** collect _upgrade */
182 void doneUpgrade( const xml::Node & _node )
184 ProductFileData::Upgrade cdata( new ProductFileData::Upgrade::Impl( _upgrade ) );
185 _pdata._upgrades.push_back( cdata );
186 _upgrade = ProductFileData::Upgrade::Impl();
188 /** collect localized data */
189 void doneLocalizedDefault( const xml::Node & _node, std::string & store_r )
191 // take 1st or default
192 if ( store_r.empty() || _tlocale.empty() )
197 void done( const xml::Node & _node )
199 _pdata._edition = Edition( _version, _release );
203 ProductFileData::Impl & _pdata;
205 std::string _version;
206 std::string _release;
209 std::string _tlocale;
211 ProductFileData::Upgrade::Impl _upgrade;
214 bool ProductFileReader::parse( const InputStream & input_r ) const
216 MIL << "+++" << input_r << endl;
219 ProductFileData::Impl * pdataImpl = 0;
220 ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) );
224 xml::Reader reader( input_r );
225 ProductNode rootNode( *pdataImpl );
226 rootNode.take( reader );
229 catch ( const Exception & err )
233 ERR << "---" << ret << " - " << input_r << endl;
239 ret = _consumer( pdata );
242 MIL << "---" << ret << " - " << input_r << endl;
246 /////////////////////////////////////////////////////////////////
248 bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r )
250 std::list<Pathname> retlist;
251 int res = filesystem::readdir( retlist, dir_r, /*dots*/false );
254 WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl;
258 ProductFileReader reader( consumer_r );
259 for_( it, retlist.begin(), retlist.end() )
261 if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) )
263 return false; // consumer_r request to stop parsing.
269 ProductFileData ProductFileReader::scanFile( const Pathname & file_r )
271 if ( ! PathInfo( file_r ).isFile() )
273 WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl;
274 return ProductFileData();
278 ProductFileReader reader( functor::getFirst( ret ), file_r );
282 /////////////////////////////////////////////////////////////////
283 } // namespace parser
284 ///////////////////////////////////////////////////////////////////
285 /////////////////////////////////////////////////////////////////
287 ///////////////////////////////////////////////////////////////////