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;
79 std::string _registerFlavor;
81 std::string _updaterepokey;
86 ProductFileData::ProductFileData( Impl * allocated_r )
87 : _pimpl( allocated_r ? allocated_r : new Impl )
90 IdString ProductFileData::vendor() const { return _pimpl->_vendor; }
91 IdString ProductFileData::name() const { return _pimpl->_name; }
92 Edition ProductFileData::edition() const { return _pimpl->_edition; }
93 Arch ProductFileData::arch() const { return _pimpl->_arch; }
95 std::string ProductFileData::shortName() const { return _pimpl->_shortName; }
96 std::string ProductFileData::summary() const { return _pimpl->_summary; }
98 std::string ProductFileData::productline() const { return _pimpl->_productline; }
99 std::string ProductFileData::registerTarget() const { return _pimpl->_registerTarget; }
100 std::string ProductFileData::registerRelease() const { return _pimpl->_registerRelease; }
101 std::string ProductFileData::registerFlavor() const { return _pimpl->_registerFlavor; }
103 std::string ProductFileData::updaterepokey() const { return _pimpl->_updaterepokey; }
105 const ProductFileData::Upgrades & ProductFileData::upgrades() const { return _pimpl->_upgrades; }
107 std::ostream & operator<<( std::ostream & str, const ProductFileData & obj )
109 str << str::form( "|product|%s|%s|%s|%s|",
111 obj.edition().c_str(),
113 obj.vendor().c_str() );
114 if ( ! obj.upgrades().empty() )
116 for_( it, obj.upgrades().begin(), obj.upgrades().end() )
117 str << endl << " " << *it;
122 std::ostream & operator<<( std::ostream & str, const ProductFileData::Upgrade & obj )
124 str << str::form( "|upgrade|%s|%s|%s|%s|%s|",
126 obj.repository().c_str(),
127 obj.product().c_str(),
128 obj.status().c_str(),
129 (obj.notify() ? "notify" : "noNotify") );
132 /////////////////////////////////////////////////////////////////
134 // class ProductFileReader
136 /////////////////////////////////////////////////////////////////
138 struct ProductNode : public xml::ParseDef
140 ProductNode( ProductFileData::Impl & pdata_r )
141 : ParseDef( "product", MANDTAORY )
145 ("vendor", OPTIONAL, xml::parseDefAssign( _pdata._vendor ) )
146 ("name", MANDTAORY, xml::parseDefAssign( _pdata._name ) )
147 ("version", MANDTAORY, xml::parseDefAssign( _version ) )
148 ("release", MANDTAORY, xml::parseDefAssign( _release ) )
149 ("arch", MANDTAORY, xml::parseDefAssign( _pdata._arch ) )
150 ("shortsummary", OPTIONAL, xml::parseDefAssign( _pdata._shortName ) )
151 ("summary", MULTIPLE_OPTIONAL, xml::parseDefAssign( _ttext )( "lang", _tlocale )
152 >>bind( &ProductNode::doneLocalizedDefault, this, _1, boost::ref(_pdata._summary) ))
153 ("productline", OPTIONAL, xml::parseDefAssign( _pdata._productline ) )
154 ("register", OPTIONAL)
155 ("updaterepokey", OPTIONAL, xml::parseDefAssign( _pdata._updaterepokey ) )
156 ("upgrades", OPTIONAL)
160 ("target", OPTIONAL, xml::parseDefAssign( _pdata._registerTarget ) )
161 ("release", OPTIONAL, xml::parseDefAssign( _pdata._registerRelease ) )
162 ("flavor", OPTIONAL, xml::parseDefAssign( _pdata._registerFlavor ) )
166 ("upgrade", MULTIPLE_OPTIONAL, xml::parseDefAssign()
167 >> bind( &ProductNode::doneUpgrade, this, _1 ))
170 (*this)["upgrades"]["upgrade"]
171 ("name", OPTIONAL, xml::parseDefAssign( _upgrade._name ) )
172 ("summary", OPTIONAL, xml::parseDefAssign( _upgrade._summary ) )
173 ("repository", OPTIONAL, xml::parseDefAssign( _upgrade._repository ) )
174 ("product", OPTIONAL, xml::parseDefAssign( _upgrade._product ) )
175 ("notify", OPTIONAL, xml::parseDefAssign( _upgrade._notify ) )
176 ("status", OPTIONAL, xml::parseDefAssign( _upgrade._status ) )
179 // </product> callback to build edition.
180 setConsumer( xml::parseDefAssign() >> bind( &ProductNode::done, this, _1 ) );
181 // xml::ParseDef::_debug = true;
184 /** collect _upgrade */
185 void doneUpgrade( const xml::Node & _node )
187 ProductFileData::Upgrade cdata( new ProductFileData::Upgrade::Impl( _upgrade ) );
188 _pdata._upgrades.push_back( cdata );
189 _upgrade = ProductFileData::Upgrade::Impl();
191 /** collect localized data */
192 void doneLocalizedDefault( const xml::Node & _node, std::string & store_r )
194 // take 1st or default
195 if ( store_r.empty() || _tlocale.empty() )
200 void done( const xml::Node & _node )
202 _pdata._edition = Edition( _version, _release );
206 ProductFileData::Impl & _pdata;
208 std::string _version;
209 std::string _release;
212 std::string _tlocale;
214 ProductFileData::Upgrade::Impl _upgrade;
217 bool ProductFileReader::parse( const InputStream & input_r ) const
219 MIL << "+++" << input_r << endl;
222 ProductFileData::Impl * pdataImpl = 0;
223 ProductFileData pdata( (pdataImpl = new ProductFileData::Impl) );
227 xml::Reader reader( input_r );
228 ProductNode rootNode( *pdataImpl );
229 rootNode.take( reader );
232 catch ( const Exception & err )
236 ERR << "---" << ret << " - " << input_r << endl;
242 ret = _consumer( pdata );
245 MIL << "---" << ret << " - " << input_r << endl;
249 /////////////////////////////////////////////////////////////////
251 bool ProductFileReader::scanDir( const Consumer & consumer_r, const Pathname & dir_r )
253 std::list<Pathname> retlist;
254 int res = filesystem::readdir( retlist, dir_r, /*dots*/false );
257 WAR << "scanDir " << dir_r << " failed (" << res << ")" << endl;
261 ProductFileReader reader( consumer_r );
262 for_( it, retlist.begin(), retlist.end() )
264 if ( PathInfo( *it, PathInfo::LSTAT ).isFile() && ! reader.parse( *it ) )
266 return false; // consumer_r request to stop parsing.
272 ProductFileData ProductFileReader::scanFile( const Pathname & file_r )
274 if ( ! PathInfo( file_r ).isFile() )
276 WAR << "scanFile " << PathInfo( file_r ) << " is not a file." << endl;
277 return ProductFileData();
281 ProductFileReader reader( functor::getFirst( ret ), file_r );
285 /////////////////////////////////////////////////////////////////
286 } // namespace parser
287 ///////////////////////////////////////////////////////////////////
288 /////////////////////////////////////////////////////////////////
290 ///////////////////////////////////////////////////////////////////