VendorAttr.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <iostream>
00020 #include <fstream>
00021 #include <set>
00022 #include <map>
00023 #include <vector>
00024
00025 #include "zypp/base/LogTools.h"
00026 #include "zypp/base/IOStream.h"
00027 #include "zypp/base/String.h"
00028
00029 #include "zypp/PathInfo.h"
00030 #include "zypp/VendorAttr.h"
00031 #include "zypp/ZYppFactory.h"
00032
00033 #include "zypp/ZConfig.h"
00034 #include "zypp/PathInfo.h"
00035 #include "zypp/parser/IniDict.h"
00036
00037 using namespace std;
00038
00039 #undef ZYPP_BASE_LOGGER_LOGGROUP
00040 #define ZYPP_BASE_LOGGER_LOGGROUP "zypp::VendorAttr"
00041
00043 namespace zypp
00044 {
00045
00047 namespace
00048 {
00049
00050 typedef map<Vendor,unsigned int> VendorMap;
00051 VendorMap _vendorMap;
00052 unsigned int vendorGroupCounter;
00053
00055 }
00057
00059 namespace
00060 {
00061 typedef DefaultIntegral<int,0> VendorMatchEntry;
00062 typedef std::tr1::unordered_map<IdString, VendorMatchEntry> VendorMatch;
00063 int _nextId = -1;
00064 VendorMatch _vendorMatch;
00065
00067 inline void vendorMatchIdReset()
00068 {
00069 _nextId = -1;
00070 _vendorMatch.clear();
00071 }
00072
00081 inline unsigned vendorMatchId( IdString vendor )
00082 {
00083 VendorMatchEntry & ent( _vendorMatch[vendor] );
00084 if ( ! ent )
00085 {
00086 IdString lcvendor( str::toLower( vendor.asString() ) );
00087 VendorMatchEntry & lcent( _vendorMatch[lcvendor] );
00088 if ( ! lcent )
00089 {
00090 unsigned myid = 0;
00091
00092
00093 for ( VendorMap::reverse_iterator it = _vendorMap.rbegin(); it != _vendorMap.rend(); ++it )
00094 {
00095 if ( str::hasPrefix( lcvendor.c_str(), it->first ) )
00096 {
00097 myid = it->second;
00098 break;
00099 }
00100 }
00101 if ( ! myid )
00102 {
00103 myid = --_nextId;
00104 }
00105 ent = lcent = myid;
00106 }
00107 else
00108 {
00109 ent = lcent;
00110 }
00111 }
00112 return ent;
00113 }
00115 }
00117
00118 const VendorAttr & VendorAttr::instance()
00119 {
00120 static VendorAttr _val;
00121 return _val;
00122 }
00123
00124 VendorAttr::VendorAttr ()
00125 {
00126 vendorGroupCounter = 1;
00127 Pathname vendorPath (ZConfig::instance().vendorPath());
00128 try
00129 {
00130 Target_Ptr trg( getZYpp()->target() );
00131 if ( trg )
00132 vendorPath = trg->root() / vendorPath;
00133 }
00134 catch ( ... )
00135 {
00136
00137 }
00138
00139
00140 addVendorDirectory (vendorPath);
00141
00142
00143
00144
00145
00146 VendorMap::const_iterator suseit( _vendorMap.find("suse") );
00147 VendorMap::const_iterator opensuseit( _vendorMap.find("opensuse") );
00148 if ( suseit == _vendorMap.end() )
00149 {
00150 if ( opensuseit == _vendorMap.end() )
00151 {
00152
00153 _vendorMap["suse"] = _vendorMap["opensuse"] = ++vendorGroupCounter;
00154 }
00155 else
00156 {
00157
00158 _vendorMap["suse"] = opensuseit->second;
00159 }
00160 }
00161 else if ( opensuseit == _vendorMap.end() )
00162 {
00163
00164 _vendorMap["opensuse"] = suseit->second;
00165 }
00166
00167
00168 VendorMap::const_iterator obsit( _vendorMap.find("opensuse build service") );
00169 if ( obsit == _vendorMap.end() )
00170 {
00171 _vendorMap["opensuse build service"] = ++vendorGroupCounter;
00172 }
00173
00174
00175 MIL << *this << endl;
00176 }
00177
00178 void VendorAttr::_addVendorList( VendorList & vendorList_r ) const
00179 {
00180 unsigned int nextId = vendorGroupCounter + 1;
00181
00182
00183
00184 for_( it, vendorList_r.begin(), vendorList_r.end() )
00185 {
00186 *it = str::toLower( *it );
00187 if (_vendorMap.find(*it) != _vendorMap.end())
00188 {
00189 if (nextId != vendorGroupCounter + 1 &&
00190 nextId != _vendorMap[*it])
00191 {
00192
00193 unsigned int moveID = _vendorMap[*it];
00194 for_( itMap, _vendorMap.begin(), _vendorMap.end() )
00195 {
00196 if (itMap->second == moveID)
00197 itMap->second = nextId;
00198 }
00199 }
00200 else
00201 {
00202 nextId = _vendorMap[*it];
00203 WAR << "Vendor " << *it << " is already used in another vendor group. --> mixing these groups" << endl;
00204 }
00205 }
00206 }
00207
00208 for_( it, vendorList_r.begin(), vendorList_r.end() )
00209 {
00210 _vendorMap[*it] = nextId;
00211 }
00212
00213 if (nextId == vendorGroupCounter + 1)
00214 ++vendorGroupCounter;
00215
00216
00217 vendorMatchIdReset();
00218 }
00219
00220 bool VendorAttr::addVendorFile( const Pathname & filename ) const
00221 {
00222 parser::IniDict dict;
00223
00224 if ( PathInfo(filename).isExist())
00225 {
00226 InputStream is(filename);
00227 dict.read(is);
00228 }
00229 else
00230 {
00231 MIL << filename << " not found." << endl;
00232 return false;
00233 }
00234
00235 for ( parser::IniDict::section_const_iterator sit = dict.sectionsBegin();
00236 sit != dict.sectionsEnd();
00237 ++sit )
00238 {
00239 string section(*sit);
00240
00241 for ( parser::IniDict::entry_const_iterator it = dict.entriesBegin(*sit);
00242 it != dict.entriesEnd(*sit);
00243 ++it )
00244 {
00245 string entry(it->first);
00246 string value(it->second);
00247 if ( section == "main" )
00248 {
00249 if ( entry == "vendors" )
00250 {
00251 VendorList vendorlist;
00252 str::split( value, back_inserter(vendorlist), "," );
00253 _addVendorList (vendorlist);
00254 break;
00255 }
00256 }
00257 }
00258 }
00259
00260 return true;
00261 }
00262
00263 bool VendorAttr::addVendorDirectory( const Pathname & dirname ) const
00264 {
00265 parser::IniDict dict;
00266
00267 if ( PathInfo(dirname).isExist())
00268 {
00269 InputStream is(dirname);
00270 dict.read(is);
00271 }
00272 else
00273 {
00274 MIL << dirname << " not found." << endl;
00275 return false;
00276 }
00277
00278 list<Pathname> filenames;
00279
00280 filesystem::readdir( filenames,
00281 dirname, false );
00282 for (list<Pathname>::iterator it = filenames.begin();
00283 it != filenames.end(); ++it) {
00284 MIL << "Adding file " << *it << endl;
00285 addVendorFile( *it );
00286 }
00287 return true;
00288 }
00289
00291
00293
00294 bool VendorAttr::equivalent( IdString lVendor, IdString rVendor ) const
00295 {
00296 if ( lVendor == rVendor )
00297 return true;
00298 return vendorMatchId( lVendor ) == vendorMatchId( rVendor );
00299 }
00300
00301 bool VendorAttr::equivalent( const Vendor & lVendor, const Vendor & rVendor ) const
00302 { return equivalent( IdString( lVendor ), IdString( rVendor ) );
00303 }
00304
00305 bool VendorAttr::equivalent( sat::Solvable lVendor, sat::Solvable rVendor ) const
00306 { return equivalent( lVendor.vendor(), rVendor.vendor() ); }
00307
00308 bool VendorAttr::equivalent( const PoolItem & lVendor, const PoolItem & rVendor ) const
00309 { return equivalent( lVendor.satSolvable().vendor(), rVendor.satSolvable().vendor() ); }
00310
00312
00313 std::ostream & operator<<( std::ostream & str, const VendorAttr & )
00314 {
00315 str << "Equivalent vendors:";
00316 for_( it, _vendorMap.begin(), _vendorMap.end() )
00317 {
00318 str << endl << " [" << it->second << "] " << it->first;
00319 }
00320 return str;
00321 }
00322
00324 }
00326