CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
refresh.cc
Go to the documentation of this file.
1 
2 #include <boost/filesystem/path.hpp>
3 #include <boost/filesystem/operations.hpp>
4 #include <boost/bind.hpp>
5 #include <boost/mem_fn.hpp>
6 
7 #include <boost/program_options.hpp>
8 
9 #include <fstream>
10 #include <iostream>
11 #include <utility>
12 #include <cstdlib>
13 #include <string>
14 #include <set>
15 #include <algorithm>
16 
23 
26 
27 using namespace edmplugin;
28 
29 namespace std {
30 ostream& operator<<(std::ostream& o, const vector<std::string>& iValue) {
31  std::string sep("");
32  std::string commaSep(",");
33  for(std::vector<std::string>::const_iterator it=iValue.begin(), itEnd=iValue.end();
34  it != itEnd;
35  ++it) {
36  o <<sep<<*it;
37  sep = commaSep;
38  }
39  return o;
40 }
41 }
42 namespace {
43  struct Listener {
44  typedef edmplugin::CacheParser::NameAndType NameAndType;
45  typedef edmplugin::CacheParser::NameAndTypes NameAndTypes;
46 
47  void newFactory(const edmplugin::PluginFactoryBase* iBase) {
48  iBase->newPluginAdded_.connect(boost::bind(boost::mem_fn(&Listener::newPlugin),this,_1,_2));
49  }
50  void newPlugin(const std::string& iCategory, const edmplugin::PluginInfo& iInfo) {
51  nameAndTypes_.push_back(NameAndType(iInfo.name_,iCategory));
52  }
53 
54  NameAndTypes nameAndTypes_;
55  };
56 }
57 int main (int argc, char **argv)
58 {
59  using namespace boost::program_options;
60 
61  static const char* const kPathsOpt = "paths";
62  static const char* const kPathsCommandOpt = "paths,p";
63  //static const char* const kAllOpt = "all";
64  //static const char* const kAllCommandOpt = "all,a";
65  static const char* const kHelpOpt = "help";
66  static const char* const kHelpCommandOpt = "help,h";
67 
68  std::string descString(argv[0]);
69  descString += " [options] [[--";
70  descString += kPathsOpt;
71  descString += "] path [path]] \nAllowed options";
72  options_description desc(descString);
73  std::string defaultDir(".");
74  std::vector<std::string> defaultDirList = edmplugin::standard::config().searchPath();
75  if( not defaultDirList.empty() ) {
76  defaultDir = defaultDirList[0];
77  }
78  desc.add_options()
79  (kHelpCommandOpt, "produce help message")
80  (kPathsCommandOpt,value<std::vector<std::string> >()->default_value(
81  std::vector<std::string>(1,defaultDir))
82  , "a directory or a list of files to scan")
83  //(kAllCommandOpt,"when no paths given, try to update caches for all known directories [default is to only scan the first directory]")
84  ;
85 
86  positional_options_description p;
87  p.add(kPathsOpt, -1);
88 
89  variables_map vm;
90  try {
91  store(command_line_parser(argc,argv).options(desc).positional(p).run(),vm);
92  notify(vm);
93  } catch(const error& iException) {
94  std::cerr <<iException.what();
95  return 1;
96  }
97 
98  if(vm.count(kHelpOpt)) {
99  std::cout << desc <<std::endl;
100  return 0;
101  }
102 
103 
105 
106  /*if(argc ==1) {
107  std::cerr <<"Requires at least one argument. Please pass either one directory or a list of files (all in the same directory)."<<std::endl;
108  return 1;
109  } */
110 
111  int returnValue = EXIT_SUCCESS;
112 
113  try {
114  std::vector<std::string> requestedPaths(vm[kPathsOpt].as<std::vector<std::string> >());
115 
116  //first find the directory and create a list of files to look at in that directory
117  path directory(requestedPaths[0]);
118  std::vector<std::string> files;
119  bool removeMissingFiles = false;
120  if(boost::filesystem::is_directory(directory)) {
121  if (requestedPaths.size()>1) {
122  std::cerr <<"if a directory is given then only one argument is allowed"<<std::endl;
123  return 1;
124  }
125 
126  //if asked to look at whole directory, then we can also remove missing files
127  removeMissingFiles = true;
128 
129  boost::filesystem::directory_iterator file (directory);
130  boost::filesystem::directory_iterator end;
131 
132  path cacheFile(directory);
133  cacheFile /= standard::cachefileName();
134 
135  std::time_t cacheLastChange(0);
136  if(exists(cacheFile)) {
137  cacheLastChange = last_write_time(cacheFile);
138  }
139  for (; file != end; ++file)
140  {
141 
142  path filename (*file);
143  path shortName(file->leaf());
144  std::string stringName = shortName.string();
145 
146  static std::string kPluginPrefix(standard::pluginPrefix());
147  if (stringName.size() < kPluginPrefix.size()) {
148  continue;
149  }
150  if(stringName.substr(0,kPluginPrefix.size()) != kPluginPrefix) {
151  continue;
152  }
153 
154  if(last_write_time(filename) > cacheLastChange) {
155  files.push_back(stringName);
156  }
157  }
158  } else {
159  //we have files
160  directory = directory.branch_path();
161  for(std::vector<std::string>::iterator it=requestedPaths.begin(), itEnd=requestedPaths.end();
162  it != itEnd; ++it) {
164  if ( not exists(f) ) {
165  std::cerr <<"the file '"<<f.native_file_string()<<"' does not exist"<<std::endl;
166  return 1;
167  }
168  if (is_directory(f) ) {
169  std::cerr <<"either one directory or a list of files are allowed as arguments"<<std::endl;
170  return 1;
171  }
172  if(directory != f.branch_path()) {
173  std::cerr <<"all files must have be in the same directory ("<<directory.native_file_string()<<")\n"
174  " the file "<<f.native_file_string()<<" does not."<<std::endl;
175  }
176  files.push_back(f.leaf());
177  }
178  }
179 
180  path cacheFile(directory);
181  cacheFile /= edmplugin::standard::cachefileName();//path(s_cacheFile);
182 
184  if(exists(cacheFile) ) {
185  std::ifstream cf(cacheFile.native_file_string().c_str());
186  if(!cf) {
187  cms::Exception("FailedToOpen")<<"unable to open file '"<<cacheFile.native_file_string()<<"' for reading even though it is present.\n"
188  "Please check permissions on the file.";
189  }
190  CacheParser::read(cf, ltp);
191  }
192 
193 
194  //load each file and 'listen' to which plugins are loaded
195  Listener listener;
197  pfm->newFactory_.connect(boost::bind(boost::mem_fn(&Listener::newFactory),&listener,_1));
198  edm::for_all(*pfm, boost::bind(boost::mem_fn(&Listener::newFactory),&listener,_1));
199 
200  for(std::vector<std::string>::iterator itFile = files.begin();
201  itFile != files.end();
202  ++itFile) {
203 
204  path loadableFile(directory);
205  loadableFile /=(*itFile);
206  listener.nameAndTypes_.clear();
207  try {
208  edmplugin::SharedLibrary lib(loadableFile);
209 
210  //PluginCapabilities is special, the plugins do not call it. Instead, for each shared library load
211  // we need to ask it to try to find plugins
213 
214  ltp[*itFile]=listener.nameAndTypes_;
215  } catch(const cms::Exception& iException) {
216  if(iException.category() == "PluginLibraryLoadError") {
217  std::cerr <<"Caught exception "<<iException.what()<<" will ignore "<<*itFile<<" and continue."<<std::endl;
218  } else {
219  throw;
220  }
221  }
222  }
223 
224  if(removeMissingFiles) {
225  for(CacheParser::LoadableToPlugins::iterator itFile = ltp.begin();
226  itFile != ltp.end();
227  /*don't advance the iterator here because it may have become invalid */) {
228  path loadableFile(directory);
229  loadableFile /=(itFile->first);
230  if(not exists(loadableFile)) {
231  std::cout <<"removing file '"<<loadableFile.native_file_string()<<"'"<<std::endl;
232  CacheParser::LoadableToPlugins::iterator itToItemBeingRemoved = itFile;
233  //advance the iterator while it is still valid
234  ++itFile;
235  ltp.erase(itToItemBeingRemoved);
236  } else {
237  //since we are not advancing the iterator in the for loop, do it here
238  ++itFile;
239  }
240  }
241  //now get rid of the items
242  }
243  //now write our new results
244  std::ofstream cf(cacheFile.native_file_string().c_str());
245  if(!cf) {
246  cms::Exception("FailedToOpen")<<"unable to open file '"<<cacheFile.native_file_string()<<"' for writing.\n"
247  "Please check permissions on the file.";
248  }
249  CacheParser::write(ltp,cf);
250  }catch(std::exception& iException) {
251  std::cerr <<"Caught exception "<<iException.what()<<std::endl;
252  returnValue = 1;
253  }
254 
255  return returnValue;
256 }
virtual char const * what() const
Definition: Exception.cc:97
const boost::filesystem::path & cachefileName()
Definition: standard.cc:48
std::pair< std::string, std::string > NameAndType
Definition: CacheParser.h:44
bool tryToFind(const SharedLibrary &iLoadable)
Check to see if any capabilities are in the file, returns &#39;true&#39; if found.
const std::string & pluginPrefix()
Definition: standard.cc:54
int main(int argc, char **argv)
int path() const
Definition: HLTadd.h:3
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
Definition: Algorithms.h:16
std::map< boost::filesystem::path, NameAndTypes > LoadableToPlugins
Definition: CacheParser.h:46
PluginManager::Config config()
Definition: standard.cc:22
std::vector< NameAndType > NameAndTypes
Definition: CacheParser.h:45
static PluginCapabilities * get()
double f[11][100]
#define end
Definition: vmac.h:38
sigc::signal< void, const std::string &, const PluginInfo & > newPluginAdded_
signal containing plugin category, and plugin info for newly added plugin
static void write(const CategoryToInfos &, std::ostream &)
Definition: CacheParser.cc:151
static const char *const kHelpCommandOpt
Definition: CmsShowMain.cc:92
std::string name_
Definition: PluginInfo.h:30
tuple filename
Definition: lut2db_cfg.py:20
Config & searchPath(const SearchPath &iPath)
Definition: PluginManager.h:48
tuple cout
Definition: gather_cfg.py:41
sigc::signal< void, const PluginFactoryBase * > newFactory_
static void read(std::istream &, const boost::filesystem::path &iDirectory, CategoryToInfos &oOut)
Definition: CacheParser.cc:125
static const char *const kHelpOpt
Definition: CmsShowMain.cc:91
static PluginFactoryManager * get()
std::string category() const
Definition: Exception.cc:74