00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <jccl/jcclConfig.h>
00034
00035 #include <fstream>
00036 #include <sys/types.h>
00037
00038 #include <vpr/vpr.h>
00039 #include <vpr/Util/FileUtils.h>
00040
00041 #include <jccl/Util/Debug.h>
00042 #include <jccl/Config/ConfigTokens.h>
00043 #include <jccl/Config/ParseUtil.h>
00044 #include <jccl/Config/ConfigElement.h>
00045 #include <jccl/Config/ElementFactory.h>
00046 #include <jccl/Config/Configuration.h>
00047
00048 namespace tokens = jccl::configuration_tokens;
00049
00050 namespace jccl
00051 {
00052
00053 Configuration::Configuration()
00054 {}
00055
00056 Configuration::Configuration(const Configuration& db)
00057 {
00058 *this = db;
00059 }
00060
00061 Configuration::~Configuration()
00062 {}
00063
00064 const std::string& Configuration::getFileName() const
00065 {
00066 return mFileName;
00067 }
00068
00069 void Configuration::setFileName(const std::string& fname)
00070 {
00071 mFileName = fname;
00072 }
00073
00074 ConfigElementPtr Configuration::get(const std::string& name) const
00075 {
00076 for ( std::vector<ConfigElementPtr>::const_iterator i = mElements.begin();
00077 i != mElements.end();
00078 ++i )
00079 {
00080 if ( name == (*i)->getName() )
00081 {
00082 return *i;
00083 }
00084 }
00085 return ConfigElementPtr();
00086 }
00087
00088 void Configuration::getByType(const std::string& typeName,
00089 std::vector<ConfigElementPtr>& elements) const
00090 {
00091
00092 for ( std::vector<ConfigElementPtr>::const_iterator i = mElements.begin();
00093 i != mElements.end();
00094 ++i )
00095 {
00096 if ( typeName == (*i)->getID() )
00097 {
00098 elements.push_back(*i);
00099 }
00100 }
00101 }
00102
00103 bool Configuration::remove(const std::string& name)
00104 {
00105 for ( std::vector<ConfigElementPtr>::iterator i = mElements.begin();
00106 i != mElements.end();
00107 ++i )
00108 {
00109 if ( name == (*i)->getName() )
00110 {
00111 mElements.erase(i);
00112 return true;
00113 }
00114 }
00115 return false;
00116 }
00117
00118
00119
00120 std::ostream& operator<<(std::ostream& out, const Configuration& self)
00121 {
00122 cppdom::NodePtr cfg_node;
00123
00124
00125
00126 out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
00127 out << "<?" << tokens::SETTINGS_INSTRUCTION << " "
00128 << tokens::CFG_VERSION_ATTR << "=\"" << tokens::CFG_VERSION << "\"?>";
00129
00130 self.createConfigurationNode(cfg_node);
00131 cfg_node->save(out);
00132 return out;
00133 }
00134
00135 std::istream& operator>>(std::istream& in, Configuration& self)
00136 {
00137
00138 cppdom::DocumentPtr cfg_doc(ElementFactory::instance()->createXMLDocument());
00139 cppdom::ContextPtr context_ptr = cfg_doc->getContext();
00140
00141
00142 cfg_doc->load(in, context_ptr);
00143
00144
00145 cppdom::NodePtr cfg_node(cfg_doc->getChild(tokens::CONFIGURATION));
00146 self.setConfigurationNode(cfg_node);
00147
00148
00149 self.loadFromElementNode(cfg_node->getChild(tokens::ELEMENTS));
00150
00151 cppdom::NodePtr def_path_node(cfg_node->getChild(tokens::DEFINITION_PATH));
00152 if ( def_path_node.get() != NULL )
00153 {
00154 self.setDefinitionPath(def_path_node);
00155 }
00156
00157
00158 cppdom::NodeList inc_list = cfg_node->getChildren(tokens::INCLUDE);
00159 for ( cppdom::NodeList::iterator itr = inc_list.begin();
00160 itr != inc_list.end();
00161 ++itr )
00162 {
00163 std::string cfg_filename = (*itr)->getCdata();
00164 vprDEBUG(jcclDBG_CONFIG, vprDBG_CONFIG_LVL)
00165 << "Including " << cfg_filename << std::endl
00166 << vprDEBUG_FLUSH;
00167
00168
00169
00170
00171 self.load(cfg_filename);
00172 }
00173
00174 return in;
00175 }
00176
00177 bool Configuration::load(const std::string& filename,
00178 const std::string& parentfile)
00179 {
00180 vprDEBUG(jcclDBG_CONFIG, vprDBG_STATE_LVL)
00181 << "[jccl::Configuration::load()] Loading file '" << filename
00182 << "' with parent file '" << parentfile << "'\n" << vprDEBUG_FLUSH;
00183
00184 mFileName = ParseUtil::expandFileName(filename, parentfile);
00185
00186 vprDEBUG_OutputGuard(jcclDBG_CONFIG, vprDBG_CONFIG_LVL,
00187 std::string("Loading config file ") + mFileName +
00188 std::string("\n"),
00189 std::string(""));
00190
00191
00192
00193 cppdom::Document cfg_doc(cppdom::ContextPtr(new cppdom::Context()));
00194 bool status(false);
00195
00196 try
00197 {
00198 cfg_doc.loadFile(mFileName);
00199
00200 cppdom::NodePtr cfg_node(cfg_doc.getChild(tokens::CONFIGURATION));
00201 vprASSERT(cfg_node.get() != NULL);
00202
00203
00204
00205 mConfigurationNode = cfg_node;
00206
00207 cppdom::NodePtr def_path_node(cfg_node->getChild(tokens::DEFINITION_PATH));
00208 if ( def_path_node.get() != NULL )
00209 {
00210 setDefinitionPath(def_path_node);
00211 }
00212
00213
00214 cppdom::NodeList inc_list = cfg_node->getChildren(tokens::INCLUDE);
00215 for ( cppdom::NodeList::iterator itr = inc_list.begin();
00216 itr != inc_list.end();
00217 ++itr )
00218 {
00219 std::string cfg_filename = (*itr)->getCdata();
00220 vprDEBUG(jcclDBG_CONFIG, vprDBG_CONFIG_LVL)
00221 << "Including " << cfg_filename << std::endl
00222 << vprDEBUG_FLUSH;
00223
00224
00225
00226
00227 load(cfg_filename, mFileName);
00228 }
00229
00230
00231 loadFromElementNode(cfg_node->getChild(tokens::ELEMENTS), mFileName);
00232
00233 status = true;
00234 }
00235 catch (cppdom::Error& xml_e)
00236 {
00237 cppdom::Location where(cfg_doc.getContext()->getLocation());
00238 std::string errmsg = xml_e.getStrError();
00239
00240 int line_num = where.getLine() + 1;
00241 int pos = where.getPos() + 1;
00242
00243
00244 vprDEBUG(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00245 << clrOutBOLD(clrRED, "Configuration XML Error:") << " "
00246 << mFileName << ": line " << line_num << " at position " << pos
00247 << std::endl << vprDEBUG_FLUSH;
00248 vprDEBUG_NEXT(vprDBG_ERROR, vprDBG_CRITICAL_LVL)
00249 << "Error: " << errmsg << std::endl << vprDEBUG_FLUSH;
00250
00251
00252 std::ifstream errfile(mFileName.c_str());
00253 if ( errfile )
00254 {
00255 char linebuffer[1024];
00256 for ( int i = 0; i < line_num && ! errfile.eof(); ++i )
00257 {
00258 errfile.getline(linebuffer, 1024);
00259 }
00260
00261 if ( pos >= 80 )
00262 {
00263 pos %= 80;
00264 }
00265
00266 std::string err_line(linebuffer + (where.getPos() - pos));
00267 if (err_line.length() >= 79)
00268 {
00269 err_line.erase(79);
00270 }
00271
00272 std::cout << err_line << std::endl;
00273 std::cout << linebuffer << std::endl;
00274
00275 for ( int i = 2; i < pos; ++i )
00276 {
00277 std::cout << " ";
00278 }
00279
00280 std::cout << '^' << std::endl;
00281 }
00282 }
00283
00284 return status;
00285 }
00286
00287 bool Configuration::save(const std::string& fname) const
00288 {
00289 cppdom::NodePtr cfg_node;
00290 createConfigurationNode(cfg_node);
00291 cppdom::DocumentPtr cfg_doc(new cppdom::Document);
00292 cfg_doc->addChild(cfg_node);
00293 cfg_doc->saveFile(fname);
00294 return true;
00295 }
00296
00297 std::vector<jccl::ConfigElementPtr>& Configuration::vec()
00298 {
00299 return mElements;
00300 }
00301
00302 void Configuration::setDefinitionPath(cppdom::NodePtr defPathNode)
00303 {
00304 mDefsPath.clear();
00305 extendDefinitionPath(defPathNode);
00306 }
00307
00308 void Configuration::setConfigurationNode(cppdom::NodePtr cfgNode)
00309 {
00310 mConfigurationNode = cfgNode;
00311 }
00312
00313 void Configuration::extendDefinitionPath(cppdom::NodePtr defPathNode)
00314 {
00315 cppdom::NodeList dirs = defPathNode->getChildren(tokens::DIR);
00316 for (cppdom::NodeList::iterator d = dirs.begin(); d != dirs.end(); ++d)
00317 {
00318 mDefsPath.push_back((*d)->getCdata());
00319 ElementFactory::instance()->loadDefs(vpr::replaceEnvVars((*d)->getCdata()));
00320 }
00321 }
00322
00326 struct ElementNamePred
00327 {
00328 ElementNamePred(const std::string& name)
00329 : mName(name)
00330 {}
00331
00332 bool operator()(jccl::ConfigElementPtr element)
00333 {
00334 return (element->getName() == mName);
00335 }
00336
00337 std::string mName;
00338 };
00339
00341 bool Configuration::loadFromElementNode(cppdom::NodePtr elementsNode,
00342 const std::string& currentFile)
00343 {
00344 if(elementsNode->getName() != tokens::ELEMENTS)
00345 {
00346 vprASSERT(false && "Trying to load a elements tree that is not an <elements> node");
00347 return false;
00348 }
00349
00350 for (cppdom::NodeList::iterator cur_child = elementsNode->getChildren().begin();
00351 cur_child != elementsNode->getChildren().end();
00352 ++cur_child)
00353 {
00354 ConfigElementPtr new_element(new ConfigElement());
00355 bool init_status = new_element->initFromNode(*cur_child);
00356
00357
00358
00359 if(!init_status)
00360 {
00361 vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00362 << " Config element load problem in file: " << currentFile
00363 << std::endl << vprDEBUG_FLUSH;
00364 vprDEBUG(vprDBG_ALL,vprDBG_CRITICAL_LVL)
00365 << " Skipping element: " << (*cur_child)->getAttribute(tokens::NAME).getString()
00366 << std::endl << vprDEBUG_FLUSH;
00367 }
00368 else
00369 {
00370
00371
00372 std::vector<ConfigElementPtr>::iterator iter =
00373 std::find_if(mElements.begin(), mElements.end(),
00374 ElementNamePred(new_element->getName()));
00375
00376
00377
00378 if ( iter == mElements.end() )
00379 {
00380 mElements.push_back(new_element);
00381 }
00382
00383 else
00384 {
00385 *iter = new_element;
00386 }
00387 }
00388 }
00389
00390 return true;
00391 }
00392
00393 void Configuration::createConfigurationNode(cppdom::NodePtr& cfgNode) const
00394 {
00395 if (NULL == mConfigurationNode.get())
00396 {
00397 cfgNode = ElementFactory::instance()->createXMLNode();
00398 cfgNode->setName(tokens::CONFIGURATION);
00399 cfgNode->setAttribute("xmlns", tokens::CFG_NS_str);
00400 cfgNode->setAttribute("name", "Active Configuration");
00401 cfgNode->setAttribute("xmlns:xsi",
00402 "http://www.w3.org/2001/XMLSchema-instance");
00403 cfgNode->setAttribute("xsi:schemaLocation",
00404 tokens::CFG_NS_str + " " + tokens::CFG_SCHEMA);
00405
00406 cppdom::NodePtr elements_node = ElementFactory::instance()->createXMLNode();
00407 elements_node->setName(tokens::ELEMENTS);
00408
00409 std::vector<ConfigElementPtr>::const_iterator cur_element;
00410
00411 for (cur_element = mElements.begin();
00412 cur_element != mElements.end();
00413 ++cur_element)
00414 {
00415 cppdom::NodePtr child_node = (*cur_element)->getNode();
00416 elements_node->addChild(child_node);
00417 }
00418
00419 cfgNode->addChild(elements_node);
00420 }
00421 else
00422 {
00423 cfgNode = mConfigurationNode;
00424 }
00425 }
00426
00427 }