- add some debug, and sorry but my emacs ate the evil tabs, I can't split the commit
[platform/upstream/libzypp.git] / zypp / Patch.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Patch.cc
10  *
11 */
12
13 #include "zypp/base/Logger.h"
14 #include "zypp/Patch.h"
15 #include "zypp/Message.h"
16
17 using std::endl;
18
19 ///////////////////////////////////////////////////////////////////
20 namespace zypp
21 { /////////////////////////////////////////////////////////////////
22
23   IMPL_PTR_TYPE( Patch );
24
25   ///////////////////////////////////////////////////////////////////
26   //
27   //    METHOD NAME : Patch::Patch
28   //    METHOD TYPE : Ctor
29   //
30   Patch::Patch( const sat::Solvable & solvable_r )
31   : ResObject( solvable_r )
32   {}
33
34   ///////////////////////////////////////////////////////////////////
35   //
36   //    METHOD NAME : Patch::~Patch
37   //    METHOD TYPE : Dtor
38   //
39   Patch::~Patch()
40   {}
41
42   ///////////////////////////////////////////////////////////////////
43   //
44   //    Patch interface forwarded to implementation
45   //
46   ///////////////////////////////////////////////////////////////////
47
48   std::string Patch::category() const
49   { return lookupStrAttribute( sat::SolvAttr::patchcategory ); }
50
51   bool Patch::reboot_needed() const
52   { return lookupBoolAttribute( sat::SolvAttr::needReboot ); }
53
54   bool Patch::affects_pkg_manager() const
55   { return lookupBoolAttribute( sat::SolvAttr::needRestart ); }
56
57   bool Patch::interactive() const
58   {
59     if ( reboot_needed()
60          || ! licenseToConfirm().empty() )
61     {
62       return true;
63     }
64
65     Patch::Contents c( contents() );
66     for_( it, c.begin(), c.end() )
67     {
68       if ( it->isKind( ResKind::message )
69            || ! licenseToConfirm().empty() )
70       {
71         return true;
72       }
73     }
74
75     return false;
76   }
77
78
79   Patch::Contents Patch::contents() const
80   {
81     Contents result;
82     sat::LookupAttr::iterator _col_name_it(sat::LookupAttr( sat::SolvAttr::updateCollectionName, *this ).begin());
83     sat::LookupAttr::iterator _col_evr_it(sat::LookupAttr( sat::SolvAttr::updateCollectionEvr, *this ).begin());
84     sat::LookupAttr::iterator _col_arch_it(sat::LookupAttr( sat::SolvAttr::updateCollectionArch, *this ).begin());
85
86     for (;_col_name_it != sat::LookupAttr( sat::SolvAttr::updateCollectionName, *this ).end(); ++_col_name_it, ++_col_evr_it, ++_col_arch_it)
87     {
88       /* safety checks, shouldn't happen (tm) */
89       if (_col_evr_it == sat::LookupAttr( sat::SolvAttr::updateCollectionEvr, *this ).end()
90           || _col_arch_it == sat::LookupAttr( sat::SolvAttr::updateCollectionArch, *this ).end())
91       {
92           /* FIXME: Raise exception ?! */
93           ERR << *this << " : The thing that should not happen, happened." << endl;
94           break;
95       }
96
97       IdString nameid( _col_name_it.asString() ); /* IdString for fast compare */
98       Arch arch( _col_arch_it.asString() );
99       
100       /* search providers of name */
101       sat::WhatProvides providers( Capability( _col_name_it.asString() ) );
102       MIL << *this << " providers: " << endl;
103       MIL << providers << endl;
104       
105       if (providers.empty())
106       {
107           WAR << *this << " misses provider for '" << _col_name_it.asString() << "'" << endl;
108           continue;
109       }
110       
111       bool is_relevant = false;
112       for_( it, providers.begin(), providers.end() )
113       {
114           if (it->ident() != nameid) /* package _name_ must match */
115               continue;
116         
117           if (it->isSystem()  /* only look at installed providers with same arch */
118               && it->arch() == arch)
119           {
120               is_relevant = true;
121           }
122       }
123       if (!is_relevant)
124       {
125           MIL << *this << " is not relevant to the system" << endl;
126           
127           continue;        /* skip if name.arch is not installed */
128       }
129       
130
131       /* find exact providers first (this matches the _real_ 'collection content' of the patch */
132       sat::WhatProvides exact_providers( Capability( _col_name_it.asString(), Rel::EQ, _col_evr_it.asString(), ResKind::package ) );
133       if (exact_providers.empty())
134       {
135           /* no exact providers: find 'best' providers */
136           sat::WhatProvides best_providers( Capability( _col_name_it.asString(), Rel::GT, _col_evr_it.asString(), ResKind::package ) );
137           if (best_providers.empty())
138           {
139               // Hmm, this patch is not installable, noone is providing the package in the collection
140               // raise execption ? fake a solvable ?
141           }
142           else
143           {
144               // FIXME ?! loop over providers and try to find installed ones ?
145               result.get().insert( *(best_providers.begin()) );
146           }
147       }
148       else
149       {
150           // FIXME ?! loop over providers and try to find installed ones ?
151           result.get().insert( *(exact_providers.begin()) );
152       }
153     } /* while (attribute array) */
154
155     return result;
156   }
157
158
159   ///////////////////////////////////////////////////////////////////
160   //
161   //    CLASS NAME : Patch::ReferenceIterator
162   //
163   ///////////////////////////////////////////////////////////////////
164
165   Patch::ReferenceIterator::ReferenceIterator( const sat::Solvable & val_r )
166   {
167     base_reference() = sat::LookupAttr( sat::SolvAttr::updateReferenceId,
168                    val_r ).begin();
169     _hrefit = sat::LookupAttr( sat::SolvAttr::updateReferenceHref,
170                                val_r ).begin();
171     _titleit = sat::LookupAttr( sat::SolvAttr::updateReferenceTitle,
172                                 val_r ).begin();
173     _typeit = sat::LookupAttr( sat::SolvAttr::updateReferenceType,
174                                val_r ).begin();
175   }
176
177
178   std::string Patch::ReferenceIterator::id() const
179   { return base_reference().asString(); }
180   std::string Patch::ReferenceIterator::href() const
181   { return _hrefit.asString(); }
182   std::string Patch::ReferenceIterator::title() const
183   { return _titleit.asString(); }
184   std::string Patch::ReferenceIterator::type() const
185   { return _typeit.asString(); }
186
187
188   void  Patch::ReferenceIterator::increment()
189   {
190     ++base_reference();
191     ++_hrefit;
192     ++_titleit;
193     ++_typeit;
194   }
195
196   /////////////////////////////////////////////////////////////////
197 } // namespace zypp
198 ///////////////////////////////////////////////////////////////////