blob: 6ba498e8e730cad938bbb39c49888e2e42529002 [file] [log] [blame]
Alex Vakulenko7c36b672014-07-16 14:50:58 -07001// Copyright 2014 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "buffet/commands/command_manager.h"
6
Alex Vakulenkofd448692014-07-22 07:46:53 -07007#include <base/file_util.h>
Alex Vakulenko5841c302014-07-23 10:49:49 -07008#include <base/files/file_enumerator.h>
Alex Vakulenkofd448692014-07-22 07:46:53 -07009#include <base/json/json_reader.h>
Alex Vakulenko5841c302014-07-23 10:49:49 -070010#include <base/values.h>
Alex Vakulenko5f472062014-08-14 17:54:04 -070011#include <chromeos/error.h>
12#include <chromeos/error_codes.h>
Alex Vakulenkofd448692014-07-22 07:46:53 -070013
14#include "buffet/commands/schema_constants.h"
Alex Vakulenkofd448692014-07-22 07:46:53 -070015
Alex Vakulenko7c36b672014-07-16 14:50:58 -070016namespace buffet {
17
18const CommandDictionary& CommandManager::GetCommandDictionary() const {
19 return dictionary_;
20}
21
Alex Vakulenkofd448692014-07-22 07:46:53 -070022bool CommandManager::LoadBaseCommands(const base::DictionaryValue& json,
Alex Vakulenko5f472062014-08-14 17:54:04 -070023 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070024 return base_dictionary_.LoadCommands(json, "", nullptr, error);
25}
26
27bool CommandManager::LoadBaseCommands(const base::FilePath& json_file_path,
Alex Vakulenko5f472062014-08-14 17:54:04 -070028 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070029 std::unique_ptr<const base::DictionaryValue> json = LoadJsonDict(
30 json_file_path, error);
31 if (!json)
32 return false;
33 return LoadBaseCommands(*json, error);
34}
35
36bool CommandManager::LoadCommands(const base::DictionaryValue& json,
37 const std::string& category,
Alex Vakulenko5f472062014-08-14 17:54:04 -070038 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070039 return dictionary_.LoadCommands(json, category, &base_dictionary_, error);
40}
41
42bool CommandManager::LoadCommands(const base::FilePath& json_file_path,
Alex Vakulenko5f472062014-08-14 17:54:04 -070043 chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070044 std::unique_ptr<const base::DictionaryValue> json = LoadJsonDict(
45 json_file_path, error);
46 if (!json)
47 return false;
48 std::string category = json_file_path.BaseName().RemoveExtension().value();
49 return LoadCommands(*json, category, error);
50}
51
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070052void CommandManager::Startup() {
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070053 LOG(INFO) << "Initializing CommandManager.";
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070054 // Load global standard GCD command dictionary.
55 base::FilePath base_command_file("/etc/buffet/gcd.json");
56 LOG(INFO) << "Loading standard commands from " << base_command_file.value();
Alex Vakulenkoc2bc9a42014-07-23 10:57:58 -070057 CHECK(LoadBaseCommands(base_command_file, nullptr))
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070058 << "Failed to load the standard command definitions.";
59
60 // Load static device command definitions.
61 base::FilePath device_command_dir("/etc/buffet/commands");
62 base::FileEnumerator enumerator(device_command_dir, false,
63 base::FileEnumerator::FILES,
64 FILE_PATH_LITERAL("*.json"));
65 base::FilePath json_file_path = enumerator.Next();
66 while (!json_file_path.empty()) {
67 LOG(INFO) << "Loading command schema from " << json_file_path.value();
Alex Vakulenkoc2bc9a42014-07-23 10:57:58 -070068 CHECK(LoadCommands(json_file_path, nullptr))
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070069 << "Failed to load the command definition file.";
70 json_file_path = enumerator.Next();
71 }
Alex Vakulenkoe4efaaf2014-07-22 08:08:44 -070072}
73
Alex Vakulenkofd448692014-07-22 07:46:53 -070074std::unique_ptr<const base::DictionaryValue> CommandManager::LoadJsonDict(
Alex Vakulenko5f472062014-08-14 17:54:04 -070075 const base::FilePath& json_file_path, chromeos::ErrorPtr* error) {
Alex Vakulenkofd448692014-07-22 07:46:53 -070076 std::string json_string;
77 if (!base::ReadFileToString(json_file_path, &json_string)) {
Alex Vakulenko5f472062014-08-14 17:54:04 -070078 chromeos::Error::AddToPrintf(error, chromeos::errors::file_system::kDomain,
79 chromeos::errors::file_system::kFileReadError,
80 "Failed to read file '%s'",
81 json_file_path.value().c_str());
Alex Vakulenkofd448692014-07-22 07:46:53 -070082 return std::unique_ptr<const base::DictionaryValue>();
83 }
84 std::string error_message;
85 base::Value* value = base::JSONReader::ReadAndReturnError(
86 json_string, base::JSON_PARSE_RFC, nullptr, &error_message);
87 if (!value) {
Alex Vakulenko5f472062014-08-14 17:54:04 -070088 chromeos::Error::AddToPrintf(error, chromeos::errors::json::kDomain,
89 chromeos::errors::json::kParseError,
90 "Error parsing content of JSON file '%s': %s",
91 json_file_path.value().c_str(),
92 error_message.c_str());
Alex Vakulenkofd448692014-07-22 07:46:53 -070093 return std::unique_ptr<const base::DictionaryValue>();
94 }
95 const base::DictionaryValue* dict_value = nullptr;
96 if (!value->GetAsDictionary(&dict_value)) {
97 delete value;
Alex Vakulenko5f472062014-08-14 17:54:04 -070098 chromeos::Error::AddToPrintf(error, chromeos::errors::json::kDomain,
99 chromeos::errors::json::kObjectExpected,
100 "Content of file '%s' is not a JSON object",
101 json_file_path.value().c_str());
Alex Vakulenkofd448692014-07-22 07:46:53 -0700102 return std::unique_ptr<const base::DictionaryValue>();
103 }
104 return std::unique_ptr<const base::DictionaryValue>(dict_value);
105}
106
Alex Vakulenko7c36b672014-07-16 14:50:58 -0700107} // namespace buffet