00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <opc/common/addons_core/config_file.h>
00013 #include <opc/common/addons_core/dynamic_addon_factory.h>
00014
00015 #include <boost/foreach.hpp>
00016 #include <boost/property_tree/ptree.hpp>
00017 #include <boost/property_tree/xml_parser.hpp>
00018 #include <boost/filesystem.hpp>
00019 #include <iostream>
00020
00021 using boost::property_tree::ptree;
00022
00023 namespace
00024 {
00025
00026 Common::ParametersGroup GetGroup(const std::string& name, const ptree& groupTree)
00027 {
00028 Common::ParametersGroup group(name);
00029
00030 if (groupTree.empty())
00031 {
00032 return group;
00033 }
00034
00035 BOOST_FOREACH(const ptree::value_type& child, groupTree)
00036 {
00037 if (child.second.empty())
00038 {
00039 group.Parameters.push_back(Common::Parameter(child.first, child.second.data()));
00040 continue;
00041 }
00042 group.Groups.push_back(GetGroup(child.first, child.second));
00043 }
00044
00045 return group;
00046 }
00047
00048 void AddParameter(Common::AddonParameters& params, const std::string& name, const ptree& tree)
00049 {
00050 if (tree.empty())
00051 {
00052 params.Parameters.push_back(Common::Parameter(name, tree.data()));
00053 return;
00054 }
00055 params.Groups.push_back(GetGroup(name, tree));
00056 }
00057
00058 }
00059
00060
00061 Common::Configuration Common::ParseConfiguration(const std::string& configPath)
00062 {
00063 ptree pt;
00064 read_xml(configPath, pt);
00065 Configuration configuration;
00066 BOOST_FOREACH(const ptree::value_type& config, pt)
00067 {
00068 if (config.first != "config")
00069 {
00070 std::cerr << "Unknown root tag " << config.first << " in the config file '" << configPath << "'" << std::endl;
00071 continue;
00072 }
00073
00074 BOOST_FOREACH(const ptree::value_type& param, config.second)
00075 {
00076 if (param.first != "modules")
00077 {
00078 AddParameter(configuration.Parameters, param.first, param.second);
00079 continue;
00080 }
00081
00082 BOOST_FOREACH(const ptree::value_type& module, param.second)
00083 {
00084 if (module.first != "module")
00085 {
00086 std::cerr << "Unknown tag " << module.first << " inside 'modules' in the config file '" << configPath << "'" << std::endl;
00087 continue;
00088 }
00089
00090 Common::ModuleConfiguration moduleConfig;
00091 moduleConfig.Id = module.second.get<std::string>("id");
00092 moduleConfig.Path = module.second.get<std::string>("path");
00093 if (boost::optional<const ptree&> dependsOn = module.second.get_child_optional("depends_on"))
00094 {
00095 BOOST_FOREACH(const ptree::value_type& depend, dependsOn.get())
00096 {
00097 if (depend.first != "id")
00098 {
00099 continue;
00100 }
00101 moduleConfig.Dependencies.push_back(depend.second.data());
00102 }
00103 }
00104
00105 if (boost::optional<const ptree&> parameters = module.second.get_child_optional("parameters"))
00106 {
00107 BOOST_FOREACH(const ptree::value_type& parameter, parameters.get())
00108 {
00109 AddParameter(moduleConfig.Parameters, parameter.first, parameter.second);
00110 }
00111 }
00112
00113 configuration.Modules.push_back(moduleConfig);
00114 }
00115 }
00116 }
00117 return configuration;
00118 }
00119
00120 Common::Configuration Common::ParseConfigurationFiles(const std::string& directory)
00121 {
00122 using namespace boost::filesystem;
00123 Common::Configuration configuration;
00124 path p(directory);
00125 directory_iterator dirIt(p);
00126 directory_iterator end;
00127
00128 std::for_each(dirIt, end, [&configuration](const directory_entry& entry)
00129 {
00130 if (entry.path().filename().extension() == ".conf")
00131 {
00132 std::cout << "Parsing config file: " << entry.path().native() << std::endl;
00133 Common::Configuration tmp = Common::ParseConfiguration(entry.path().string());
00134 configuration.Modules.insert(configuration.Modules.end(), tmp.Modules.begin(), tmp.Modules.end());
00135 configuration.Parameters.Groups.insert(configuration.Parameters.Groups.end(), tmp.Parameters.Groups.begin(), tmp.Parameters.Groups.end());
00136 configuration.Parameters.Parameters.insert(configuration.Parameters.Parameters.end(), tmp.Parameters.Parameters.begin(), tmp.Parameters.Parameters.end());
00137 }
00138 });
00139 return configuration;
00140 }
00141
00142
00143 namespace
00144 {
00145 void AddDependencies(ptree& moduleTree, const std::vector<Common::AddonId>& ids)
00146 {
00147 if (ids.empty())
00148 {
00149 return;
00150 }
00151
00152 ptree& deps = moduleTree.add("depends_on", "");
00153 for (auto idIt = ids.begin(); idIt != ids.end(); ++idIt)
00154 {
00155 deps.add("id", *idIt);
00156 }
00157 }
00158
00159 void AddGroup(ptree& moduleTree, const Common::ParametersGroup& group)
00160 {
00161 ptree& groupTree = moduleTree.add(group.Name, "");
00162 for (auto paramIt = group.Parameters.begin(); paramIt != group.Parameters.end(); ++paramIt)
00163 {
00164 groupTree.add(paramIt->Name, paramIt->Value);
00165 }
00166 for (auto groupIt = group.Groups.begin(); groupIt != group.Groups.end(); ++groupIt)
00167 {
00168 AddGroup(groupTree, *groupIt);
00169 }
00170 }
00171
00172 void AddParameters(ptree& moduleTree, const Common::AddonParameters& params, const char* groupName)
00173 {
00174 if (params.Parameters.empty() && params.Groups.empty())
00175 {
00176 return;
00177 }
00178
00179 ptree& paramsTree = moduleTree.add(groupName, "");
00180 for (auto paramIt = params.Parameters.begin(); paramIt != params.Parameters.end(); ++paramIt)
00181 {
00182 paramsTree.add(paramIt->Name, paramIt->Value);
00183 }
00184 for (auto groupIt = params.Groups.begin(); groupIt != params.Groups.end(); ++groupIt)
00185 {
00186 AddGroup(paramsTree, *groupIt);
00187 }
00188 }
00189 }
00190
00191 void Common::SaveConfiguration(const Common::ModulesConfiguration& modules, const std::string& configPath)
00192 {
00193 ptree pt;
00194 ptree& modulesPt = pt.put("config.modules", "");
00195
00196 for (auto configIt = modules.begin(); configIt != modules.end(); ++configIt)
00197 {
00198 ptree& moduleTree = modulesPt.add("module", "");
00199 const Common::ModuleConfiguration& config = *configIt;
00200 moduleTree.add("id", config.Id);
00201 moduleTree.add("path", config.Path);
00202 AddDependencies(moduleTree, config.Dependencies);
00203 AddParameters(moduleTree, config.Parameters, "parameters");
00204 }
00205
00206 write_xml(configPath, pt);
00207 }
00208
00209 Common::AddonInformation Common::GetAddonInfomation(const Common::ModuleConfiguration& config)
00210 {
00211 Common::AddonInformation info;
00212 info.Id = config.Id;
00213 info.Dependencies = config.Dependencies;
00214 info.Parameters = config.Parameters;
00215 info.Factory = Common::CreateDynamicAddonFactory(config.Path);
00216 return info;
00217 }