00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <map>
00023 #include <sstream>
00024
00025 #include "zypp/solver/detail/Resolver.h"
00026 #include "zypp/Resolver.h"
00027 #include "zypp/solver/detail/ResolverContext.h"
00028 #include "zypp/ResolverProblem.h"
00029 #include "zypp/solver/detail/ProblemSolutionIgnore.h"
00030 #include "zypp/solver/detail/ProblemSolutionInstall.h"
00031 #include "zypp/solver/detail/ProblemSolutionUninstall.h"
00032 #include "zypp/solver/detail/ProblemSolutionUnlock.h"
00033 #include "zypp/solver/detail/ProblemSolutionKeep.h"
00034
00035 #include "zypp/solver/detail/ResolverInfoChildOf.h"
00036 #include "zypp/solver/detail/ResolverInfoConflictsWith.h"
00037 #include "zypp/solver/detail/ResolverInfoContainer.h"
00038 #include "zypp/solver/detail/ResolverInfoDependsOn.h"
00039 #include "zypp/solver/detail/ResolverInfoMisc.h"
00040 #include "zypp/solver/detail/ResolverInfoMissingReq.h"
00041 #include "zypp/solver/detail/ResolverInfoNeededBy.h"
00042 #include "zypp/solver/detail/ResolverInfoObsoletes.h"
00043
00044 #include "zypp/base/String.h"
00045 #include "zypp/base/Logger.h"
00046 #include "zypp/base/Gettext.h"
00047
00048 #include "zypp/base/Algorithm.h"
00049 #include "zypp/ResPool.h"
00050 #include "zypp/ResFilters.h"
00051 #include "zypp/CapFilters.h"
00052
00053
00055 namespace zypp
00056 {
00057
00058 namespace solver
00059 {
00060
00061 namespace detail
00062 {
00063
00064 using namespace std;
00065
00066 typedef map<PoolItem_Ref, ResolverInfo_Ptr> ProblemMap;
00067 typedef multimap<PoolItem_Ref, Capability> ItemCapabilityMap;
00068 typedef multimap<PoolItem_Ref, PoolItem_Ref> ConflictMap;
00069
00070
00071 template <class K, class V>
00072 class cap_equals {
00073 private:
00074 V value;
00075 public:
00076 cap_equals (const V& v)
00077 : value(v) {
00078 }
00079
00080 bool operator() (pair<const K, V> elem) {
00081 return value.matches (elem.second) == CapMatch::yes;
00082 }
00083 };
00084
00085
00086 template <class K, class V>
00087 class conflict_equals {
00088 private:
00089 V value;
00090 public:
00091 conflict_equals (const V& v)
00092 : value(v) {
00093 }
00094
00095 bool operator() (pair<const K, V> elem) {
00096 return value = elem.second;
00097 }
00098 };
00099
00100
00101
00102 typedef struct {
00103 ProblemMap problems;
00104
00105
00106 ItemCapabilityMap provideAndDeleteMap;
00107
00108 ItemCapabilityMap provideAndLockMap;
00109
00110 ItemCapabilityMap provideAndOtherArchMap;
00111
00112 ConflictMap conflictMap;
00113 } ResItemCollector;
00114
00115
00116 static void
00117 collector_cb (ResolverInfo_Ptr info, void *data)
00118 {
00119 ResItemCollector *collector = (ResItemCollector *)data;
00120 PoolItem_Ref item = info->affected();
00121 if (item
00122 && info->error()) {
00123 collector->problems[item] = info;
00124 }
00125
00126
00127 if (info->type() == RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER) {
00128 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00129
00130 ItemCapabilityMap::iterator pos = find_if (collector->provideAndDeleteMap.begin(),
00131 collector->provideAndDeleteMap.end(),
00132 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00133
00134 if (pos == collector->provideAndDeleteMap.end()) {
00135 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00136 << " into provideAndDelete map");
00137 collector->provideAndDeleteMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00138 }
00139 }
00140
00141
00142 if (info->type() == RESOLVER_INFO_TYPE_LOCKED_PROVIDER) {
00143 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00144
00145 ItemCapabilityMap::iterator pos = find_if (collector->provideAndLockMap.begin(),
00146 collector->provideAndLockMap.end(),
00147 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00148
00149 if (pos == collector->provideAndLockMap.end()) {
00150 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00151 << " into provideAndLockMap map");
00152 collector->provideAndLockMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00153 }
00154 }
00155
00156
00157 if (info->type() == RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER) {
00158 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00159
00160 ItemCapabilityMap::iterator pos = find_if (collector->provideAndOtherArchMap.begin(),
00161 collector->provideAndOtherArchMap.end(),
00162 cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00163
00164 if (pos == collector->provideAndOtherArchMap.end()) {
00165 _XDEBUG ("Inserting " << misc_info->capability() << "/" << misc_info->other()
00166 << " into provideAndOtherArchMap map");
00167 collector->provideAndOtherArchMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00168 }
00169 }
00170
00171
00172
00173 if (info->type() == RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE
00174 || info->type() == RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL) {
00175 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00176
00177
00178 ConflictMap::iterator pos = find_if (collector->conflictMap.lower_bound(misc_info->other()),
00179 collector->conflictMap.upper_bound(misc_info->other()),
00180 conflict_equals<PoolItem_Ref, PoolItem_Ref>(misc_info->affected()));
00181 if (pos == collector->conflictMap.end()) {
00182 _XDEBUG ("Inserting " << misc_info->affected() << "/" << misc_info->other()
00183 << " into conflictMap map");
00184 collector->conflictMap.insert (make_pair(misc_info->affected(), misc_info->other()));
00185 collector->conflictMap.insert (make_pair(misc_info->other(), misc_info->affected()));
00186 }
00187 }
00188
00189 }
00190
00191 struct AllRequires
00192 {
00193 PoolItemList requirers;
00194
00195 bool operator()( const CapAndItem & cai )
00196 {
00197 DBG << cai.item << " requires " << cai.cap << endl;
00198 requirers.push_back( cai.item );
00199
00200 return true;
00201 }
00202 };
00203
00204
00205 ResolverProblemList
00206 Resolver::problems (void) const
00207 {
00208 ResolverProblemList problems;
00209
00210 if (_best_context) {
00211 MIL << "Valid solution found, no problems" << endl;
00212 return problems;
00213 }
00214
00215
00216
00217 ResolverQueueList invalid = invalidQueues();
00218 MIL << invalid.size() << " invalid queues" << endl;
00219
00220 if (invalid.empty()) {
00221 WAR << "No solver problems, but there is also no valid solution." << endl;
00222 return problems;
00223 }
00224
00225 ResolverContext_Ptr context = invalid.front()->context();
00226 ResItemCollector collector;
00227 context->foreachInfo (PoolItem(), RESOLVER_INFO_PRIORITY_VERBOSE, collector_cb, &collector);
00228
00229 for (ProblemMap::const_iterator iter = collector.problems.begin(); iter != collector.problems.end(); ++iter) {
00230 PoolItem_Ref item = iter->first;
00231 ResolverInfo_Ptr info = iter->second;
00232
00233 bool problem_created = false;
00234
00235 DBG << "Problem: " << *info;
00236 DBG << "; Evaluate solutions..." << endl;
00237
00238 string who = ResolverInfo::toString( item );
00239 string what;
00240 string details;
00241 switch (info->type()) {
00242 case RESOLVER_INFO_TYPE_INVALID: {
00243 what = _("Invalid information");
00244 }
00245 break;
00246 case RESOLVER_INFO_TYPE_NEEDED_BY: {
00247 ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
00248 if (needed_by->items().size() >= 1)
00249
00250 what = str::form (_("%s is needed by other resolvables"), who.c_str());
00251 else
00252
00253 what = str::form (_("%s is needed by %s"), who.c_str(), needed_by->itemsToString(true).c_str());
00254 details = str::form (_("%s is needed by:\n%s"), who.c_str(), needed_by->itemsToString(false).c_str());
00255 }
00256 break;
00257 case RESOLVER_INFO_TYPE_CONFLICTS_WITH: {
00258 ResolverInfoConflictsWith_constPtr conflicts_with = dynamic_pointer_cast<const ResolverInfoConflictsWith>(info);
00259 if (conflicts_with->items().size() >= 1)
00260
00261 what = str::form (_("%s conflicts with other resolvables"), who.c_str() );
00262 else
00263
00264 what = str::form (_("%s conflicts with %s"), who.c_str(), conflicts_with->itemsToString(true).c_str());
00265 details = str::form (_("%s conflicts with:\n%s"), who.c_str(), conflicts_with->itemsToString(false).c_str());
00266 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00267
00268 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00269 if (conflicts_with->items().size() == 1) {
00270
00271 problem->addSolution (new ProblemSolutionUninstall (problem, *(conflicts_with->items().begin())));
00272 } else {
00273
00274 PoolItemList conflict_items = conflicts_with->items();
00275 problem->addSolution (new ProblemSolutionUninstall (problem, conflict_items));
00276 }
00277
00278 problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, conflicts_with->capability(),
00279 conflicts_with->items()));
00280 problems.push_back (problem);
00281 problem_created = true;
00282 }
00283 break;
00284 case RESOLVER_INFO_TYPE_OBSOLETES: {
00285 ResolverInfoObsoletes_constPtr obsoletes = dynamic_pointer_cast<const ResolverInfoObsoletes>(info);
00286 if (obsoletes->items().size() >= 1)
00287
00288 what = str::form (_("%s obsoletes other resolvables"), who.c_str());
00289 else
00290
00291 what = str::form (_("%s obsoletes %s"), who.c_str(), obsoletes->itemsToString(true).c_str());
00292
00293 details = str::form (_("%s obsoletes:%s"), who.c_str(), obsoletes->itemsToString(false).c_str());
00294 details += _("\nThese resolvables will be deleted from the system.");
00295 }
00296 break;
00297 case RESOLVER_INFO_TYPE_DEPENDS_ON: {
00298 ResolverInfoDependsOn_constPtr depends_on = dynamic_pointer_cast<const ResolverInfoDependsOn>(info);
00299 if (depends_on->items().size() >= 1)
00300
00301 what = str::form (_("%s depends on other resolvables"), who.c_str(),
00302 depends_on->itemsToString(true).c_str());
00303 else
00304
00305 what = str::form (_("%s depends on %s"), who.c_str(),
00306 depends_on->itemsToString(true).c_str());
00307
00308 details = str::form (_("%s depends on:%s"), who.c_str(), depends_on->itemsToString(false).c_str());
00309 }
00310 break;
00311 case RESOLVER_INFO_TYPE_CHILD_OF: {
00312 ResolverInfoChildOf_constPtr child_of = dynamic_pointer_cast<const ResolverInfoChildOf>(info);
00313
00314 what = _("Child of");
00315 }
00316 break;
00317 case RESOLVER_INFO_TYPE_MISSING_REQ: {
00318 ResolverInfoMissingReq_constPtr missing_req = dynamic_pointer_cast<const ResolverInfoMissingReq>(info);
00319
00320 what = str::form (_("Cannot install %s"), who.c_str());
00321
00322 details = str::form (_("None provides %s"), missing_req->capability().asString().c_str());
00323 details += _("\nThere is no resource available which support this requirement.");
00324 }
00325 break;
00326
00327
00328 case RESOLVER_INFO_TYPE_INVALID_SOLUTION: {
00329 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00330 what = misc_info->message();
00331 details = _("Due problems which are described above/below this resolution will not solve all dependencies");
00332
00333 }
00334 break;
00335 case RESOLVER_INFO_TYPE_UNINSTALLABLE: {
00336 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00337
00338
00339 for (ConflictMap::const_iterator it = collector.conflictMap.begin();
00340 it != collector.conflictMap.end(); ++it) {
00341 if (it->first == item) {
00342 what = str::form (_("Cannot install %s because it is conflicting with %s"),
00343 who.c_str(),
00344 it->second->name().c_str());
00345 details = "";
00346 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00347
00348 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00349
00350 problem->addSolution (new ProblemSolutionUninstall (problem, it->second));
00351 problems.push_back (problem);
00352 problem_created = true;
00353 }
00354 }
00355 if (!problem_created) {
00356
00357 what = misc_info->message();
00358
00359 details = str::form (_("%s is not installed and has been marked as uninstallable"), who.c_str());
00360 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00361 problem->addSolution (new ProblemSolutionInstall (problem, item));
00362 problems.push_back (problem);
00363 problem_created = true;
00364 }
00365 }
00366 break;
00367 case RESOLVER_INFO_TYPE_REJECT_INSTALL: {
00368 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00369
00370 what = str::form (_("Cannot install %s due to dependency problems"), who.c_str());
00371 details = misc_info->message();
00372 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00373
00374 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00375
00376 problems.push_back (problem);
00377 problem_created = true;
00378 }
00379 break;
00380 case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: {
00381 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00382
00383 what = misc_info->message();
00384 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00385 problem->addSolution (new ProblemSolutionInstall (problem, item));
00386 problems.push_back (problem);
00387 problem_created = true;
00388 }
00389 break;
00390 case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: {
00391 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00392
00393 what = misc_info->message();
00394
00395 }
00396 break;
00397 case RESOLVER_INFO_TYPE_INSTALL_PARALLEL: {
00398 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00399
00400 what = str::form (_("Cannot install %s"), who.c_str());
00401 details = misc_info->message();
00402 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00403
00404 ResStatus status = item.status();
00405 string description = "";
00406 if (status.isInstalled())
00407
00408 description = str::form (_("delete %s"), ResolverInfo::toString (item).c_str());
00409 else
00410
00411 description = str::form (_("do not install %s"), ResolverInfo::toString (item).c_str());
00412 problem->addSolution (new ProblemSolutionUninstall (problem, item, description, ""));
00413
00414
00415 status = misc_info->other().status();
00416 if (status.isInstalled())
00417
00418 description = str::form (_("delete %s"), ResolverInfo::toString (misc_info->other()).c_str());
00419 else
00420
00421 description = str::form (_("do not install %s"), ResolverInfo::toString (misc_info->other()).c_str());
00422 problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other(), description, ""));
00423
00424
00425 problem->addSolution (new ProblemSolutionIgnoreInstalled (problem, item, misc_info->other()));
00426 problems.push_back (problem);
00427 problem_created = true;
00428 }
00429 break;
00430 case RESOLVER_INFO_TYPE_INCOMPLETES: {
00431 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00432 what = misc_info->message();
00433
00434 details = str::form (_("%s has unfulfilled requirements"), who.c_str());
00435 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00436
00437 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00438 problems.push_back (problem);
00439 problem_created = true;
00440 }
00441 break;
00442
00443 case RESOLVER_INFO_TYPE_ESTABLISHING: {
00444 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00445 what = misc_info->message();
00446
00447 }
00448 break;
00449
00450 case RESOLVER_INFO_TYPE_INSTALLING: {
00451 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00452 what = misc_info->message();
00453
00454 }
00455 break;
00456 case RESOLVER_INFO_TYPE_UPDATING: {
00457 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00458 what = misc_info->message();
00459
00460 }
00461 break;
00462 case RESOLVER_INFO_TYPE_SKIPPING: {
00463 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00464 what = misc_info->message();
00465
00466 }
00467 break;
00468
00469 case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: {
00470 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00471
00472 what = str::form (_("%s has missing dependencies"), who.c_str());
00473 details = misc_info->message();
00474 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00475
00476
00477 for (ItemCapabilityMap::const_iterator it = collector.provideAndDeleteMap.begin();
00478 it != collector.provideAndDeleteMap.end(); ++it) {
00479 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00480
00481 problem->addSolution (new ProblemSolutionKeep (problem, it->first));
00482 }
00483 }
00484
00485
00486 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00487
00488
00489 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00490
00491
00492
00493 AllRequires info;
00494 Dep dep( Dep::REQUIRES );
00495
00496 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ),
00497 _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),
00498 resfilter::ByCapMatch( misc_info->capability() ),
00499 functor::functorRef<bool,CapAndItem>(info) );
00500 if (info.requirers.size() > 1)
00501 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00502
00503 problems.push_back (problem);
00504 problem_created = true;
00505 }
00506 break;
00507 case RESOLVER_INFO_TYPE_NO_PROVIDER: {
00508 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00509
00510 what = str::form (_("%s cannot be installed due to missing dependencies"), who.c_str());
00511 details = misc_info->message();
00512 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00513
00514
00515 for (ItemCapabilityMap::const_iterator it = collector.provideAndLockMap.begin();
00516 it != collector.provideAndLockMap.end(); ++it) {
00517 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00518
00519 problem->addSolution (new ProblemSolutionUnlock (problem, it->first));
00520 }
00521 }
00522
00523 for (ItemCapabilityMap::const_iterator it = collector.provideAndOtherArchMap.begin();
00524 it != collector.provideAndOtherArchMap.end(); ++it) {
00525 if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00526
00527 problem->addSolution (new ProblemSolutionIgnoreArchitecture (problem, it->first));
00528 }
00529 }
00530
00531
00532 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00533
00534 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00535 problems.push_back (problem);
00536 problem_created = true;
00537 }
00538 break;
00539 case RESOLVER_INFO_TYPE_NO_UPGRADE: {
00540 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00541 what = misc_info->message();
00542
00543 }
00544 break;
00545 case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {
00546 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00547
00548 what =str::form (_("%s fulfil dependencies of %s but will be uninstalled"),
00549 misc_info->other()->name().c_str(),
00550 who.c_str());
00551 details = misc_info->message();
00552
00553 }
00554 break;
00555 case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: {
00556 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00557
00558 what = str::form (_("No need to install %s"), misc_info->other()->name().c_str());
00559 details = misc_info->message();
00560
00561 }
00562 break;
00563 case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: {
00564 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00565
00566 what = str::form (_("Cannot install %s to fulfil the dependencies of %s"),
00567 misc_info->other()->name().c_str(),
00568 who.c_str());
00569 details = misc_info->message();
00570
00571 }
00572 case RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER: {
00573 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00574 what = misc_info->message();
00575
00576 }
00577 break;
00578 case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: {
00579 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00580
00581 what = str::form (_("Cannot be install %s to fulfil the dependencies of %s"),
00582 misc_info->other()->name().c_str(),
00583 who.c_str());
00584 what = misc_info->message();
00585
00586 }
00587 break;
00588 case RESOLVER_INFO_TYPE_CANT_SATISFY: {
00589 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00590 what = misc_info->message();
00591 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00592
00593 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00594
00595
00596 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00597
00598
00599
00600 AllRequires info;
00601 Dep dep( Dep::REQUIRES );
00602
00603 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ),
00604 _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),
00605 resfilter::ByCapMatch( misc_info->capability() ),
00606 functor::functorRef<bool,CapAndItem>(info) );
00607 if (info.requirers.size() > 1)
00608 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00609
00610 problems.push_back (problem);
00611 problem_created = true;
00612 }
00613 break;
00614
00615 case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: {
00616 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00617
00618 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());
00619 details = misc_info->message();
00620
00621 }
00622 break;
00623 case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: {
00624 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00625
00626 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());
00627 details = misc_info->message();
00628
00629 }
00630 break;
00631 case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {
00632 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00633 what = misc_info->message();
00634
00635 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00636
00637 details = str::form (_("%s obsoletes %s. But %s cannot be deleted because it is locked."),
00638 misc_info->other()->name().c_str(),
00639 who.c_str(), who.c_str());
00640 }
00641
00642 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00643 problem->addSolution (new ProblemSolutionUnlock (problem, item));
00644 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00645
00646 problem->addSolution (new ProblemSolutionIgnoreObsoletes (problem, item, misc_info->capability(),
00647 misc_info->other()));
00648 } else {
00649
00650
00651 problem->addSolution (new ProblemSolutionKeep (problem, item));
00652 }
00653 problems.push_back (problem);
00654 problem_created = true;
00655 }
00656 break;
00657
00658 case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {
00659 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00660
00661 what = str::form (_("Cannot install %s because it is conflicting with %s"),
00662 who.c_str(),
00663 misc_info->other()->name().c_str());
00664 details = misc_info->message();
00665 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00666
00667 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00668
00669 problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
00670
00671 problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, misc_info->other_capability(),
00672 misc_info->other()));
00673 problems.push_back (problem);
00674 problem_created = true;
00675
00676 }
00677 break;
00678 case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: {
00679 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00680
00681 what = str::form (_("%s is uninstallable due to conflicts with %s"),
00682 who.c_str(),
00683 misc_info->other()->name().c_str());
00684 details = misc_info->message();
00685
00686 }
00687 break;
00688 }
00689 if (!problem_created) {
00690 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00691 problems.push_back (problem);
00692 }
00693 }
00694 if (problems.empty()) {
00695 context->spewInfo();
00696 }
00697 return problems;
00698 }
00699
00700 void
00701 Resolver::applySolutions (const ProblemSolutionList & solutions)
00702 {
00703 for (ProblemSolutionList::const_iterator iter = solutions.begin();
00704 iter != solutions.end(); ++iter) {
00705 ProblemSolution_Ptr solution = *iter;
00706 if (!solution->apply (*this))
00707 break;
00708 }
00709 }
00710
00712 };
00715 };
00718 };
00720