Back to index

nordugrid-arc-nox  1.1.0~rc6
configcore.cpp
Go to the documentation of this file.
00001 /*
00002  * Core configuration class
00003  */
00004 
00005 #ifdef HAVE_CONFIG_H
00006 #include "config.h"
00007 #endif
00008 
00009 #include <fstream>
00010 #include <iostream>
00011 #include <map>
00012 #include <string>
00013 
00014 #include "configcore.h"
00015 #include "ngconfig.h"
00016 #include "xmlconfig.h"
00017 
00018 namespace ARex {
00019 
00020 Arc::Logger ConfigLogger(Arc::Logger::getRootLogger(), "Config");
00021 
00022 Option::Option(const std::string& a, const std::string& v) : attr(a),
00023                                                              value(v) {}
00024 
00025 Option::Option(const std::string& a, const std::string& v,
00026                const std::map<std::string, std::string>& s) : attr(a),
00027                                                               value(v),
00028                                                               suboptions(s) {}
00029 
00030 Option::~Option() {}
00031 
00032 void Option::AddSubOption(const std::string& attr, const std::string& value) {
00033        suboptions[attr] = value;
00034 }
00035 
00036 std::string Option::FindSubOptionValue(const std::string& attr) const {
00037        std::map<std::string, std::string>::const_iterator
00038               i = suboptions.find(attr);
00039        return (i == suboptions.end() ? std::string() : i->second);
00040 }
00041 
00042 const std::string& Option::GetAttr() const {
00043        return attr;
00044 }
00045 
00046 const std::string& Option::GetValue() const {
00047        return value;
00048 }
00049 
00050 const std::map<std::string, std::string>& Option::GetSubOptions() const {
00051        return suboptions;
00052 }
00053 
00054 
00055 ConfGrp::ConfGrp(const std::string& s) : section(s) {}
00056 
00057 ConfGrp::ConfGrp(const std::string& s,
00058                  const std::string& i) : section(s), id (i) {}
00059 
00060 ConfGrp::ConfGrp(const std::string& s, const std::string& i,
00061                  const std::list<Option>& o) : section(s), id (i),
00062                                                options(o) {}
00063 
00064 void ConfGrp::AddOption(const Option& opt) {
00065        options.push_back(opt);
00066 }
00067 
00068 std::list<Option> ConfGrp::FindOption(const std::string& attr) const {
00069        std::list<Option> opts;
00070        for (std::list<Option>::const_iterator it = options.begin();
00071             it != options.end(); it++)
00072               if (it->GetAttr() == attr)
00073                      opts.push_back(*it);
00074        return opts;
00075 }
00076 
00077 std::list<std::string> ConfGrp::FindOptionValue(const std::string& attr) const {
00078        std::list<std::string> opts;
00079        for (std::list<Option>::const_iterator it = options.begin();
00080             it != options.end(); it++)
00081               if (it->GetAttr() == attr)
00082                      opts.push_back(it->GetValue());
00083        return opts;
00084 }
00085 
00086 const std::string& ConfGrp::GetSection() const {
00087        return section;
00088 }
00089 
00090 const std::string& ConfGrp::GetID() const {
00091        return id;
00092 }
00093 
00094 const std::list<Option>& ConfGrp::GetOptions() const {
00095        return options;
00096 }
00097 
00098 
00099 Config::Config() {}
00100 
00101 Config::~Config() {}
00102 
00103 void Config::AddConfGrp(const ConfGrp& confgrp) {
00104        configs.push_back(confgrp);
00105 }
00106 
00107 const ConfGrp& Config::FindConfGrp(const std::string& section,
00108                                    const std::string& id) const {
00109        for (std::list<ConfGrp>::const_reverse_iterator it = configs.rbegin();
00110             it != configs.rend(); it++)
00111               if (it->GetSection() == section && it->GetID() == id)
00112                      return *it;
00113        throw ConfigError("Configuration group not defined");
00114 }
00115 
00116 const std::list<ConfGrp>& Config::GetConfigs() const {
00117        return configs;
00118 }
00119 
00120 std::list<std::string> Config::ConfValue(const std::string& path) const {
00121        try {
00122               std::string id;
00123               std::string::size_type pos1 = path.find('@');
00124               if (pos1 != std::string::npos)
00125                      id = path.substr(0, pos1++);
00126               else
00127                      pos1 = 0;
00128               std::string::size_type pos2 = path.rfind('/');
00129               if (pos2 == std::string::npos || pos2 < pos1)
00130                      throw ConfigError("Illegal configuration path");
00131               return FindConfGrp(path.substr(pos1, pos2 - pos1),
00132                                  id).FindOptionValue(path.substr(pos2 + 1));
00133        }
00134        catch(ConfigError) {
00135               return std::list<std::string>();
00136        }
00137 }
00138 
00139 
00140 std::string Config::FirstConfValue(const std::string& path) const {
00141        std::list<std::string> values = ConfValue(path);
00142        if (!values.empty())
00143               return values.front();
00144        else
00145               return std::string();
00146 }
00147 
00148 
00149 Config ReadConfig(std::istream& is) {
00150 
00151        try {
00152               is.seekg(0, std::ios::beg);
00153               return XMLConfig().Read(is);
00154        }
00155        catch(ConfigError) {
00156               is.clear();
00157        }
00158        try {
00159               is.seekg(0, std::ios::beg);
00160               return NGConfig().Read(is);
00161        }
00162        catch(ConfigError) {
00163               is.clear();
00164        }
00165        throw ConfigError("Unknown configuration format");
00166 }
00167 
00168 
00169 Config ReadConfig(const std::string& filename) {
00170 
00171        static std::map<std::string, Config> configcache;
00172 
00173        if (configcache.find(filename) != configcache.end()) {
00174               ConfigLogger.msg(Arc::DEBUG, "Using cached configuration: %s", filename);
00175               return configcache[filename];
00176        }
00177 
00178        ConfigLogger.msg(Arc::DEBUG, "Reading configuration file: %s", filename);
00179 
00180        std::ifstream is(filename.c_str());
00181        Config conf = ReadConfig(is);
00182        is.close();
00183        configcache[filename] = conf;
00184        return conf;
00185 }
00186 
00187 }
00188