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 }