00001
00002
00003
00004
00005
00006
00007
00008
00012 #include <iostream>
00013 #include "zypp/base/Logger.h"
00014
00015 #include "zypp/base/Iterator.h"
00016 #include "zypp/base/Algorithm.h"
00017 #include "zypp/base/Functional.h"
00018
00019 #include "zypp/ResPoolProxy.h"
00020 #include "zypp/ui/SelectableImpl.h"
00021
00022 using std::endl;
00023
00025 namespace zypp
00026 {
00027
00029 struct PoolItemSaver
00030 {
00031 void saveState( ResPool_Ref pool_r )
00032 {
00033 std::for_each( pool_r.begin(), pool_r.end(),
00034 std::mem_fun_ref(&PoolItem::saveState) );
00035 }
00036
00037 void saveState( ResPool_Ref pool_r, const ResObject::Kind & kind_r )
00038 {
00039 std::for_each( pool_r.byKindBegin(kind_r), pool_r.byKindEnd(kind_r),
00040 std::mem_fun_ref(&PoolItem::saveState) );
00041 }
00042
00043 void restoreState( ResPool_Ref pool_r )
00044 {
00045 std::for_each( pool_r.begin(), pool_r.end(),
00046 std::mem_fun_ref(&PoolItem::restoreState) );
00047 }
00048
00049 void restoreState( ResPool_Ref pool_r, const ResObject::Kind & kind_r )
00050 {
00051 std::for_each( pool_r.byKindBegin(kind_r), pool_r.byKindEnd(kind_r),
00052 std::mem_fun_ref(&PoolItem::restoreState) );
00053 }
00054
00055 bool diffState( ResPool_Ref pool_r ) const
00056 {
00057
00058 return( invokeOnEach( pool_r.begin(), pool_r.end(),
00059 std::mem_fun_ref(&PoolItem::sameState) ) < 0 );
00060 }
00061
00062 bool diffState( ResPool_Ref pool_r, const ResObject::Kind & kind_r ) const
00063 {
00064
00065 return( invokeOnEach( pool_r.byKindBegin(kind_r), pool_r.byKindEnd(kind_r),
00066 std::mem_fun_ref(&PoolItem::sameState) ) < 0 );
00067 }
00068 };
00069
00070 struct SelPoolHelper
00071 {
00072 typedef std::set<ResPool::Item> ItemC;
00073 struct SelC
00074 {
00075 void add( ResPool::Item it )
00076 {
00077 if ( it.status().isInstalled() )
00078 installed.insert( it );
00079 else
00080 available.insert( it );
00081 }
00082 ItemC installed;
00083 ItemC available;
00084 };
00085 typedef std::map<std::string,SelC> NameC;
00086 typedef std::map<ResObject::Kind,NameC> KindC;
00087
00088 KindC _kinds;
00089
00091 void operator()( ResPool::Item it )
00092 {
00093 _kinds[it->kind()][it->name()].add( it );
00094 }
00095
00096
00097 ui::Selectable::Ptr buildSelectable( const ResObject::Kind & kind_r,
00098 const std::string & name_r,
00099 const PoolItem & installedItem_r,
00100 const ItemC & available )
00101 {
00102 return ui::Selectable::Ptr( new ui::Selectable(
00103 ui::Selectable::Impl_Ptr( new ui::Selectable::Impl( kind_r, name_r,
00104 installedItem_r,
00105 available.begin(),
00106 available.end() ) )
00107 ) );
00108 }
00109
00113 typedef std::set<ui::Selectable::Ptr> SelectableIndex;
00114 typedef std::map<ResObject::Kind,SelectableIndex> SelectablePool;
00115
00116 void feed( SelectablePool & _selPool )
00117 {
00118 for ( KindC::const_iterator kindIt = _kinds.begin(); kindIt != _kinds.end(); ++kindIt )
00119 {
00120 for ( NameC::const_iterator nameIt = kindIt->second.begin(); nameIt != kindIt->second.end(); ++nameIt )
00121 {
00122 const ItemC & installed( nameIt->second.installed );
00123 const ItemC & available( nameIt->second.available );
00124
00125 if ( installed.empty() )
00126 {
00127 if ( available.empty() )
00128 continue;
00129 _selPool[kindIt->first].insert( buildSelectable( kindIt->first, nameIt->first, PoolItem(), available ) );
00130 }
00131 else
00132 {
00133
00134 for ( ItemC::const_iterator instIt = installed.begin(); instIt != installed.end(); ++instIt )
00135 {
00136 _selPool[kindIt->first].insert( buildSelectable( kindIt->first, nameIt->first, *instIt, available ) );
00137 }
00138 }
00139 }
00140 }
00141 }
00142 };
00143
00145
00146
00147
00149 struct ResPoolProxy::Impl
00150 {
00151 public:
00152 Impl()
00153 {}
00154
00155 Impl( ResPool_Ref pool_r )
00156 : _pool( pool_r )
00157 {
00158
00159 SelPoolHelper collect;
00160 std::for_each( _pool.begin(), _pool.end(),
00161 functor::functorRef<void,ResPool::Item>( collect ) );
00162 collect.feed( _selPool );
00163 }
00164
00165 public:
00166
00167 bool empty( const ResObject::Kind & kind_r ) const
00168 { return _selPool[kind_r].empty(); }
00169
00170 size_type size( const ResObject::Kind & kind_r ) const
00171 { return _selPool[kind_r].size(); }
00172
00173 const_iterator byKindBegin( const ResObject::Kind & kind_r ) const
00174 { return _selPool[kind_r].begin(); }
00175
00176 const_iterator byKindEnd( const ResObject::Kind & kind_r ) const
00177 { return _selPool[kind_r].end(); }
00178
00179
00180 public:
00181
00182 void saveState() const
00183 { PoolItemSaver().saveState( _pool ); }
00184
00185 void saveState( const ResObject::Kind & kind_r ) const
00186 { PoolItemSaver().saveState( _pool, kind_r ); }
00187
00188 void restoreState() const
00189 { PoolItemSaver().restoreState( _pool ); }
00190
00191 void restoreState( const ResObject::Kind & kind_r ) const
00192 { PoolItemSaver().restoreState( _pool, kind_r ); }
00193
00194 bool diffState() const
00195 { return PoolItemSaver().diffState( _pool ); }
00196
00197 bool diffState( const ResObject::Kind & kind_r ) const
00198 { return PoolItemSaver().diffState( _pool, kind_r ); }
00199
00200 private:
00201 ResPool_Ref _pool;
00202 mutable SelectablePool _selPool;
00203
00204 public:
00206 static shared_ptr<Impl> nullimpl()
00207 {
00208 static shared_ptr<Impl> _nullimpl( new Impl );
00209 return _nullimpl;
00210 }
00211 };
00213
00215 inline std::ostream & operator<<( std::ostream & str, const ResPoolProxy::Impl & obj )
00216 {
00217 return str << "ResPoolProxy::Impl";
00218 }
00219
00221
00222
00223
00225
00227
00228
00229
00230
00231 ResPoolProxy::ResPoolProxy()
00232 : _pimpl( Impl::nullimpl() )
00233 {}
00234
00236
00237
00238
00239
00240 ResPoolProxy::ResPoolProxy( ResPool_Ref pool_r )
00241 : _pimpl( new Impl( pool_r ) )
00242 {}
00243
00245
00246
00247
00248
00249 ResPoolProxy::~ResPoolProxy()
00250 {}
00251
00253
00254
00255
00257
00258 bool ResPoolProxy::empty( const ResObject::Kind & kind_r ) const
00259 { return _pimpl->empty( kind_r ); }
00260
00261 ResPoolProxy::size_type ResPoolProxy::size( const ResObject::Kind & kind_r ) const
00262 { return _pimpl->size( kind_r ); }
00263
00264 ResPoolProxy::const_iterator ResPoolProxy::byKindBegin( const ResObject::Kind & kind_r ) const
00265 { return _pimpl->byKindBegin( kind_r ); }
00266
00267 ResPoolProxy::const_iterator ResPoolProxy::byKindEnd( const ResObject::Kind & kind_r ) const
00268 { return _pimpl->byKindEnd( kind_r ); }
00269
00270 void ResPoolProxy::saveState() const
00271 { _pimpl->saveState(); }
00272
00273 void ResPoolProxy::saveState( const ResObject::Kind & kind_r ) const
00274 { _pimpl->saveState( kind_r ); }
00275
00276 void ResPoolProxy::restoreState() const
00277 { _pimpl->restoreState(); }
00278
00279 void ResPoolProxy::restoreState( const ResObject::Kind & kind_r ) const
00280 { _pimpl->restoreState( kind_r ); }
00281
00282 bool ResPoolProxy::diffState() const
00283 { return _pimpl->diffState(); }
00284
00285 bool ResPoolProxy::diffState( const ResObject::Kind & kind_r ) const
00286 { return _pimpl->diffState( kind_r ); }
00287
00288
00289
00290
00291
00292
00293 std::ostream & operator<<( std::ostream & str, const ResPoolProxy & obj )
00294 {
00295 return str << *obj._pimpl;
00296 }
00297
00299 }