blob: 12923390d05610cb37421a5e925f2fc6477fe3f6 [file] [log] [blame]
Alex Vakulenko07216fe2014-09-19 15:31:09 -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/states/state_package.h"
6
7#include <base/logging.h>
8#include <base/values.h>
9#include <chromeos/dbus/data_serialization.h>
10
11#include "buffet/commands/prop_types.h"
12#include "buffet/commands/prop_values.h"
13#include "buffet/commands/schema_utils.h"
14#include "buffet/states/error_codes.h"
15
16namespace buffet {
17
18StatePackage::StatePackage(const std::string& name) : name_(name) {
19}
20
21bool StatePackage::AddSchemaFromJson(const base::DictionaryValue* json,
22 chromeos::ErrorPtr* error) {
23 ObjectSchema schema;
24 if (!schema.FromJson(json, nullptr, error))
25 return false;
26
27 // Scan first to make sure we have no property redefinitions.
28 for (const auto& pair : schema.GetProps()) {
29 if (types_.GetProp(pair.first)) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080030 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
Alex Vakulenko07216fe2014-09-19 15:31:09 -070031 errors::state::kPropertyRedefinition,
32 "State property '%s.%s' is already defined",
33 name_.c_str(), pair.first.c_str());
34 return false;
35 }
36 }
37
38 // Now move all the properties to |types_| object.
39 for (const auto& pair : schema.GetProps()) {
Alex Vakulenko5ef75792015-03-19 15:50:44 -070040 types_.AddProp(pair.first, pair.second->Clone());
Alex Vakulenko07216fe2014-09-19 15:31:09 -070041 // Create default value for this state property.
Alex Vakulenko3e864c02015-03-24 10:19:32 -070042 values_.emplace(pair.first, pair.second->CreateValue());
Alex Vakulenko07216fe2014-09-19 15:31:09 -070043 }
44
45 return true;
46}
47
48bool StatePackage::AddValuesFromJson(const base::DictionaryValue* json,
49 chromeos::ErrorPtr* error) {
50 base::DictionaryValue::Iterator iter(*json);
51 while (!iter.IsAtEnd()) {
52 std::string property_name = iter.key();
53 auto it = values_.find(property_name);
54 if (it == values_.end()) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080055 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
Alex Vakulenko07216fe2014-09-19 15:31:09 -070056 errors::state::kPropertyNotDefined,
57 "State property '%s.%s' is not defined",
58 name_.c_str(), property_name.c_str());
59 return false;
60 }
61 auto new_value = it->second->GetPropType()->CreateValue();
62 if (!new_value->FromJson(&iter.value(), error))
63 return false;
Alex Vakulenko5ef75792015-03-19 15:50:44 -070064 it->second = std::move(new_value);
Alex Vakulenko07216fe2014-09-19 15:31:09 -070065 iter.Advance();
66 }
67 return true;
68}
69
70std::unique_ptr<base::DictionaryValue> StatePackage::GetValuesAsJson(
71 chromeos::ErrorPtr* error) const {
72 std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
73 for (const auto& pair : values_) {
74 auto value = pair.second->ToJson(error);
75 if (!value) {
76 dict.reset();
77 break;
78 }
79 dict->SetWithoutPathExpansion(pair.first, value.release());
80 }
81 return dict;
82}
83
84chromeos::Any StatePackage::GetPropertyValue(const std::string& property_name,
85 chromeos::ErrorPtr* error) const {
86 auto it = values_.find(property_name);
87 if (it == values_.end()) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080088 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
Alex Vakulenko07216fe2014-09-19 15:31:09 -070089 errors::state::kPropertyNotDefined,
90 "State property '%s.%s' is not defined",
91 name_.c_str(), property_name.c_str());
92 return chromeos::Any();
93 }
94 return PropValueToDBusVariant(it->second.get());
95}
96
97bool StatePackage::SetPropertyValue(const std::string& property_name,
98 const chromeos::Any& value,
99 chromeos::ErrorPtr* error) {
100 auto it = values_.find(property_name);
101 if (it == values_.end()) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -0800102 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700103 errors::state::kPropertyNotDefined,
104 "State property '%s.%s' is not defined",
105 name_.c_str(), property_name.c_str());
106 return false;
107 }
108 auto new_value = PropValueFromDBusVariant(it->second->GetPropType(),
109 value, error);
110 if (!new_value)
111 return false;
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700112 it->second = std::move(new_value);
Alex Vakulenko07216fe2014-09-19 15:31:09 -0700113 return true;
114}
115
116} // namespace buffet