00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include <fstream>
00014 #include "zypp/base/Logger.h"
00015 #include "zypp/base/Exception.h"
00016 #include "zypp/base/String.h"
00017
00018 #include "zypp/SourceFactory.h"
00019 #include "zypp/source/Builtin.h"
00020 #include "zypp/media/MediaAccess.h"
00021 #include "zypp/ZYppCallbacks.h"
00022
00023 using std::endl;
00024 using namespace zypp::source;
00025
00027 namespace zypp
00028 {
00029
00030 media::MediaManager media_mgr;
00031
00033
00034
00035
00037 struct SourceFactory::Impl
00038 {
00042 template<class _SourceImpl>
00043 static Source_Ref::Impl_Ptr createSourceImpl( const media::MediaId & media_r,
00044 const Pathname & path_r,
00045 const std::string & alias_r,
00046 const Pathname & cache_dir_r)
00047 {
00048 Source_Ref::Impl_Ptr impl( new _SourceImpl );
00049 impl->factoryCtor( media_r, path_r, alias_r, cache_dir_r, false );
00050 return impl;
00051 }
00052
00056 template<class _SourceImpl>
00057 static Source_Ref::Impl_Ptr createBaseSourceImpl( const media::MediaId & media_r,
00058 const Pathname & path_r,
00059 const std::string & alias_r,
00060 const Pathname & cache_dir_r)
00061 {
00062 Source_Ref::Impl_Ptr impl( new _SourceImpl );
00063 impl->factoryCtor( media_r, path_r, alias_r, cache_dir_r, true );
00064 return impl;
00065 }
00066
00067 };
00069
00071
00072
00073
00075
00077
00078
00079
00080
00081 SourceFactory::SourceFactory()
00082 {}
00083
00085
00086
00087
00088
00089 SourceFactory::~SourceFactory()
00090 {}
00091
00093
00094
00095
00096
00097 Source_Ref SourceFactory::createFrom( const Source_Ref::Impl_Ptr & impl_r )
00098 {
00099 return impl_r ? Source_Ref( impl_r ) : Source_Ref::noSource;
00100 }
00101
00102 void SourceFactory::listProducts( const Url & url_r, ProductSet & products_r )
00103 {
00104 if (! url_r.isValid())
00105 ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
00106
00107
00108 media::MediaId id = media_mgr.open(url_r);
00109 media_mgr.attach(id);
00110 Pathname products_file = Pathname("media.1/products");
00111
00112 try {
00113 media_mgr.provideFile (id, products_file);
00114 products_file = media_mgr.localPath (id, products_file);
00115 scanProductsFile (products_file, products_r);
00116 }
00117 catch ( const Exception & excpt ) {
00118 ZYPP_CAUGHT(excpt);
00119
00120 MIL << "No products description found on the Url" << endl;
00121 }
00122
00123 media_mgr.release(id);
00124 }
00125
00126 Source_Ref SourceFactory::createFrom( const Url & url_r, const Pathname & path_r, const std::string & alias_r, const Pathname & cache_dir_r, const bool base_source )
00127 {
00128 if (! url_r.isValid())
00129 ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
00130
00131 callback::SendReport<CreateSourceReport> report;
00132
00133 report->startProbe (url_r);
00134
00135 #warning if cache_dir is provided, no need to open the original url
00136
00137 media::MediaId id = media_mgr.open(url_r);
00138
00139
00140 media_mgr.addVerifier(id, media::MediaVerifierRef(new media::NoVerifier()));
00141
00142 if (cache_dir_r == "")
00143 {
00144 media_mgr.attach(id);
00145 }
00146 else
00147 {
00148 MIL << "Initializing from cache" << endl;
00149 }
00150
00151 try
00152 {
00153 MIL << "Trying the YUM source" << endl;
00154 Source_Ref::Impl_Ptr impl( base_source
00155 ? Impl::createBaseSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r)
00156 : Impl::createSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r) );
00157 MIL << "Found the YUM source" << endl;
00158
00159 report->endProbe (url_r);
00160
00161 return Source_Ref(impl);
00162 }
00163 catch (const Exception & excpt_r)
00164 {
00165 ZYPP_CAUGHT(excpt_r);
00166 MIL << "Not YUM source, trying next type" << endl;
00167 }
00168 try
00169 {
00170 MIL << "Trying the SUSE tags source" << endl;
00171 Source_Ref::Impl_Ptr impl( base_source
00172 ? Impl::createBaseSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r)
00173 : Impl::createSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r) );
00174 MIL << "Found the SUSE tags source" << endl;
00175
00176 report->endProbe (url_r);
00177
00178 return Source_Ref(impl);
00179 }
00180 catch (const Exception & excpt_r)
00181 {
00182 ZYPP_CAUGHT(excpt_r);
00183 MIL << "Not SUSE tags source, trying next type" << endl;
00184 }
00185
00186 #warning Plaindir disabled in autoprobing
00187 #if 0
00188 try
00189 {
00190 MIL << "Trying the Plaindir source" << endl;
00191 Source_Ref::Impl_Ptr impl( base_source
00192 ? Impl::createBaseSourceImpl<PlaindirImpl>(id, path_r, alias_r, cache_dir_r)
00193 : Impl::createSourceImpl<PlaindirImpl>(id, path_r, alias_r, cache_dir_r) );
00194 MIL << "Found the Plaindir source" << endl;
00195
00196 report->endProbe (url_r);
00197
00198 return Source_Ref(impl);
00199 }
00200 catch (const Exception & excpt_r)
00201 {
00202 ZYPP_CAUGHT(excpt_r);
00203 MIL << "Not Plaindir source, trying next type" << endl;
00204 }
00205 #endif
00206
00207 report->endProbe (url_r);
00208
00209 ERR << "No next type of source" << endl;
00210 ZYPP_THROW(Exception("Cannot create the installation source"));
00211 return Source_Ref();
00212 }
00213
00214 Source_Ref SourceFactory::createFrom( const std::string & type, const Url & url_r, const Pathname & path_r, const std::string & alias_r, const Pathname & cache_dir_r, const bool base_source )
00215 {
00216 if (! url_r.isValid())
00217 ZYPP_THROW( Exception("Empty URL passed to SourceFactory") );
00218
00219 callback::SendReport<CreateSourceReport> report;
00220
00221 report->startProbe (url_r);
00222
00223 #warning if cache_dir is provided, no need to open the original url
00224
00225 media::MediaId id = media_mgr.open(url_r);
00226
00227
00228 media_mgr.addVerifier(id, media::MediaVerifierRef(new media::NoVerifier()));
00229
00230 if (cache_dir_r == "")
00231 {
00232 media_mgr.attach(id);
00233 }
00234 else
00235 {
00236 MIL << "Initializing from cache" << endl;
00237 }
00238
00239 try
00240 {
00241
00242 Source_Ref::Impl_Ptr impl;
00243
00244 if( type == yum::YUMSourceImpl::typeString() ) {
00245 MIL << "Trying the YUM source" << endl;
00246 impl = Source_Ref::Impl_Ptr( base_source
00247 ? Impl::createBaseSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r)
00248 : Impl::createSourceImpl<yum::YUMSourceImpl>(id, path_r, alias_r, cache_dir_r) );
00249 MIL << "Found the YUM source" << endl;
00250 } else if ( type == susetags::SuseTagsImpl::typeString() ) {
00251 MIL << "Trying the SUSE tags source" << endl;
00252 impl = Source_Ref::Impl_Ptr( base_source
00253 ? Impl::createBaseSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r)
00254 : Impl::createSourceImpl<susetags::SuseTagsImpl>(id, path_r, alias_r, cache_dir_r) );
00255 MIL << "Found the SUSE tags source" << endl;
00256 } else if ( type == PlaindirImpl::typeString() ) {
00257 MIL << "Trying the Plaindir source" << endl;
00258 impl = Source_Ref::Impl_Ptr( base_source
00259 ? Impl::createBaseSourceImpl<PlaindirImpl>(id, path_r, alias_r, cache_dir_r)
00260 : Impl::createSourceImpl<PlaindirImpl>(id, path_r, alias_r, cache_dir_r) );
00261 MIL << "Found the Plaindir source" << endl;
00262 } else {
00263 ZYPP_THROW( Exception ("Cannot create source of unknown type '" + type + "'"));
00264 }
00265
00266 report->endProbe (url_r);
00267
00268 return Source_Ref(impl);
00269 }
00270 catch (const Exception & excpt_r)
00271 {
00272 ZYPP_CAUGHT(excpt_r);
00273 MIL << "Creating a source of type " << type << " failed " << endl;
00274 }
00275
00276 report->endProbe (url_r);
00277
00278 ERR << "No next type of source" << endl;
00279 ZYPP_THROW(Exception("Cannot create the installation source"));
00280 return Source_Ref();
00281 }
00282
00283
00284
00285
00286
00287
00288
00289 std::ostream & operator<<( std::ostream & str, const SourceFactory & obj )
00290 {
00291 return str << "SourceFactory";
00292 }
00293
00294 void SourceFactory::scanProductsFile( const Pathname & file_r, ProductSet & pset_r ) const
00295 {
00296 std::ifstream pfile( file_r.asString().c_str() );
00297 while ( pfile.good() ) {
00298
00299 std::string value = str::getline( pfile, str::TRIM );
00300 if ( pfile.bad() ) {
00301 ERR << "Error parsing " << file_r << endl;
00302 ZYPP_THROW(Exception("Error parsing " + file_r.asString()));
00303 }
00304 if ( pfile.fail() ) {
00305 break;
00306 }
00307 std::string tag = str::stripFirstWord( value, true );
00308
00309 if ( tag.size() ) {
00310 pset_r.insert( ProductEntry( tag, value ) );
00311 }
00312 }
00313 }
00314
00315
00316
00318 }