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 set
00108     // to be kept
00109     ItemCapabilityMap provideAndKeptMap;    
00110     // A map of PoolItems which provides a capability but are locked
00111     ItemCapabilityMap provideAndLockMap;
00112     // A map of PoolItems which provides a capability but have another architecture
00113     ItemCapabilityMap provideAndOtherArchMap;
00114     // A map of conflicting Items
00115     ConflictMap conflictMap;
00116 } ResItemCollector;
00117 
00118 
00119 static void
00120 collector_cb (ResolverInfo_Ptr info, void *data)
00121 {
00122     ResItemCollector *collector = (ResItemCollector *)data;
00123     PoolItem_Ref item = info->affected();
00124     if (item
00125         && info->error()) {
00126         collector->problems[item] = info;
00127     }
00128     // Collicting items which are providing requirements but they
00129     // are set for uninstall
00130     if (info->type() == RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER) {
00131         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00132         // does entry already exists ?
00133         ItemCapabilityMap::iterator pos = find_if (collector->provideAndDeleteMap.begin(),
00134                                                    collector->provideAndDeleteMap.end(),
00135                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00136         
00137         if (pos == collector->provideAndDeleteMap.end()) {
00138             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00139                      << " into provideAndDelete map");
00140             collector->provideAndDeleteMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00141         }
00142     }
00143     // Collicting items which are providing requirements but they
00144     // are set to be kept
00145     if (info->type() == RESOLVER_INFO_TYPE_KEEP_PROVIDER) {
00146         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00147         // does entry already exists ?
00148         ItemCapabilityMap::iterator pos = find_if (collector->provideAndKeptMap.begin(),
00149                                                    collector->provideAndKeptMap.end(),
00150                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00151         
00152         if (pos == collector->provideAndKeptMap.end()) {
00153             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00154                      << " into provideAndKeptMap map");
00155             collector->provideAndKeptMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00156         }
00157     }    
00158     // Collecting items which are providing requirements but they
00159     // are locked
00160     if (info->type() == RESOLVER_INFO_TYPE_LOCKED_PROVIDER) {
00161         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00162         // does entry already exists ?
00163         ItemCapabilityMap::iterator pos = find_if (collector->provideAndLockMap.begin(),
00164                                                    collector->provideAndLockMap.end(),
00165                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00166         
00167         if (pos == collector->provideAndLockMap.end()) {
00168             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00169                      << " into provideAndLockMap map");
00170             collector->provideAndLockMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00171         }
00172     }
00173     // Collecting items which are providing requirements but they
00174     // have another architecture
00175     if (info->type() == RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER) {
00176         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00177         // does entry already exists ?
00178         ItemCapabilityMap::iterator pos = find_if (collector->provideAndOtherArchMap.begin(),
00179                                                    collector->provideAndOtherArchMap.end(),
00180                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00181         
00182         if (pos == collector->provideAndOtherArchMap.end()) {
00183             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00184                      << " into provideAndOtherArchMap map");
00185             collector->provideAndOtherArchMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00186         }
00187     }
00188     
00189 
00190     // Collecting all conflicting Items
00191     if (info->type() == RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE
00192         || info->type() == RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL) {
00193         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00194 
00195         // does entry already exists ?
00196         ConflictMap::iterator pos = find_if (collector->conflictMap.lower_bound(misc_info->other()),
00197                                              collector->conflictMap.upper_bound(misc_info->other()),
00198                                              conflict_equals<PoolItem_Ref, PoolItem_Ref>(misc_info->affected()));
00199         if (pos == collector->conflictMap.end()) {
00200             _XDEBUG ("Inserting " << misc_info->affected() << "/" <<  misc_info->other()
00201                      << " into conflictMap map");
00202             collector->conflictMap.insert (make_pair(misc_info->affected(), misc_info->other()));
00203             collector->conflictMap.insert (make_pair(misc_info->other(), misc_info->affected())); // reverse
00204         }
00205     }
00206     
00207 }
00208 
00209 struct AllRequires
00210 {
00211     PoolItemList requirers;
00212 
00213     bool operator()( const CapAndItem & cai )
00214     {
00215         DBG << cai.item << " requires " << cai.cap << endl;
00216         requirers.push_back( cai.item );
00217 
00218         return true;
00219     }
00220 };
00221 
00222 
00223 ResolverProblemList
00224 Resolver::problems (const bool ignoreValidSolution) const
00225 {
00226     ResolverProblemList problems;
00227 
00228     if (_best_context && !ignoreValidSolution) {
00229         MIL << "Valid solution found, no problems" << endl;
00230         return problems;
00231     }
00232 
00233     // collect all resolvables with error
00234 
00235     ResolverQueueList invalid = invalidQueues();
00236     MIL << invalid.size() << " invalid queues" << endl;
00237 
00238     if (invalid.empty()) {
00239         WAR << "No solver problems, but there is also no valid solution." << endl;
00240         return problems;
00241     }
00242 
00243     ResolverContext_Ptr context = invalid.front()->context();
00244     ResItemCollector collector;
00245     context->foreachInfo (PoolItem(), RESOLVER_INFO_PRIORITY_VERBOSE, collector_cb, &collector);
00246 
00247     for (ProblemMap::const_iterator iter = collector.problems.begin(); iter != collector.problems.end(); ++iter) {
00248         PoolItem_Ref item = iter->first;
00249         ResolverInfo_Ptr info = iter->second;
00250 
00251         bool problem_created = false;
00252 
00253         DBG << "Problem: " << *info;
00254         DBG << "; Evaluate solutions..." << endl;
00255         
00256         string who = ResolverInfo::toString( item );
00257         string what;
00258         string details;
00259         switch (info->type()) {
00260             case RESOLVER_INFO_TYPE_INVALID: {
00261                 what = _("Invalid information");
00262             }
00263             break;
00264             case RESOLVER_INFO_TYPE_NEEDED_BY: { // no solution; it is only a info
00265                 ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
00266                 if (needed_by->items().size() >= 1)
00267                     // TranslatorExplanation %s = name of package, patch, selection ...
00268                     what = str::form (_("%s is needed by other resolvables"), who.c_str());
00269                 else
00270                     // TranslatorExplanation %s = name of package, patch, selection ...             
00271                     what = str::form (_("%s is needed by %s"), who.c_str(), needed_by->itemsToString(true).c_str());
00272                 details = str::form (_("%s is needed by:\n%s"), who.c_str(), needed_by->itemsToString(false).c_str());
00273             }
00274             break;
00275             case RESOLVER_INFO_TYPE_CONFLICTS_WITH: {
00276                 ResolverInfoConflictsWith_constPtr conflicts_with = dynamic_pointer_cast<const ResolverInfoConflictsWith>(info);
00277                 if (conflicts_with->items().size() >= 1)
00278                     // TranslatorExplanation %s = name of package, patch, selection ...
00279                     what = str::form (_("%s conflicts with other resolvables"), who.c_str() );
00280                 else
00281                     // TranslatorExplanation %s = name of package, patch, selection ...         
00282                     what = str::form (_("%s conflicts with %s"), who.c_str(), conflicts_with->itemsToString(true).c_str());
00283                 details = str::form (_("%s conflicts with:\n%s"), who.c_str(), conflicts_with->itemsToString(false).c_str());
00284                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);              
00285                 // Uninstall p
00286                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00287                 if (conflicts_with->items().size() == 1) {
00288                     // Uninstall q
00289                     problem->addSolution (new ProblemSolutionUninstall (problem, *(conflicts_with->items().begin())));
00290                 } else {
00291                     // Uninstall all other
00292                     PoolItemList conflict_items = conflicts_with->items();
00293                     problem->addSolution (new ProblemSolutionUninstall (problem, conflict_items));
00294                 }
00295                 // Remove conflict in the resolvable which has to be installed
00296                 problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, conflicts_with->capability(),
00297                                                                           conflicts_with->items())); 
00298                 problems.push_back (problem);
00299                 problem_created = true;
00300             }
00301             break;
00302             case RESOLVER_INFO_TYPE_OBSOLETES: { // no solution; it is only a info
00303                 ResolverInfoObsoletes_constPtr obsoletes = dynamic_pointer_cast<const ResolverInfoObsoletes>(info);
00304                 if (obsoletes->items().size() >= 1)
00305                     // TranslatorExplanation %s = name of package, patch, selection ...
00306                     what = str::form (_("%s obsoletes other resolvables"), who.c_str());
00307                 else
00308                     // TranslatorExplanation %s = name of package, patch, selection ...         
00309                     what = str::form (_("%s obsoletes %s"), who.c_str(), obsoletes->itemsToString(true).c_str());
00310                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00311                 details = str::form (_("%s obsoletes:%s"), who.c_str(), obsoletes->itemsToString(false).c_str());
00312                 details += _("\nThese resolvables will be deleted from the system.");
00313             }
00314             break;
00315             case RESOLVER_INFO_TYPE_DEPENDS_ON: { // no solution; it is only a info
00316                 ResolverInfoDependsOn_constPtr depends_on = dynamic_pointer_cast<const ResolverInfoDependsOn>(info);
00317                 if (depends_on->items().size() >= 1)
00318                     // TranslatorExplanation %s = name of package, patch, selection ...
00319                     what = str::form (_("%s depends on other resolvables"), who.c_str(),
00320                                       depends_on->itemsToString(true).c_str());
00321                 else
00322                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00323                     what = str::form (_("%s depends on %s"), who.c_str(),
00324                                       depends_on->itemsToString(true).c_str());
00325                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00326                 details = str::form (_("%s depends on:%s"), who.c_str(), depends_on->itemsToString(false).c_str());             
00327             }
00328             break;
00329             case RESOLVER_INFO_TYPE_CHILD_OF: {                         // unused
00330                 ResolverInfoChildOf_constPtr child_of = dynamic_pointer_cast<const ResolverInfoChildOf>(info);
00331                 // TranslatorExplanation: currently it is unused.
00332                 what = _("Child of");
00333             }
00334             break;
00335             case RESOLVER_INFO_TYPE_MISSING_REQ: { // no solution; it is only a info
00336                 ResolverInfoMissingReq_constPtr missing_req = dynamic_pointer_cast<const ResolverInfoMissingReq>(info);
00337                 // TranslatorExplanation %s = dependency
00338                 what = str::form (_("Cannot install %s"), who.c_str());
00339                 // TranslatorExplanation %s = capability                
00340                 details = str::form (_("None provides %s"), missing_req->capability().asString().c_str());
00341                 details += _("\nThere is no resource available which support this requirement.");
00342             }
00343             break;
00344 
00345         // from ResolverContext
00346             case RESOLVER_INFO_TYPE_INVALID_SOLUTION: {                 // Marking this resolution attempt as invalid.
00347                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00348                 what = misc_info->message();
00349                 details = _("Due problems which are described above/below this resolution will not solve all dependencies");
00350                 // no solution available
00351             }
00352             break;
00353             case RESOLVER_INFO_TYPE_UNINSTALLABLE: {                    // Marking p as uninstallable
00354                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00355                 // Trying to find a concerning conflict
00356 
00357                 for (ConflictMap::const_iterator it = collector.conflictMap.begin();
00358                      it != collector.conflictMap.end(); ++it) {
00359                     if (it->first == item) {
00360                         what = str::form (_("Cannot install %s because it is conflicting with %s"),
00361                                           who.c_str(),
00362                                           it->second->name().c_str());                          
00363                         details = ""; // no further details
00364                         ResolverProblem_Ptr problem = new ResolverProblem (what, details);              
00365                         // Uninstall p
00366                         problem->addSolution (new ProblemSolutionUninstall (problem, item));
00367                         // Uninstall q
00368                         problem->addSolution (new ProblemSolutionUninstall (problem, it->second));
00369                         problems.push_back (problem);
00370                         problem_created = true;
00371                     }
00372                 }
00373                 if (!problem_created) {
00374                     // default 
00375                     what = misc_info->message();
00376                     // TranslatorExplanation %s = name of package,patch,...             
00377                     details = str::form (_("%s is not installed and has been marked as uninstallable"), who.c_str());
00378                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00379                     problem->addSolution (new ProblemSolutionInstall (problem, item)); // Install resolvable again
00380                     problems.push_back (problem);
00381                     problem_created = true;
00382                 }
00383             }
00384             break;
00385             case RESOLVER_INFO_TYPE_REJECT_INSTALL: {                   // p is scheduled to be installed, but this is not possible because of dependency problems.
00386                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00387                 // TranslatorExplanation %s = name of package,patch,...                         
00388                 what = str::form (_("Cannot install %s due to dependency problems"), who.c_str());
00389                 details = misc_info->message();
00390                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00391                 // Uninstall it; 
00392                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00393                 // currently no solution concerning "ignore" is available               
00394                 problems.push_back (problem);
00395                 problem_created = true;
00396             }
00397             break;
00398             case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: {        // Can't install p since it is already marked as needing to be uninstalled
00399                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00400                 // TranslatorExplanation %s = name of package,patch,...                         
00401                 what = misc_info->message();
00402                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00403                 problem->addSolution (new ProblemSolutionInstall (problem, item)); // Install resolvable again
00404                 problems.push_back (problem);
00405                 problem_created = true;
00406             }
00407             break;
00408             case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: {                 // Can't install p since it is does not apply to this system.
00409                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00410                 // TranslatorExplanation %s = name of package,patch,...                         
00411                 what = misc_info->message();
00412                 // no solution; it is only a info
00413             }
00414             break;
00415             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.
00416                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00417                 // TranslatorExplanation %s = name of package,patch,...                         
00418                 what = str::form (_("Cannot install %s"), who.c_str());
00419                 details = misc_info->message();
00420                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00421                 // Uninstall the item
00422                 ResStatus status = item.status();
00423                 string description = "";
00424                 if (status.isInstalled())
00425                     // TranslatorExplanation %s = name of package, patch, selection ...
00426                     description = str::form (_("delete %s"), ResolverInfo::toString (item).c_str());
00427                 else
00428                     // TranslatorExplanation %s = name of package, patch, selection ... 
00429                     description = str::form (_("do not install %s"), ResolverInfo::toString (item).c_str());
00430                 problem->addSolution (new ProblemSolutionUninstall (problem, item, description, ""));
00431                 
00432                 // Uninstall the other
00433                 status = misc_info->other().status();
00434                 if (status.isInstalled())
00435                     // TranslatorExplanation %s = name of package, patch, selection ...
00436                     description = str::form (_("delete %s"), ResolverInfo::toString (misc_info->other()).c_str());
00437                 else
00438                     // TranslatorExplanation %s = name of package, patch, selection ... 
00439                     description = str::form (_("do not install %s"), ResolverInfo::toString (misc_info->other()).c_str());              
00440                 problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other(), description, ""));
00441                 
00442                 // Ignore it
00443                 problem->addSolution (new ProblemSolutionIgnoreInstalled (problem, item, misc_info->other()));
00444                 problems.push_back (problem);
00445                 problem_created = true;         
00446             }
00447             break;
00448             case RESOLVER_INFO_TYPE_INCOMPLETES: {                      // This would invalidate p
00449                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00450                 what = misc_info->message();
00451                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00452                 details = str::form (_("%s has unfulfilled requirements"), who.c_str());
00453                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00454                 // Uninstall 
00455                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00456                 problems.push_back (problem);
00457                 problem_created = true;         
00458             }
00459             break;
00460         // from QueueItemEstablish
00461             case RESOLVER_INFO_TYPE_ESTABLISHING: {                     // Establishing p
00462                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00463                 what = misc_info->message();
00464                 // no solution is needed cause it is only a progress indicator
00465             }
00466             break;
00467         // from QueueItemInstall
00468             case RESOLVER_INFO_TYPE_INSTALLING: {                       // Installing p
00469                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00470                 what = misc_info->message();
00471                 // no solution is needed cause it is only a progress indicator          
00472             }
00473             break;
00474             case RESOLVER_INFO_TYPE_UPDATING: {                         // Updating p
00475                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00476                 what = misc_info->message();
00477                 // no solution is needed cause it is only a progress indicator          
00478             }
00479             break;
00480             case RESOLVER_INFO_TYPE_SKIPPING: {                         // Skipping p, already installed
00481                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00482                 what = misc_info->message();
00483                 // It is only an info and happens while upgrading
00484             }
00485             break;
00486         // from QueueItemRequire
00487             case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: {                // There are no alternative installed providers of c [for p]
00488                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00489                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00490                 what = str::form (_("%s has missing dependencies"), who.c_str());
00491                 details = misc_info->message();
00492                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00493 
00494                 // Searching for another item which provides this requires BUT has been set to uninstall
00495                 for (ItemCapabilityMap::const_iterator it = collector.provideAndDeleteMap.begin();
00496                      it != collector.provideAndDeleteMap.end(); ++it) {
00497                     if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00498                         // Do not delete
00499                         problem->addSolution (new ProblemSolutionKeep (problem, it->first));
00500                     }
00501                 }
00502 
00503                 // Searching for another item which provides this requires BUT has been set to be kept
00504                 for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
00505                      it != collector.provideAndKeptMap.end(); ++it) {
00506                     if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00507                         // Do install
00508                         problem->addSolution (new ProblemSolutionInstall (problem, it->first));
00509                     }
00510                 }               
00511 
00512                 // uninstall
00513                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00514 
00515                 // Unflag require ONLY for this item
00516                 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));              
00517 
00518                 // Unflag ALL require
00519                 // Evaluating all require Items
00520                 AllRequires info;
00521                 Dep dep( Dep::REQUIRES );
00522 
00523                 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
00524                               _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),   // end()
00525                               resfilter::ByCapMatch( misc_info->capability() ),
00526                               functor::functorRef<bool,CapAndItem>(info) );
00527                 if (info.requirers.size() > 1)
00528                     problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00529 
00530                 problems.push_back (problem);
00531                 problem_created = true;
00532             }
00533             break;
00534             case RESOLVER_INFO_TYPE_NO_PROVIDER: {                      // There are no installable providers of c [for p]
00535                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00536                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00537                 what = str::form (_("%s cannot be installed due to missing dependencies"), who.c_str());                
00538                 details = misc_info->message();
00539                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00540                 
00541                 // Searching for another item which provides this requires BUT has been locked
00542                 for (ItemCapabilityMap::const_iterator it = collector.provideAndLockMap.begin();
00543                      it != collector.provideAndLockMap.end(); ++it) {
00544                     if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00545                         // unlock this item
00546                         problem->addSolution (new ProblemSolutionUnlock (problem, it->first));
00547                         // unlock ALL existing resolvables
00548                         problem->addSolution (new ProblemSolutionUnlock (problem, pool()));                     
00549                     }
00550                 }
00551                 // Searching for another item which provides this requires BUT has another architec
00552                 for (ItemCapabilityMap::const_iterator it = collector.provideAndOtherArchMap.begin();
00553                      it != collector.provideAndOtherArchMap.end(); ++it) {
00554                     if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00555                         // ignoring architecture
00556                         problem->addSolution (new ProblemSolutionIgnoreArchitecture (problem, it->first));
00557                     }
00558                 }
00559                 // Searching for another item which provides this requires BUT has been set to be kept
00560                 for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
00561                      it != collector.provideAndKeptMap.end(); ++it) {
00562                     if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00563                         // Do install
00564                         problem->addSolution (new ProblemSolutionInstall (problem, it->first));
00565                     }
00566                 }               
00567                 
00568                 // uninstall
00569                 problem->addSolution (new ProblemSolutionUninstall (problem, item)); 
00570                 // ignore requirement
00571                 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability())); 
00572                 problems.push_back (problem);
00573                 problem_created = true;         
00574             }
00575             break;
00576             case RESOLVER_INFO_TYPE_NO_UPGRADE: {                       // Upgrade to q to avoid removing p is not possible.
00577                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00578                 what = misc_info->message();
00579                 // It is only an info --> no solution is needed         
00580             }
00581             break;
00582             case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {               // p provides c but is scheduled to be uninstalled
00583                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00584                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00585                 what =str::form (_("%s fulfil dependencies of %s but will be uninstalled"),
00586                                  misc_info->other()->name().c_str(),
00587                                  who.c_str());
00588                 details = misc_info->message();
00589                 // It is only an info --> no solution is needed
00590             }
00591             break;              
00592             case RESOLVER_INFO_TYPE_KEEP_PROVIDER: {            // p provides c but is scheduled to be kept
00593                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00594                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00595                 what =str::form (_("%s fulfil dependencies of %s but will be kept on your system"),
00596                                  misc_info->other()->name().c_str(),
00597                                  who.c_str());
00598                 details = misc_info->message();
00599                 // It is only an info --> no solution is needed
00600             }           
00601             break;
00602             case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: {                // p provides c but another version is already installed
00603                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00604                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00605                 what = str::form (_("No need to install %s"), misc_info->other()->name().c_str());
00606                 details = misc_info->message();
00607                 // It is only an info --> no solution is needed         
00608             }
00609             break;
00610             case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: {         // p provides c but is uninstallable
00611                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00612                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00613                 what = str::form (_("Cannot install %s to fulfil the dependencies of %s"),
00614                                   misc_info->other()->name().c_str(),
00615                                   who.c_str());
00616                 details = misc_info->message();
00617                 // It is only an info --> no solution is needed         
00618             }
00619             case RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER: {              // p provides c but has other architecture
00620                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00621                 what = misc_info->message();
00622                 // It is only an info --> no solution is needed         
00623             }           
00624             break;
00625             case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: {                  // p provides c but is locked
00626                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00627                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00628                 what = str::form (_("Cannot be install %s to fulfil the dependencies of %s"),
00629                                   misc_info->other()->name().c_str(),
00630                                   who.c_str());                         
00631                 what = misc_info->message();
00632                 // It is only an info --> no solution is needed         
00633             }
00634             break;
00635             case RESOLVER_INFO_TYPE_CANT_SATISFY: {                     // Can't satisfy requirement c
00636                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00637                 what = misc_info->message();
00638                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00639                 // uninstall
00640                 problem->addSolution (new ProblemSolutionUninstall (problem, item)); 
00641                 
00642                 // Unflag requirement for this item
00643                 problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00644                 
00645                 // Unflag ALL require
00646                 // Evaluating all require Items
00647                 AllRequires info;
00648                 Dep dep( Dep::REQUIRES );
00649 
00650                 invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
00651                               _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),   // end()
00652                               resfilter::ByCapMatch( misc_info->capability() ),
00653                               functor::functorRef<bool,CapAndItem>(info) );
00654                 if (info.requirers.size() > 1)
00655                     problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00656                 
00657                 problems.push_back (problem);
00658                 problem_created = true;         
00659             }
00660             break;
00661         // from QueueItemUninstall
00662             case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: {        // p is to-be-installed, so it won't be unlinked.
00663                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00664                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00665                 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());
00666                 details = misc_info->message();
00667                 // It is only an info --> no solution is needed                         
00668             }
00669             break;
00670             case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: {              // p is required by installed, so it won't be unlinked.
00671                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00672                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00673                 what = str::form (_("%s will not be uninstalled cause it is still required"), who.c_str());             
00674                 details = misc_info->message();
00675                 // It is only an info --> no solution is needed                         
00676             }
00677             break;
00678             case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {                 // cant uninstall, its locked
00679                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00680                 what = misc_info->message();
00681                 
00682                 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00683                     // TranslatorExplanation %s = name of package, patch, selection ...                                             
00684                     details = str::form (_("%s obsoletes %s. But %s cannot be deleted because it is locked."),
00685                                          misc_info->other()->name().c_str(),
00686                                          who.c_str(), who.c_str());
00687                 }
00688                 
00689                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00690                 problem->addSolution (new ProblemSolutionUnlock (problem, item)); // Unlocking resItem
00691                 // unlock ALL existing resolvables
00692                 problem->addSolution (new ProblemSolutionUnlock (problem, pool()));                                     
00693                 if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00694                     // Ignore obsoletes
00695                     problem->addSolution (new ProblemSolutionIgnoreObsoletes (problem, item, misc_info->capability(),
00696                                                                               misc_info->other())); 
00697                 } else {
00698                     // This is an "default" soltution
00699                     // keep installed
00700                     problem->addSolution (new ProblemSolutionKeep (problem, item));
00701                 }
00702                 problems.push_back (problem);
00703                 problem_created = true;
00704             }
00705             break;
00706         // from QueueItemConflict
00707             case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {            // to-be-installed p conflicts with q due to c
00708                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00709                 // TranslatorExplanation %s = name of package, patch, selection ...
00710                 if (misc_info->other())
00711                     what = str::form (_("Cannot install %s because it is conflicting with %s"),
00712                                       who.c_str(),
00713                                       misc_info->other()->name().c_str());
00714                 else
00715                     what = str::form (_("Cannot install %s because it is conflicting"),
00716                                       who.c_str());
00717                 details = misc_info->message();
00718                 ResolverProblem_Ptr problem = new ResolverProblem (what, details);              
00719                 // Uninstall p
00720                 problem->addSolution (new ProblemSolutionUninstall (problem, item));
00721                 if (misc_info->other())
00722                     // Uninstall q
00723                     problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
00724                 // Remove conflict in the resolvable which has to be installed
00725                 problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, misc_info->other_capability(),
00726                                                                           misc_info->other()));
00727                 problems.push_back (problem);
00728                 problem_created = true;
00729             }
00730             break;
00731             case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: {           // uninstalled p is marked uninstallable it conflicts [with q] due to c
00732                 ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00733                 // TranslatorExplanation %s = name of package, patch, selection ...                             
00734                 what = str::form (_("%s is uninstallable due to conflicts with %s"),
00735                                 who.c_str(),
00736                                 misc_info->other()->name().c_str());                            
00737                 details = misc_info->message();
00738                 // It is only an info --> no solution is needed
00739             }
00740             break;
00741         }
00742         if (!problem_created) {
00743             ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00744             problems.push_back (problem);
00745         }
00746     }
00747     if (problems.empty()) {
00748         context->spewInfo();
00749     }
00750     return problems;
00751 }
00752 
00753 void
00754 Resolver::applySolutions (const ProblemSolutionList & solutions)
00755 {
00756     for (ProblemSolutionList::const_iterator iter = solutions.begin();
00757          iter != solutions.end(); ++iter) {
00758         ProblemSolution_Ptr solution = *iter;
00759         if (!solution->apply (*this))
00760             break;
00761     }    
00762 }
00763 
00765     };// namespace detail
00768   };// namespace solver
00771 };// namespace zypp
00773 

Generated on Fri Jul 4 16:57:59 2008 for zypp by  doxygen 1.5.0