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