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