blob: ce71c50b01cda5fa3aa5bc14e2519332ad9dcd5a [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)) {
30 chromeos::Error::AddToPrintf(error, errors::state::kDomain,
31 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()) {
40 types_.AddProp(pair.first, pair.second);
41 // Create default value for this state property.
42 values_.insert(std::make_pair(pair.first, pair.second->CreateValue()));
43 }
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()) {
55 chromeos::Error::AddToPrintf(error, errors::state::kDomain,
56 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;
64 it->second = new_value;
65 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()) {
88 chromeos::Error::AddToPrintf(error, errors::state::kDomain,
89 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()) {
102 chromeos::Error::AddToPrintf(error, errors::state::kDomain,
103 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;
112 it->second = new_value;
113 return true;
114}
115
116} // namespace buffet