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 #include "zypp/solver/detail/ProblemSolutionAllBranches.h"
00035 #include "zypp/solver/detail/ProblemSolutionDoubleTimeout.h"
00036 
00037 #include "zypp/solver/detail/ResolverInfoChildOf.h"
00038 #include "zypp/solver/detail/ResolverInfoConflictsWith.h"
00039 #include "zypp/solver/detail/ResolverInfoContainer.h"
00040 #include "zypp/solver/detail/ResolverInfoDependsOn.h"
00041 #include "zypp/solver/detail/ResolverInfoMisc.h"
00042 #include "zypp/solver/detail/ResolverInfoMissingReq.h"
00043 #include "zypp/solver/detail/ResolverInfoNeededBy.h"
00044 #include "zypp/solver/detail/ResolverInfoObsoletes.h"
00045 
00046 #include "zypp/base/String.h"
00047 #include "zypp/base/Logger.h"
00048 #include "zypp/base/Gettext.h"
00049 
00050 #include "zypp/base/Algorithm.h"
00051 #include "zypp/ResPool.h"
00052 #include "zypp/ResFilters.h"
00053 #include "zypp/CapFilters.h"
00054 
00055 
00057 namespace zypp
00058 { 
00059 
00060   namespace solver
00061   { 
00062 
00063     namespace detail
00064     { 
00065 
00066 using namespace std;
00067 
00068         
00069 typedef multimap<PoolItem_Ref, ResolverInfo_Ptr> ProblemMap;    
00070 typedef multimap<PoolItem_Ref, Capability> ItemCapabilityMap;
00071 typedef multimap<PoolItem_Ref, PoolItem_Ref> ConflictMap;
00072 
00073 #define MAXPROBLEMS 20
00074 #define TAB "    "
00075 
00076 // match template over ItemCapabilityMap
00077 template <class K, class V>
00078 class cap_equals {
00079   private:
00080     V value;
00081 public:
00082     cap_equals (const V& v)
00083         : value(v) {
00084     }
00085     // comparison
00086     bool operator() (pair<const K, V> elem) {
00087         return value.matches (elem.second) == CapMatch::yes;
00088     }
00089 };
00090 
00091 // match template over ConflictMap
00092 template <class K, class V>
00093 class conflict_equals {
00094   private:
00095     V value;
00096 public:
00097     conflict_equals (const V& v)
00098         : value(v) {
00099     }
00100     // comparison
00101     bool operator() (pair<const K, V> elem) {
00102         return value = elem.second;
00103     }
00104 };      
00105         
00106 // set resolvables with errors
00107 
00108 typedef struct {
00109     // Map of errors 
00110     ProblemMap problems;
00111     // Map of additional information applied to an item
00112     ProblemMap additionalInfo;    
00113     // A map of PoolItems which provides a capability but are set
00114     // for uninstallation
00115     ItemCapabilityMap provideAndDeleteMap;
00116     // A map of PoolItems which provides a capability but are set
00117     // to be kept
00118     ItemCapabilityMap provideAndKeptMap;    
00119     // A map of PoolItems which provides a capability but are locked
00120     ItemCapabilityMap provideAndLockMap;
00121     // A map of PoolItems which provides a capability but have another architecture
00122     ItemCapabilityMap provideAndOtherArchMap;
00123     // A map of PoolItems which provides a capability but have another vendor
00124     ItemCapabilityMap provideAndOtherVendorMap;
00125     // A map of conflicting Items
00126     ConflictMap conflictMap;
00127 } ResItemCollector;
00128 
00129 
00130 static void
00131 collector_cb (ResolverInfo_Ptr info, void *data)
00132 {
00133     ResItemCollector *collector = (ResItemCollector *)data;
00134     PoolItem_Ref item = info->affected();
00135     if (info->error()) {
00136         collector->problems.insert (make_pair( item, info));
00137     } else {
00138         collector->additionalInfo.insert (make_pair( item, info));
00139 
00140         if (info->type()==RESOLVER_INFO_TYPE_NEEDED_BY) { // logging reverse needed by
00141             ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
00142             PoolItemList itemList = needed_by->items();
00143             for (PoolItemList::const_iterator iter = itemList.begin();
00144                  iter != itemList.end(); ++iter)
00145             {
00146                 collector->additionalInfo.insert (make_pair( *iter, info));
00147             }
00148         }
00149     }
00150 
00151     // Collicting items which are providing requirements but they
00152     // are set for uninstall
00153     if (info->type() == RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER) {
00154         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00155         // does entry already exists ?
00156         ItemCapabilityMap::iterator pos = find_if (collector->provideAndDeleteMap.begin(),
00157                                                    collector->provideAndDeleteMap.end(),
00158                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00159         
00160         if (pos == collector->provideAndDeleteMap.end()) {
00161             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00162                      << " into provideAndDelete map");
00163             collector->provideAndDeleteMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00164         }
00165     }
00166     // Collicting items which are providing requirements but they
00167     // are set to be kept
00168     if (info->type() == RESOLVER_INFO_TYPE_KEEP_PROVIDER) {
00169         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00170         // does entry already exists ?
00171         ItemCapabilityMap::iterator pos = find_if (collector->provideAndKeptMap.begin(),
00172                                                    collector->provideAndKeptMap.end(),
00173                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00174         
00175         if (pos == collector->provideAndKeptMap.end()) {
00176             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00177                      << " into provideAndKeptMap map");
00178             collector->provideAndKeptMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00179         }
00180     }    
00181     // Collecting items which are providing requirements but they
00182     // are locked
00183     if (info->type() == RESOLVER_INFO_TYPE_LOCKED_PROVIDER) {
00184         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00185         // does entry already exists ?
00186         ItemCapabilityMap::iterator pos = find_if (collector->provideAndLockMap.begin(),
00187                                                    collector->provideAndLockMap.end(),
00188                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00189         
00190         if (pos == collector->provideAndLockMap.end()) {
00191             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00192                      << " into provideAndLockMap map");
00193             collector->provideAndLockMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00194         }
00195     }
00196     // Collecting items which are providing requirements but they
00197     // have another architecture
00198     if (info->type() == RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER) {
00199         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00200         // does entry already exists ?
00201         ItemCapabilityMap::iterator pos = find_if (collector->provideAndOtherArchMap.begin(),
00202                                                    collector->provideAndOtherArchMap.end(),
00203                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00204         
00205         if (pos == collector->provideAndOtherArchMap.end()) {
00206             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00207                      << " into provideAndOtherArchMap map");
00208             collector->provideAndOtherArchMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00209         }
00210     }
00211     // Collecting items which are providing requirements but they
00212     // have another vendor
00213     if (info->type() == RESOLVER_INFO_TYPE_OTHER_VENDOR_PROVIDER) {
00214         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00215         // does entry already exists ?
00216         ItemCapabilityMap::iterator pos = find_if (collector->provideAndOtherVendorMap.begin(),
00217                                                    collector->provideAndOtherVendorMap.end(),
00218                                                    cap_equals<PoolItem_Ref, Capability>(misc_info->capability()));
00219         
00220         if (pos == collector->provideAndOtherVendorMap.end()) {
00221             _XDEBUG ("Inserting " << misc_info->capability() << "/" <<  misc_info->other()
00222                      << " into provideAndOtherVendorMap map");
00223             collector->provideAndOtherVendorMap.insert (make_pair( misc_info->other(), misc_info->capability()));
00224         }
00225     }    
00226     // Collecting all conflicting Items
00227     if (info->type() == RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE
00228         || info->type() == RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL) {
00229         ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00230 
00231         // does entry already exists ?
00232         ConflictMap::iterator pos = find_if (collector->conflictMap.lower_bound(misc_info->other()),
00233                                              collector->conflictMap.upper_bound(misc_info->other()),
00234                                              conflict_equals<PoolItem_Ref, PoolItem_Ref>(misc_info->affected()));
00235         if (pos == collector->conflictMap.end()) {
00236             _XDEBUG ("Inserting " << misc_info->affected() << "/" <<  misc_info->other()
00237                      << " into conflictMap map");
00238             collector->conflictMap.insert (make_pair(misc_info->affected(), misc_info->other()));
00239             collector->conflictMap.insert (make_pair(misc_info->other(), misc_info->affected())); // reverse
00240         }
00241     }
00242     
00243 }
00244 
00245 struct AllRequires
00246 {
00247     PoolItemList requirers;
00248 
00249     bool operator()( const CapAndItem & cai )
00250     {
00251         _XDEBUG (cai.item << " requires " << cai.cap);
00252         requirers.push_back( cai.item );
00253 
00254         return true;
00255     }
00256 };
00257 
00258 std::string logAdditionalInfo ( const ProblemMap &additionalInfo, const PoolItem_Ref item)
00259 {
00260     string infoStr = "";
00261     for (ProblemMap::const_iterator iter = additionalInfo.find(item); iter != additionalInfo.end();) {
00262         ResolverInfo_Ptr info = iter->second;
00263         PoolItem_Ref iterItem = iter->first;
00264         
00265         if (iter == additionalInfo.find(item)) {
00266             string who = ResolverInfo::toString( item );
00267             infoStr = "=== " + who + " ===\n";
00268             
00269             ResStatus status = iterItem.status();
00270             if (status.isToBeUninstalled()) {
00271                 if (status.isByUser())
00272                     // Translator: all.%s = name of package,patch,...
00273                     infoStr += TAB + str::form (_("%s will be deleted by the user.\n"),
00274                                           who.c_str());
00275                 if (status.isByApplHigh()
00276                     || status.isByApplLow())
00277                     // Translator: all.%s = name of package,patch,...
00278                     infoStr += TAB + str::form (_("%s will be deleted by another application. (ApplLow/ApplHigh)\n"),
00279                                           who.c_str());
00280             }
00281             if (status.isToBeInstalled()) {
00282                 if (status.isByUser())
00283                     // Translator: all.%s = name of package,patch,...
00284                     infoStr += TAB + str::form (_("%s will be installed by the user.\n"),
00285                                           who.c_str());
00286                 if (status.isByApplHigh()
00287                     || status.isByApplLow())
00288                     // Translator: all.%s = name of package,patch,...
00289                     infoStr += TAB + str::form (_("%s will be installed by another application. (ApplLow/ApplHigh)\n"),
00290                                           who.c_str());
00291             }
00292         }
00293         if (iterItem == item) {
00294             // filter out useless information
00295             if (info->type() != RESOLVER_INFO_TYPE_INSTALLING
00296                 && info->type() != RESOLVER_INFO_TYPE_ESTABLISHING
00297                 && info->type() != RESOLVER_INFO_TYPE_UPDATING
00298                 && info->type() != RESOLVER_INFO_TYPE_SKIPPING
00299                 && info->type() != RESOLVER_INFO_TYPE_UNINSTALLABLE
00300                 && info->type() != RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE) {
00301                 infoStr += TAB +info->message();
00302                 infoStr += "\n";
00303             }
00304             iter++;
00305         } else {
00306             // exit
00307             iter = additionalInfo.end();
00308         }
00309     }
00310     return infoStr;
00311 }
00312 
00313    
00314 static void
00315 moreDetailsCb( ResolverInfo_Ptr info, void *data )
00316 {
00317   if (info->important()
00318       && info->priority() >= RESOLVER_INFO_PRIORITY_USER) {
00319     std::list<std::string> *details = (std::list<std::string> *)data;
00320     details->push_back( info->message() );
00321   }
00322    
00323 }       
00324        
00325 static string
00326 moreDetails( ResolverContext_Ptr context, PoolItem_Ref item )
00327 {
00328   MIL << "moreDetails for " << item << endl;
00329   std::list<std::string> details;
00330   context->foreachInfo( item, RESOLVER_INFO_PRIORITY_USER, moreDetailsCb, &details, true, true ); //, const bool merge=true, const bool findImportant = true) const;
00331   string result;
00332   std::list<std::string>::iterator it;
00333   for (it = details.begin(); it != details.end(); ++it) 
00334      {
00335         result += "    ";
00336         result += *it;
00337         result += "\n";
00338      }
00339    
00340   return result;
00341 }
00342       
00343              
00344 
00345 ResolverProblemList
00346 Resolver::problems (const bool ignoreValidSolution) const
00347 {
00348     ResolverProblemList problems;
00349 
00350     MIL << "Resolver::problems(" << (ignoreValidSolution ? "ignoreValidSolution": "") << ")" << endl;
00351 
00352     if (_best_context && !ignoreValidSolution) {
00353         MIL << "Valid solution found, no problems" << endl;
00354         return problems;
00355     }
00356 
00357     // collect all resolvables with error
00358     ResolverQueueList invalid = invalidQueues();
00359     MIL << invalid.size() << " invalid queues" << endl;
00360 
00361     if (invalid.empty()) {
00362         WAR << "No solver problems, but there is also no valid solution." << endl;
00363         if (!_best_context
00364             && timeout() > 0) {
00365             // This can be generated by a timout only
00366             string what = str::form (_("No valid solution found within %d seconds"), timeout());
00367             string details = _("The solver has reached a defined timout");
00368             ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00369             problem->addSolution (new ProblemSolutionDoubleTimeout (problem));
00370             if (tryAllPossibilities())
00371                 problem->addSolution (new ProblemSolutionAllBranches (problem,false));
00372             problems.push_back (problem);
00373         }
00374         
00375         return problems;
00376     }
00377 
00378     bool skippedPossibilities = false;    
00379     
00380     for (ResolverQueueList::iterator iter = invalid.begin();
00381          iter != invalid.end(); iter++) {
00382         // evaluate if there are other possibilities which have not been regarded
00383         ResolverQueue_Ptr invalidQ =    *iter;              
00384         if (invalidQ->context()->skippedPossibilities()) {
00385             skippedPossibilities = true;
00386             break;
00387         }
00388     }
00389         
00390     if (!_tryAllPossibilities       // a second run with ALL possibilities has not been tried 
00391         && skippedPossibilities) { // possible other solutions skipped
00392         // give the user an additional solution for trying all branches
00393         string what = _("No valid solution found with just resolvables of best architecture.");
00394         string details = _("With this run only resolvables with the best architecture have been regarded.\n");
00395         details = details + _("Regarding all possible resolvables takes time, but can come to a valid result.");
00396         ResolverProblem_Ptr problem = new ResolverProblem (what, details);              
00397         problem->addSolution (new ProblemSolutionAllBranches (problem));
00398         problems.push_back (problem);
00399     }
00400 
00401     ResolverContext_Ptr context = invalid.front()->context();
00402     ResItemCollector collector;
00403     context->foreachInfo (PoolItem(), RESOLVER_INFO_PRIORITY_VERBOSE, collector_cb, &collector);
00404 
00405     for (ProblemMap::const_iterator iter = collector.problems.begin(); iter != collector.problems.end(); ++iter) {
00406         PoolItem_Ref item = iter->first;
00407         ResolverInfo_Ptr info = iter->second;
00408 
00409         bool problem_created = false;
00410 
00411         MIL << "Problem: " << *info;
00412         XXX << "; Evaluate solutions..." << endl;
00413         string what;
00414         string details;
00415 
00416         if (item) {
00417             string who = ResolverInfo::toString( item );
00418             string whoShort = ResolverInfo::toString( item, true ); // short version
00419             switch (info->type()) {
00420                 case RESOLVER_INFO_TYPE_INVALID: {
00421                     what = _("Invalid information");
00422                 }
00423                     break;
00424                 case RESOLVER_INFO_TYPE_NEEDED_BY: { // no solution; it is only a info
00425                     ResolverInfoNeededBy_constPtr needed_by = dynamic_pointer_cast<const ResolverInfoNeededBy>(info);
00426                     if (needed_by->items().size() >= 1)
00427                         // TranslatorExplanation %s = name of package, patch, selection ...
00428                         what = str::form (_("%s is needed by other resolvables"), whoShort.c_str());
00429                     else
00430                         // TranslatorExplanation %s = name of package, patch, selection ...                 
00431                         what = str::form (_("%s is needed by %s"), whoShort.c_str(), needed_by->itemsToString(true).c_str());
00432                     details = str::form (_("%s is needed by:\n%s"), who.c_str(), needed_by->itemsToString(false).c_str());
00433                 }
00434                     break;
00435                 case RESOLVER_INFO_TYPE_CONFLICTS_WITH: {
00436                     ResolverInfoConflictsWith_constPtr conflicts_with = dynamic_pointer_cast<const ResolverInfoConflictsWith>(info);
00437                     if (conflicts_with->items().size() >= 1)
00438                         // TranslatorExplanation %s = name of package, patch, selection ...
00439                         what = str::form (_("%s conflicts with other resolvables"), whoShort.c_str() );
00440                     else
00441                         // TranslatorExplanation %s = name of package, patch, selection ...             
00442                         what = str::form (_("%s conflicts with %s"), whoShort.c_str(), conflicts_with->itemsToString(true).c_str());
00443                 
00444                     details = str::form (_("%s conflicts with:\n%s"), who.c_str(), conflicts_with->itemsToString(false).c_str()) + "\n";
00445                     details += logAdditionalInfo(collector.additionalInfo, item);
00446                     PoolItemList item_list = conflicts_with->items();
00447                     for (PoolItemList::const_iterator it = item_list.begin(); it != item_list.end(); ++it) {
00448                         details += logAdditionalInfo(collector.additionalInfo, *it);
00449                     }
00450                     
00451                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);          
00452                     // Uninstall p
00453                     problem->addSolution (new ProblemSolutionUninstall (problem, item));
00454                     if (conflicts_with->items().size() == 1) {
00455                         // Uninstall q
00456                         problem->addSolution (new ProblemSolutionUninstall (problem, *(conflicts_with->items().begin())));
00457                     } else {
00458                         // Uninstall all other
00459                         PoolItemList conflict_items = conflicts_with->items();
00460                         problem->addSolution (new ProblemSolutionUninstall (problem, conflict_items));
00461                     }
00462                     // Remove conflict in the resolvable which has to be installed
00463                     problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, conflicts_with->capability(),
00464                                                                               conflicts_with->items())); 
00465                     problems.push_back (problem);
00466                     problem_created = true;
00467                 }
00468                     break;
00469                 case RESOLVER_INFO_TYPE_OBSOLETES: { // no solution; it is only a info
00470                     ResolverInfoObsoletes_constPtr obsoletes = dynamic_pointer_cast<const ResolverInfoObsoletes>(info);
00471                     if (obsoletes->items().size() >= 1)
00472                         // TranslatorExplanation %s = name of package, patch, selection ...
00473                         what = str::form (_("%s obsoletes other resolvables"), whoShort.c_str());
00474                     else
00475                         // TranslatorExplanation %s = name of package, patch, selection ...             
00476                         what = str::form (_("%s obsoletes %s"), whoShort.c_str(), obsoletes->itemsToString(true).c_str());
00477                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00478                     details = str::form (_("%s obsoletes:%s"), who.c_str(), obsoletes->itemsToString(false).c_str());
00479                     details += _("\nThese resolvables will be deleted from the system.");
00480                     details += "\n" + logAdditionalInfo(collector.additionalInfo, item);                
00481                 }
00482                     break;
00483                 case RESOLVER_INFO_TYPE_DEPENDS_ON: { // no solution; it is only a info
00484                     ResolverInfoDependsOn_constPtr depends_on = dynamic_pointer_cast<const ResolverInfoDependsOn>(info);
00485                     if (depends_on->items().size() >= 1)
00486                         // TranslatorExplanation %s = name of package, patch, selection ...
00487                         what = str::form (_("%s depends on other resolvables"), whoShort.c_str(),
00488                                           depends_on->itemsToString(true).c_str());
00489                     else
00490                         // TranslatorExplanation %s = name of package, patch, selection ...                             
00491                         what = str::form (_("%s depends on %s"), whoShort.c_str(),
00492                                           depends_on->itemsToString(true).c_str());
00493                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00494                     details = str::form (_("%s depends on:%s"), who.c_str(), depends_on->itemsToString(false).c_str());         
00495                 }
00496                     break;
00497                 case RESOLVER_INFO_TYPE_CHILD_OF: {                             // unused
00498                     ResolverInfoChildOf_constPtr child_of = dynamic_pointer_cast<const ResolverInfoChildOf>(info);
00499                     // TranslatorExplanation: currently it is unused.
00500                     what = _("Child of");
00501                 }
00502                     break;
00503                 case RESOLVER_INFO_TYPE_MISSING_REQ: { // no solution; it is only a info
00504                     ResolverInfoMissingReq_constPtr missing_req = dynamic_pointer_cast<const ResolverInfoMissingReq>(info);
00505                     // TranslatorExplanation %s = dependency
00506                     what = str::form (_("Cannot install %s"), whoShort.c_str());
00507                     // TranslatorExplanation %s = capability            
00508                     details = str::form (_("None provides %s"), missing_req->capability().asString().c_str());
00509                     details += _("\nThere is no resource available which supports this requirement.");
00510                 }
00511                     break;
00512 
00513                     // from ResolverContext
00514                 case RESOLVER_INFO_TYPE_INVALID_SOLUTION: {                     // Marking this resolution attempt as invalid.
00515                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00516                     what = misc_info->message();
00517                     details = _("Due to the problems described above/below, this resolution will not solve all dependencies");
00518                     // no solution available
00519                 }
00520                     break;
00521                 case RESOLVER_INFO_TYPE_UNINSTALLABLE: {                        // Marking p as uninstallable
00522                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00523                     // Trying to find a concerning conflict
00524 
00525                     for (ConflictMap::const_iterator it = collector.conflictMap.begin();
00526                          it != collector.conflictMap.end(); ++it) {
00527                         if (it->first == item) {
00528                             what = str::form (_("Cannot install %s, because it is conflicting with %s"),
00529                                               whoShort.c_str(),
00530                                               it->second->name().c_str()) + "\n";
00531                             details = logAdditionalInfo(collector.additionalInfo, item);
00532                             details += logAdditionalInfo(collector.additionalInfo, it->second);                 
00533                             ResolverProblem_Ptr problem = new ResolverProblem (what, details);          
00534                             // Uninstall p
00535                             problem->addSolution (new ProblemSolutionUninstall (problem, item));
00536                             // Uninstall q
00537                             problem->addSolution (new ProblemSolutionUninstall (problem, it->second));
00538                             problems.push_back (problem);
00539                             problem_created = true;
00540                         }
00541                     }
00542                     if (!problem_created) {
00543                         // default 
00544                         what = misc_info->message();
00545                         // TranslatorExplanation %s = name of package,patch,...         
00546                         details = str::form (_("%s is not installed and has been marked as uninstallable"), who.c_str()) + "\n";
00547                         details += logAdditionalInfo(collector.additionalInfo, item);               
00548                         ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00549                         problem->addSolution (new ProblemSolutionUninstall (problem, item)); // Uninstall resolvable 
00550                         problems.push_back (problem);
00551                         problem_created = true;
00552                     }
00553                 }
00554                     break;
00555                 case RESOLVER_INFO_TYPE_REJECT_INSTALL: {                       // p is scheduled to be installed, but this is not possible because of dependency problems.
00556                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00557                     // TranslatorExplanation %s = name of package,patch,...                             
00558                     what = str::form (_("Cannot install %s due to dependency problems"), whoShort.c_str());
00559                     details = misc_info->message() + "\n";
00560                     details += logAdditionalInfo(collector.additionalInfo, item);               
00561                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00562                     // Uninstall it; 
00563                     problem->addSolution (new ProblemSolutionUninstall (problem, item));
00564                     // currently no solution concerning "ignore" is available           
00565                     problems.push_back (problem);
00566                     problem_created = true;
00567                 }
00568                     break;
00569                 case RESOLVER_INFO_TYPE_INSTALL_TO_BE_UNINSTALLED: {    // Can't install p since it is already marked as needing to be uninstalled
00570                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00571                     // TranslatorExplanation %s = name of package,patch,...                             
00572                     what = misc_info->message() + "\n";
00573                     details = logAdditionalInfo(collector.additionalInfo, item);                
00574                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00575                     problem->addSolution (new ProblemSolutionInstall (problem, item)); // Install resolvable again
00576                     problems.push_back (problem);
00577                     problem_created = true;
00578                 }
00579                     break;
00580                 case RESOLVER_INFO_TYPE_INSTALL_UNNEEDED: {                     // Can't install p since it is does not apply to this system.
00581                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00582                     // TranslatorExplanation %s = name of package,patch,...                             
00583                     what = misc_info->message();
00584                     // no solution; it is only a info
00585                 }
00586                     break;
00587                 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.
00588                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00589                     // TranslatorExplanation %s = name of package,patch,...                             
00590                     what = str::form (_("Cannot install %s"), whoShort.c_str());
00591                     details = misc_info->message() + "\n";
00592                     details += logAdditionalInfo(collector.additionalInfo, item);
00593                     details += logAdditionalInfo(collector.additionalInfo, misc_info->other());                         
00594                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00595                     // Uninstall the item
00596                     ResStatus status = item.status();
00597                     string description = "";
00598                     if (status.isInstalled())
00599                         // TranslatorExplanation %s = name of package, patch, selection ...
00600                         description = str::form (_("delete %s"), ResolverInfo::toString (item).c_str());
00601                     else
00602                         // TranslatorExplanation %s = name of package, patch, selection ...     
00603                         description = str::form (_("do not install %s"), ResolverInfo::toString (item).c_str());
00604                     problem->addSolution (new ProblemSolutionUninstall (problem, item, description, ""));
00605                 
00606                     // Uninstall the other
00607                     status = misc_info->other().status();
00608                     if (status.isInstalled())
00609                         // TranslatorExplanation %s = name of package, patch, selection ...
00610                         description = str::form (_("delete %s"), ResolverInfo::toString (misc_info->other()).c_str());
00611                     else
00612                         // TranslatorExplanation %s = name of package, patch, selection ...     
00613                         description = str::form (_("do not install %s"), ResolverInfo::toString (misc_info->other()).c_str());          
00614                     problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other(), description, ""));
00615                 
00616                     // Ignore it
00617                     problem->addSolution (new ProblemSolutionIgnoreInstalled (problem, item, misc_info->other()));
00618                     problems.push_back (problem);
00619                     problem_created = true;             
00620                 }
00621                     break;
00622                 case RESOLVER_INFO_TYPE_INCOMPLETES: {                  // This would invalidate p
00623                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00624                     what = misc_info->message();
00625                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00626                     details = str::form (_("%s has unfulfilled requirements"), who.c_str())+ "\n";
00627                     details += logAdditionalInfo(collector.additionalInfo, item);               
00628                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00629                     // Uninstall 
00630                     problem->addSolution (new ProblemSolutionUninstall (problem, item));
00631                     problems.push_back (problem);
00632                     problem_created = true;             
00633                 }
00634                     break;
00635                     // from QueueItemEstablish
00636                 case RESOLVER_INFO_TYPE_ESTABLISHING: {                 // Establishing p
00637                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00638                     what = misc_info->message();
00639                     // no solution is needed cause it is only a progress indicator
00640                 }
00641                     break;
00642                     // from QueueItemInstall
00643                 case RESOLVER_INFO_TYPE_INSTALLING: {                   // Installing p
00644                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00645                     what = misc_info->message();
00646                     // no solution is needed cause it is only a progress indicator              
00647                 }
00648                     break;
00649                 case RESOLVER_INFO_TYPE_UPDATING: {                             // Updating p
00650                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00651                     what = misc_info->message();
00652                     // no solution is needed cause it is only a progress indicator              
00653                 }
00654                     break;
00655                 case RESOLVER_INFO_TYPE_SKIPPING: {                             // Skipping p, already installed
00656                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00657                     what = misc_info->message();
00658                     // It is only an info and happens while upgrading
00659                 }
00660                     break;
00661                     // from QueueItemRequire
00662                 case RESOLVER_INFO_TYPE_NO_OTHER_PROVIDER: {            // There are no alternative installed providers of c [for p]
00663                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00664                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00665                     what = str::form (_("%s has missing dependencies"), whoShort.c_str());
00666                     details = misc_info->message() + "\n";
00667                     details += logAdditionalInfo(collector.additionalInfo, item);                               
00668                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00669 
00670                     // Searching for another item which provides this requires BUT has been set to uninstall
00671                     for (ItemCapabilityMap::const_iterator it = collector.provideAndDeleteMap.begin();
00672                          it != collector.provideAndDeleteMap.end(); ++it) {
00673                         if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00674                             // Do not delete
00675                             problem->addSolution (new ProblemSolutionKeep (problem, it->first));
00676                         }
00677                     }
00678 
00679                     // Searching for another item which provides this requires BUT has been set to be kept
00680                     for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
00681                          it != collector.provideAndKeptMap.end(); ++it) {
00682                         if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00683                             // Do install
00684                             problem->addSolution (new ProblemSolutionInstall (problem, it->first));
00685                         }
00686                     }           
00687 
00688                     // uninstall
00689                     problem->addSolution (new ProblemSolutionUninstall (problem, item));
00690 
00691                     // Unflag require ONLY for this item
00692                     problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));          
00693 
00694                     // Unflag ALL require
00695                     // Evaluating all require Items
00696                     AllRequires info;
00697                     Dep dep( Dep::REQUIRES );
00698 
00699                     invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
00700                                   _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),   // end()
00701                                   resfilter::ByCapMatch( misc_info->capability() ),
00702                                   functor::functorRef<bool,CapAndItem>(info) );
00703                     if (info.requirers.size() > 1)
00704                         problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00705 
00706                     problems.push_back (problem);
00707                     problem_created = true;
00708                 }
00709                     break;
00710                 case RESOLVER_INFO_TYPE_NO_PROVIDER: {                  // There are no installable providers of c [for p]
00711                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00712                     if (item.status().isInstalled()) {
00713                         // TranslatorExplanation %s = name of package, patch, selection ...                             
00714                         what = str::form (_("%s has missing dependencies"), whoShort.c_str());
00715                     } else {
00716                         // TranslatorExplanation %s = name of package, patch, selection ...
00717                         what = str::form (_("%s cannot be installed due to missing dependencies"), whoShort.c_str());                   
00718                     }
00719                     details = misc_info->message() + "\n";
00720                     details += logAdditionalInfo(collector.additionalInfo, item);                               
00721                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00722                 
00723                     // Searching for another item which provides this requires BUT has been locked
00724                     for (ItemCapabilityMap::const_iterator it = collector.provideAndLockMap.begin();
00725                          it != collector.provideAndLockMap.end(); ++it) {
00726                         if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00727                             // unlock this item
00728                             problem->addSolution (new ProblemSolutionUnlock (problem, it->first));
00729                             // unlock ALL existing resolvables
00730                             problem->addSolution (new ProblemSolutionUnlock (problem, pool()));                 
00731                         }
00732                     }
00733                     // Searching for another item which provides this requires BUT has another architec
00734                     for (ItemCapabilityMap::const_iterator it = collector.provideAndOtherArchMap.begin();
00735                          it != collector.provideAndOtherArchMap.end(); ++it) {
00736                         if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00737                             // ignoring architecture
00738                             problem->addSolution (new ProblemSolutionIgnoreArchitecture (problem, it->first));
00739                         }
00740                     }
00741                     // Searching for another item which provides this requires BUT has another vendor
00742                     for (ItemCapabilityMap::const_iterator it = collector.provideAndOtherVendorMap.begin();
00743                          it != collector.provideAndOtherVendorMap.end(); ++it) {
00744                         if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00745                             // ignoring vendor
00746                             problem->addSolution (new ProblemSolutionIgnoreVendor (problem, it->first));
00747                         }
00748                     }               
00749                     // Searching for another item which provides this requires BUT has been set to be kept
00750                     for (ItemCapabilityMap::const_iterator it = collector.provideAndKeptMap.begin();
00751                          it != collector.provideAndKeptMap.end(); ++it) {
00752                         if (it->second.matches (misc_info->capability()) == CapMatch::yes) {
00753                             // Do install
00754                             problem->addSolution (new ProblemSolutionInstall (problem, it->first));
00755                         }
00756                     }           
00757                 
00758                     // uninstall
00759                     problem->addSolution (new ProblemSolutionUninstall (problem, item)); 
00760                     // ignore requirement
00761                     problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability())); 
00762                     problems.push_back (problem);
00763                     problem_created = true;             
00764                 }
00765                     break;
00766                 case RESOLVER_INFO_TYPE_NO_UPGRADE: {                   // Upgrade to q to avoid removing p is not possible.
00767                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00768                     what = misc_info->message();
00769                     // It is only an info --> no solution is needed             
00770                 }
00771                     break;
00772                 case RESOLVER_INFO_TYPE_UNINSTALL_PROVIDER: {           // p provides c but is scheduled to be uninstalled
00773                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00774                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00775                     what =str::form (_("%s fulfills dependencies of %s but will be uninstalled"),
00776                                      misc_info->other()->name().c_str(),
00777                                      whoShort.c_str());
00778                     details = misc_info->message();
00779                     // It is only an info --> no solution is needed
00780                 }
00781                     break;              
00782                 case RESOLVER_INFO_TYPE_KEEP_PROVIDER: {                // p provides c but is scheduled to be kept
00783                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00784                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00785                     what =str::form (_("%s fulfills dependencies of %s but will be kept on your system"),
00786                                      misc_info->other()->name().c_str(),
00787                                      whoShort.c_str());
00788                     details = misc_info->message();
00789                     // It is only an info --> no solution is needed
00790                 }               
00791                     break;
00792                 case RESOLVER_INFO_TYPE_PARALLEL_PROVIDER: {            // p provides c but another version is already installed
00793                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00794                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00795                     what = str::form (_("No need to install %s"), misc_info->other()->name().c_str());
00796                     details = misc_info->message();
00797                     // It is only an info --> no solution is needed             
00798                 }
00799                     break;
00800                 case RESOLVER_INFO_TYPE_NOT_INSTALLABLE_PROVIDER: {             // p provides c but is uninstallable
00801                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00802                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00803                     what = str::form (_("Cannot install %s to fulfill the dependencies of %s"),
00804                                       misc_info->other()->name().c_str(),
00805                                       whoShort.c_str());
00806                     details = misc_info->message();
00807                     // It is only an info --> no solution is needed             
00808                 }
00809                 case RESOLVER_INFO_TYPE_OTHER_ARCH_PROVIDER: {          // p provides c but has other architecture
00810                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00811                     what = misc_info->message();
00812                     // It is only an info --> no solution is needed             
00813                 }               
00814                     break;
00815                 case RESOLVER_INFO_TYPE_LOCKED_PROVIDER: {                      // p provides c but is locked
00816                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00817                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00818                     what = str::form (_("Cannot install %s to fulfil the dependencies of %s"),
00819                                       misc_info->other()->name().c_str(),
00820                                       whoShort.c_str());                                
00821                     what = misc_info->message();
00822                     // It is only an info --> no solution is needed             
00823                 }
00824                     break;
00825                 case RESOLVER_INFO_TYPE_CANT_SATISFY: {                 // Can't satisfy requirement c
00826                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00827                     what = misc_info->message() + "\n";
00828                     details = logAdditionalInfo(collector.additionalInfo, item);                                
00829                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00830                     // uninstall
00831                     problem->addSolution (new ProblemSolutionUninstall (problem, item)); 
00832                 
00833                     // Unflag requirement for this item
00834                     problem->addSolution (new ProblemSolutionIgnoreRequires (problem, item, misc_info->capability()));
00835                 
00836                     // Unflag ALL require
00837                     // Evaluating all require Items
00838                     AllRequires info;
00839                     Dep dep( Dep::REQUIRES );
00840 
00841                     invokeOnEach( _pool.byCapabilityIndexBegin( misc_info->capability().index(), dep ), // begin()
00842                                   _pool.byCapabilityIndexEnd( misc_info->capability().index(), dep ),   // end()
00843                                   resfilter::ByCapMatch( misc_info->capability() ),
00844                                   functor::functorRef<bool,CapAndItem>(info) );
00845                     if (info.requirers.size() > 1)
00846                         problem->addSolution (new ProblemSolutionIgnoreRequires (problem, info.requirers, misc_info->capability()));
00847                 
00848                     problems.push_back (problem);
00849                     problem_created = true;             
00850                 }
00851                     break;
00852                     // from QueueItemUninstall
00853                 case RESOLVER_INFO_TYPE_UNINSTALL_TO_BE_INSTALLED: {    // p is to-be-installed, so it won't be unlinked.
00854                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00855                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00856                     what = str::form (_("%s will not be uninstalled, because it is still required"), whoShort.c_str());
00857                     details = misc_info->message();
00858                     // It is only an info --> no solution is needed                             
00859                 }
00860                     break;
00861                 case RESOLVER_INFO_TYPE_UNINSTALL_INSTALLED: {          // p is required by installed, so it won't be unlinked.
00862                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00863                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00864                     what = str::form (_("%s will not be uninstalled, because it is still required"), whoShort.c_str());         
00865                     details = misc_info->message() + "\n";
00866                     details += logAdditionalInfo(collector.additionalInfo, item);                                               
00867 
00868                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00869                     if (item.status().isInstalled()) {
00870                         // keep installed
00871                         problem->addSolution (new ProblemSolutionKeep (problem, item));
00872                     } else {
00873                         // Do install
00874                         problem->addSolution (new ProblemSolutionInstall (problem, item));
00875                     }
00876                     problems.push_back (problem);
00877                     problem_created = true;
00878 
00879                 }
00880                     break;
00881                 case RESOLVER_INFO_TYPE_UNINSTALL_LOCKED: {                     // cant uninstall, its locked
00882                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00883                     what = misc_info->message();
00884                 
00885                     if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00886                         // TranslatorExplanation %s = name of package, patch, selection ...                                                 
00887                         details = str::form (_("%s obsoletes %s. But %s cannot be deleted, because it is locked."),
00888                                              misc_info->other()->name().c_str(),
00889                                              who.c_str(), who.c_str()) + "\n";
00890                         details += logAdditionalInfo(collector.additionalInfo, item);                                               
00891                     }
00892                 
00893                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00894                     problem->addSolution (new ProblemSolutionUnlock (problem, item)); // Unlocking resItem
00895                     // unlock ALL existing resolvables
00896                     problem->addSolution (new ProblemSolutionUnlock (problem, pool()));                                 
00897                     if (misc_info->trigger() == ResolverInfoMisc::OBSOLETE) {
00898                         // Ignore obsoletes
00899                         problem->addSolution (new ProblemSolutionIgnoreObsoletes (problem, item, misc_info->capability(),
00900                                                                                   misc_info->other())); 
00901                     } else {
00902                         // This is an "default" soltution
00903                         // keep installed
00904                         problem->addSolution (new ProblemSolutionKeep (problem, item));
00905                     }
00906                     problems.push_back (problem);
00907                     problem_created = true;
00908                 }
00909                     break;
00910                     // from QueueItemConflict
00911                 case RESOLVER_INFO_TYPE_CONFLICT_CANT_INSTALL: {                // to-be-installed p conflicts with q due to c
00912                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00913                     // TranslatorExplanation %s = name of package, patch, selection ...
00914                     if (misc_info->other())
00915                         what = str::form (_("Cannot install %s, because it is conflicting with %s"),
00916                                           whoShort.c_str(),
00917                                           misc_info->other()->name().c_str());
00918                     else
00919                         what = str::form (_("Cannot install %s, because it is conflicting"),
00920                                           whoShort.c_str());
00921                     details = misc_info->message() + "\n";
00922                     details += logAdditionalInfo(collector.additionalInfo, item);
00923                     if (misc_info->other())             
00924                         details += logAdditionalInfo(collector.additionalInfo, misc_info->other());
00925                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);          
00926                     // Uninstall p
00927                     problem->addSolution (new ProblemSolutionUninstall (problem, item));
00928                     if (misc_info->other())
00929                         // Uninstall q
00930                         problem->addSolution (new ProblemSolutionUninstall (problem, misc_info->other()));
00931                     // Remove conflict in the resolvable which has to be installed
00932                     problem->addSolution (new ProblemSolutionIgnoreConflicts (problem, item, misc_info->other_capability(),
00933                                                                               misc_info->other()));
00934                     problems.push_back (problem);
00935                     problem_created = true;
00936                 }
00937                     break;
00938                 case RESOLVER_INFO_TYPE_CONFLICT_UNINSTALLABLE: {               // uninstalled p is marked uninstallable it conflicts [with q] due to c
00939                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00940                     // TranslatorExplanation %s = name of package, patch, selection ...                         
00941                     what = str::form (_("%s is uninstallable due to conflicts with %s"),
00942                                       whoShort.c_str(),
00943                                       misc_info->other()->name().c_str());                              
00944                     details = misc_info->message();
00945                     // It is only an info --> no solution is needed
00946                 }
00947                     break;
00948             }
00949         } else {
00950             // No item available
00951             switch (info->type()) {
00952                 case RESOLVER_INFO_TYPE_NO_PROVIDER: {                  // There are no installable providers of c [for p]
00953                     ResolverInfoMisc_constPtr misc_info = dynamic_pointer_cast<const ResolverInfoMisc>(info);
00954                    // TranslatorExplanation %s = name requirement ...                           
00955                     what = str::form (_("Requirememt %s cannot be fulfilled."), misc_info->capability().asString().c_str());
00956                     details = misc_info->message() + "\n";
00957                     PoolItem_Ref item = misc_info->affected();
00958                     if (!item) 
00959                     {
00960                         // user request, get more details
00961                         string more_details = moreDetails( context, item );
00962                         details += more_details;
00963                     }
00964                     ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00965                     // ignore requirement
00966                     problem->addSolution (new ProblemSolutionIgnoreRequires (problem, PoolItem_Ref(), misc_info->capability())); 
00967                     problems.push_back (problem);
00968                     problem_created = true;             
00969                 }
00970                     break;
00971                 default:
00972                     ERR << "No item available for error:" << info << endl;
00973                     // but do not generate a default problem
00974                     problem_created = true;                                 
00975             }
00976         }
00977         if (!problem_created) {
00978             ResolverProblem_Ptr problem = new ResolverProblem (what, details);
00979             problems.push_back (problem);
00980         }
00981         
00982         if (problems.size() >= MAXPROBLEMS) {
00983             MIL << "Max problems reached: " << MAXPROBLEMS << ". Do not regarding the rest." << endl;
00984             break;
00985         }
00986         
00987     }
00988     if (problems.empty()) {
00989         context->spewInfo();
00990     }
00991     return problems;
00992 }
00993 
00994 void
00995 Resolver::applySolutions (const ProblemSolutionList & solutions)
00996 {
00997     for (ProblemSolutionList::const_iterator iter = solutions.begin();
00998          iter != solutions.end(); ++iter) {
00999         ProblemSolution_Ptr solution = *iter;
01000         if (!solution->apply (*this))
01001             break;
01002     }    
01003 }
01004 
01006     };// namespace detail
01009   };// namespace solver
01012 };// namespace zypp
01014 

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