libzypp  10.5.0
Helper.cc
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /* Helper.cc
00003  *
00004  * Static helpers
00005  *
00006  * Copyright (C) 2000-2002 Ximian, Inc.
00007  * Copyright (C) 2005 SUSE Linux Products GmbH
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU General Public License,
00011  * version 2, as published by the Free Software Foundation.
00012  *
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  * General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00021  * 02111-1307, USA.
00022  */
00023 #include <sstream>
00024 
00025 #include "zypp/solver/detail/Helper.h"
00026 #include "zypp/Capabilities.h"
00027 #include "zypp/base/Logger.h"
00028 #include "zypp/base/String.h"
00029 #include "zypp/base/Gettext.h"
00030 #include "zypp/VendorAttr.h"
00031 #include "zypp/base/Algorithm.h"
00032 #include "zypp/ResPool.h"
00033 #include "zypp/ResFilters.h"
00034 #include "zypp/RepoInfo.h"
00035 
00036 using namespace std;
00037 
00039 namespace zypp
00040 { 
00041 
00042   namespace solver
00043   { 
00044 
00045     namespace detail
00046     { 
00047 
00048 ostream &
00049 operator<< (ostream & os, const PoolItemList & itemlist)
00050 {
00051     for (PoolItemList::const_iterator iter = itemlist.begin(); iter != itemlist.end(); ++iter) {
00052         if (iter != itemlist.begin())
00053             os << ", ";
00054         os << *iter;
00055     }
00056     return os;
00057 }
00058 
00059 
00060 class LookFor : public resfilter::PoolItemFilterFunctor
00061 {
00062   public:
00063     PoolItem item;
00064 
00065     bool operator()( PoolItem provider )
00066     {
00067         item = provider;
00068         return false;                           // stop here, we found it
00069     }
00070 };
00071 
00072 
00073 // just find installed item with same kind/name as item
00074 
00075 template<class _Iter>
00076 static PoolItem findInstalledByNameAndKind ( _Iter begin, _Iter end, const string & name, const Resolvable::Kind & kind)
00077 {
00078     LookFor info;
00079 
00080     invokeOnEach(begin, end,
00081                   resfilter::ByInstalled (),                                    // ByInstalled
00082                   functor::functorRef<bool,PoolItem> (info) );
00083 
00084     _XDEBUG("Helper::findInstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
00085     return info.item;
00086 
00087 }
00088 
00089 PoolItem Helper::findInstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
00090 { return detail::findInstalledByNameAndKind( pool.byIdentBegin( kind, name ), pool.byIdentEnd( kind, name ), name, kind ); }
00091 
00092 PoolItem Helper::findInstalledItem (const ResPool & pool, PoolItem item)
00093 { return findInstalledByNameAndKind(pool, item->name(), item->kind() ); }
00094 
00095 PoolItem Helper::findInstalledItem( const std::vector<PoolItem> & pool, PoolItem item )
00096 { return detail::findInstalledByNameAndKind( pool.begin(), pool.end(), item->name(), item->kind() ); }
00097 
00098 
00099 // just find uninstalled item with same kind/name as item
00100 
00101 PoolItem
00102 Helper::findUninstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
00103 {
00104     LookFor info;
00105 
00106     invokeOnEach( pool.byIdentBegin( kind, name ),
00107                   pool.byIdentEnd( kind, name ),
00108                   resfilter::ByUninstalled(),                                   // ByUninstalled
00109                   functor::functorRef<bool,PoolItem> (info) );
00110 
00111     _XDEBUG("Helper::findUninstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
00112     return info.item;
00113 }
00114 
00115 
00116 //----------------------------------------------------------------------------
00117 
00118 class LookForUpdate : public resfilter::PoolItemFilterFunctor
00119 {
00120   public:
00121     PoolItem uninstalled;
00122     PoolItem installed;
00123 
00124     bool operator()( PoolItem provider )
00125     {
00126         // is valid
00127         if ( ! provider.resolvable() )
00128         {
00129           WAR << "Warning: '" << provider << "' not valid" << endl;
00130           return true;
00131         }
00132 
00133         if ( installed.resolvable() )
00134         {
00135           if ( !VendorAttr::instance().equivalent( installed, provider ) )
00136           {
00137             MIL << "Discarding '" << provider << "' from vendor '"
00138                 << provider->vendor() << "' different to uninstalled '"
00139                 << installed->vendor() << "' vendor." << endl;
00140             return true;
00141           }
00142         }
00143 
00144         if ((!uninstalled                                                       // none yet
00145             || (uninstalled->edition().compare( provider->edition() ) < 0)      // or a better edition
00146             || (uninstalled->arch().compare( provider->arch() ) < 0) ) // or a better architecture
00147             && !provider.status().isLocked() )                                  // is not locked
00148         {
00149             uninstalled = provider;                                             // store
00150         }
00151         return true;
00152     }
00153 };
00154 
00155 
00156 // just find best (according to edition) uninstalled item with same kind/name as item
00157 // *DOES* check edition
00158 
00159 template<class _Iter>
00160 static PoolItem findUpdateItem( _Iter begin, _Iter end, PoolItem item )
00161 {
00162     LookForUpdate info;
00163     info.installed = item;
00164 
00165     invokeOnEach( begin, end,
00166                   functor::chain (resfilter::ByUninstalled (),                                          // ByUninstalled
00167                                   resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),      // only look at better editions
00168                   functor::functorRef<bool,PoolItem> (info) );
00169 
00170     _XDEBUG("Helper::findUpdateItem(" << item << ") => " << info.uninstalled);
00171     return info.uninstalled;
00172 }
00173 
00174 PoolItem Helper::findUpdateItem (const ResPool & pool, PoolItem item)
00175 { return detail::findUpdateItem( pool.byIdentBegin( item ), pool.byIdentEnd( item ), item ); }
00176 
00177 PoolItem Helper::findUpdateItem (const std::vector<PoolItem> & pool, PoolItem item)
00178 { return detail::findUpdateItem( pool.begin(), pool.end(), item ); }
00179 
00180 
00181 //----------------------------------------------------------------------------
00182 
00183 class LookForReinstall : public resfilter::PoolItemFilterFunctor
00184 {
00185   public:
00186     PoolItem uninstalled;
00187 
00188     bool operator()( PoolItem provider )
00189     {
00190         if (provider.status().isLocked()) {
00191             return true; // search next
00192         } else {
00193             uninstalled = provider;
00194             return false;                               // stop here, we found it
00195         }
00196     }
00197 };
00198 
00199 
00200 PoolItem
00201 Helper::findReinstallItem (const ResPool & pool, PoolItem item)
00202 {
00203     LookForReinstall info;
00204 
00205     invokeOnEach( pool.byIdentBegin( item ),
00206                   pool.byIdentEnd( item ),
00207                   functor::chain (resfilter::ByUninstalled (),                                          // ByUninstalled
00208                                   resfilter::byEdition<CompareByEQ<Edition> >( item->edition() )),
00209                   functor::functorRef<bool,PoolItem> (info) );
00210 
00211     _XDEBUG("Helper::findReinstallItem(" << item << ") => " << info.uninstalled);
00212     return info.uninstalled;
00213 }
00214 
00215 //----------------------------------------------------------------------------
00216 
00217 class CheckIfBest : public resfilter::PoolItemFilterFunctor
00218 {
00219   public:
00220     PoolItem _item;
00221     bool is_best;
00222 
00223     CheckIfBest( PoolItem item )
00224         : _item( item )
00225         , is_best( true )               // assume we already have the best
00226     {}
00227 
00228     // check if provider is better. If yes, end the search.
00229 
00230     bool operator()( PoolItem provider )
00231     {
00232         int archcmp = _item->arch().compare( provider->arch() );
00233         if (((archcmp < 0)                                                      // provider has a better architecture
00234              || ((archcmp == 0)
00235                  && (_item->edition().compare( provider->edition() ) < 0)))     // or a better edition
00236             && !provider.status().isLocked())                                   // and is not locked
00237         {
00238             is_best = false;
00239             return false;
00240         }
00241         return true;
00242     }
00243 };
00244 
00245 
00246 // check if the given item is the best one of the pool
00247 
00248 bool
00249 Helper::isBestUninstalledItem (const ResPool & pool, PoolItem item)
00250 {
00251     CheckIfBest info( item );
00252 
00253     invokeOnEach( pool.byIdentBegin( item ),
00254                   pool.byIdentEnd( item ),
00255                   resfilter::ByUninstalled(),                   // ByUninstalled
00256                   functor::functorRef<bool,PoolItem>( info ) );
00257 
00258     _XDEBUG("Helper::isBestUninstalledItem(" << item << ") => " << info.is_best);
00259     return info.is_best;
00260 }
00261 
00262 std::string
00263 Helper::itemToString (PoolItem item, bool shortVersion)
00264 {
00265     ostringstream os;
00266     if (!item) return "";
00267 
00268     if (item->kind() != ResKind::package)
00269         os << item->kind() << ':';
00270     os  << item->name();
00271     if (!shortVersion) {
00272         os << '-' << item->edition();
00273         if (item->arch() != "") {
00274             os << '.' << item->arch();
00275         }
00276 
00277         string alias = item->repoInfo().alias();
00278         if (!alias.empty()
00279             && alias != "@System")
00280         {
00281             os << '[' << alias << ']';
00282         }
00283     }
00284     return os.str();
00285 }
00286 
00287 std::string
00288 Helper::capToString (const Capability & capability)
00289 {
00290     ostringstream os;
00291     os << capability.asString();
00292     return os.str();
00293 }
00294 
00295 
00297     };// namespace detail
00300   };// namespace solver
00303 };// namespace zypp
00305