libzypp  10.5.0
Patch.cc
Go to the documentation of this file.
00001 /*---------------------------------------------------------------------\
00002 |                          ____ _   __ __ ___                          |
00003 |                         |__  / \ / / . \ . \                         |
00004 |                           / / \ V /|  _/  _/                         |
00005 |                          / /__ | | | | | |                           |
00006 |                         /_____||_| |_| |_|                           |
00007 |                                                                      |
00008 \---------------------------------------------------------------------*/
00012 #include <iostream>
00013 
00014 #include "zypp/base/LogTools.h"
00015 #include "zypp/Patch.h"
00016 #include "zypp/sat/WhatProvides.h"
00017 
00018 using std::endl;
00019 
00021 namespace zypp
00022 { 
00023 
00024   IMPL_PTR_TYPE( Patch );
00025 
00027   //
00028   //    METHOD NAME : Patch::Patch
00029   //    METHOD TYPE : Ctor
00030   //
00031   Patch::Patch( const sat::Solvable & solvable_r )
00032   : ResObject( solvable_r )
00033   {}
00034 
00036   //
00037   //    METHOD NAME : Patch::~Patch
00038   //    METHOD TYPE : Dtor
00039   //
00040   Patch::~Patch()
00041   {}
00042 
00044   //
00045   //    Patch interface forwarded to implementation
00046   //
00048 
00049   Patch::Category Patch::categoryEnum() const
00050   {
00051     std::string cat( category() );
00052     switch ( cat[0] )
00053     {
00054       //        CAT_YAST
00055       case 'y':
00056       case 'Y':
00057         if ( str::compareCI( cat, "yast" ) == 0 )
00058           return CAT_YAST;
00059         break;
00060 
00061       //        CAT_SECURITY
00062       case 's':
00063       case 'S':
00064         if ( str::compareCI( cat, "security" ) == 0 )
00065           return CAT_SECURITY;
00066         break;
00067 
00068       //        CAT_RECOMMENDED
00069       case 'r':
00070       case 'R':
00071         if ( str::compareCI( cat, "recommended" ) == 0 )
00072           return CAT_RECOMMENDED;
00073         break;
00074       case 'b':
00075       case 'B':
00076         if ( str::compareCI( cat, "bugfix" ) == 0 )     // rhn
00077           return CAT_RECOMMENDED;
00078         break;
00079 
00080       //        CAT_OPTIONAL
00081       case 'o':
00082       case 'O':
00083         if ( str::compareCI( cat, "optional" ) == 0 )
00084           return CAT_OPTIONAL;
00085         break;
00086       case 'f':
00087       case 'F':
00088         if ( str::compareCI( cat, "feature" ) == 0 )
00089           return CAT_OPTIONAL;
00090         break;
00091       case 'e':
00092       case 'E':
00093         if ( str::compareCI( cat, "enhancement" ) == 0 )        // rhn
00094           return CAT_OPTIONAL;
00095         break;
00096 
00097       //        CAT_DOCUMENT
00098       case 'd':
00099       case 'D':
00100         if ( str::compareCI( cat, "document" ) == 0 )
00101           return CAT_DOCUMENT;
00102         break;
00103     }
00104     // default:
00105     return CAT_OTHER;
00106   }
00107 
00108   std::string Patch::message( const Locale & lang_r ) const
00109   { return lookupStrAttribute( sat::SolvAttr::message, lang_r ); }
00110 
00111   std::string Patch::category() const
00112   { return lookupStrAttribute( sat::SolvAttr::patchcategory ); }
00113 
00114   bool Patch::rebootSuggested() const
00115   { return lookupBoolAttribute( sat::SolvAttr::rebootSuggested ); }
00116 
00117   bool Patch::restartSuggested() const
00118   { return lookupBoolAttribute( sat::SolvAttr::restartSuggested ); }
00119 
00120   bool Patch::reloginSuggested() const
00121   { return lookupBoolAttribute( sat::SolvAttr::reloginSuggested ); }
00122 
00123   Patch::InteractiveFlags Patch::interactiveFlags() const
00124   {
00125     InteractiveFlags patchFlags (NoFlags);
00126     if ( rebootSuggested() )
00127       patchFlags |= Reboot;
00128 
00129     if ( ! message().empty() )
00130       patchFlags |= Message;
00131 
00132     if ( ! licenseToConfirm().empty() )
00133       patchFlags |= License;
00134 
00135     Patch::Contents c( contents() );
00136     for_( it, c.begin(), c.end() )
00137     {
00138       if ( ! makeResObject(*it)->licenseToConfirm().empty() )
00139       {
00140         patchFlags |= License;
00141         break;
00142       }
00143     }
00144     return patchFlags;
00145   }
00146 
00147   bool Patch::interactiveWhenIgnoring( InteractiveFlags flags_r ) const
00148   {
00149     if ( interactiveFlags() & ( ~flags_r ) )
00150     {
00151       return true;
00152     }
00153     else
00154     {
00155       return false;
00156     }
00157   }
00158 
00159   bool Patch::interactive() const
00160   {
00161     return interactiveWhenIgnoring();
00162   }
00163 
00164   Patch::Contents Patch::contents() const
00165   {
00166     Contents result;
00167     // DBG << *this << endl;
00168     sat::LookupAttr updateCollection( sat::SolvAttr::updateCollection, satSolvable() );
00169     for_( entry, updateCollection.begin(), updateCollection.end() )
00170     {
00171       IdString name    ( entry.subFind( sat::SolvAttr::updateCollectionName ).idStr() );
00172       Edition  edition ( entry.subFind( sat::SolvAttr::updateCollectionEvr ).idStr() );
00173       Arch     arch    ( entry.subFind( sat::SolvAttr::updateCollectionArch ).idStr() );
00174       if ( name.empty() )
00175       {
00176         WAR << "Ignore malformed updateCollection entry: " << name << "-" << edition << "." << arch << endl;
00177         continue;
00178       }
00179 
00180       // The entry is relevant if there is an installed
00181       // package with the same name and arch.
00182       bool relevant = false;
00183       sat::WhatProvides providers( (Capability( name.id() )) );
00184       for_( it, providers.begin(), providers.end() )
00185       {
00186         if ( it->isSystem() && it->ident() == name && it->arch() == arch )
00187         {
00188           relevant = true;
00189           break;
00190         }
00191       }
00192       if ( ! relevant )
00193       {
00194         // DBG << "Not relevant: " << name << "-" << edition << "." << arch << endl;
00195         continue;
00196       }
00197 
00198       /* find exact providers first (this matches the _real_ 'collection content' of the patch */
00199       providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::EQ, edition, ResKind::package ) );
00200       if ( providers.empty() )
00201       {
00202         /* no exact providers: find 'best' providers: those with a larger evr */
00203         providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::GT, edition, ResKind::package ) );
00204         if ( providers.empty() )
00205         {
00206           // Hmm, this patch is not installable, no one is providing the package in the collection
00207           // FIXME: raise execption ? fake a solvable ?
00208           WAR << "Missing provider: " << name << "-" << edition << "." << arch << endl;
00209           continue;
00210         }
00211       }
00212 
00213       // FIXME ?! loop over providers and try to find installed ones ?
00214       // DBG << "Found " << name << "-" << edition << "." << arch << ": " << *(providers.begin()) << endl;
00215       result.get().insert( *(providers.begin()) );
00216     }
00217 
00218     return result;
00219   }
00220 
00222   //
00223   //    CLASS NAME : Patch::ReferenceIterator
00224   //
00226 
00227   Patch::ReferenceIterator::ReferenceIterator( const sat::Solvable & val_r )
00228   { base_reference() = sat::LookupAttr( sat::SolvAttr::updateReference, val_r ).begin(); }
00229 
00230   std::string Patch::ReferenceIterator::id() const
00231   { return base_reference().subFind( sat::SolvAttr::updateReferenceId ).asString(); }
00232   std::string Patch::ReferenceIterator::href() const
00233   { return base_reference().subFind( sat::SolvAttr::updateReferenceHref ).asString(); }
00234   std::string Patch::ReferenceIterator::title() const
00235   { return base_reference().subFind( sat::SolvAttr::updateReferenceTitle ).asString(); }
00236   std::string Patch::ReferenceIterator::type() const
00237   { return base_reference().subFind( sat::SolvAttr::updateReferenceType ).asString(); }
00238 
00240 } // namespace zypp