4 * @brief Settings manager implementation.
6 * @author Ossama Othman @<ossama.othman@@intel.com@>
9 * Copyright 2012, 2013 Intel Corporation All Rights Reserved.
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation;
14 * version 2.1 of the License.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 * Boston, MA 02110-1301 USA
29 #include "manager.hpp"
30 #include <settingsd/plugin.hpp>
31 #include <settingsd/response_callback.hpp>
32 #include <settingsd/json_glib_traits.hpp>
33 #include <settingsd/smart_ptr.hpp>
37 #include <boost/filesystem.hpp>
40 ivi::settings::manager::manager(std::string const & dir)
47 ivi::settings::manager::~manager()
52 ivi::settings::manager::register_setting(std::unique_ptr<plugin> p)
54 std::string const & id = p->id();
57 settings_.insert(std::make_pair(id, std::move(p)));
60 std::cerr << "Settings plugin registration for \""
61 << id << "\" failed." << std::endl;
67 ivi::settings::manager::load_settings(std::string const & dir)
69 if (dir.length() == 0)
70 throw std::logic_error("Zero length settings plugin directory path.");
72 namespace fs = boost::filesystem;
74 // Find all settings plugins in the plugin directory.
75 fs::path settings_dir(dir);
77 if (fs::is_directory(settings_dir)) {
78 // Iterate over directory entries, create settings instances
79 // for each settings plugin, and store in settings map.
81 fs::directory_iterator const end;
82 for (fs::directory_iterator i(settings_dir); i != end; ++i) {
84 fs::path const & plugin_path = (*i).path();
86 // Verify that the plugin is actually a file with the
87 // appropriate extension (e.g. ".so").
89 // Note that the .extension() method returns a string like
90 // ".so" whereas G_MODULE_SUFFIX is preprocessor symbol/string
91 // like "so". We prepend a period to G_MODULE_SUFFIX using
92 // standard string literal concatenation.
93 if (!fs::is_regular_file(plugin_path)
94 || plugin_path.extension() != "." G_MODULE_SUFFIX)
97 std::string const & plugin_name = plugin_path.string();
99 std::unique_ptr<loader> plugin(new loader(plugin_name, *this));
101 loaders_.push_back(std::move(plugin));
103 catch (std::logic_error & e) {
105 * @todo I really hate catching an exception like this, but I
106 * really don't want to resort to a construct/init()
107 * style of object initialization. Fix.
108 */std::cerr << "Error loading plugin: " << e.what() << "\n";
112 if (settings_.size() == 0) {
113 std::cerr << "Settings plugin directory \""
114 << dir << "\" has no plugins.\n";
116 std::cerr << "Registered settings plugins: \n";
117 for (auto const & i : settings_)
118 std::cerr << "\t" << i.first << '\n';
121 std::cerr << "Settings plugin directory \""
122 << dir << "\" does not exist.\n";
127 ivi::settings::manager::dispatch(std::string request,
128 struct libwebsocket * wsi)
130 if (request.empty()) {
131 response_callback response(wsi, std::string(), std::string());
132 response.send_error("Empty settings request.");
135 smart_ptr<JsonParser> const parser(json_parser_new());
136 json_parser_load_from_data(parser.get(), request.c_str(), -1, nullptr);
138 JsonReader * const reader = json_reader_new(json_parser_get_root(parser.get()));
139 smart_ptr<JsonReader> const safe_reader(reader);
141 // Retrieve setting name and transcation ID from the JSON request
143 char const * type = nullptr;
144 if (json_reader_read_member(reader, "type")) {
145 type = json_reader_get_string_value(reader);
147 json_reader_end_member(reader);
150 * @todo Allow transaction ID to be null?
152 char const * transaction_id = "";
153 if (json_reader_read_member(reader, "transactionid")) {
154 transaction_id = json_reader_get_string_value(reader);
156 json_reader_end_member(reader);
158 response_callback response(wsi,
159 type == nullptr ? "" : type,
163 if (type != nullptr) {
164 // Dispatch the request to the corresponding settings plugin.
165 auto i = settings_.find(type);
166 if (i != settings_.end())
167 (*i).second->handle_request(request, response);
170 std::string("Settings type \"")
171 + type + "\" not supported.";
173 response.send_error(error);
177 "Settings type not specified in request.\n"
178 "Supported plugins:\n";
180 for (auto const & i : settings_)
181 error += "\t" + i.first + "\n";
183 response.send_error(error);
191 // indent-tabs-mode: nil