libzypp  11.13.5
SelectableImpl.h
Go to the documentation of this file.
1 /*---------------------------------------------------------------------\
2 | ____ _ __ __ ___ |
3 | |__ / \ / / . \ . \ |
4 | / / \ V /| _/ _/ |
5 | / /__ | | | | | | |
6 | /_____||_| |_| |_| |
7 | |
8 \---------------------------------------------------------------------*/
12 #ifndef ZYPP_UI_SELECTABLEIMPL_H
13 #define ZYPP_UI_SELECTABLEIMPL_H
14 
15 #include <iostream>
16 #include "zypp/base/LogTools.h"
17 
18 #include "zypp/base/PtrTypes.h"
19 
20 #include "zypp/ResPool.h"
21 #include "zypp/Resolver.h"
22 #include "zypp/ui/Selectable.h"
24 
25 using std::endl;
26 
28 namespace zypp
29 {
30 
31  namespace ui
32  {
33 
35  //
36  // CLASS NAME : Selectable::Impl
37  //
43  {
44  public:
45 
50 
55 
57 
58  public:
59  template <class _Iterator>
60  Impl( const ResObject::Kind & kind_r,
61  const std::string & name_r,
62  _Iterator begin_r,
63  _Iterator end_r )
64  : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
65  , _kind( kind_r )
66  , _name( name_r )
67  {
68  for_( it, begin_r, end_r )
69  {
70  if ( it->status().isInstalled() )
71  _installedItems.insert( *it );
72  else
73  _availableItems.insert( *it );
74  }
75  }
76 
77  public:
79  IdString ident() const
80  { return _ident; }
81 
84  { return _kind; }
85 
87  const std::string & name() const
88  { return _name; }
89 
91  Status status() const;
92 
94  bool setStatus( Status state_r, ResStatus::TransactByValue causer_r );
95 
98  {
99  if ( installedEmpty() )
100  return PoolItem();
102  return ret ? ret : *_installedItems.begin();
103  }
104 
110  {
112  if ( ret )
113  return ret;
115  }
116 
121  PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r );
122 
129  {
130  for_( it, availableBegin(), availableEnd() )
131  {
132  if ( (*it)->repository() == repo_r )
133  return *it;
134  }
135  return PoolItem();
136  }
137 
145  {
146  PoolItem defaultCand( defaultCandidate() );
147 
148  if ( multiversionInstall() )
149  return identicalInstalled( defaultCand ) ? PoolItem() : defaultCand;
150 
151  if ( installedEmpty() || ! defaultCand )
152  return defaultCand;
153  // Here: installed and defaultCand are non NULL and it's not a
154  // multiversion install.
155 
156  PoolItem installed( installedObj() );
157  // check vendor change
158  if ( ! ( ResPool::instance().resolver().allowVendorChange()
159  || VendorAttr::instance().equivalent( defaultCand->vendor(), installed->vendor() ) ) )
160  return PoolItem();
161 
162  // check arch change (arch noarch changes are allowed)
163  if ( defaultCand->arch() != installed->arch()
164  && ! ( defaultCand->arch() == Arch_noarch || installed->arch() == Arch_noarch ) )
165  return PoolItem();
166 
167  // check greater edition
168  if ( defaultCand->edition() <= installed->edition() )
169  return PoolItem();
170 
171  return defaultCand;
172  }
173 
176  {
177  PoolItem ret;
178  for_( it, availableBegin(), availableEnd() )
179  {
180  if ( !ret || (*it).satSolvable().edition() > ret.satSolvable().edition() )
181  ret = *it;
182  }
183  return ret;
184  }
185 
187  bool identicalAvailable( const PoolItem & rhs ) const
188  { return identicalAvailableObj( rhs ); }
189 
191  bool identicalInstalled( const PoolItem & rhs ) const
192  { return identicalInstalledObj( rhs ); }
193 
196  {
197  if ( !availableEmpty() && rhs )
198  {
199  for_( it, _availableItems.begin(), _availableItems.end() )
200  {
201  if ( identical( *it, rhs ) )
202  return *it;
203  }
204  }
205  return PoolItem();
206  }
207 
210  {
211  if ( !installedEmpty() && rhs )
212  {
213  for_( it, _installedItems.begin(), _installedItems.end() )
214  {
215  if ( identical( *it, rhs ) )
216  return *it;
217  }
218  }
219  return PoolItem();
220  }
221 
223  PoolItem theObj() const
224  {
225  PoolItem ret( candidateObj() );
226  if ( ret )
227  return ret;
228  return installedObj();
229  }
230 
232 
233  bool availableEmpty() const
234  { return _availableItems.empty(); }
235 
237  { return _availableItems.size(); }
238 
240  { return _availableItems.begin(); }
241 
243  { return _availableItems.end(); }
244 
246 
247  bool installedEmpty() const
248  { return _installedItems.empty(); }
249 
251  { return _installedItems.size(); }
252 
254  { return _installedItems.begin(); }
255 
257  { return _installedItems.end(); }
258 
260 
261  const PickList & picklist() const
262  {
263  if ( ! _picklistPtr )
264  {
265  _picklistPtr.reset( new PickList );
266  // installed without identical avaialble first:
267  for_( it, _installedItems.begin(), _installedItems.end() )
268  {
269  if ( ! identicalAvailable( *it ) )
270  _picklistPtr->push_back( *it );
271  }
272  _picklistPtr->insert( _picklistPtr->end(), availableBegin(), availableEnd() );
273  }
274  return *_picklistPtr;
275  }
276 
277  bool picklistEmpty() const
278  { return picklist().empty(); }
279 
281  { return picklist().size(); }
282 
284  { return picklist().begin(); }
285 
287  { return picklist().end(); }
288 
290 
291  bool isUnmaintained() const
292  { return availableEmpty(); }
293 
294  bool multiversionInstall() const
295  { return sat::Pool::instance().isMultiversion( ident() ); }
296 
297  bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
298 
299  bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r, bool yesno_r );
300 
301  Status pickStatus( const PoolItem & pi_r ) const;
302 
303  bool setPickStatus( const PoolItem & pi_r, Status state_r, ResStatus::TransactByValue causer_r );
304 
306 
307  bool isUndetermined() const
308  {
309  PoolItem cand( candidateObj() );
310  return ! cand || cand.isUndetermined();
311  }
312  bool isRelevant() const
313  {
314  PoolItem cand( candidateObj() );
315  return cand && cand.isRelevant();
316  }
317  bool isSatisfied() const
318  {
319  PoolItem cand( candidateObj() );
320  return cand && cand.isSatisfied();
321  }
322  bool isBroken() const
323  {
324  PoolItem cand( candidateObj() );
325  return cand && cand.isBroken();
326  }
327 
330 
332  bool hasLicenceConfirmed() const
333  { return candidateObj() && candidateObj().status().isLicenceConfirmed(); }
334 
336  void setLicenceConfirmed( bool val_r )
337  { if ( candidateObj() ) candidateObj().status().setLicenceConfirmed( val_r ); }
338 
339  private:
341  {
342  for_( it, installedBegin(), installedEnd() )
343  {
344  if ( (*it).status().transacts() )
345  return (*it);
346  }
347  return PoolItem();
348  }
349 
351  {
352  for_( it, availableBegin(), availableEnd() )
353  {
354  if ( (*it).status().transacts() )
355  return (*it);
356  }
357  return PoolItem();
358  }
359 
361  {
362  if ( ! ( multiversionInstall() || installedEmpty() ) )
363  {
364  // prefer the installed objects arch and vendor
365  bool solver_allowVendorChange( ResPool::instance().resolver().allowVendorChange() );
367  iit != installedEnd(); ++iit )
368  {
369  PoolItem sameArch; // in case there's no same vendor at least stay with same arch.
371  it != availableEnd(); ++it )
372  {
373  // 'same arch' includes allowed changes to/from noarch.
374  if ( (*iit)->arch() == (*it)->arch() || (*iit)->arch() == Arch_noarch || (*it)->arch() == Arch_noarch )
375  {
376  if ( ! solver_allowVendorChange )
377  {
378  if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
379  return *it;
380  else if ( ! sameArch ) // remember best same arch in case no same vendor found
381  sameArch = *it;
382  }
383  else // same arch is sufficient
384  return *it;
385  }
386  }
387  if ( sameArch )
388  return sameArch;
389  }
390  }
391  if ( _availableItems.empty() )
392  return PoolItem();
393 
394  return *_availableItems.begin();
395  }
396 
397  bool allCandidatesLocked() const
398  {
400  it != availableEnd(); ++it )
401  {
402  if ( ! (*it).status().isLocked() )
403  return false;
404  }
405  return( ! _availableItems.empty() );
406  }
407 
408  bool allInstalledLocked() const
409  {
411  it != installedEnd(); ++it )
412  {
413  if ( ! (*it).status().isLocked() )
414  return false;
415  }
416  return( ! _installedItems.empty() );
417  }
418 
419 
420  private:
423  const std::string _name;
429  mutable scoped_ptr<PickList> _picklistPtr;
430  };
432 
434  inline std::ostream & operator<<( std::ostream & str, const Selectable::Impl & obj )
435  {
436  return str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
437  << " (I " << obj.installedSize() << ")"
438  << " (A " << obj.availableSize() << ")"
439  << obj.candidateObj();
440  }
441 
443  inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
444  {
445  str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
446  << ( obj.multiversionInstall() ? " (multiversion)" : "") << endl;
447 
448  if ( obj.installedEmpty() )
449  str << " (I 0) {}" << endl << " ";
450  else
451  {
452  PoolItem icand( obj.installedObj() );
453  str << " (I " << obj.installedSize() << ") {" << endl;
454  for_( it, obj.installedBegin(), obj.installedEnd() )
455  {
456  char t = ' ';
457  if ( *it == icand )
458  {
459  t = 'i';
460  }
461  str << " " << t << " " << *it << endl;
462  }
463  str << "} ";
464  }
465 
466  if ( obj.availableEmpty() )
467  {
468  str << "(A 0) {}" << endl << " ";
469  }
470  else
471  {
472  PoolItem cand( obj.candidateObj() );
473  PoolItem up( obj.updateCandidateObj() );
474  str << "(A " << obj.availableSize() << ") {" << endl;
475  for_( it, obj.availableBegin(), obj.availableEnd() )
476  {
477  char t = ' ';
478  if ( *it == cand )
479  {
480  t = *it == up ? 'C' : 'c';
481  }
482  else if ( *it == up )
483  {
484  t = 'u';
485  }
486  str << " " << t << " " << *it << endl;
487  }
488  str << "} ";
489  }
490 
491  if ( obj.picklistEmpty() )
492  {
493  str << "(P 0) {}";
494  }
495  else
496  {
497  PoolItem cand( obj.candidateObj() );
498  PoolItem up( obj.updateCandidateObj() );
499  str << "(P " << obj.picklistSize() << ") {" << endl;
500  for_( it, obj.picklistBegin(), obj.picklistEnd() )
501  {
502  char t = ' ';
503  if ( *it == cand )
504  {
505  t = *it == up ? 'C' : 'c';
506  }
507  else if ( *it == up )
508  {
509  t = 'u';
510  }
511  str << " " << t << " " << *it << "\t" << obj.pickStatus( *it ) << endl;
512  }
513  str << "} ";
514  }
515 
516  return str;
517  }
519  } // namespace ui
522 } // namespace zypp
524 #endif // ZYPP_UI_SELECTABLEIMPL_H