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 
00024 #include "zypp/solver/detail/Helper.h"
00025 
00026 #include "zypp/CapSet.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/CapFilters.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_Ref item;
00064 
00065     bool operator()( PoolItem_Ref 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 PoolItem_Ref
00076 Helper::findInstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
00077 {
00078     LookFor info;
00079 
00080     invokeOnEach( pool.byNameBegin( name ),
00081                   pool.byNameEnd( name ),
00082                   functor::chain (resfilter::ByInstalled (),                    // ByInstalled
00083                                   resfilter::ByKind( kind ) ),                  // equal kind
00084                   functor::functorRef<bool,PoolItem> (info) );
00085 
00086     _XDEBUG("Helper::findInstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
00087     return info.item;
00088 }
00089 
00090 
00091 // just find uninstalled item with same kind/name as item
00092 
00093 PoolItem_Ref
00094 Helper::findUninstalledByNameAndKind (const ResPool & pool, const string & name, const Resolvable::Kind & kind)
00095 {
00096     LookFor info;
00097 
00098     invokeOnEach( pool.byNameBegin( name ),
00099                   pool.byNameEnd( name ),
00100                   functor::chain (resfilter::ByUninstalled (),                  // ByUninstalled
00101                                   resfilter::ByKind( kind ) ),                  // equal kind
00102                   functor::functorRef<bool,PoolItem> (info) );
00103 
00104     _XDEBUG("Helper::findUninstalledByNameAndKind (" << name << ", " << kind << ") => " << info.item);
00105     return info.item;
00106 }
00107 
00108 
00109 // just find installed item with same kind/name as item
00110 // does *NOT* check edition
00111 
00112 PoolItem_Ref
00113 Helper::findInstalledItem (const ResPool & pool, PoolItem_Ref item)
00114 {
00115     return findInstalledByNameAndKind (pool, item->name(), item->kind() );
00116 }
00117 
00118 //----------------------------------------------------------------------------
00119 
00120 class LookForUpdate : public resfilter::PoolItemFilterFunctor
00121 {
00122   public:
00123     PoolItem_Ref uninstalled;
00124     PoolItem_Ref installed;
00125 
00126     bool operator()( PoolItem_Ref provider )
00127     {
00128         // is valid
00129         if ( ! provider.resolvable() )
00130         {
00131           WAR << "Warning: '" << provider << "' not valid" << endl;
00132           return true;
00133         }
00134 
00135         if ( installed.resolvable() )
00136         {
00137           if ( !VendorAttr::instance().equivalent(installed->vendor(),provider->vendor()) )
00138           {
00139             MIL << "Discarding '" << provider << "' from vendor '"
00140                 << provider->vendor() << "' different to uninstalled '"
00141                 << installed->vendor() << "' vendor." << endl;
00142             return true;
00143           }
00144         }
00145         
00146         if ((!uninstalled                                                       // none yet
00147             || (uninstalled->edition().compare( provider->edition() ) < 0)      // or a better edition
00148             || (uninstalled->arch().compare( provider->arch() ) < 0) ) // or a better architecture
00149             && !provider.status().isLocked() )                                  // is not locked
00150         {
00151             uninstalled = provider;                                             // store 
00152         }
00153         return true;
00154     }
00155 };
00156 
00157 
00158 // just find best (according to edition) uninstalled item with same kind/name as item
00159 // *DOES* check edition
00160 
00161 PoolItem_Ref
00162 Helper::findUpdateItem (const ResPool & pool, PoolItem_Ref item)
00163 {
00164     LookForUpdate info;
00165     info.installed = item;
00166 
00167     invokeOnEach( pool.byNameBegin( item->name() ),
00168                   pool.byNameEnd( item->name() ),
00169                   functor::chain (functor::chain (resfilter::ByUninstalled (),                  // ByUninstalled
00170                                                   resfilter::ByKind( item->kind() ) ),          // equal kind
00171                                   resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),      // only look at better editions
00172                   functor::functorRef<bool,PoolItem> (info) );
00173 
00174     _XDEBUG("Helper::findUpdateItem(" << item << ") => " << info.uninstalled);
00175     return info.uninstalled;
00176 }
00177 
00178 
00179 //----------------------------------------------------------------------------
00180 
00181 class LookForReinstall : public resfilter::PoolItemFilterFunctor
00182 {
00183   public:
00184     PoolItem_Ref uninstalled;
00185 
00186     bool operator()( PoolItem_Ref provider )
00187     {
00188         if (provider.status().isLocked()) {
00189             return true; // search next
00190         } else {
00191             uninstalled = provider;
00192             return false;                               // stop here, we found it
00193         }
00194     }
00195 };
00196 
00197 
00198 PoolItem_Ref
00199 Helper::findReinstallItem (const ResPool & pool, PoolItem_Ref item)
00200 {
00201     LookForReinstall info;
00202 
00203     invokeOnEach( pool.byNameBegin( item->name() ),
00204                   pool.byNameEnd( item->name() ),
00205                   functor::chain (functor::chain (resfilter::ByUninstalled (),                  // ByUninstalled
00206                                                   resfilter::ByKind( item->kind() ) ),          // equal kind
00207                                   resfilter::byEdition<CompareByEQ<Edition> >( item->edition() )),
00208                   functor::functorRef<bool,PoolItem> (info) );
00209 
00210     _XDEBUG("Helper::findReinstallItem(" << item << ") => " << info.uninstalled);
00211     return info.uninstalled;
00212 }
00213 
00214 //----------------------------------------------------------------------------
00215 
00216 class CheckIfBest : public resfilter::PoolItemFilterFunctor
00217 {
00218   public:
00219     PoolItem_Ref _item;
00220     bool is_best;
00221 
00222     CheckIfBest( PoolItem_Ref item )
00223         : _item( item )
00224         , is_best( true )               // assume we already have the best
00225     {}
00226 
00227     // check if provider is better. If yes, end the search.
00228 
00229     bool operator()( PoolItem_Ref provider )
00230     {
00231         int archcmp = _item->arch().compare( provider->arch() );
00232         if (((archcmp < 0)                                                      // provider has a better architecture
00233              || ((archcmp == 0)
00234                  && (_item->edition().compare( provider->edition() ) < 0)))     // or a better edition
00235             && !provider.status().isLocked())                                   // and is not locked
00236         {
00237             is_best = false;
00238             return false;
00239         }
00240         return true;
00241     }
00242 };
00243 
00244 
00245 // check if the given item is the best one of the pool
00246 
00247 bool
00248 Helper::isBestUninstalledItem (const ResPool & pool, PoolItem_Ref item)
00249 {
00250     CheckIfBest info( item );
00251 
00252     invokeOnEach( pool.byNameBegin( item->name() ),
00253                   pool.byNameEnd( item->name() ),
00254                   functor::chain( resfilter::ByUninstalled(),                   // ByUninstalled
00255                                   resfilter::ByKind( item->kind() ) ),          // equal kind
00256                   functor::functorRef<bool,PoolItem>( info ) );
00257 
00258     _XDEBUG("Helper::isBestUninstalledItem(" << item << ") => " << info.is_best);
00259     return info.is_best;
00260 }
00261 
00262 
00264     };// namespace detail
00267   };// namespace solver
00270 };// namespace zypp
00272 

Generated on Tue Sep 25 19:23:06 2007 for libzypp by  doxygen 1.5.3