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