libzypp 9.41.1
|
00001 /*---------------------------------------------------------------------\ 00002 | ____ _ __ __ ___ | 00003 | |__ / \ / / . \ . \ | 00004 | / / \ V /| _/ _/ | 00005 | / /__ | | | | | | | 00006 | /_____||_| |_| |_| | 00007 | | 00008 \---------------------------------------------------------------------*/ 00012 #include <iostream> 00013 #include "zypp/base/LogTools.h" 00014 00015 #include "zypp/Product.h" 00016 #include "zypp/Url.h" 00017 00018 #include "zypp/sat/LookupAttr.h" 00019 #include "zypp/sat/AttrMatcher.h" 00020 #include "zypp/sat/WhatProvides.h" 00021 #include "zypp/sat/WhatObsoletes.h" 00022 #include "zypp/PoolItem.h" 00023 00024 using std::endl; 00025 00027 namespace zypp 00028 { 00029 00030 IMPL_PTR_TYPE(Product); 00031 00032 namespace 00033 { 00034 void fillList( std::list<Url> & ret_r, sat::Solvable solv_r, sat::SolvAttr attr_r ) 00035 { 00036 sat::LookupAttr query( attr_r, solv_r ); 00037 for_( it, query.begin(), query.end() ) 00038 { 00039 try // ignore malformed urls 00040 { 00041 ret_r.push_back( Url( it.asString() ) ); 00042 } 00043 catch( const url::UrlException & ) 00044 {} 00045 } 00046 } 00047 00048 void fillList( std::list<std::string> & ret_r, sat::Solvable solv_r, sat::SolvAttr attr_r ) 00049 { 00050 sat::LookupAttr query( attr_r, solv_r ); 00051 for_( it, query.begin(), query.end() ) 00052 { 00053 ret_r.push_back( it.asString() ); 00054 } 00055 } 00056 } 00057 00059 // 00060 // METHOD NAME : Product::Product 00061 // METHOD TYPE : Ctor 00062 // 00063 Product::Product( const sat::Solvable & solvable_r ) 00064 : ResObject( solvable_r ) 00065 {} 00066 00068 // 00069 // METHOD NAME : Product::~Product 00070 // METHOD TYPE : Dtor 00071 // 00072 Product::~Product() 00073 {} 00074 00076 00077 sat::Solvable Product::referencePackage() const 00078 { 00079 // Look for a provider of 'product(name) = version' of same 00080 // architecture and within the same repo. 00081 // 00082 // bnc #497696: Update repos may have multiple release package versions 00083 // providing the same product. As a workaround we link to the one with 00084 // the highest version. 00085 Capability identCap( str::form( "product(%s) = %s", name().c_str(), edition().c_str() ) ); 00086 00087 sat::Solvable found; 00088 sat::WhatProvides providers( identCap ); 00089 for_( it, providers.begin(), providers.end() ) 00090 { 00091 if ( it->repository() == repository() 00092 && it->arch() == arch() ) 00093 { 00094 if ( ! found || found.edition() < it->edition() ) 00095 found = *it; 00096 } 00097 } 00098 00099 if ( ! found && isSystem() ) 00100 { 00101 // bnc#784900: for installed products check whether the file is owned by 00102 // some package. If so, ust this as buddy. 00103 sat::LookupAttr q( sat::SolvAttr::filelist, repository() ); 00104 std::string refFile( referenceFilename() ); 00105 if ( ! refFile.empty() ) 00106 { 00107 sat::AttrMatcher matcher( referenceFilename() ); 00108 q.setAttrMatcher( matcher ); 00109 if ( ! q.empty() ) 00110 found = q.begin().inSolvable(); 00111 } 00112 else 00113 INT << "Product referenceFilename unexpectedly empty!" << endl; 00114 } 00115 00116 if ( ! found ) 00117 WAR << *this << ": no reference package found: " << identCap << endl; 00118 return found; 00119 } 00120 00121 std::string Product::referenceFilename() const 00122 { return lookupStrAttribute( sat::SolvAttr::productReferenceFile ); } 00123 00124 Product::ReplacedProducts Product::replacedProducts() const 00125 { 00126 std::vector<constPtr> ret; 00127 // By now we simply collect what is obsoleted by the Product, 00128 // or by the products buddy (release-package). 00129 00130 // Check our own dependencies. We should not have any, 00131 // but just to be shure. 00132 sat::WhatObsoletes obsoleting( satSolvable() ); 00133 for_( it, obsoleting.begin(), obsoleting.end() ) 00134 { 00135 if ( it->isKind( ResKind::product ) ) 00136 ret.push_back( make<Product>( *it ) ); 00137 } 00138 00139 // If we have a buddy, we check what product buddies the 00140 // buddy replaces. 00141 obsoleting = sat::WhatObsoletes( poolItem().buddy() ); 00142 for_( it, obsoleting.poolItemBegin(), obsoleting.poolItemEnd() ) 00143 { 00144 if ( (*it).buddy().isKind( ResKind::product ) ) 00145 ret.push_back( make<Product>( (*it).buddy() ) ); 00146 } 00147 return ret; 00148 } 00149 00150 CapabilitySet Product::droplist() const 00151 { return poolItem().buddy().valuesOfNamespace( "weakremover" ); } 00152 00153 std::string Product::productLine() const 00154 { return lookupStrAttribute( sat::SolvAttr::productProductLine ); } 00155 00157 00158 std::string Product::shortName() const 00159 { return lookupStrAttribute( sat::SolvAttr::productShortlabel ); } 00160 00161 std::string Product::flavor() const 00162 { 00163 // Look for a provider of 'product_flavor(name) = version' 00164 // within the same repo. Unlike the reference package, we 00165 // can be relaxed and ignore the architecture. 00166 Capability identCap( str::form( "product_flavor(%s) = %s", name().c_str(), edition().c_str() ) ); 00167 00168 sat::WhatProvides providers( identCap ); 00169 for_( it, providers.begin(), providers.end() ) 00170 { 00171 if ( it->repository() == repository() ) 00172 { 00173 // Got the package now try to get the provided 'flavor(...)' 00174 Capabilities provides( it->provides() ); 00175 for_( cap, provides.begin(), provides.end() ) 00176 { 00177 std::string capstr( cap->asString() ); 00178 if ( str::hasPrefix( capstr, "flavor(" ) ) 00179 { 00180 capstr = str::stripPrefix( capstr, "flavor(" ); 00181 capstr.erase( capstr.size()-1 ); // trailing ')' 00182 return capstr; 00183 } 00184 } 00185 } 00186 } 00187 return std::string(); 00188 } 00189 00190 std::string Product::type() const 00191 { return lookupStrAttribute( sat::SolvAttr::productType ); } 00192 00193 std::list<std::string> Product::flags() const 00194 { 00195 std::list<std::string> ret; 00196 fillList( ret, satSolvable(), sat::SolvAttr::productFlags ); 00197 return ret; 00198 } 00199 00200 Date Product::endOfLife() const 00201 { return Date( lookupNumAttribute( sat::SolvAttr::productEndOfLife ) );} 00202 00203 bool Product::isTargetDistribution() const 00204 { return isSystem() && lookupStrAttribute( sat::SolvAttr::productType ) == "base"; } 00205 00206 std::string Product::registerTarget() const 00207 { return lookupStrAttribute( sat::SolvAttr::productRegisterTarget ); } 00208 00209 std::string Product::registerRelease() const 00210 { return lookupStrAttribute( sat::SolvAttr::productRegisterRelease ); } 00211 00213 00214 Product::UrlList Product::urls( const std::string & key_r ) const 00215 { 00216 UrlList ret; 00217 00218 sat::LookupAttr url( sat::SolvAttr::productUrl, *this ); 00219 sat::LookupAttr url_type( sat::SolvAttr::productUrlType, *this ); 00220 00221 sat::LookupAttr::iterator url_it(url.begin()); 00222 sat::LookupAttr::iterator url_type_it(url_type.begin()); 00223 00224 for (;url_it != url.end(); ++url_it, ++url_type_it) 00225 { 00226 /* safety checks, shouldn't happen (tm) */ 00227 if (url_type_it == url_type.end()) 00228 { 00229 ERR << *this << " : The thing that should not happen, happened." << endl; 00230 break; 00231 } 00232 00233 if ( url_type_it.asString() == key_r ) 00234 { 00235 ret._list.push_back(url_it.asString()); 00236 } 00237 } /* while (attribute array) */ 00238 00239 return ret; 00240 } 00241 00242 Product::UrlList Product::releaseNotesUrls() const { return urls( "releasenotes" ); } 00243 Product::UrlList Product::registerUrls() const { return urls( "register" ); } 00244 Product::UrlList Product::smoltUrls() const { return urls( "smolt" ); } 00245 Product::UrlList Product::updateUrls() const { return urls( "update" ); } 00246 Product::UrlList Product::extraUrls() const { return urls( "extra" ); } 00247 Product::UrlList Product::optionalUrls() const { return urls( "optional" ); } 00248 00249 std::ostream & operator<<( std::ostream & str, const Product::UrlList & obj ) 00250 { return dumpRange( str << obj.key() << ' ', obj.begin(), obj.end() ); } 00251 00253 } // namespace zypp