CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FWConfigurationManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWConfigurationManager
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Sun Feb 24 14:42:32 EST 2008
11 //
12 
13 // system include files
14 #include <fstream>
15 #include <iostream>
16 #include <memory>
17 #include <stdexcept>
18 #include "TROOT.h"
19 
20 // user include files
26 
27 //
28 // constants, enums and typedefs
29 //
30 
31 //
32 // static data member definitions
33 //
34 
35 //
36 // constructors and destructor
37 //
39 {
40 }
41 
42 // FWConfigurationManager::FWConfigurationManager(const FWConfigurationManager& rhs)
43 // {
44 // // do actual copying here;
45 // }
46 
48 {
49 }
50 
51 //
52 // assignment operators
53 //
54 // const FWConfigurationManager& FWConfigurationManager::operator=(const FWConfigurationManager& rhs)
55 // {
56 // //An exception safe implementation is
57 // FWConfigurationManager temp(rhs);
58 // swap(rhs);
59 //
60 // return *this;
61 // }
62 
63 //
64 // member functions
65 //
66 void
68 {
69  assert(0!=iConf);
70  m_configurables[iName]=iConf;
71 }
72 
73 //
74 // const member functions
75 //
76 void
78 {
79  assert(0!=iConfig.keyValues());
80  for(FWConfiguration::KeyValues::const_iterator it = iConfig.keyValues()->begin(),
81  itEnd = iConfig.keyValues()->end();
82  it != itEnd;
83  ++it) {
84  std::map<std::string,FWConfigurable*>::const_iterator itFound = m_configurables.find(it->first);
85  assert(itFound != m_configurables.end());
86  itFound->second->setFrom(it->second);
87  }
88 }
89 
90 void
92 {
94  for(std::map<std::string,FWConfigurable*>::const_iterator it = m_configurables.begin(),
95  itEnd = m_configurables.end();
96  it != itEnd;
97  ++it) {
98  it->second->addTo(config);
99  oConfig.addKeyValue(it->first, config, true);
100  }
101 }
102 
103 
104 void
106 {
107  try
108  {
109  std::ofstream file(iName.c_str());
110  if(not file) {
111  std::string message = "unable to open file " + iName;
112  message += iName;
113  throw std::runtime_error(message.c_str());
114  }
116  to(top);
117  fwLog(fwlog::kInfo) << "Writing to file "<< iName.c_str() << "...\n";
118  fflush(stdout);
119 
120  streamTo(file, top, "top");
121  }
122  catch (std::runtime_error &e)
123  {
124  fwLog(fwlog::kError) << "FWConfigurationManager::writeToFile() " << e.what() << std::endl;
125  }
126 }
127 
128 void
130 {
131  Int_t error=0;
132  // Int_t value =
133  gROOT->LoadMacro( iName.c_str(), &error );
134  if(0 != error) {
135  std::string message("unable to load macro file ");
136  message += iName;
137  throw std::runtime_error(message.c_str());
138  }
139 
140  const std::string command("(Long_t)(fwConfig() )");
141 
142  error = 0;
143  Long_t lConfig = gROOT->ProcessLineFast(command.c_str(),
144  &error);
145 
146  {
147  //need to unload this macro so that we can load a new configuration
148  // which uses the same function name in the macro
149  Int_t error = 0;
150  gROOT->ProcessLineSync((std::string(".U ")+iName).c_str(), &error);
151  }
152  if(0 != error) {
153  std::string message("unable to properly parse configuration file ");
154  message += iName;
155  throw std::runtime_error(message.c_str());
156  }
157  std::auto_ptr<FWConfiguration> config( reinterpret_cast<FWConfiguration*>(lConfig) );
158 
159  setFrom( *config);
160 }
161 
162 void
163 debug_config_state_machine(const char *where, const std::string &tag, int state)
164 {
165 #ifdef FW_CONFIG_PARSER_DEBUG
166  static char *debug_states[] = {
167  "IN_BEGIN_DOCUMENT",
168  "IN_PUSHED_CONFIG",
169  "IN_POPPED_CONFIG",
170  "IN_BEGIN_STRING",
171  "IN_STORED_STRING"
172  };
173 
174  std::cerr << " " << where << " tag/data " << tag << "in state " << debug_states[state] << std::endl;
175 #endif
176 }
177 
202 {
203  enum STATES {
209  };
210 
211 public:
212  FWXMLConfigParser(istream &f)
213  : SimpleSAXParser(f),
215  m_first(0)
216  {}
217 
220  {
222  int version = 0;
223  for (size_t i = 0, e = attributes.size(); i != e; ++i)
224  {
225  Attribute &attr = attributes[i];
226  if (attr.key == "name")
227  name = attr.value;
228  else if (attr.key == "version")
229  {
230  char *endptr;
231  version = strtol(attr.value.c_str(), &endptr, 10);
232  if (endptr == attr.value.c_str())
233  throw ParserError("Version must be an integer.");
234  }
235  else
236  throw ParserError("Unexpected attribute " + attr.key);
237  }
238  m_configs.push_back(std::make_pair(name, new FWConfiguration(version)));
239  }
240 
241 
245  virtual void startElement(const std::string &tag, Attributes &attributes) override
246  {
247  debug_config_state_machine("start", tag, m_state);
248  if (m_state == IN_BEGIN_DOCUMENT)
249  {
250  if (tag != "config")
251  throw ParserError("Expecting toplevel <config> tag");
252  pushConfig(attributes);
253  m_first.reset(m_configs.back().second);
255  }
256  else if (m_state == IN_PUSHED_CONFIG)
257  {
258  if (tag == "config")
259  pushConfig(attributes);
260  else if (tag == "string")
262  else
263  throw ParserError("Unexpected element " + tag);
264  }
265  else if (m_state == IN_POPPED_CONFIG)
266  {
267  if (tag != "config")
268  throw ParserError("Unexpected element " + tag);
269  pushConfig(attributes);
271  }
272  else
273  throw ParserError("Wrong opening tag found " + tag);
274  }
275 
284  virtual void endElement(const std::string &tag) override
285  {
286  debug_config_state_machine("end", tag, m_state);
288  {
289  if (tag != "config")
290  throw ParserError("Wrong closing tag found " + tag);
291 
292  FWConfiguration *current = m_configs.back().second;
293  std::string key = m_configs.back().first;
294  m_configs.pop_back();
295  if (!m_configs.empty())
296  m_configs.back().second->addKeyValue(key, *current);
298  }
299  else if (m_state == IN_BEGIN_STRING && tag == "string")
300  {
301  m_configs.back().second->addValue("");
303  }
304  else if (m_state == IN_STORED_STRING && tag == "string")
306  else
307  throw ParserError("Wrong closing tag found " + tag);
308  }
309 
315  virtual void data(const std::string &data) override
316  {
317  debug_config_state_machine("data", data, m_state);
318  // We ignore whitespace but complain about any text which is not
319  // in the <string> tag.
320  if (m_state == IN_BEGIN_STRING)
321  {
322  m_configs.back().second->addValue(data);
324  }
325  else if (strspn(data.c_str(), " \t\n") != data.size())
326  throw ParserError("Unexpected text " + data);
327  }
328 
333  {
334  return m_first.get();
335  }
336 
337 private:
338  std::vector<std::pair<std::string, FWConfiguration *> > m_configs;
340  std::auto_ptr<FWConfiguration> m_first;
341  // unsigned int m_currentConfigVersion;
343 };
344 
351 void
353 {
354  std::ifstream f(iName.c_str());
355  if (f.peek() != (int) '<')
356  return readFromOldFile(iName);
357 
358  // Check that the syntax is correct.
359  SimpleSAXParser syntaxTest(f);
360  syntaxTest.parse();
361  f.close();
362 
363  // Read again, this time actually parse.
364  std::ifstream g(iName.c_str());
365  // Actually parse the results.
367  parser.parse();
368  setFrom(*parser.config());
369 }
370 
371 //
372 // static member functions
373 //
int i
Definition: DBlmapReader.cc:9
std::vector< Attribute > Attributes
void to(FWConfiguration &) const
std::auto_ptr< FWConfiguration > m_first
const KeyValues * keyValues() const
std::vector< std::pair< std::string, FWConfiguration * > > m_configs
void streamTo(std::ostream &, const FWConfiguration &, const std::string &name)
void writeToFile(const std::string &) const
void debug_config_state_machine(const char *where, const std::string &tag, int state)
void readFromOldFile(const std::string &) const
void readFromFile(const std::string &) const
FWConfiguration * config(void)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
virtual void startElement(const std::string &tag, Attributes &attributes) override
void pushConfig(Attributes &attributes)
void setFrom(const FWConfiguration &) const
list attributes
Definition: asciidump.py:415
double f[11][100]
virtual void endElement(const std::string &tag) override
FWConfiguration & addKeyValue(const std::string &, const FWConfiguration &)
virtual void data(const std::string &data) override
string top
Definition: fff_deleter.py:272
tuple attr
Definition: asciidump.py:432
#define fwLog(_level_)
Definition: fwLog.h:50
void add(const std::string &iName, FWConfigurable *)
does not take ownership
list key
Definition: combine.py:13
std::map< std::string, FWConfigurable * > m_configurables