00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "zypp/solver/detail/Types.h"
00023
00024 #include "zypp/solver/detail/QueueItemEstablish.h"
00025 #include "zypp/solver/detail/QueueItemInstall.h"
00026 #include "zypp/solver/detail/QueueItemRequire.h"
00027 #include "zypp/solver/detail/QueueItemConflict.h"
00028 #include "zypp/solver/detail/QueueItemUninstall.h"
00029 #include "zypp/solver/detail/QueueItem.h"
00030 #include "zypp/solver/detail/Helper.h"
00031 #include "zypp/solver/detail/ResolverContext.h"
00032 #include "zypp/solver/detail/ResolverInfoConflictsWith.h"
00033 #include "zypp/solver/detail/ResolverInfoNeededBy.h"
00034 #include "zypp/solver/detail/ResolverInfoMisc.h"
00035
00036 #include "zypp/CapSet.h"
00037 #include "zypp/base/Logger.h"
00038 #include "zypp/base/String.h"
00039 #include "zypp/base/Gettext.h"
00040
00042 namespace zypp
00043 {
00044
00045 namespace solver
00046 {
00047
00048 namespace detail
00049 {
00050
00051 using namespace std;
00052
00053 IMPL_PTR_TYPE(QueueItemEstablish);
00054
00055
00056
00057 std::ostream &
00058 QueueItemEstablish::dumpOn( std::ostream & os ) const
00059 {
00060 os <<"[Establish: ";
00061 os << _item;
00062 if (_explicitly_requested) os << ", Explicit !";
00063 os << "]";
00064 return os;
00065 }
00066
00067
00068
00069 QueueItemEstablish::QueueItemEstablish (const ResPool & pool, PoolItem_Ref item, bool soft)
00070 : QueueItem (QUEUE_ITEM_TYPE_ESTABLISH, pool)
00071 , _item(item)
00072 , _soft(soft)
00073 , _channel_priority (0)
00074 , _other_penalty (0)
00075 , _explicitly_requested (false)
00076 {
00077 _XDEBUG("QueueItemEstablish::QueueItemEstablish (" << item << ")");
00078
00079 }
00080
00081
00082 QueueItemEstablish::~QueueItemEstablish()
00083 {
00084 }
00085
00086
00087
00088 bool
00089 QueueItemEstablish::isSatisfied (ResolverContext_Ptr context) const
00090 {
00091 return context->isPresent (_item);
00092 }
00093
00094
00095
00096
00097
00098 bool
00099 QueueItemEstablish::process (const QueueItemList & mainQueue, ResolverContext_Ptr context, QueueItemList & qil)
00100 {
00101 _XDEBUG("QueueItemEstablish::process(" << *this << ")");
00102
00103 ResStatus status = context->getStatus(_item);
00104
00105 if (_item.status().isLocked()
00106 || status.isLocked()) {
00107 _XDEBUG("Item " << _item << " is locked. --> NO establish");
00108 return true;
00109 }
00110 if ( ! _item->arch().compatibleWith( context->architecture() ) ) {
00111 context->unneeded (_item, _other_penalty);
00112 _XDEBUG( _item << " has incompatible architecture, unneeded" );
00113 return true;
00114 }
00115
00116 _item.status().setUndetermined();
00117
00118 CapSet freshens = _item->dep(Dep::FRESHENS);
00119
00120 _XDEBUG("simple establish of " << _item << " with " << freshens.size() << " freshens");
00121
00122 ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_ESTABLISHING, _item, RESOLVER_INFO_PRIORITY_VERBOSE);
00123 context->addInfo (misc_info);
00124 logInfo (context);
00125
00126
00127
00128 CapSet::const_iterator iter;
00129 for (iter = freshens.begin(); iter != freshens.end(); iter++) {
00130 const Capability cap = *iter;
00131 bool dummy1, dummy2;
00132 if (context->requirementIsMet (cap, _item, Dep::FRESHENS, &dummy1, &dummy2, true)) {
00133 _XDEBUG("this freshens " << cap);
00134 break;
00135 }
00136 }
00137
00138
00139
00140
00141
00142
00143
00144 if (freshens.size() > 0
00145 && iter == freshens.end())
00146 {
00147 _XDEBUG(_item << " freshens nothing -> unneeded");
00148 if (_item->kind() != ResTraits<Package>::kind)
00149 context->unneeded (_item, _other_penalty);
00150 }
00151 else {
00152
00153 CapSet supplements = _item->dep(Dep::SUPPLEMENTS);
00154 if (supplements.size() != 0) {
00155 CapSet::const_iterator iter;
00156 for (iter = supplements.begin(); iter != supplements.end(); iter++) {
00157 const Capability cap = *iter;
00158 bool dummy1, dummy2;
00159 if (context->requirementIsMet (cap, _item, Dep::SUPPLEMENTS, &dummy1, &dummy2, true)) {
00160 _XDEBUG("this supplements " << cap);
00161 break;
00162 }
00163 }
00164 if (iter == supplements.end()) {
00165 _XDEBUG(_item << " none of the supplements match -> unneeded");
00166 if (_item->kind() != ResTraits<Package>::kind)
00167 context->unneeded (_item, _other_penalty);
00168 return true;
00169 }
00170
00171 PoolItem_Ref installed = Helper::findInstalledItem( pool(), _item );
00172 if (!installed
00173 && Helper::isBestUninstalledItem( pool(), _item ))
00174 {
00175
00176 _DEBUG("Uninstalled " << _item << " supplements " << *iter << " -> install");
00177 QueueItemInstall_Ptr install_item = new QueueItemInstall( pool(), _item, true );
00178 qil.push_front( install_item );
00179 return true;
00180 }
00181 }
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 CapSet requires = _item->dep(Dep::REQUIRES);
00200 Capability missing;
00201 bool all_unneeded = true;
00202 for (iter = requires.begin(); iter != requires.end(); iter++) {
00203 missing = *iter;
00204 bool unneeded;
00205 if (!context->requirementIsMet (missing, _item, Dep::REQUIRES, &unneeded)) {
00206 all_unneeded = false;
00207 break;
00208 }
00209 if (!unneeded) all_unneeded = false;
00210 }
00211 if (iter == requires.end()) {
00212 if (all_unneeded
00213 && _item->kind() == ResTraits<Patch>::kind)
00214 {
00215 _XDEBUG("all requirements of " << _item << " unneeded -> unneeded");
00216 context->unneeded( _item, _other_penalty );
00217 }
00218 else if (_item->kind() == ResTraits<Package>::kind)
00219 {
00220 PoolItem_Ref installed = Helper::findInstalledItem( pool(), _item );
00221 if (!installed
00222 && Helper::isBestUninstalledItem( pool(), _item ))
00223 {
00224
00225 _DEBUG("Uninstalled " << _item << " freshens -> install");
00226 QueueItemInstall_Ptr install_item = new QueueItemInstall( pool(), _item, true );
00227 qil.push_front( install_item );
00228 return true;
00229 }
00230 }
00231 else
00232 {
00233 _XDEBUG("all requirements of " << _item << " met -> satisfied");
00234 context->satisfy( _item, _other_penalty );
00235 }
00236 }
00237 else {
00238
00239 if ((_item->kind() == ResTraits<Patch>::kind
00240 || _item->kind() == ResTraits<Atom>::kind)
00241 || status.staysInstalled())
00242 {
00243 _XDEBUG("Atom/Patch/Installed/Establishing " << _item << " has unfulfilled requirement " << *iter << " -> incomplete");
00244 context->incomplete( _item, _other_penalty );
00245
00246
00247 if ( status.staysInstalled()
00248 &&!context->establishing()) {
00249
00250
00251
00252 QueueItemList::const_iterator iterQueue;
00253 for (iterQueue = mainQueue.begin(); iterQueue != mainQueue.end(); iterQueue++) {
00254 QueueItem_Ptr qitem = *iterQueue;
00255 if (qitem->isUninstall()) {
00256 QueueItemUninstall_Ptr uninstall = dynamic_pointer_cast<QueueItemUninstall>(qitem);
00257 if (uninstall->deletedItem() == _item) {
00258 _DEBUG(_item << " will be uninstalled later. So, we do not have to inform the user.");
00259 break;
00260 }
00261 }
00262 }
00263
00264 if (iterQueue == mainQueue.end()) {
00265 ResolverInfo_Ptr misc_info = new ResolverInfoMisc (RESOLVER_INFO_TYPE_INCOMPLETES, _item, RESOLVER_INFO_PRIORITY_VERBOSE);
00266 context->addError (misc_info);
00267 }
00268 }
00269 }
00270 else {
00271 _XDEBUG("Transacted " << _item << " has unfulfilled requirement " << *iter << " -> leave");
00272
00273 }
00274 }
00275 }
00276
00277 return true;
00278 }
00279
00280
00281 QueueItem_Ptr
00282 QueueItemEstablish::copy (void) const
00283 {
00284 QueueItemEstablish_Ptr new_install = new QueueItemEstablish (pool(), _item, _soft);
00285 new_install->QueueItem::copy(this);
00286
00287 new_install->_channel_priority = _channel_priority;
00288 new_install->_other_penalty = _other_penalty;
00289 new_install->_explicitly_requested = _explicitly_requested;
00290
00291 return new_install;
00292 }
00293
00294
00295 int
00296 QueueItemEstablish::cmp (QueueItem_constPtr item) const
00297 {
00298 int cmp = this->compare (item);
00299 if (cmp != 0)
00300 return cmp;
00301 QueueItemEstablish_constPtr establish = dynamic_pointer_cast<const QueueItemEstablish>(item);
00302 return compareByNVR(_item.resolvable(), establish->_item.resolvable());
00303 }
00304
00306 };
00309 };
00312 };