00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
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;
00069 }
00070 };
00071
00072
00073
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 (),
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
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(),
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
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
00145 || (uninstalled->edition().compare( provider->edition() ) < 0)
00146 || (uninstalled->arch().compare( provider->arch() ) < 0) )
00147 && !provider.status().isLocked() )
00148 {
00149 uninstalled = provider;
00150 }
00151 return true;
00152 }
00153 };
00154
00155
00156
00157
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 (),
00167 resfilter::byEdition<CompareByGT<Edition> >( item->edition() )),
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;
00192 } else {
00193 uninstalled = provider;
00194 return false;
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 (),
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 )
00226 {}
00227
00228
00229
00230 bool operator()( PoolItem provider )
00231 {
00232 int archcmp = _item->arch().compare( provider->arch() );
00233 if (((archcmp < 0)
00234 || ((archcmp == 0)
00235 && (_item->edition().compare( provider->edition() ) < 0)))
00236 && !provider.status().isLocked())
00237 {
00238 is_best = false;
00239 return false;
00240 }
00241 return true;
00242 }
00243 };
00244
00245
00246
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(),
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 };
00300 };
00303 };
00305