blob: 12923390d05610cb37421a5e925f2fc6477fe3f6 [file] [log] [blame]
// Copyright 2014 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "buffet/states/state_package.h"
#include <base/logging.h>
#include <base/values.h>
#include <chromeos/dbus/data_serialization.h>
#include "buffet/commands/prop_types.h"
#include "buffet/commands/prop_values.h"
#include "buffet/commands/schema_utils.h"
#include "buffet/states/error_codes.h"
namespace buffet {
StatePackage::StatePackage(const std::string& name) : name_(name) {
}
bool StatePackage::AddSchemaFromJson(const base::DictionaryValue* json,
chromeos::ErrorPtr* error) {
ObjectSchema schema;
if (!schema.FromJson(json, nullptr, error))
return false;
// Scan first to make sure we have no property redefinitions.
for (const auto& pair : schema.GetProps()) {
if (types_.GetProp(pair.first)) {
chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
errors::state::kPropertyRedefinition,
"State property '%s.%s' is already defined",
name_.c_str(), pair.first.c_str());
return false;
}
}
// Now move all the properties to |types_| object.
for (const auto& pair : schema.GetProps()) {
types_.AddProp(pair.first, pair.second->Clone());
// Create default value for this state property.
values_.emplace(pair.first, pair.second->CreateValue());
}
return true;
}
bool StatePackage::AddValuesFromJson(const base::DictionaryValue* json,
chromeos::ErrorPtr* error) {
base::DictionaryValue::Iterator iter(*json);
while (!iter.IsAtEnd()) {
std::string property_name = iter.key();
auto it = values_.find(property_name);
if (it == values_.end()) {
chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
errors::state::kPropertyNotDefined,
"State property '%s.%s' is not defined",
name_.c_str(), property_name.c_str());
return false;
}
auto new_value = it->second->GetPropType()->CreateValue();
if (!new_value->FromJson(&iter.value(), error))
return false;
it->second = std::move(new_value);
iter.Advance();
}
return true;
}
std::unique_ptr<base::DictionaryValue> StatePackage::GetValuesAsJson(
chromeos::ErrorPtr* error) const {
std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue);
for (const auto& pair : values_) {
auto value = pair.second->ToJson(error);
if (!value) {
dict.reset();
break;
}
dict->SetWithoutPathExpansion(pair.first, value.release());
}
return dict;
}
chromeos::Any StatePackage::GetPropertyValue(const std::string& property_name,
chromeos::ErrorPtr* error) const {
auto it = values_.find(property_name);
if (it == values_.end()) {
chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
errors::state::kPropertyNotDefined,
"State property '%s.%s' is not defined",
name_.c_str(), property_name.c_str());
return chromeos::Any();
}
return PropValueToDBusVariant(it->second.get());
}
bool StatePackage::SetPropertyValue(const std::string& property_name,
const chromeos::Any& value,
chromeos::ErrorPtr* error) {
auto it = values_.find(property_name);
if (it == values_.end()) {
chromeos::Error::AddToPrintf(error, FROM_HERE, errors::state::kDomain,
errors::state::kPropertyNotDefined,
"State property '%s.%s' is not defined",
name_.c_str(), property_name.c_str());
return false;
}
auto new_value = PropValueFromDBusVariant(it->second->GetPropType(),
value, error);
if (!new_value)
return false;
it->second = std::move(new_value);
return true;
}
} // namespace buffet