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