Relax evaluation of patch category tags (case insensitive)
[platform/upstream/libzypp.git] / zypp / Patch.cc
1 /*---------------------------------------------------------------------\
2 |                          ____ _   __ __ ___                          |
3 |                         |__  / \ / / . \ . \                         |
4 |                           / / \ V /|  _/  _/                         |
5 |                          / /__ | | | | | |                           |
6 |                         /_____||_| |_| |_|                           |
7 |                                                                      |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/Patch.cc
10  *
11 */
12 #include <iostream>
13
14 #include "zypp/base/LogTools.h"
15 #include "zypp/base/String.h"
16 #include "zypp/Patch.h"
17 #include "zypp/sat/WhatProvides.h"
18
19 using std::endl;
20
21 ///////////////////////////////////////////////////////////////////
22 namespace zypp
23 { /////////////////////////////////////////////////////////////////
24
25   IMPL_PTR_TYPE( Patch );
26
27   ///////////////////////////////////////////////////////////////////
28   //
29   //    METHOD NAME : Patch::Patch
30   //    METHOD TYPE : Ctor
31   //
32   Patch::Patch( const sat::Solvable & solvable_r )
33   : ResObject( solvable_r )
34   {}
35
36   ///////////////////////////////////////////////////////////////////
37   //
38   //    METHOD NAME : Patch::~Patch
39   //    METHOD TYPE : Dtor
40   //
41   Patch::~Patch()
42   {}
43
44   ///////////////////////////////////////////////////////////////////
45   //
46   //    Patch interface forwarded to implementation
47   //
48   ///////////////////////////////////////////////////////////////////
49
50   Patch::Category Patch::categoryEnum() const
51   {
52     std::string cat( category() );
53     switch ( cat[0] )
54     {
55       //        CAT_YAST
56       case 'y':
57       case 'Y':
58         if ( str::compareCI( cat, "yast" ) == 0 )
59           return CAT_YAST;
60         break;
61
62       //        CAT_SECURITY
63       case 's':
64       case 'S':
65         if ( str::compareCI( cat, "security" ) == 0 )
66           return CAT_SECURITY;
67         break;
68
69       //        CAT_RECOMMENDED
70       case 'r':
71       case 'R':
72         if ( str::compareCI( cat, "recommended" ) == 0 )
73           return CAT_RECOMMENDED;
74         break;
75       case 'b':
76       case 'B':
77         if ( str::compareCI( cat, "bugfix" ) == 0 )     // rhn
78           return CAT_RECOMMENDED;
79         break;
80
81       //        CAT_OPTIONAL
82       case 'o':
83       case 'O':
84         if ( str::compareCI( cat, "optional" ) == 0 )
85           return CAT_OPTIONAL;
86         break;
87       case 'f':
88       case 'F':
89         if ( str::compareCI( cat, "feature" ) == 0 )
90           return CAT_OPTIONAL;
91         break;
92       case 'e':
93       case 'E':
94         if ( str::compareCI( cat, "enhancement" ) == 0 )        // rhn
95           return CAT_OPTIONAL;
96         break;
97
98       //        CAT_DOCUMENT
99       case 'd':
100       case 'D':
101         if ( str::compareCI( cat, "document" ) == 0 )
102           return CAT_DOCUMENT;
103         break;
104     }
105     // default:
106     return CAT_OTHER;
107   }
108
109   std::string Patch::severity() const
110   { return lookupStrAttribute( sat::SolvAttr::severity ); }
111
112   Patch::SeverityFlag Patch::severityFlag() const
113   {
114     std::string sev( severity() );
115     switch ( sev[0] )
116     {
117       case 'l':
118       case 'L':
119         if ( str::compareCI( sev, "low" ) == 0 )
120           return SEV_LOW;
121         break;
122
123       case 'm':
124       case 'M':
125         if ( str::compareCI( sev, "moderate" ) == 0 )
126           return SEV_MODERATE;
127         break;
128
129       case 'i':
130       case 'I':
131         if ( str::compareCI( sev, "important" ) == 0 )
132           return SEV_IMPORTANT;
133         break;
134
135       case 'c':
136       case 'C':
137         if ( str::compareCI( sev, "critical" ) == 0 )
138           return SEV_CRITICAL;
139         break;
140
141       case '\0':
142         return SEV_NONE;
143         break;
144     }
145     // default:
146     return SEV_OTHER;
147   }
148
149   std::string asString( const Patch::SeverityFlag & obj )
150   {
151     switch ( obj )
152     {
153       case Patch::SEV_NONE:     return std::string( "unspecified" );    break;
154       case Patch::SEV_OTHER:    return std::string( "unknown" );        break;
155       case Patch::SEV_LOW:      return std::string( "low" );            break;
156       case Patch::SEV_MODERATE: return std::string( "moderate" );       break;
157       case Patch::SEV_IMPORTANT:return std::string( "important" );      break;
158       case Patch::SEV_CRITICAL: return std::string( "critical" );       break;
159     }
160     // make gcc happy:
161     return std::string( "unknown" );
162   }
163
164   std::string Patch::message( const Locale & lang_r ) const
165   { return lookupStrAttribute( sat::SolvAttr::message, lang_r ); }
166
167   std::string Patch::category() const
168   { return lookupStrAttribute( sat::SolvAttr::patchcategory ); }
169
170   bool Patch::rebootSuggested() const
171   { return lookupBoolAttribute( sat::SolvAttr::rebootSuggested ); }
172
173   bool Patch::restartSuggested() const
174   { return lookupBoolAttribute( sat::SolvAttr::restartSuggested ); }
175
176   bool Patch::reloginSuggested() const
177   { return lookupBoolAttribute( sat::SolvAttr::reloginSuggested ); }
178
179   Patch::InteractiveFlags Patch::interactiveFlags() const
180   {
181     InteractiveFlags patchFlags (NoFlags);
182     if ( rebootSuggested() )
183       patchFlags |= Reboot;
184
185     if ( ! message().empty() )
186       patchFlags |= Message;
187
188     if ( ! licenseToConfirm().empty() )
189       patchFlags |= License;
190
191     Patch::Contents c( contents() );
192     for_( it, c.begin(), c.end() )
193     {
194       if ( ! makeResObject(*it)->licenseToConfirm().empty() )
195       {
196         patchFlags |= License;
197         break;
198       }
199     }
200     return patchFlags;
201   }
202
203   bool Patch::interactiveWhenIgnoring( InteractiveFlags flags_r ) const
204   {
205     if ( interactiveFlags() & ( ~flags_r ) )
206     {
207       return true;
208     }
209     else
210     {
211       return false;
212     }
213   }
214
215   bool Patch::interactive() const
216   {
217     return interactiveWhenIgnoring();
218   }
219
220   Patch::Contents Patch::contents() const
221   {
222     Contents result;
223     // DBG << *this << endl;
224     sat::LookupAttr updateCollection( sat::SolvAttr::updateCollection, satSolvable() );
225     for_( entry, updateCollection.begin(), updateCollection.end() )
226     {
227       IdString name    ( entry.subFind( sat::SolvAttr::updateCollectionName ).idStr() );
228       Edition  edition ( entry.subFind( sat::SolvAttr::updateCollectionEvr ).idStr() );
229       Arch     arch    ( entry.subFind( sat::SolvAttr::updateCollectionArch ).idStr() );
230       if ( name.empty() )
231       {
232         WAR << "Ignore malformed updateCollection entry: " << name << "-" << edition << "." << arch << endl;
233         continue;
234       }
235
236       // The entry is relevant if there is an installed
237       // package with the same name and arch.
238       bool relevant = false;
239       sat::WhatProvides providers( (Capability( name.id() )) );
240       for_( it, providers.begin(), providers.end() )
241       {
242         if ( it->isSystem() && it->ident() == name && it->arch() == arch )
243         {
244           relevant = true;
245           break;
246         }
247       }
248       if ( ! relevant )
249       {
250         // DBG << "Not relevant: " << name << "-" << edition << "." << arch << endl;
251         continue;
252       }
253
254       /* find exact providers first (this matches the _real_ 'collection content' of the patch */
255       providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::EQ, edition, ResKind::package ) );
256       if ( providers.empty() )
257       {
258         /* no exact providers: find 'best' providers: those with a larger evr */
259         providers = sat::WhatProvides( Capability( arch, name.c_str(), Rel::GT, edition, ResKind::package ) );
260         if ( providers.empty() )
261         {
262           // Hmm, this patch is not installable, no one is providing the package in the collection
263           // FIXME: raise execption ? fake a solvable ?
264           WAR << "Missing provider: " << name << "-" << edition << "." << arch << endl;
265           continue;
266         }
267       }
268
269       // FIXME ?! loop over providers and try to find installed ones ?
270       // DBG << "Found " << name << "-" << edition << "." << arch << ": " << *(providers.begin()) << endl;
271       result.get().insert( *(providers.begin()) );
272     }
273
274     return result;
275   }
276
277   ///////////////////////////////////////////////////////////////////
278   //
279   //    CLASS NAME : Patch::ReferenceIterator
280   //
281   ///////////////////////////////////////////////////////////////////
282
283   Patch::ReferenceIterator::ReferenceIterator( const sat::Solvable & val_r )
284   { base_reference() = sat::LookupAttr( sat::SolvAttr::updateReference, val_r ).begin(); }
285
286   std::string Patch::ReferenceIterator::id() const
287   { return base_reference().subFind( sat::SolvAttr::updateReferenceId ).asString(); }
288   std::string Patch::ReferenceIterator::href() const
289   { return base_reference().subFind( sat::SolvAttr::updateReferenceHref ).asString(); }
290   std::string Patch::ReferenceIterator::title() const
291   { return base_reference().subFind( sat::SolvAttr::updateReferenceTitle ).asString(); }
292   std::string Patch::ReferenceIterator::type() const
293   { return base_reference().subFind( sat::SolvAttr::updateReferenceType ).asString(); }
294
295   /////////////////////////////////////////////////////////////////
296 } // namespace zypp
297 ///////////////////////////////////////////////////////////////////