Resolver_problems.cc

Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
00002 /* Resolver_problems.cc
00003  *
00004  * Copyright (C) 2000-2002 Ximian, Inc.
00005  * Copyright (C) 2005 SUSE Linux Products GmbH
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License,
00009  * version 2, as published by the Free Software Foundation.
00010  *
00011  * This program is distributed in the hope that it will be useful, but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019  * 02111-1307, USA.
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 // match template over ItemCapabilityMap
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     // comparison
00080     bool operator() (pair<const K, V> elem) {
00081         return value.matches (elem.second) == CapMatch::yes;
00082     }
00083 };
00084 
00085 // match template over ConflictMap
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     // comparison
00095     bool operator() (pair<const K, V> elem) {
00096         return value = elem.second;
00097     }
00098 };      
00099         
00100 // set resolvables with errors
00101 
00102 typedef struct {
00103     ProblemMap problems;
00104     // A map of PoolItems which provides a capability but are set
00105     // for uninstallation
00106     ItemCapabilityMap provideAndDeleteMap;
00107     // A map of PoolItems which provides a capability but are locked
00108     ItemCapabilityMap provideAndLockMap;
00109     // A map of PoolItems which provides a capability but have another architecture
00110     ItemCapabilityMap provideAndOtherArchMap;
00111     // A map of conflicting Items
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     // Collicting items which are providing requirements but they
00126     // are set for uninstall
00127     if (info->type() == RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER) {
00128         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00129         // does entry already exists ?
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     // Collecting items which are providing requirements but they
00141     // are locked
00142     if (info->type() == RESOLVER_INFO_TYPE_LOCKED_PROVIDER) {
00143         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00144         // does entry already exists ?
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     // Collecting items which are providing requirements but they
00156     // have another architecture
00157     if (info->type() == RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER) {
00158         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00159         // does entry already exists ?
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     // Collecting all conflicting Items
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         // does entry already exists ?
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())); // reverse
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     // collect all resolvables with error
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: { // no solution; it is only a info
00247                 ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
00248                 if (needed_by->items().size() >= 1)
00249                     // TranslatorExplanation %s = name of package, patch, selection ...
00250                     what = str::form (_("%s is needed by other resolvables"), who.c_str());
00251                 else
00252                     // TranslatorExplanation %s = name of package, patch, selection ...             
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                     // TranslatorExplanation %s = name of package, patch, selection ...
00261                     what = str::form (_("%s conflicts with other resolvables"), who.c_str() );
00262                 else
00263                     // TranslatorExplanation %s = name of package, patch, selection ...         
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                 // Uninstall p
00268                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00269                 if (conflicts_with->items().size() == 1) {
00270                     // Uninstall q
00271                     problem->addSolution (new ProblemSolutionUninstall (problem, *(conflicts_with->items().begin())));
00272                 } else {
00273                     // Uninstall all other
00274                     PoolItemList conflict_items = conflicts_with->items();
00275                     problem->addSolution (new ProblemSolutionUninstall (problem, conflict_items));
00276                 }
00277                 // Remove conflict in the resolvable which has to be installed
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: { // no solution; it is only a info
00285                 ResolverInfoObsoletes_constPtr obsoletes = dynamic_pointer_cast<const ResolverInfoObsoletes>(info);
00286                 if (obsoletes->items().size() >= 1)
00287                     // TranslatorExplanation %s = name of package, patch, selection ...
00288                     what = str::form (_("%s obsoletes other resolvables"), who.c_str());
00289                 else
00290                     // TranslatorExplanation %s = name of package, patch, selection ...         
00291                     what = str::form (_("%s obsoletes %s"), who.c_str(), obsoletes->itemsToString(true).c_str());
00292                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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: { // no solution; it is only a info
00298                 ResolverInfoDependsOn_constPtr depends_on = dynamic_pointer_cast<const ResolverInfoDependsOn>(info);
00299                 if (depends_on->items().size() >= 1)
00300                     // TranslatorExplanation %s = name of package, patch, selection ...
00301                     what = str::form (_("%s depends on other resolvables"), who.c_str(),
00302                                       depends_on->itemsToString(true).c_str());
00303                 else
00304                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00305                     what = str::form (_("%s depends on %s"), who.c_str(),
00306                                       depends_on->itemsToString(true).c_str());
00307                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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: {                         // unused
00312                 ResolverInfoChildOf_constPtr child_of = dynamic_pointer_cast<const ResolverInfoChildOf>(info);
00313                 // TranslatorExplanation: currently it is unused.
00314                 what = _("Child of");
00315             }
00316             break;
00317             case RESOLVER_INFO_TYPE_MISSING_REQ: { // no solution; it is only a info
00318                 ResolverInfoMissingReq_constPtr missing_req = dynamic_pointer_cast<const ResolverInfoMissingReq>(info);
00319                 // TranslatorExplanation %s = dependency
00320                 what = str::form (_("Cannot install %s"), who.c_str());
00321                 // TranslatorExplanation %s = capability                
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         // from ResolverContext
00328             case RESOLVER_INFO_TYPE_INVALID_SOLUTION: {                 // Marking this resolution attempt as invalid.
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                 // no solution available
00333             }
00334             break;
00335             case RESOLVER_INFO_TYPE_UNINSTALLABLE: {                    // Marking p as uninstallable
00336                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00337                 // Trying to find a concerning conflict
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 = ""; // no further details
00346                         ResolverProblem_Ptr problem = new ResolverProblem (what, details);              
00347                         // Uninstall p
00348                         problem->addSolution (new ProblemSolutionUninstall (problem, item));
00349                         // Uninstall q
00350                         problem->addSolution (new ProblemSolutionUninstall (problem, it->second));
00351                         problems.push_back (problem);
00352                         problem_created = true;
00353                     }
00354                 }
00355                 if (!problem_created) {
00356                     // default 
00357                     what = misc_info->message();
00358                     // TranslatorExplanation %s = name of package,patch,...             
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)); // Install resolvable again
00362                     problems.push_back (problem);
00363                     problem_created = true;
00364                 }
00365             }
00366             break;
00367             case RESOLVER_INFO_TYPE_REJECT_INSTALL: {                   // p is scheduled to be installed, but this is not possible because of dependency problems.
00368                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00369                 // TranslatorExplanation %s = name of package,patch,...                         
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                 // Uninstall it; 
00374                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00375                 // currently no solution concerning "ignore" is available               
00376                 problems.push_back (problem);
00377                 problem_created = true;
00378             }
00379             break;
00380             case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: {        // Can't install p since it is already marked as needing to be uninstalled
00381                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00382                 // TranslatorExplanation %s = name of package,patch,...                         
00383                 what = misc_info->message();
00384                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00385                 problem->addSolution (new ProblemSolutionInstall (problem, item)); // Install resolvable again
00386                 problems.push_back (problem);
00387                 problem_created = true;
00388             }
00389             break;
00390             case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: {                 // Can't install p since it is does not apply to this system.
00391                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00392                 // TranslatorExplanation %s = name of package,patch,...                         
00393                 what = misc_info->message();
00394                 // no solution; it is only a info
00395             }
00396             break;
00397             case RESOLVER_INFO_TYPE_INSTALL_PARALLEL: {                 // Can't install p, since a resolvable of the same name is already marked as needing to be installed.
00398                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00399                 // TranslatorExplanation %s = name of package,patch,...                         
00400                 what = str::form (_("Cannot install %s"), who.c_str());
00401                 details = misc_info->message();
00402                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00403                 // Uninstall the item
00404                 ResStatus status = item.status();
00405                 string description = "";
00406                 if (status.isInstalled())
00407                     // TranslatorExplanation %s = name of package, patch, selection ...
00408                     description = str::form (_("delete %s"), ResolverInfo::toString (item).c_str());
00409                 else
00410                     // TranslatorExplanation %s = name of package, patch, selection ... 
00411                     description = str::form (_("do not install %s"), ResolverInfo::toString (item).c_str());
00412                 problem->addSolution (new ProblemSolutionUninstall (problem, item, description, ""));
00413                 
00414                 // Uninstall the other
00415                 status = misc_info->other().status();
00416                 if (status.isInstalled())
00417                     // TranslatorExplanation %s = name of package, patch, selection ...
00418                     description = str::form (_("delete %s"), ResolverInfo::toString (misc_info->other()).c_str());
00419                 else
00420                     // TranslatorExplanation %s = name of package, patch, selection ... 
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                 // Ignore it
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: {                      // This would invalidate p
00431                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00432                 what = misc_info->message();
00433                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00434                 details = str::form (_("%s has unfulfilled requirements"), who.c_str());
00435                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00436                 // Uninstall 
00437                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00438                 problems.push_back (problem);
00439                 problem_created = true;         
00440             }
00441             break;
00442         // from QueueItemEstablish
00443             case RESOLVER_INFO_TYPE_ESTABLISHING: {                     // Establishing p
00444                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00445                 what = misc_info->message();
00446                 // no solution is needed cause it is only a progress indicator
00447             }
00448             break;
00449         // from QueueItemInstall
00450             case RESOLVER_INFO_TYPE_INSTALLING: {                       // Installing p
00451                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00452                 what = misc_info->message();
00453                 // no solution is needed cause it is only a progress indicator          
00454             }
00455             break;
00456             case RESOLVER_INFO_TYPE_UPDATING: {                         // Updating p
00457                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00458                 what = misc_info->message();
00459                 // no solution is needed cause it is only a progress indicator          
00460             }
00461             break;
00462             case RESOLVER_INFO_TYPE_SKIPPING: {                         // Skipping p, already installed
00463                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00464                 what = misc_info->message();
00465                 // It is only an info and happens while upgrading
00466             }
00467             break;
00468         // from QueueItemRequire
00469             case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: {                // There are no alternative installed providers of c [for p]
00470                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00471                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // Searching for another item which provides this requires BUT has been set to uninstall
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                         // Do not delete
00481                         problem->addSolution (new ProblemSolutionKeep (problem, it->first));
00482                     }
00483                 }
00484 
00485                 // uninstall
00486                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00487 
00488                 // Unflag require ONLY for this item
00489                 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));              
00490 
00491                 // Unflag ALL require
00492                 // Evaluating all require Items
00493                 AllRequires info;
00494                 Dep dep( Dep::REQUIRES );
00495 
00496                 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
00497                               _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),   // end()
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: {                      // There are no installable providers of c [for p]
00508                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00509                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // Searching for another item which provides this requires BUT has been locked
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                         // unlock this item
00519                         problem->addSolution (new ProblemSolutionUnlock (problem, it->first));
00520                     }
00521                 }
00522                 // Searching for another item which provides this requires BUT has another architec
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                         // ignoring architecture
00527                         problem->addSolution (new ProblemSolutionIgnoreArchitecture (problem, it->first));
00528                     }
00529                 }
00530                 
00531                 // uninstall
00532                 problem->addSolution (new ProblemSolutionUninstall (problem, item)); 
00533                 // ignore requirement
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: {                       // Upgrade to q to avoid removing p is not possible.
00540                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00541                 what = misc_info->message();
00542                 // It is only an info --> no solution is needed         
00543             }
00544             break;
00545             case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {               // p provides c but is scheduled to be uninstalled
00546                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00547                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // It is only an info --> no solution is needed
00553             }
00554             break;
00555             case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: {                // p provides c but another version is already installed
00556                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00557                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00558                 what = str::form (_("No need to install %s"), misc_info->other()->name().c_str());
00559                 details = misc_info->message();
00560                 // It is only an info --> no solution is needed         
00561             }
00562             break;
00563             case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: {         // p provides c but is uninstallable
00564                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00565                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // It is only an info --> no solution is needed         
00571             }
00572             case RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER: {              // p provides c but has other architecture
00573                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00574                 what = misc_info->message();
00575                 // It is only an info --> no solution is needed         
00576             }           
00577             break;
00578             case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: {                  // p provides c but is locked
00579                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00580                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // It is only an info --> no solution is needed         
00586             }
00587             break;
00588             case RESOLVER_INFO_TYPE_CANT_SATISFY: {                     // Can't satisfy requirement c
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                 // uninstall
00593                 problem->addSolution (new ProblemSolutionUninstall (problem, item)); 
00594                 
00595                 // Unflag requirement for this item
00596                 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00597                 
00598                 // Unflag ALL require
00599                 // Evaluating all require Items
00600                 AllRequires info;
00601                 Dep dep( Dep::REQUIRES );
00602 
00603                 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
00604                               _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),   // end()
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         // from QueueItemUninstall
00615             case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: {        // p is to-be-installed, so it won't be unlinked.
00616                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00617                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00618                 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());
00619                 details = misc_info->message();
00620                 // It is only an info --> no solution is needed                         
00621             }
00622             break;
00623             case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: {              // p is required by installed, so it won't be unlinked.
00624                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00625                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00626                 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());             
00627                 details = misc_info->message();
00628                 // It is only an info --> no solution is needed                         
00629             }
00630             break;
00631             case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {                 // cant uninstall, its 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                     // TranslatorExplanation %s = name of package, patch, selection ...                                             
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)); // Unlocking resItem
00644                 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00645                     // Ignore obsoletes
00646                     problem->addSolution (new ProblemSolutionIgnoreObsoletes (problem, item, misc_info->capability(),
00647                                                                               misc_info->other())); 
00648                 } else {
00649                     // This is an "default" soltution
00650                     // keep installed
00651                     problem->addSolution (new ProblemSolutionKeep (problem, item));
00652                 }
00653                 problems.push_back (problem);
00654                 problem_created = true;
00655             }
00656             break;
00657         // from QueueItemConflict
00658             case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {            // to-be-installed p conflicts with q due to c
00659                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00660                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // Uninstall p
00667                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00668                 // Uninstall q
00669                 problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
00670                 // Remove conflict in the resolvable which has to be installed
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: {           // uninstalled p is marked uninstallable it conflicts [with q] due to c
00679                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00680                 // TranslatorExplanation %s = name of package, patch, selection ...                             
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                 // It is only an info --> no solution is needed
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     };// namespace detail
00715   };// namespace solver
00718 };// namespace zypp
00720 

Generated on Thu Jul 6 00:07:23 2006 for zypp by  doxygen 1.4.6