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 _productline;
74 std::string _registerTarget;
75 std::string _registerRelease;
77 std::string _updaterepokey;
82 ProductFileData::ProductFileData( Impl * allocated_r )
83 : _pimpl( allocated_r ? allocated_r : new Impl )
86 IdString ProductFileData::vendor() const { return _pimpl->_vendor; }
87 IdString ProductFileData::name() const { return _pimpl->_name; }
88 Edition ProductFileData::edition() const { return _pimpl->_edition; }
89 Arch ProductFileData::arch() const { return _pimpl->_arch; }
91 std::string ProductFileData::productline() const { return _pimpl->_productline; }
92 std::string ProductFileData::registerTarget() const { return _pimpl->_registerTarget; }
93 std::string ProductFileData::registerRelease() const { return _pimpl->_registerRelease; }
95 std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; }
97 const ProductFileData::Upgrades & ProductFileData::upgrades() const { return _pimpl->_upgrades; }
99 std::ostream & operator<<( std::ostream & str, const ProductFileData & obj )
101 str << str::form( "|product|%s|%s|%s|%s|",
103 obj.edition().c_str(),
105 obj.vendor().c_str() );
106 if ( ! obj.upgrades().empty() )
108 for_( it, obj.upgrades().begin(), obj.upgrades().end() )
109 str << endl << " " << *it;
114 std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj )
116 str << str::form( "|upgrade|%s|%s|%s|%s|%s|",
118 obj.repository().c_str(),
119 obj.product().c_str(),
120 obj.status().c_str(),
121 (obj.notify() ? "notify" : "noNotify") );
124 /////////////////////////////////////////////////////////////////
126 // class ProductFileReader
128 /////////////////////////////////////////////////////////////////
130 struct ProductNode : public xml::ParseDef
132 ProductNode( ProductFileData::Impl & pdata_r )
133 : ParseDef( "product", MANDTAORY )
137 ("vendor", OPTIONAL, xml::parseDefAssign( _pdata._vendor ) )
138 ("name", MANDTAORY, xml::parseDefAssign( _pdata._name ) )
139 ("version", MANDTAORY, xml::parseDefAssign( _version ) )
140 ("release", MANDTAORY, xml::parseDefAssign( _release ) )
141 ("arch", MANDTAORY, xml::parseDefAssign( _pdata._arch ) )
142 ("productline", OPTIONAL, xml::parseDefAssign( _pdata._productline ) )
143 ("register", OPTIONAL)
144 ("updaterepokey", OPTIONAL, xml::parseDefAssign( _pdata._updaterepokey ) )
145 ("upgrades", OPTIONAL)
149 ("target", OPTIONAL, xml::parseDefAssign( _pdata._registerTarget ) )
150 ("release", OPTIONAL, xml::parseDefAssign( _pdata._registerRelease ) )
154 ("upgrade", MULTIPLE_OPTIONAL, xml::parseDefAssign()
155 >> bind( &ProductNode::doneUpgrade, this, _1 ))
158 (*this)["upgrades"]["upgrade"]
159 ("name", OPTIONAL, xml::parseDefAssign( _upgrade._name ) )
160 ("summary", OPTIONAL, xml::parseDefAssign( _upgrade._summary ) )
161 ("repository", OPTIONAL, xml::parseDefAssign( _upgrade._repository ) )
162 ("product", OPTIONAL, xml::parseDefAssign( _upgrade._product ) )
163 ("notify", OPTIONAL, xml::parseDefAssign( _upgrade._notify ) )
164 ("status", OPTIONAL, xml::parseDefAssign( _upgrade._status ) )
167 // </product> callback to build edition.
168 setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) );
169 // xml::ParseDef::_debug = true;
172 /** collect _upgrade */
173 void doneUpgrade( const xml::Node & _node )
175 ProductFileData::Upgrade cdata( new ProductFileData::Upgrade::Impl( _upgrade ) );
176 _pdata._upgrades.push_back( cdata );
177 _upgrade = ProductFileData::Upgrade::Impl();
181 void done( const xml::Node & _node )
183 _pdata._edition = Edition( _version, _release );
187 ProductFileData::Impl & _pdata;
189 std::string _version;
190 std::string _release;
192 ProductFileData::Upgrade::Impl _upgrade;
195 bool ProductFileReader::parse( const InputStream & input_r ) const
197 MIL << "+++" << input_r << endl;
200 ProductFileData::Impl * pdataImpl = 0;
201 ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) );
205 xml::Reader reader( input_r );
206 ProductNode rootNode( *pdataImpl );
207 rootNode.take( reader );
210 catch ( const Exception & err )
214 ERR << "---" << ret << " - " << input_r << endl;
220 ret = _consumer( pdata );
223 MIL << "---" << ret << " - " << input_r << endl;
227 /////////////////////////////////////////////////////////////////
229 bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r )
231 std::list<Pathname> retlist;
232 int res = filesystem::readdir( retlist, dir_r, /*dots*/false );
235 WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl;
239 ProductFileReader reader( consumer_r );
240 for_( it, retlist.begin(), retlist.end() )
242 if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) )
244 return false; // consumer_r request to stop parsing.
250 ProductFileData ProductFileReader::scanFile( const Pathname & file_r )
252 if ( ! PathInfo( file_r ).isFile() )
254 WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl;
255 return ProductFileData();
259 ProductFileReader reader( functor::getFirst( ret ), file_r );
263 /////////////////////////////////////////////////////////////////
264 } // namespace parser
265 ///////////////////////////////////////////////////////////////////
266 /////////////////////////////////////////////////////////////////
268 ///////////////////////////////////////////////////////////////////