};
public:
- /**
- * CTOR
- *
- * \see RepomdFileReader::RepomdFileReader(Pathname,ProcessResource)
- */
- Impl(const Pathname &repomd_file, const ProcessResource & callback);
+ /** Ctro taking a ProcessResource2 callback */
+ Impl(const Pathname &repomd_file, const ProcessResource2 & callback )
+ : _tag( tag_NONE )
+ , _type( ResourceType::NONE_e )
+ , _callback( callback )
+ {
+ Reader reader( repomd_file );
+ MIL << "Reading " << repomd_file << endl;
+ reader.foreachNode( bind( &RepomdFileReader::Impl::consumeNode, this, _1 ) );
+ }
+ /** \overload Redirect an old ProcessResource callback */
+ Impl(const Pathname &repomd_file, const ProcessResource & callback)
+ : Impl( repomd_file, ProcessResource2( bind( callback, _1, _2 ) ) )
+ {}
/**
* Callback provided to the XML parser.
private:
- /** Location of metadata file. */
- OnMediaLocation _location;
+ /** Function for processing collected data. Passed-in through constructor. */
+ ProcessResource2 _callback;
/** Used to remember currently processed tag */
Tag _tag;
- /** Type of metadata file. */
- repo::yum::ResourceType _type;
-
- /** Function for processing collected data. Passed-in through constructor. */
- ProcessResource _callback;
-
- /** Checksum of metadata file */
- CheckSum _checksum;
+ /** Type of metadata file (string) */
+ std::string _typeStr;
- /** Type of checksum of metadata file */
- std::string _checksum_type;
+ /** Type of metadata file as enum of well known repoinded.xml entries. */
+ repo::yum::ResourceType _type;
- /** Metadata file time-stamp. */
- Date _timestamp;
+ /** Location of metadata file. */
+ OnMediaLocation _location;
};
///////////////////////////////////////////////////////////////////////
- RepomdFileReader::Impl::Impl(
- const Pathname &repomd_file, const ProcessResource & callback)
- :
- _tag(tag_NONE), _type(ResourceType::NONE_e), _callback(callback)
- {
- Reader reader( repomd_file );
- MIL << "Reading " << repomd_file << endl;
- reader.foreachNode( bind( &RepomdFileReader::Impl::consumeNode, this, _1 ) );
- }
-
- // --------------------------------------------------------------------------
-
/*
* xpath and multiplicity of processed nodes are included in the code
* for convenience:
if ( reader_r->name() == "data" )
{
_tag = tag_Data;
- _type = ResourceType(reader_r->getAttribute("type").asString());
+ _typeStr = reader_r->getAttribute("type").asString();
+ _type = ResourceType(_typeStr);
return true;
}
if ( reader_r->name() == "data" )
{
if (_callback)
- _callback( _location, _type );
+ _callback( _location, _type, _typeStr );
return true;
}
//
///////////////////////////////////////////////////////////////////
- RepomdFileReader::RepomdFileReader(
- const Pathname & repomd_file, const ProcessResource & callback)
- :
- _pimpl(new Impl(repomd_file, callback))
+ RepomdFileReader::RepomdFileReader( const Pathname & repomd_file, const ProcessResource & callback )
+ : _pimpl( new Impl(repomd_file, callback) )
+ {}
+
+ RepomdFileReader::RepomdFileReader( const Pathname & repomd_file, const ProcessResource2 & callback )
+ : _pimpl( new Impl(repomd_file, callback) )
{}
RepomdFileReader::~RepomdFileReader()
* Reads through a repomd.xml file and collects type, location, checksum and
* other data about metadata files to be processed.
*
- * After each package is read, a \ref OnMediaLocation
- * and \ref repo::yum::ResourceType is prepared and \ref _callback
- * is called with these two objects passed in.
- *
- * The \ref _callback is provided on construction.
+ * After each file entry is read, a \ref OnMediaLocation
+ * and \ref repo::yum::ResourceType are prepared and passed to the \ref _callback.
*
+ * Depending on the \ref _callback type provided on construction, ResourceType may
+ * additionally be passed as a plain string. This form allows handling custom
+ * resource types (e.g. ones with embedded locale tag).
*
* \code
* RepomdFileReader reader(repomd_file,
class RepomdFileReader : private base::NonCopyable
{
public:
- /**
- * Callback definition.
- * First parameter is a \ref OnMediaLocation object with the resource
- * second parameter is the resource type.
- */
- typedef function< bool(
- const OnMediaLocation &,
- const repo::yum::ResourceType &)>
- ProcessResource;
+ /** Callbacl taking \ref OnMediaLocation and \ref repo::yum::ResourceType */
+ typedef function< bool( const OnMediaLocation &, const repo::yum::ResourceType & )> ProcessResource;
+
+ /** Alternate callback also receiving the ResourceType as string. */
+ typedef function< bool( const OnMediaLocation &, const repo::yum::ResourceType &, const std::string & )> ProcessResource2;
/**
* CTOR. Creates also \ref xml::Reader and starts reading.
*
* \see RepomdFileReader::ProcessResource
*/
- RepomdFileReader(
- const Pathname & repomd_file, const ProcessResource & callback);
+ RepomdFileReader( const Pathname & repomd_file, const ProcessResource & callback );
+ /** \overload taking ProcessResource2 callback */
+ RepomdFileReader( const Pathname & repomd_file, const ProcessResource2 & callback );
- /**
- * DTOR
- */
+ /** DTOR */
~RepomdFileReader();
private:
};
- } // ns yum
- } // ns parser
-} // ns zypp
-
-#endif /*zypp_source_yum_RepomdFileReader_H*/
+ } // namespace yum
+ } // namespace parser
+} // namespace zypp
-// vim: set ts=2 sts=2 sw=2 et ai:
+#endif // zypp_source_yum_RepomdFileReader_H
#include <fstream>
#include "zypp/base/String.h"
-#include "zypp/base/Logger.h"
+#include "zypp/base/LogTools.h"
#include "zypp/base/Function.h"
+#include "zypp/ZConfig.h"
#include "zypp/parser/yum/RepomdFileReader.h"
#include "zypp/parser/yum/PatchesFileReader.h"
Downloader::Downloader( const RepoInfo &repoinfo , const Pathname &delta_dir)
: repo::Downloader(repoinfo), _delta_dir(delta_dir), _media_ptr(0L)
-{
-}
-
+{}
RepoStatus Downloader::status( MediaSetAccess &media )
{
return RepoStatus(repomd);
}
-static OnMediaLocation
-loc_with_path_prefix(const OnMediaLocation & loc,
- const Pathname & prefix)
+static OnMediaLocation loc_with_path_prefix( const OnMediaLocation & loc, const Pathname & prefix )
{
if (prefix.empty() || prefix == "/")
return loc;
}
// search old repository file file to run the delta algorithm on
-static Pathname search_deltafile( const Pathname &dir, const Pathname &file )
+static Pathname search_deltafile( const Pathname & dir, const Pathname & file )
{
Pathname deltafile;
if (!PathInfo(dir).isDir())
return deltafile;
}
-bool Downloader::patches_Callback( const OnMediaLocation &loc,
- const string &id )
+bool Downloader::patches_Callback( const OnMediaLocation & loc_r, const string & id_r )
{
- OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
- MIL << id << " : " << loc_with_path << endl;
- this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
+ OnMediaLocation loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
+ MIL << id_r << " : " << loc_with_path << endl;
+ this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
return true;
}
-bool Downloader::repomd_Callback( const OnMediaLocation &loc,
- const ResourceType &dtype )
-{
- OnMediaLocation loc_with_path(loc_with_path_prefix(loc, repoInfo().path()));
- MIL << dtype << " : " << loc_with_path << endl;
- //! \todo do this through a ZConfig call so that it is always in sync with parser
- // skip other
- if ( dtype == ResourceType::OTHER )
- {
- MIL << "Skipping other.xml" << endl;
- return true;
- }
- // skip filelists
- if ( dtype == ResourceType::FILELISTS )
+//bool repomd_Callback2( const OnMediaLocation &loc, const ResourceType &dtype, const std::string &typestr, UserData & userData_r );
+
+///////////////////////////////////////////////////////////////////
+namespace
+{
+ ///////////////////////////////////////////////////////////////////
+ /// \class Impl
+ /// \brief Helper filtering the files offered by a RepomdFileReader
+ ///
+ /// Clumsy construct; basically an Impl class for Downloader, maintained
+ /// in Downloader::download only while parsing a repomd.xml.
+ ///
+ /// Introduced because Downloader itself lacks an Impl class, thus can't
+ /// be extended to provide more data to the callbacks without losing
+ /// binary compatibility.
+ ///////////////////////////////////////////////////////////////////
+ struct RepomdFileReaderCallback2
{
- MIL << "Skipping filelists.xml.gz" << endl;
- return true;
- }
+ RepomdFileReaderCallback2( const RepomdFileReader::ProcessResource & origCallback_r )
+ : _origCallback( origCallback_r )
+ {
+ addWantedLocale( ZConfig::instance().textLocale() );
+ for ( const Locale & it : ZConfig::instance().repoRefreshLocales() )
+ addWantedLocale( it );
+ }
- this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc.filename()));
+ /** The callback invoked by the RepomdFileReader */
+ bool repomd_Callback2( const OnMediaLocation & loc_r, const ResourceType & dtype_r, const std::string & typestr_r )
+ {
+ // filter well known resource types
+ if ( dtype_r == ResourceType::OTHER || dtype_r == ResourceType::FILELISTS )
+ return true; // skip it
+
+ // filter custom resource types (by string)
+ if ( dtype_r == ResourceType::NONE )
+ {
+ // susedata.LANG
+ if ( str::hasPrefix( typestr_r, "susedata." ) && ! wantLocale( Locale(typestr_r.c_str()+9) ) )
+ return true; // skip it
+ }
+
+ // take it
+ return( _origCallback ? _origCallback( loc_r, dtype_r ) : true );
+ }
+
+ private:
+ bool wantLocale( const Locale & locale_r ) const
+ { return _wantedLocales.count( locale_r ); }
+
+ void addWantedLocale( Locale locale_r )
+ {
+ while ( locale_r )
+ {
+ _wantedLocales.insert( locale_r );
+ locale_r = locale_r.fallback();
+ }
+ }
+
+ private:
+ RepomdFileReader::ProcessResource _origCallback; ///< Original Downloader callback
+ LocaleSet _wantedLocales; ///< Locales do download
+
+ };
+} // namespace
+///////////////////////////////////////////////////////////////////
+
+bool Downloader::repomd_Callback( const OnMediaLocation & loc_r, const ResourceType & dtype_r )
+{
+ // NOTE: Filtering of unwanted files is done in RepomdFileReaderCallback2!
+
+ // schedule file for download
+ const OnMediaLocation & loc_with_path(loc_with_path_prefix(loc_r, repoInfo().path()));
+ this->enqueueDigested(loc_with_path, FileChecker(), search_deltafile(_delta_dir + "repodata", loc_r.filename()));
// We got a patches file we need to read, to add patches listed
// there, so we transfer what we have in the queue, and
// queue the patches in the patches callback
- if ( dtype == ResourceType::PATCHES )
+ if ( dtype_r == ResourceType::PATCHES )
{
this->start( _dest_dir, *_media_ptr );
// now the patches.xml file must exists
- PatchesFileReader( _dest_dir + repoInfo().path() + loc.filename(),
+ PatchesFileReader( _dest_dir + repoInfo().path() + loc_r.filename(),
bind( &Downloader::patches_Callback, this, _1, _2));
}
-
return true;
}
-/** \todo: Downloading/sigcheck of master index shoudl be common in base class */
-void Downloader::download( MediaSetAccess &media,
- const Pathname &dest_dir,
- const ProgressData::ReceiverFnc & progressrcv )
+void Downloader::download( MediaSetAccess & media, const Pathname & dest_dir, const ProgressData::ReceiverFnc & progressrcv )
{
Pathname masterIndex( repoInfo().path() / "/repodata/repomd.xml" );
defaultDownloadMasterIndex( media, dest_dir, masterIndex );
+ // init the data stored in Downloader itself
_media_ptr = (&media);
_dest_dir = dest_dir;
- RepomdFileReader( dest_dir / masterIndex, bind( &Downloader::repomd_Callback, this, _1, _2));
+
+ // init the extended data
+ RepomdFileReaderCallback2 pimpl( bind(&Downloader::repomd_Callback, this, _1, _2) );
+
+ // setup parser
+ RepomdFileReader( dest_dir / masterIndex,
+ RepomdFileReader::ProcessResource2( bind(&RepomdFileReaderCallback2::repomd_Callback2, &pimpl, _1, _2, _3) ) );
// ready, go!
start( dest_dir, media );
}
-}// ns yum
-}// ns source
-} // ns zypp
+} // namespace yum
+} // namespace repo
+} // namespace zypp