00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "configlistener.h"
00023 #include "configuration.h"
00024 #include "log.h"
00025 
00026 #include "utils/stringutils.h"
00027 #include "utils/xml.h"
00028 
00029 void ConfigurationObject::setValue(const std::string &key,
00030                                    const std::string &value)
00031 {
00032     mOptions[key] = value;
00033 }
00034 
00035 void Configuration::setValue(const std::string &key, const std::string &value)
00036 {
00037     ConfigurationObject::setValue(key, value);
00038 
00039     
00040     ListenerMapIterator list = mListenerMap.find(key);
00041     if (list != mListenerMap.end()) {
00042         Listeners listeners = list->second;
00043         for (ListenerIterator i = listeners.begin(); i != listeners.end(); i++)
00044         {
00045             (*i)->optionChanged(key);
00046         }
00047     }
00048 }
00049 
00050 std::string ConfigurationObject::getValue(const std::string &key,
00051                                           const std::string &deflt) const
00052 {
00053     Options::const_iterator iter = mOptions.find(key);
00054     return ((iter != mOptions.end()) ? iter->second : deflt);
00055 }
00056 
00057 int ConfigurationObject::getValue(const std::string &key, int deflt) const
00058 {
00059     Options::const_iterator iter = mOptions.find(key);
00060     return (iter != mOptions.end()) ? atoi(iter->second.c_str()) : deflt;
00061 }
00062 
00063 unsigned ConfigurationObject::getValue(const std::string &key,
00064                                        unsigned deflt) const
00065 {
00066     Options::const_iterator iter = mOptions.find(key);
00067     return (iter != mOptions.end()) ? atol(iter->second.c_str()) : deflt;
00068 }
00069 
00070 double ConfigurationObject::getValue(const std::string &key,
00071                                      double deflt) const
00072 {
00073     Options::const_iterator iter = mOptions.find(key);
00074     return (iter != mOptions.end()) ? atof(iter->second.c_str()) : deflt;
00075 }
00076 
00077 void ConfigurationObject::deleteList(const std::string &name)
00078 {
00079     for (ConfigurationList::const_iterator
00080              it = mContainerOptions[name].begin(); it != mContainerOptions[name].end(); it++)
00081         delete *it;
00082 
00083     mContainerOptions[name].clear();
00084 }
00085 
00086 void ConfigurationObject::clear()
00087 {
00088     for (std::map<std::string, ConfigurationList>::const_iterator
00089              it = mContainerOptions.begin(); it != mContainerOptions.end(); it++)
00090         deleteList(it->first);
00091     mOptions.clear();
00092 }
00093 
00094 ConfigurationObject::~ConfigurationObject()
00095 {
00096     clear();
00097 }
00098 
00099 void ConfigurationObject::initFromXML(xmlNodePtr parent_node)
00100 {
00101     clear();
00102 
00103     for_each_xml_child_node(node, parent_node)
00104     {
00105         if (xmlStrEqual(node->name, BAD_CAST "list")) {
00106             
00107 
00108             std::string name = XML::getProperty(node, "name", std::string());
00109 
00110             for_each_xml_child_node(subnode, node)
00111             {
00112                 if (xmlStrEqual(subnode->name, BAD_CAST name.c_str())
00113                     && subnode->type == XML_ELEMENT_NODE) {
00114                     ConfigurationObject *cobj = new ConfigurationObject;
00115 
00116                     cobj->initFromXML(subnode); 
00117 
00118                     mContainerOptions[name].push_back(cobj);
00119                 }
00120             }
00121 
00122         } else if (xmlStrEqual(node->name, BAD_CAST "option")) {
00123             
00124 
00125             std::string name = XML::getProperty(node, "name", std::string());
00126             std::string value = XML::getProperty(node, "value", std::string());
00127 
00128             if (!name.empty() && !value.empty())
00129                 mOptions[name] = value;
00130         } 
00131     }
00132 }
00133 
00134 void Configuration::init(const std::string &filename)
00135 {
00136     mConfigPath = filename;
00137 
00138     
00139     FILE *testFile = fopen(filename.c_str(), "r");
00140     if (!testFile) {
00141         return;
00142     }
00143     else {
00144         fclose(testFile);
00145     }
00146 
00147     xmlDocPtr doc = xmlReadFile(filename.c_str(), NULL, 0);
00148 
00149     if (!doc) return;
00150 
00151     xmlNodePtr rootNode = xmlDocGetRootElement(doc);
00152 
00153     if (!rootNode || !xmlStrEqual(rootNode->name, BAD_CAST "configuration")) {
00154         logger->log("Warning: No configuration file (%s)", filename.c_str());
00155         xmlFreeDoc(doc);
00156         return;
00157     }
00158 
00159     initFromXML(rootNode);
00160 
00161     xmlFreeDoc(doc);
00162 }
00163 
00164 void ConfigurationObject::writeToXML(xmlTextWriterPtr writer)
00165 {
00166     for (Options::const_iterator i = mOptions.begin(), i_end = mOptions.end();
00167          i != i_end; ++i)
00168     {
00169         xmlTextWriterStartElement(writer, BAD_CAST "option");
00170         xmlTextWriterWriteAttribute(writer,
00171                 BAD_CAST "name", BAD_CAST i->first.c_str());
00172         xmlTextWriterWriteAttribute(writer,
00173                 BAD_CAST "value", BAD_CAST i->second.c_str());
00174         xmlTextWriterEndElement(writer);
00175     }
00176 
00177     for (std::map<std::string, ConfigurationList>::const_iterator
00178              it = mContainerOptions.begin(); it != mContainerOptions.end(); it++) {
00179         const char *name = it->first.c_str();
00180 
00181         xmlTextWriterStartElement(writer, BAD_CAST "list");
00182         xmlTextWriterWriteAttribute(writer, BAD_CAST "name", BAD_CAST name);
00183 
00184         
00185         for (ConfigurationList::const_iterator
00186                  elt_it = it->second.begin(); elt_it != it->second.end(); elt_it++) {
00187 
00188             xmlTextWriterStartElement(writer, BAD_CAST name);
00189             (*elt_it)->writeToXML(writer);
00190             xmlTextWriterEndElement(writer);
00191         }
00192 
00193         xmlTextWriterEndElement(writer);
00194     }
00195 }
00196 
00197 void Configuration::write()
00198 {
00199     
00200     FILE *testFile = fopen(mConfigPath.c_str(), "w");
00201     if (!testFile) {
00202         logger->log("Configuration::write() couldn't open %s for writing",
00203                     mConfigPath.c_str());
00204         return;
00205     }
00206     else {
00207         fclose(testFile);
00208     }
00209 
00210     xmlTextWriterPtr writer = xmlNewTextWriterFilename(mConfigPath.c_str(), 0);
00211 
00212     if (!writer) {
00213         logger->log("Configuration::write() error while creating writer");
00214         return;
00215     }
00216 
00217     logger->log("Configuration::write() writing configuration...");
00218 
00219     xmlTextWriterSetIndent(writer, 1);
00220     xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
00221     xmlTextWriterStartElement(writer, BAD_CAST "configuration");
00222 
00223     writeToXML(writer);
00224 
00225     xmlTextWriterEndDocument(writer);
00226     xmlFreeTextWriter(writer);
00227 }
00228 
00229 void Configuration::addListener(
00230         const std::string &key, ConfigListener *listener)
00231 {
00232     mListenerMap[key].push_front(listener);
00233 }
00234 
00235 void Configuration::removeListener(
00236         const std::string &key, ConfigListener *listener)
00237 {
00238     mListenerMap[key].remove(listener);
00239 }