SelectableImpl.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00012 #ifndef ZYPP_UI_SELECTABLEIMPL_H
00013 #define ZYPP_UI_SELECTABLEIMPL_H
00014
00015 #include <iostream>
00016 #include "zypp/base/LogTools.h"
00017
00018 #include "zypp/base/PtrTypes.h"
00019
00020 #include "zypp/ResPool.h"
00021 #include "zypp/Resolver.h"
00022 #include "zypp/ui/Selectable.h"
00023 #include "zypp/ui/SelectableTraits.h"
00024
00025 using std::endl;
00026
00028 namespace zypp
00029 {
00030
00031 namespace ui
00032 {
00033
00035
00036
00037
00042 struct Selectable::Impl
00043 {
00044 public:
00045
00046 typedef SelectableTraits::AvailableItemSet AvailableItemSet;
00047 typedef SelectableTraits::available_iterator available_iterator;
00048 typedef SelectableTraits::available_const_iterator available_const_iterator;
00049 typedef SelectableTraits::available_size_type available_size_type;
00050
00051 typedef SelectableTraits::InstalledItemSet InstalledItemSet;
00052 typedef SelectableTraits::installed_iterator installed_iterator;
00053 typedef SelectableTraits::installed_const_iterator installed_const_iterator;
00054 typedef SelectableTraits::installed_size_type installed_size_type;
00055
00056 typedef SelectableTraits::PickList PickList;
00057
00058 public:
00059 template <class _Iterator>
00060 Impl( const ResObject::Kind & kind_r,
00061 const std::string & name_r,
00062 _Iterator begin_r,
00063 _Iterator end_r )
00064 : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
00065 , _kind( kind_r )
00066 , _name( name_r )
00067 {
00068 for_( it, begin_r, end_r )
00069 {
00070 if ( it->status().isInstalled() )
00071 _installedItems.insert( *it );
00072 else
00073 _availableItems.insert( *it );
00074 }
00075 }
00076
00077 public:
00079 IdString ident() const
00080 { return _ident; }
00081
00083 ResObject::Kind kind() const
00084 { return _kind; }
00085
00087 const std::string & name() const
00088 { return _name; }
00089
00091 Status status() const;
00092
00094 bool setStatus( Status state_r, ResStatus::TransactByValue causer_r );
00095
00097 PoolItem installedObj() const
00098 {
00099 if ( installedEmpty() )
00100 return PoolItem();
00101 PoolItem ret( transactingInstalled() );
00102 return ret ? ret : *_installedItems.begin();
00103 }
00104
00109 PoolItem candidateObj() const
00110 {
00111 PoolItem ret( transactingCandidate() );
00112 if ( ret )
00113 return ret;
00114 return _candidate ? _candidate : defaultCandidate();
00115 }
00116
00121 PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r );
00122
00128 PoolItem candidateObjFrom( Repository repo_r ) const
00129 {
00130 for_( it, availableBegin(), availableEnd() )
00131 {
00132 if ( (*it)->repository() == repo_r )
00133 return *it;
00134 }
00135 return PoolItem();
00136 }
00137
00144 PoolItem updateCandidateObj() const
00145 {
00146 PoolItem defaultCand( defaultCandidate() );
00147
00148 if ( multiversionInstall() )
00149 return identicalInstalled( defaultCand ) ? PoolItem() : defaultCand;
00150
00151 if ( installedEmpty() || ! defaultCand )
00152 return defaultCand;
00153
00154
00155
00156
00157 if ( defaultCand->repoInfo().priority() != (*availableBegin())->repoInfo().priority() )
00158 return PoolItem();
00159
00160 PoolItem installed( installedObj() );
00161
00162 if ( ! ( ResPool::instance().resolver().allowVendorChange()
00163 || VendorAttr::instance().equivalent( defaultCand->vendor(), installed->vendor() ) ) )
00164 return PoolItem();
00165
00166
00167 if ( defaultCand->arch() != installed->arch()
00168 && ! ( defaultCand->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
00169 return PoolItem();
00170
00171
00172 if ( defaultCand->edition() <= installed->edition() )
00173 return PoolItem();
00174
00175 return defaultCand;
00176 }
00177
00179 PoolItem highestAvailableVersionObj() const
00180 {
00181 PoolItem ret;
00182 for_( it, availableBegin(), availableEnd() )
00183 {
00184 if ( !ret || (*it).satSolvable().edition() > ret.satSolvable().edition() )
00185 ret = *it;
00186 }
00187 return ret;
00188 }
00189
00191 bool identicalAvailable( const PoolItem & rhs ) const
00192 { return identicalAvailableObj( rhs ); }
00193
00195 bool identicalInstalled( const PoolItem & rhs ) const
00196 { return identicalInstalledObj( rhs ); }
00197
00199 PoolItem identicalAvailableObj( const PoolItem & rhs ) const
00200 {
00201 if ( !availableEmpty() && rhs )
00202 {
00203 for_( it, _availableItems.begin(), _availableItems.end() )
00204 {
00205 if ( identical( *it, rhs ) )
00206 return *it;
00207 }
00208 }
00209 return PoolItem();
00210 }
00211
00213 PoolItem identicalInstalledObj( const PoolItem & rhs ) const
00214 {
00215 if ( !installedEmpty() && rhs )
00216 {
00217 for_( it, _installedItems.begin(), _installedItems.end() )
00218 {
00219 if ( identical( *it, rhs ) )
00220 return *it;
00221 }
00222 }
00223 return PoolItem();
00224 }
00225
00227 PoolItem theObj() const
00228 {
00229 PoolItem ret( candidateObj() );
00230 if ( ret )
00231 return ret;
00232 return installedObj();
00233 }
00234
00236
00237 bool availableEmpty() const
00238 { return _availableItems.empty(); }
00239
00240 available_size_type availableSize() const
00241 { return _availableItems.size(); }
00242
00243 available_const_iterator availableBegin() const
00244 { return _availableItems.begin(); }
00245
00246 available_const_iterator availableEnd() const
00247 { return _availableItems.end(); }
00248
00250
00251 bool installedEmpty() const
00252 { return _installedItems.empty(); }
00253
00254 installed_size_type installedSize() const
00255 { return _installedItems.size(); }
00256
00257 installed_iterator installedBegin() const
00258 { return _installedItems.begin(); }
00259
00260 installed_iterator installedEnd() const
00261 { return _installedItems.end(); }
00262
00264
00265 const PickList & picklist() const
00266 {
00267 if ( ! _picklistPtr )
00268 {
00269 _picklistPtr.reset( new PickList );
00270
00271 for_( it, _installedItems.begin(), _installedItems.end() )
00272 {
00273 if ( ! identicalAvailable( *it ) )
00274 _picklistPtr->push_back( *it );
00275 }
00276 _picklistPtr->insert( _picklistPtr->end(), availableBegin(), availableEnd() );
00277 }
00278 return *_picklistPtr;
00279 }
00280
00281 bool picklistEmpty() const
00282 { return picklist().empty(); }
00283
00284 picklist_size_type picklistSize() const
00285 { return picklist().size(); }
00286
00287 picklist_iterator picklistBegin() const
00288 { return picklist().begin(); }
00289
00290 picklist_iterator picklistEnd() const
00291 { return picklist().end(); }
00292
00294
00295 bool isUnmaintained() const
00296 { return availableEmpty(); }
00297
00298 bool multiversionInstall() const
00299 { return sat::Pool::instance().isMultiversion( ident() ); }
00300
00301 bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
00302
00303 bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
00304
00305 Status pickStatus( const PoolItem & pi_r ) const;
00306
00307 bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r );
00308
00310
00311 bool isUndetermined() const
00312 {
00313 PoolItem cand( candidateObj() );
00314 return ! cand || cand.isUndetermined();
00315 }
00316 bool isRelevant() const
00317 {
00318 PoolItem cand( candidateObj() );
00319 return cand && cand.isRelevant();
00320 }
00321 bool isSatisfied() const
00322 {
00323 PoolItem cand( candidateObj() );
00324 return cand && cand.isSatisfied();
00325 }
00326 bool isBroken() const
00327 {
00328 PoolItem cand( candidateObj() );
00329 return cand && cand.isBroken();
00330 }
00331
00333 ResStatus::TransactByValue modifiedBy() const;
00334
00336 bool hasLicenceConfirmed() const
00337 { return candidateObj() && candidateObj().status().isLicenceConfirmed(); }
00338
00340 void setLicenceConfirmed( bool val_r )
00341 { if ( candidateObj() ) candidateObj().status().setLicenceConfirmed( val_r ); }
00342
00343 private:
00344 PoolItem transactingInstalled() const
00345 {
00346 for_( it, installedBegin(), installedEnd() )
00347 {
00348 if ( (*it).status().transacts() )
00349 return (*it);
00350 }
00351 return PoolItem();
00352 }
00353
00354 PoolItem transactingCandidate() const
00355 {
00356 for_( it, availableBegin(), availableEnd() )
00357 {
00358 if ( (*it).status().transacts() )
00359 return (*it);
00360 }
00361 return PoolItem();
00362 }
00363
00364 PoolItem defaultCandidate() const
00365 {
00366 if ( ! ( multiversionInstall() || installedEmpty() ) )
00367 {
00368
00369 bool solver_allowVendorChange( ResPool::instance().resolver().allowVendorChange() );
00370 for ( installed_const_iterator iit = installedBegin();
00371 iit != installedEnd(); ++iit )
00372 {
00373 PoolItem sameArch;
00374 for ( available_const_iterator it = availableBegin();
00375 it != availableEnd(); ++it )
00376 {
00377
00378 if ( (*iit)->arch() == (*it)->arch() || (*iit)->arch() == Arch_noarch || (*it)->arch() == Arch_noarch )
00379 {
00380 if ( ! solver_allowVendorChange )
00381 {
00382 if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
00383 return *it;
00384 else if ( ! sameArch )
00385 sameArch = *it;
00386 }
00387 else
00388 return *it;
00389 }
00390 }
00391 if ( sameArch )
00392 return sameArch;
00393 }
00394 }
00395 if ( _availableItems.empty() )
00396 return PoolItem();
00397
00398 return *_availableItems.begin();
00399 }
00400
00401 bool allCandidatesLocked() const
00402 {
00403 for ( available_const_iterator it = availableBegin();
00404 it != availableEnd(); ++it )
00405 {
00406 if ( ! (*it).status().isLocked() )
00407 return false;
00408 }
00409 return( ! _availableItems.empty() );
00410 }
00411
00412 bool allInstalledLocked() const
00413 {
00414 for ( installed_const_iterator it = installedBegin();
00415 it != installedEnd(); ++it )
00416 {
00417 if ( ! (*it).status().isLocked() )
00418 return false;
00419 }
00420 return( ! _installedItems.empty() );
00421 }
00422
00423
00424 private:
00425 const IdString _ident;
00426 const ResObject::Kind _kind;
00427 const std::string _name;
00428 InstalledItemSet _installedItems;
00429 AvailableItemSet _availableItems;
00431 PoolItem _candidate;
00433 mutable scoped_ptr<PickList> _picklistPtr;
00434 };
00436
00438 inline std::ostream & operator<<( std::ostream & str, const Selectable::Impl & obj )
00439 {
00440 return str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
00441 << " (I " << obj.installedSize() << ")"
00442 << " (A " << obj.availableSize() << ")"
00443 << obj.candidateObj();
00444 }
00445
00447 inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
00448 {
00449 str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
00450 << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl;
00451
00452 if ( obj.installedEmpty() )
00453 str << " (I 0) {}" << endl << " ";
00454 else
00455 {
00456 PoolItem icand( obj.installedObj() );
00457 str << " (I " << obj.installedSize() << ") {" << endl;
00458 for_( it, obj.installedBegin(), obj.installedEnd() )
00459 {
00460 char t = ' ';
00461 if ( *it == icand )
00462 {
00463 t = 'i';
00464 }
00465 str << " " << t << " " << *it << endl;
00466 }
00467 str << "} ";
00468 }
00469
00470 if ( obj.availableEmpty() )
00471 {
00472 str << "(A 0) {}" << endl << " ";
00473 }
00474 else
00475 {
00476 PoolItem cand( obj.candidateObj() );
00477 PoolItem up( obj.updateCandidateObj() );
00478 str << "(A " << obj.availableSize() << ") {" << endl;
00479 for_( it, obj.availableBegin(), obj.availableEnd() )
00480 {
00481 char t = ' ';
00482 if ( *it == cand )
00483 {
00484 t = *it == up ? 'C' : 'c';
00485 }
00486 else if ( *it == up )
00487 {
00488 t = 'u';
00489 }
00490 str << " " << t << " " << *it << endl;
00491 }
00492 str << "} ";
00493 }
00494
00495 if ( obj.picklistEmpty() )
00496 {
00497 str << "(P 0) {}";
00498 }
00499 else
00500 {
00501 PoolItem cand( obj.candidateObj() );
00502 PoolItem up( obj.updateCandidateObj() );
00503 str << "(P " << obj.picklistSize() << ") {" << endl;
00504 for_( it, obj.picklistBegin(), obj.picklistEnd() )
00505 {
00506 char t = ' ';
00507 if ( *it == cand )
00508 {
00509 t = *it == up ? 'C' : 'c';
00510 }
00511 else if ( *it == up )
00512 {
00513 t = 'u';
00514 }
00515 str << " " << t << " " << *it << "\t" << obj.pickStatus( *it ) << endl;
00516 }
00517 str << "} ";
00518 }
00519
00520 return str;
00521 }
00523 }
00526 }
00528 #endif // ZYPP_UI_SELECTABLEIMPL_H