Add Selectable::locked (short for TABOO||PROTECED)
[platform/upstream/libzypp.git] / zypp / ui / SelectableImpl.h
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file       zypp/ui/SelectableImpl.h
10  *
11 */
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/ZConfig.h"
21 #include "zypp/ui/Selectable.h"
22 #include "zypp/ui/SelectableTraits.h"
23
24 using std::endl;
25
26 ///////////////////////////////////////////////////////////////////
27 namespace zypp
28 { /////////////////////////////////////////////////////////////////
29   ///////////////////////////////////////////////////////////////////
30   namespace ui
31   { /////////////////////////////////////////////////////////////////
32
33     ///////////////////////////////////////////////////////////////////
34     //
35     //  CLASS NAME : Selectable::Impl
36     //
37     /** Selectable implementation.
38      * \note Implementation is based in PoolItem, just the Selectable
39      * inteface restricts them to ResObject::constPtr.
40     */
41     struct Selectable::Impl
42     {
43     public:
44
45       typedef SelectableTraits::AvailableItemSet         AvailableItemSet;
46       typedef SelectableTraits::available_iterator       available_iterator;
47       typedef SelectableTraits::available_const_iterator available_const_iterator;
48       typedef SelectableTraits::available_size_type      available_size_type;
49
50       typedef SelectableTraits::InstalledItemSet         InstalledItemSet;
51       typedef SelectableTraits::installed_iterator       installed_iterator;
52       typedef SelectableTraits::installed_const_iterator installed_const_iterator;
53       typedef SelectableTraits::installed_size_type      installed_size_type;
54
55     public:
56       template <class _Iterator>
57       Impl( const ResObject::Kind & kind_r,
58             const std::string & name_r,
59             _Iterator begin_r,
60             _Iterator end_r )
61       : _ident( sat::Solvable::SplitIdent( kind_r, name_r ).ident() )
62       , _kind( kind_r )
63       , _name( name_r )
64       {
65         for_( it, begin_r, end_r )
66         {
67           if ( it->status().isInstalled() )
68             _installedItems.insert( *it );
69           else
70             _availableItems.insert( *it );
71         }
72         _defaultCandidate = defaultCandidate();
73       }
74
75     public:
76       /**  */
77       IdString ident() const
78       { return _ident; }
79
80       /**  */
81       ResObject::Kind kind() const
82       { return _kind; }
83
84       /**  */
85       const std::string & name() const
86       { return _name; }
87
88       /**  */
89       Status status() const;
90
91       /**  */
92       bool setStatus( const Status state_r, ResStatus::TransactByValue causer_r );
93
94       /** Installed object. */
95       PoolItem installedObj() const
96       {
97           if (!installedEmpty())
98               return *_installedItems.begin();
99           return PoolItem();
100       }
101
102       /** Best among available objects.
103        * The transacting candidate or the one scheduled to receive
104        * the transact bit.
105       */
106       PoolItem candidateObj() const
107       {
108         PoolItem ret( transactingCandidate() );
109         if ( ret )
110           return ret;
111         return _candidate ? _candidate : _defaultCandidate;
112       }
113
114       /** Set a userCandidate (out of available objects).
115        * \return The new userCandidate or NULL if choice was invalid
116        * (not among availableObjs).
117       */
118       PoolItem setCandidate( const PoolItem & newCandidate_r, ResStatus::TransactByValue causer_r );
119
120       /** The best candidate provided by a specific \ref Repository, if there is one.
121        * In contrary to \ref candidateObj, this may return no item even if
122        * there are available objects. This simply means the \ref Repository
123        * does not provide this object.
124        */
125       PoolItem candidateObjFrom( Repository repo_r ) const
126       {
127         for_( it, availableBegin(), availableEnd() )
128         {
129           if ( (*it)->repository() == repo_r )
130             return *it;
131         }
132         return PoolItem();
133       }
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         if ( installedEmpty() || ! _defaultCandidate )
144           return _defaultCandidate;
145         // Here: installed and _defaultCandidate are non NULL.
146
147         // update candidate must come from the highest priority repo
148         if ( _defaultCandidate->repoInfo().priority() != (*availableBegin())->repoInfo().priority() )
149           return PoolItem();
150
151         PoolItem installed( installedObj() );
152         // check vendor change
153         if ( ! ( ZConfig::instance().solver_allowVendorChange()
154                  || VendorAttr::instance().equivalent( _defaultCandidate->vendor(), installed->vendor() ) ) )
155           return PoolItem();
156
157         // check arch change
158         if ( _defaultCandidate->arch() != installed->arch() )
159           return PoolItem();
160
161         // check greater edition
162         if ( _defaultCandidate->edition() <= installed->edition() )
163           return PoolItem();
164
165         return _defaultCandidate;
166       }
167
168       /** \c True if \a rhs has the same content as an installed one.
169        * \see \ref sat::Solvable::identical
170        */
171       bool identicalInstalled( const PoolItem & rhs ) const
172       {
173         if ( !installedEmpty() && rhs )
174         {
175           for_( it, _installedItems.begin(), _installedItems.end() )
176           {
177             if ( identical( *it, rhs ) )
178               return true;
179           }
180         }
181         return false;
182       }
183
184       /** Best among all objects. */
185       PoolItem theObj() const
186       {
187         PoolItem ret( candidateObj() );
188         if (ret)
189             return ret;
190
191         if ( ! _installedItems.empty() )
192             return  (*_installedItems.begin());
193
194         return PoolItem();
195       }
196
197       ////////////////////////////////////////////////////////////////////////
198
199       bool availableEmpty() const
200       { return _availableItems.empty(); }
201
202       available_size_type availableSize() const
203       { return _availableItems.size(); }
204
205       available_const_iterator availableBegin() const
206       { return _availableItems.begin(); }
207
208       available_const_iterator availableEnd() const
209       { return _availableItems.end(); }
210
211       ////////////////////////////////////////////////////////////////////////
212
213       bool installedEmpty() const
214       { return _installedItems.empty(); }
215
216       installed_size_type installedSize() const
217       { return _installedItems.size(); }
218
219       installed_iterator installedBegin() const
220       { return _installedItems.begin(); }
221
222       installed_iterator installedEnd() const
223       { return _installedItems.end(); }
224
225       ////////////////////////////////////////////////////////////////////////
226
227       bool isUnmaintained() const
228       { return availableEmpty(); }
229
230       bool isUndetermined() const
231       {
232         PoolItem cand( candidateObj() );
233         return ! cand || cand.isUndetermined();
234       }
235       bool isRelevant() const
236       {
237         PoolItem cand( candidateObj() );
238         return cand && cand.isRelevant();
239       }
240       bool isSatisfied() const
241        {
242         PoolItem cand( candidateObj() );
243         return cand && cand.isSatisfied();
244       }
245       bool isBroken() const
246       {
247         PoolItem cand( candidateObj() );
248         return cand && cand.isBroken();
249       }
250
251       /** Return who caused the modification. */
252       ResStatus::TransactByValue modifiedBy() const;
253
254       /** Return value of LicenceConfirmed bit. */
255       bool hasLicenceConfirmed() const
256       { return candidateObj() && candidateObj().status().isLicenceConfirmed(); }
257
258       /** Set LicenceConfirmed bit. */
259       void setLicenceConfirmed( bool val_r )
260       { if ( candidateObj() ) candidateObj().status().setLicenceConfirmed( val_r ); }
261
262     private:
263       PoolItem transactingCandidate() const
264       {
265         for ( available_const_iterator it = availableBegin();
266               it != availableEnd(); ++it )
267           {
268             if ( (*it).status().transacts() )
269               return (*it);
270           }
271         return PoolItem();
272       }
273
274       PoolItem defaultCandidate() const
275       {
276         if ( !installedEmpty() )
277         {
278           // prefer the installed objects arch and vendor
279           bool solver_allowVendorChange( ZConfig::instance().solver_allowVendorChange() );
280           for ( installed_const_iterator iit = installedBegin();
281                 iit != installedEnd(); ++iit )
282           {
283             PoolItem sameArch; // in case there's no same vendor at least stay with same arch
284             for ( available_const_iterator it = availableBegin();
285                   it != availableEnd(); ++it )
286             {
287               if ( (*iit)->arch() == (*it)->arch() )
288               {
289                 if ( ! solver_allowVendorChange )
290                 {
291                   if ( VendorAttr::instance().equivalent( (*iit), (*it) ) )
292                     return *it;
293                   else if ( ! sameArch ) // remember best same arch in case no same vendor found
294                      sameArch = *it;
295                 }
296                 else // same arch is sufficient
297                   return *it;
298               }
299             }
300             if ( sameArch )
301               return sameArch;
302           }
303         }
304         if ( _availableItems.empty() )
305           return PoolItem();
306
307         return *_availableItems.begin();
308       }
309
310       bool allCandidatesLocked() const
311       {
312         for ( available_const_iterator it = availableBegin();
313               it != availableEnd(); ++it )
314           {
315             if ( ! (*it).status().isLocked() )
316               return false;
317           }
318         return( ! _availableItems.empty() );
319       }
320
321     private:
322       const IdString         _ident;
323       const ResObject::Kind  _kind;
324       const std::string      _name;
325       InstalledItemSet       _installedItems;
326       AvailableItemSet       _availableItems;
327       //! Best among availabe with restpect to installed.
328       PoolItem               _defaultCandidate;
329
330       //! The object selected by setCandidateObj() method.
331       PoolItem               _candidate;
332     };
333     ///////////////////////////////////////////////////////////////////
334
335     /** \relates Selectable::Impl Stream output */
336     inline std::ostream & operator<<( std::ostream & str, const Selectable::Impl & obj )
337     {
338       return str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status()
339                  << " (I " << obj.installedSize() << ")"
340                  << " (A " << obj.availableSize() << ")"
341                  << obj.candidateObj();
342     }
343
344     /** \relates Selectable::Impl Stream output */
345     inline std::ostream & dumpOn( std::ostream & str, const Selectable::Impl & obj )
346     {
347       str << '[' << obj.kind() << ']' << obj.name() << ": " << obj.status() << endl;
348       if ( obj.candidateObj() )
349         str << "(C " << obj.candidateObj() << ")" << endl;
350       else
351         str << "(C NONE )" << endl;
352       dumpRange( str << "  (I " << obj.installedSize() << ") ", obj.installedBegin(), obj.installedEnd() );
353       if ( obj.installedEmpty() )
354         str << endl << " ";
355       dumpRange( str << " (A " << obj.availableSize() << ") ", obj.availableBegin(), obj.availableEnd() ) << endl;
356
357       return str;
358     }
359     /////////////////////////////////////////////////////////////////
360   } // namespace ui
361   ///////////////////////////////////////////////////////////////////
362   /////////////////////////////////////////////////////////////////
363 } // namespace zypp
364 ///////////////////////////////////////////////////////////////////
365 #endif // ZYPP_UI_SELECTABLEIMPL_H