Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <fstream>
00016 #include <iostream>
00017 #include <memory>
00018 #include <stdexcept>
00019 #include "TROOT.h"
00020
00021
00022 #include "Fireworks/Core/interface/FWConfigurationManager.h"
00023 #include "Fireworks/Core/interface/FWConfiguration.h"
00024 #include "Fireworks/Core/interface/FWConfigurable.h"
00025 #include "Fireworks/Core/interface/fwLog.h"
00026 #include "Fireworks/Core/src/SimpleSAXParser.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 FWConfigurationManager::FWConfigurationManager()
00040 {
00041 }
00042
00043
00044
00045
00046
00047
00048 FWConfigurationManager::~FWConfigurationManager()
00049 {
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 void
00068 FWConfigurationManager::add(const std::string& iName, FWConfigurable* iConf)
00069 {
00070 assert(0!=iConf);
00071 m_configurables[iName]=iConf;
00072 }
00073
00074
00075
00076
00077 void
00078 FWConfigurationManager::setFrom(const FWConfiguration& iConfig) const
00079 {
00080 assert(0!=iConfig.keyValues());
00081 for(FWConfiguration::KeyValues::const_iterator it = iConfig.keyValues()->begin(),
00082 itEnd = iConfig.keyValues()->end();
00083 it != itEnd;
00084 ++it) {
00085 std::map<std::string,FWConfigurable*>::const_iterator itFound = m_configurables.find(it->first);
00086 assert(itFound != m_configurables.end());
00087 itFound->second->setFrom(it->second);
00088 }
00089 }
00090
00091 void
00092 FWConfigurationManager::to(FWConfiguration& oConfig) const
00093 {
00094 FWConfiguration config;
00095 for(std::map<std::string,FWConfigurable*>::const_iterator it = m_configurables.begin(),
00096 itEnd = m_configurables.end();
00097 it != itEnd;
00098 ++it) {
00099 it->second->addTo(config);
00100 oConfig.addKeyValue(it->first, config, true);
00101 }
00102 }
00103
00104
00105 void
00106 FWConfigurationManager::writeToFile(const std::string& iName) const
00107 {
00108 try
00109 {
00110 ofstream file(iName.c_str());
00111 if(not file) {
00112 std::string message("unable to open file %s ", iName.c_str());
00113 fflush(stdout);
00114 message += iName;
00115 throw std::runtime_error(message.c_str());
00116 }
00117 FWConfiguration top;
00118 to(top);
00119 fwLog(fwlog::kInfo) << "Writing to file "<< iName.c_str() << "...\n";
00120 fflush(stdout);
00121
00122 streamTo(file, top, "top");
00123 }
00124 catch (std::runtime_error &e) { std::cout << e.what() << std::endl; }
00125 }
00126
00127 void
00128 FWConfigurationManager::readFromOldFile(const std::string& iName) const
00129 {
00130 Int_t error=0;
00131
00132 gROOT->LoadMacro( iName.c_str(), &error );
00133 if(0 != error) {
00134 std::string message("unable to load macro file ");
00135 message += iName;
00136 throw std::runtime_error(message.c_str());
00137 }
00138
00139 const std::string command("(Long_t)(fwConfig() )");
00140
00141 error = 0;
00142 Long_t lConfig = gROOT->ProcessLineFast(command.c_str(),
00143 &error);
00144
00145 {
00146
00147
00148 Int_t error = 0;
00149 gROOT->ProcessLineSync((std::string(".U ")+iName).c_str(), &error);
00150 }
00151 if(0 != error) {
00152 std::string message("unable to properly parse configuration file ");
00153 message += iName;
00154 throw std::runtime_error(message.c_str());
00155 }
00156 std::auto_ptr<FWConfiguration> config( reinterpret_cast<FWConfiguration*>(lConfig) );
00157
00158 setFrom( *config);
00159 }
00160
00161 void
00162 debug_config_state_machine(const char *where, const std::string &tag, int state)
00163 {
00164 #ifdef FW_CONFIG_PARSER_DEBUG
00165 static char *debug_states[] = {
00166 "IN_BEGIN_DOCUMENT",
00167 "IN_PUSHED_CONFIG",
00168 "IN_POPPED_CONFIG",
00169 "IN_BEGIN_STRING",
00170 "IN_STORED_STRING"
00171 };
00172
00173 std::cerr << " " << where << " tag/data " << tag << "in state " << debug_states[state] << std::endl;
00174 #endif
00175 }
00176
00200 class FWXMLConfigParser : public SimpleSAXParser
00201 {
00202 enum STATES {
00203 IN_BEGIN_DOCUMENT,
00204 IN_PUSHED_CONFIG,
00205 IN_POPPED_CONFIG,
00206 IN_BEGIN_STRING,
00207 IN_STORED_STRING
00208 };
00209
00210 public:
00211 FWXMLConfigParser(istream &f)
00212 : SimpleSAXParser(f),
00213 m_state(IN_BEGIN_DOCUMENT),
00214 m_first(0)
00215 {}
00216
00218 void pushConfig(Attributes &attributes)
00219 {
00220 std::string name;
00221 int version = 0;
00222 for (size_t i = 0, e = attributes.size(); i != e; ++i)
00223 {
00224 Attribute &attr = attributes[i];
00225 if (attr.key == "name")
00226 name = attr.value;
00227 else if (attr.key == "version")
00228 {
00229 char *endptr;
00230 version = strtol(attr.value.c_str(), &endptr, 10);
00231 if (endptr == attr.value.c_str())
00232 throw ParserError("Version must be an integer.");
00233 }
00234 else
00235 throw ParserError("Unexpected attribute " + attr.key);
00236 }
00237 m_configs.push_back(std::make_pair(name, new FWConfiguration(version)));
00238 }
00239
00240
00244 virtual void startElement(const std::string &tag, Attributes &attributes)
00245 {
00246 debug_config_state_machine("start", tag, m_state);
00247 if (m_state == IN_BEGIN_DOCUMENT)
00248 {
00249 if (tag != "config")
00250 throw ParserError("Expecting toplevel <config> tag");
00251 pushConfig(attributes);
00252 m_first.reset(m_configs.back().second);
00253 m_state = IN_PUSHED_CONFIG;
00254 }
00255 else if (m_state == IN_PUSHED_CONFIG)
00256 {
00257 if (tag == "config")
00258 pushConfig(attributes);
00259 else if (tag == "string")
00260 m_state = IN_BEGIN_STRING;
00261 else
00262 throw ParserError("Unexpected element " + tag);
00263 }
00264 else if (m_state == IN_POPPED_CONFIG)
00265 {
00266 if (tag != "config")
00267 throw ParserError("Unexpected element " + tag);
00268 pushConfig(attributes);
00269 m_state = IN_PUSHED_CONFIG;
00270 }
00271 else
00272 throw ParserError("Wrong opening tag found " + tag);
00273 }
00274
00283 virtual void endElement(const std::string &tag)
00284 {
00285 debug_config_state_machine("end", tag, m_state);
00286 if (m_state == IN_PUSHED_CONFIG || m_state == IN_POPPED_CONFIG)
00287 {
00288 if (tag != "config")
00289 throw ParserError("Wrong closing tag found " + tag);
00290
00291 FWConfiguration *current = m_configs.back().second;
00292 std::string key = m_configs.back().first;
00293 m_configs.pop_back();
00294 if (!m_configs.empty())
00295 m_configs.back().second->addKeyValue(key, *current);
00296 m_state = IN_POPPED_CONFIG;
00297 }
00298 else if (m_state == IN_BEGIN_STRING && tag == "string")
00299 {
00300 m_configs.back().second->addValue("");
00301 m_state = IN_PUSHED_CONFIG;
00302 }
00303 else if (m_state == IN_STORED_STRING && tag == "string")
00304 m_state = IN_PUSHED_CONFIG;
00305 else
00306 throw ParserError("Wrong closing tag found " + tag);
00307 }
00308
00314 virtual void data(const std::string &data)
00315 {
00316 debug_config_state_machine("data", data, m_state);
00317
00318
00319 if (m_state == IN_BEGIN_STRING)
00320 {
00321 m_configs.back().second->addValue(data);
00322 m_state = IN_STORED_STRING;
00323 }
00324 else if (strspn(data.c_str(), " \t\n") != data.size())
00325 throw ParserError("Unexpected text " + data);
00326 }
00327
00331 FWConfiguration *config(void)
00332 {
00333 return m_first.get();
00334 }
00335
00336 private:
00337 std::vector<std::pair<std::string, FWConfiguration *> > m_configs;
00338 enum STATES m_state;
00339 std::auto_ptr<FWConfiguration> m_first;
00340
00341 std::string m_currentConfigName;
00342 };
00343
00350 void
00351 FWConfigurationManager::readFromFile(const std::string& iName) const
00352 {
00353 std::ifstream f(iName.c_str());
00354 if (f.peek() != (int) '<')
00355 return readFromOldFile(iName);
00356
00357
00358 SimpleSAXParser syntaxTest(f);
00359 syntaxTest.parse();
00360 f.close();
00361
00362
00363 std::ifstream g(iName.c_str());
00364
00365 FWXMLConfigParser parser(g);
00366 parser.parse();
00367 setFrom(*parser.config());
00368 }
00369
00370
00371
00372