Add Selectable::highestAvailableVersionObj. (bnc #557557)
[platform/upstream/libzypp.git] / zypp / ui / Selectable.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ui/Selectable.h
10  *
11 */
12 #ifndef ZYPP_UI_SELECTABLE_H
13 #define ZYPP_UI_SELECTABLE_H
14
15 #include <iosfwd>
16
17 #include "zypp/base/ReferenceCounted.h"
18 #include "zypp/base/NonCopyable.h"
19 #include "zypp/base/PtrTypes.h"
20 #include "zypp/base/Iterator.h"
21
22 #include "zypp/ui/SelectableTraits.h"
23 #include "zypp/ui/Status.h"
24
25 ///////////////////////////////////////////////////////////////////
26 namespace zypp
27 { /////////////////////////////////////////////////////////////////
28
29   ///////////////////////////////////////////////////////////////////
30   namespace ui
31   { /////////////////////////////////////////////////////////////////
32
33     DEFINE_PTR_TYPE(Selectable);
34
35     ///////////////////////////////////////////////////////////////////
36     //
37     //  CLASS NAME : Selectable
38     //
39     /** Collects PoolItems of same kind and name.
40      *
41      * Selectable is a status wrapper. The ui::Status is calculated
42      * from (and transated to) \ref PoolItems individual \ref ResStatus
43      * values.
44      *
45      * Available objects are sorted according the solver policies, 'best'
46      * packages first (e.g. by repository priority, then Arch, then Edition).
47      *
48      * Installed objects are sorted according the installation date, newer install
49      * time first.
50     */
51     class Selectable : public base::ReferenceCounted, private base::NonCopyable
52     {
53       friend std::ostream & operator<<( std::ostream & str, const Selectable & obj );
54       friend std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
55
56     public:
57       typedef intrusive_ptr<Selectable>        Ptr;
58       typedef intrusive_ptr<const Selectable>  constPtr;
59
60       /** Iterates over ResObject::constPtr */
61       typedef SelectableTraits::available_iterator      available_iterator;
62       typedef SelectableTraits::available_size_type     available_size_type;
63
64       typedef SelectableTraits::installed_iterator      installed_iterator;
65       typedef SelectableTraits::installed_size_type     installed_size_type;
66
67     public:
68       /** \name Static ctor substitues picking the item from the pool.
69        * \code
70        * Selectable::Ptr item;
71        * item = Selectable::get( "amarok );                  // package amamrok
72        * item = Selectable::get( ResKind::patch, "amarok );  // patch amamrok
73        * item = Selectable::get( IdString( "patch:amarok" ); // patch amamrok
74        * \endcode
75       */
76       //@{
77       /** Get the \ref Selctable */
78       static Ptr get( const pool::ByIdent & ident_r );
79
80       /** Get the \ref Selctable by it's \c sat-identifyer. */
81       static Ptr get( IdString ident_r )
82       { return get( pool::ByIdent( ident_r ) ); }
83
84       /** Get the \ref Selctable by \c kind and \c name. */
85       static Ptr get( ResKind kind_r, const std::string & name_r )
86       { return get( pool::ByIdent( kind_r, name_r ) ); }
87
88       /** Get the \c Package \ref Selctable by \c name. */
89       static Ptr get( const std::string & name_r )
90       { return get( pool::ByIdent( ResKind::package, name_r ) ); }
91
92       /** Get the \ref Selctable containing a specific \ref sat::Solvable. */
93       static Ptr get( const sat::Solvable & solv_r )
94       { return get( pool::ByIdent( solv_r ) ); }
95
96       /** Get the \ref Selctable containing a specific \ref ResObject. */
97       static Ptr get( const ResObject::constPtr & resolvable_r )
98       { return resolvable_r ? get( resolvable_r->satSolvable() ) : Ptr(); }
99
100       /** Get the \ref Selctable containing a specific \ref PoolItem. */
101       static Ptr get( const PoolItem & pi_r )
102       { return get( pi_r.satSolvable() ); }
103       //@}
104
105     public:
106       /** The identifier.
107        * This is the solvables \ref name, \b except for packages and
108        * source packes, prefixed by it's \ref kind.
109        * \see \ref sat::Solvable.
110        */
111       IdString ident() const;
112
113       /** The ResObjects kind. */
114       ResObject::Kind kind() const;
115
116       /** The ResObjects name.  */
117       const std::string & name() const;
118
119       /** The last Installed object. */
120       PoolItem installedObj() const;
121
122       /** The 'best' or 'most interesting' among all available objects.
123        * One that is, or is likely to be, chosen for installation, unless
124        * it violated any solver policy (see \ref updateCandidateObj).
125        */
126       PoolItem candidateObj() const;
127
128       /** The best candidate provided by a specific \ref Repository, if there is one.
129        * In contrary to \ref candidateObj, this may return no item even if
130        * there are available objects. This simply means the \ref Repository
131        * does not provide this object.
132        */
133       PoolItem candidateObjFrom( Repository repo_r ) const;
134
135       /** The best candidate for update, if there is one.
136        * In contrary to \ref candidateObj, this may return no item even if
137        * there are available objects. This simply means the best object is
138        * already installed, and all available objects violate at least one
139        * update policy.
140        */
141       PoolItem updateCandidateObj() const;
142
143       /** Simply the highest available version, ignoring priorities and policies.
144        * It's doubtful whether solely looking at the version makes a good
145        * candidate, but apps ask for it. Beware that different vendors may
146        * use different (uncomparable) version schemata.
147        */
148       PoolItem highestAvailableVersionObj() const;
149
150       /** \c True if \a rhs has the same content as an installed one.
151        *  Basically the same name, edition, arch, vendor and buildtime.
152        * \see \ref sat::Solvable::identical
153        */
154       bool identicalInstalled( const PoolItem & rhs ) const;
155
156       /** \c True if the \ref candidateObj is installed (same content).
157        * \see \ref identicalInstalled.
158        */
159       bool identicalInstalledCandidate() const
160       { return identicalInstalled( candidateObj() ); }
161
162       /** \c True if the \ref updateCandidateObj is installed (same content).
163        * \see \ref identicalInstalled.
164        */
165       bool identicalInstalledUpdateCandidate() const
166       { return identicalInstalled( updateCandidateObj() ); }
167
168
169       /** Return the \ref installedObj resolvable casted to a specific kind.
170        * \code
171        *   Selectable mySelectable;
172        *   Package::constPtr p( mySelectable.installedAsKind<Package>() );
173        * \endcode
174       */
175       template<class _Res>
176       typename ResTraits<_Res>::constPtrType installedAsKind() const
177       { return asKind<_Res>( candidateObj() ); }
178
179       /** Return the \ref candidateObj resolvable casted to a specific kind.
180        * \code
181        *   Selectable mySelectable;
182        *   Package::constPtr p( mySelectable.candidateAsKind<Package>() );
183        * \endcode
184       */
185       template<class _Res>
186       typename ResTraits<_Res>::constPtrType candidateAsKind() const
187       { return asKind<_Res>( candidateObj() ); }
188
189       /** Set a candidate (out of available objects).
190        * \return The new candidate, or NULL if choice was invalid
191        * (NULL or not among availableObjs). An invalid choice
192        * selects the default candidate.
193        * In case the causer is not \c ResStatus::USER the operation
194        * may also fail if there are insufficient permissions to change
195        * a transacting candidate.
196        */
197       PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
198       /** \overload */
199       PoolItem setCandidate( ResObject::constPtr newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
200
201       /** Arrange the specified candidate (out of available objects) to be on system after commit.
202        * If the specified candidate is not already installed (\ref identicalInstalled),
203        * and the \a causer_r has sufficient permisssion, then \a newCandidate_r is set as the new
204        * candidate (\ref setCandidate) and selected for installation.
205        * \returns \c True if \a newCandidate_r is already installed or sucessfully selected for installation.
206        */
207       bool setOnSystem( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
208
209       /** An object you could use as pars pro toto.
210        *
211        * \return the \ref candidateObj, or ,if no available objects
212        * exist, the \ref installedObj.
213        */
214       PoolItem theObj() const;
215
216       ////////////////////////////////////////////////////////////////////////
217
218       /** \name Available objects iterators.
219        * Oredered according to solver policy. 'Best' first.
220       */
221       //@{
222       bool availableEmpty() const;
223       available_size_type availableSize() const;
224       available_iterator availableBegin() const;
225       available_iterator availableEnd() const;
226       //@}
227
228       ////////////////////////////////////////////////////////////////////////
229
230       /** \name Insatlled objects iterators.
231        * Ordered by install time. Latest first.
232       */
233       //@{
234       bool installedEmpty() const;
235       installed_size_type installedSize() const;
236       installed_iterator installedBegin() const;
237       installed_iterator installedEnd() const;
238       //}
239
240       ////////////////////////////////////////////////////////////////////////
241
242     public:
243       /** \name Query for objects within this Selectable.
244       */
245       //@{
246       /** True if either installed or candidate object is present */
247       bool hasObject() const
248       { return (! installedEmpty()) || candidateObj(); }
249
250       /** True if installed object is present. */
251       bool hasInstalledObj() const
252       { return ! installedEmpty(); }
253
254       /** True if candidate object is present. */
255       bool hasCandidateObj() const
256       { return candidateObj(); }
257
258       /** True if installed and candidate object is present */
259       bool hasBothObjects() const
260       { return (! installedEmpty()) && candidateObj(); }
261
262       /** True if installed object is present but no candidate. */
263       bool hasInstalledObjOnly() const
264       { return (! installedEmpty()) && ! candidateObj(); }
265
266       /** True if candidate object is present but no installed. */
267       bool hasCandidateObjOnly() const
268       { return ( installedEmpty() ) && candidateObj(); }
269       //@}
270
271       /**
272        * True if this package has no replacement from
273        * the available repositories
274        */
275       bool isUnmaintained() const;
276
277       /** \name Multiversion install.
278        *
279        * Using \ref pickInstall or \ref pickDelete with non-multiversionInstall items
280        * is possible, but additional constraints will apply. E.g. selecting one item for
281        * install will deselect any other.
282        */
283       //@{
284       /** Whether different versions of this package can be installed at the same time.
285        * Per default \c false. \see also \ref ZConfig::multiversion.
286        */
287       bool multiversionInstall() const;
288
289       /** Select a specific available item for installation.
290        */
291       bool pickInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
292
293       /** Deselect a specific available item from installation.
294       */
295       bool pickNoInstall( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
296       { return pickInstall( pi_r, causer_r, false ); }
297
298       /** Select a specific installed item for deletion.
299        */
300       bool pickDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER, bool yesno_r = true );
301
302       /** Deselect a specific installed item from deletion.
303        */
304       bool pickNoDelete( const PoolItem & pi_r, ResStatus::TransactByValue causer_r = ResStatus::USER )
305       { return pickDelete( pi_r, causer_r, false ); }
306       //@}
307
308       /** \name Classification of available patches (pseudo installed items).
309        * A patch is either \c not \c relevant, \c satisfied or \c broken.
310        * The same applies to other pseudo installed kinds.
311        * \see \ref traits::isPseudoInstalled
312        */
313       //@{
314       /** Returns true for packages, because packages are not
315        * classified by the solver.
316       */
317       bool isUndetermined() const;
318
319       /** Returns true if the patch is relevant which means that at least
320        *  one package of the patch is installed.
321        */
322       bool isRelevant() const;
323
324       /** Whether a relevant patchs requirements are met. */
325       bool isSatisfied() const;
326
327       /** Whether a relevant patchs requirements are broken. */
328       bool isBroken() const;
329
330       /** This includes still broken patches, as well as those already
331        *  selected to be installed.
332        * This is because already selected patches will be classified as
333        * \c satisfied.
334        */
335       bool isNeeded() const;
336       //@}
337
338      public:
339       /** \name Query and maip objects fate in case of commit.
340       */
341       //@{
342       enum Fate {
343         TO_DELETE  = -1,
344         UNMODIFIED = 0,
345         TO_INSTALL = 1
346       };
347       /**  */
348       Fate fate() const;
349
350       /** True if neither to delete or to install */
351       bool unmodified() const
352       { return fate() == UNMODIFIED; }
353
354       /** True if locked (subclass of unmodified). */
355       bool locked() const
356       { Status st( status() ); return( st == S_Protected || st == S_Taboo ); }
357
358       /** True if either to delete or to install */
359       bool toModify() const
360       { return fate() != UNMODIFIED; }
361
362       /** True if to delete */
363       bool toDelete() const
364       { return fate() == TO_DELETE; }
365
366       /** True if to install */
367       bool toInstall() const
368       { return fate() == TO_INSTALL; }
369
370       /** True if would be on system after commit. */
371       bool onSystem() const
372       { return( ( hasInstalledObj() && !toDelete() )
373               ||( hasCandidateObj() && toInstall() ) ); }
374
375       /** True if would be off system after commit. */
376       bool offSystem() const
377       { return ! onSystem(); }
378
379       /** */
380       bool setFate( Fate fate_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
381
382       /** Set the item to be installed (new- or re-install). */
383       bool setToInstall( ResStatus::TransactByValue causer_r = ResStatus::USER )
384       { return setFate( TO_INSTALL, causer_r ); }
385
386       /** Take care the item gets installed if it is not. */
387       bool setInstalled( ResStatus::TransactByValue causer_r = ResStatus::USER );
388
389       /** Take care the item gets installed if it is not, or is older. */
390       bool setUpToDate( ResStatus::TransactByValue causer_r = ResStatus::USER );
391
392       /** Set the item to be deleted (must be installed). */
393       bool setToDelete( ResStatus::TransactByValue causer_r = ResStatus::USER )
394       { return setFate( TO_DELETE, causer_r ); }
395
396       /** Take care the item gets deleted if it is installed. */
397       bool setDeleted( ResStatus::TransactByValue causer_r = ResStatus::USER );
398
399       /** Set the item to stay unmodified. */
400       bool unset( ResStatus::TransactByValue causer_r = ResStatus::USER )
401       { return setFate( UNMODIFIED, causer_r ); }
402       //@}
403
404     public:
405       /**
406        * \name Special inteface for Y2UI.
407        * \note This interface acts on \ref ResStatus::USER level.
408        * The \ref Status enum, and allowed state transitions are
409        * tightly related to the Y2UI.
410       */
411       //@{
412       /** Return the current Status */
413       Status status() const;
414
415       /**
416        * Try to set a new Status.
417        * Returns \c false if the transitions is not allowed.
418        */
419       bool setStatus( const Status state_r, ResStatus::TransactByValue causer_r = ResStatus::USER );
420
421       /** Return who caused the modification. */
422       ResStatus::TransactByValue modifiedBy() const;
423
424       /** Return value of LicenceConfirmed bit. */
425       bool hasLicenceConfirmed() const;
426
427       /** Set LicenceConfirmed bit. */
428       void setLicenceConfirmed( bool val_r = true );
429       //@}
430
431     public:
432       /** Implementation  */
433       class Impl;
434       typedef shared_ptr<Impl> Impl_Ptr;
435       /** Default ctor */
436       Selectable( Impl_Ptr pimpl_r );
437     private:
438       /** Dtor */
439       ~Selectable();
440     private:
441       /** Pointer to implementation */
442       RW_pointer<Impl> _pimpl;
443     };
444     ///////////////////////////////////////////////////////////////////
445
446     /** \relates Selectable Stream output */
447     std::ostream & operator<<( std::ostream & str, const Selectable & obj );
448
449     /** \relates Selectable More verbose stream output */
450     std::ostream & dumpOn( std::ostream & str, const Selectable & obj );
451
452     /** Solvable to Selectable transform functor.
453      * \relates Selectable
454      * \relates sat::SolvIterMixin
455      */
456     struct asSelectable
457     {
458       typedef Selectable_Ptr result_type;
459
460       Selectable_Ptr operator()( const sat::Solvable & solv_r ) const;
461
462       Selectable_Ptr operator()( const PoolItem & pi_r ) const
463       { return operator()( pi_r.satSolvable() ); }
464     };
465
466     /////////////////////////////////////////////////////////////////
467   } // namespace ui
468   ///////////////////////////////////////////////////////////////////
469   /////////////////////////////////////////////////////////////////
470 } // namespace zypp
471 ///////////////////////////////////////////////////////////////////
472 #endif // ZYPP_UI_SELECTABLE_H