blob: f7732909ce61ed64057bd5bdf8be6b6553874272 [file] [log] [blame]
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -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/prop_constraints.h"
Alex Deymof6cbe322014-11-10 19:55:35 -08006
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -07007#include <base/json/json_writer.h>
8
Alex Vakulenko66ec2922014-06-17 15:30:22 -07009#include "buffet/commands/prop_values.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070010#include "buffet/commands/schema_constants.h"
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070011
12namespace buffet {
13
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -070014namespace {
15
16// Helper function to convert a property value to string, which is used for
17// error reporting.
18std::string PropValueToString(const PropValue& value) {
19 std::string result;
20 auto json = value.ToJson(nullptr);
21 if (json)
22 base::JSONWriter::Write(json.get(), &result);
23 return result;
24}
25
26} // anonymous namespace
27
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070028// Constraint ----------------------------------------------------------------
29Constraint::~Constraint() {}
30
Alex Vakulenko5f472062014-08-14 17:54:04 -070031bool Constraint::ReportErrorLessThan(chromeos::ErrorPtr* error,
32 const std::string& val,
33 const std::string& limit) {
34 chromeos::Error::AddToPrintf(
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080035 error, FROM_HERE, errors::commands::kDomain,
Alex Vakulenko5f472062014-08-14 17:54:04 -070036 errors::commands::kOutOfRange,
37 "Value %s is out of range. It must not be less than %s",
38 val.c_str(), limit.c_str());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070039 return false;
40}
41
Alex Vakulenko5f472062014-08-14 17:54:04 -070042bool Constraint::ReportErrorGreaterThan(chromeos::ErrorPtr* error,
43 const std::string& val,
44 const std::string& limit) {
45 chromeos::Error::AddToPrintf(
Alex Vakulenkoac8037d2014-11-11 11:42:05 -080046 error, FROM_HERE, errors::commands::kDomain,
Alex Vakulenko5f472062014-08-14 17:54:04 -070047 errors::commands::kOutOfRange,
48 "Value %s is out of range. It must not be greater than %s",
49 val.c_str(), limit.c_str());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070050 return false;
51}
52
Alex Vakulenko5f472062014-08-14 17:54:04 -070053bool Constraint::ReportErrorNotOneOf(chromeos::ErrorPtr* error,
54 const std::string& val,
55 const std::vector<std::string>& values) {
Vitaly Bukadb770e72015-03-10 19:33:33 -070056 chromeos::Error::AddToPrintf(
57 error, FROM_HERE, errors::commands::kDomain,
58 errors::commands::kOutOfRange,
59 "Value %s is invalid. Expected one of [%s]", val.c_str(),
60 chromeos::string_utils::Join(",", values).c_str());
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070061 return false;
62}
63
64bool Constraint::AddToJsonDict(base::DictionaryValue* dict,
65 bool overridden_only,
Alex Vakulenko5f472062014-08-14 17:54:04 -070066 chromeos::ErrorPtr* error) const {
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070067 if (!overridden_only || HasOverriddenAttributes()) {
68 auto value = ToJson(error);
69 if (!value)
70 return false;
71 dict->SetWithoutPathExpansion(GetDictKey(), value.release());
72 }
73 return true;
74}
75
76// ConstraintStringLength -----------------------------------------------------
77ConstraintStringLength::ConstraintStringLength(
78 const InheritableAttribute<int>& limit) : limit_(limit) {}
79ConstraintStringLength::ConstraintStringLength(int limit) : limit_(limit) {}
80
81bool ConstraintStringLength::HasOverriddenAttributes() const {
82 return !limit_.is_inherited;
83}
84
85std::unique_ptr<base::Value> ConstraintStringLength::ToJson(
Alex Vakulenko5f472062014-08-14 17:54:04 -070086 chromeos::ErrorPtr* error) const {
Alex Vakulenko66ec2922014-06-17 15:30:22 -070087 return TypedValueToJson(limit_.value, error);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -070088}
89
90// ConstraintStringLengthMin --------------------------------------------------
91ConstraintStringLengthMin::ConstraintStringLengthMin(
92 const InheritableAttribute<int>& limit) : ConstraintStringLength(limit) {}
93ConstraintStringLengthMin::ConstraintStringLengthMin(int limit)
94 : ConstraintStringLength(limit) {}
95
Alex Vakulenko66ec2922014-06-17 15:30:22 -070096bool ConstraintStringLengthMin::Validate(const PropValue& value,
Alex Vakulenko5f472062014-08-14 17:54:04 -070097 chromeos::ErrorPtr* error) const {
Alex Vakulenko66ec2922014-06-17 15:30:22 -070098 CHECK(value.GetString()) << "Expecting a string value for this constraint";
99 const std::string& str = value.GetString()->GetValue();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700100 int length = static_cast<int>(str.size());
101 if (length < limit_.value) {
102 if (limit_.value == 1) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -0800103 chromeos::Error::AddTo(error, FROM_HERE, errors::commands::kDomain,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700104 errors::commands::kOutOfRange,
105 "String must not be empty");
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700106 } else {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -0800107 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700108 errors::commands::kOutOfRange,
109 "String must be at least %d characters long,"
110 " actual length of string '%s' is %d",
111 limit_.value, str.c_str(), length);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700112 }
113 return false;
114 }
115 return true;
116}
117
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700118std::unique_ptr<Constraint>
119ConstraintStringLengthMin::Clone() const {
120 return std::unique_ptr<Constraint>{new ConstraintStringLengthMin{limit_}};
121}
122
123std::unique_ptr<Constraint>
124ConstraintStringLengthMin::CloneAsInherited() const {
125 return std::unique_ptr<Constraint>{
126 new ConstraintStringLengthMin{limit_.value}};
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700127}
128
129// ConstraintStringLengthMax --------------------------------------------------
130ConstraintStringLengthMax::ConstraintStringLengthMax(
131 const InheritableAttribute<int>& limit) : ConstraintStringLength(limit) {}
132ConstraintStringLengthMax::ConstraintStringLengthMax(int limit)
133 : ConstraintStringLength(limit) {}
134
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700135bool ConstraintStringLengthMax::Validate(const PropValue& value,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700136 chromeos::ErrorPtr* error) const {
Alex Vakulenko66ec2922014-06-17 15:30:22 -0700137 CHECK(value.GetString()) << "Expecting a string value for this constraint";
138 const std::string& str = value.GetString()->GetValue();
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700139 int length = static_cast<int>(str.size());
140 if (length > limit_.value) {
Alex Vakulenkoac8037d2014-11-11 11:42:05 -0800141 chromeos::Error::AddToPrintf(error, FROM_HERE, errors::commands::kDomain,
Alex Vakulenko5f472062014-08-14 17:54:04 -0700142 errors::commands::kOutOfRange,
143 "String must be no more than %d character(s) "
144 "long, actual length of string '%s' is %d",
145 limit_.value, str.c_str(), length);
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700146 return false;
147 }
148 return true;
149}
150
Alex Vakulenko5ef75792015-03-19 15:50:44 -0700151std::unique_ptr<Constraint>
152ConstraintStringLengthMax::Clone() const {
153 return std::unique_ptr<Constraint>{new ConstraintStringLengthMax{limit_}};
154}
155
156std::unique_ptr<Constraint>
157ConstraintStringLengthMax::CloneAsInherited() const {
158 return std::unique_ptr<Constraint>{
159 new ConstraintStringLengthMax{limit_.value}};
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700160}
161
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700162// ConstraintOneOf --------------------------------------------------
Alex Vakulenko29e64442015-03-20 13:59:19 -0700163ConstraintOneOf::ConstraintOneOf(InheritableAttribute<native_types::Array> set)
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700164 : set_(std::move(set)) {}
Alex Vakulenko29e64442015-03-20 13:59:19 -0700165ConstraintOneOf::ConstraintOneOf(native_types::Array set)
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700166 : set_(std::move(set)) {}
167
168bool ConstraintOneOf::Validate(const PropValue& value,
169 chromeos::ErrorPtr* error) const {
170 for (const auto& item : set_.value) {
171 if (value.IsEqual(item.get()))
172 return true;
173 }
174 std::vector<std::string> choice_list;
175 choice_list.reserve(set_.value.size());
176 for (const auto& item : set_.value) {
177 choice_list.push_back(PropValueToString(*item));
178 }
179 return ReportErrorNotOneOf(error, PropValueToString(value), choice_list);
180}
181
182std::unique_ptr<Constraint> ConstraintOneOf::Clone() const {
Alex Vakulenko29e64442015-03-20 13:59:19 -0700183 InheritableAttribute<native_types::Array> attr;
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700184 attr.is_inherited = set_.is_inherited;
185 attr.value.reserve(set_.value.size());
186 for (const auto& prop_value : set_.value) {
187 attr.value.push_back(prop_value->Clone());
188 }
189 return std::unique_ptr<Constraint>{new ConstraintOneOf{std::move(attr)}};
190}
191
192std::unique_ptr<Constraint> ConstraintOneOf::CloneAsInherited() const {
Alex Vakulenko29e64442015-03-20 13:59:19 -0700193 native_types::Array cloned;
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700194 cloned.reserve(set_.value.size());
195 for (const auto& prop_value : set_.value) {
196 cloned.push_back(prop_value->Clone());
197 }
198 return std::unique_ptr<Constraint>{new ConstraintOneOf{std::move(cloned)}};
199}
200
201std::unique_ptr<base::Value> ConstraintOneOf::ToJson(
202 chromeos::ErrorPtr* error) const {
Alex Vakulenko29e64442015-03-20 13:59:19 -0700203 return TypedValueToJson(set_.value, error);
Alex Vakulenko9e25ecd2015-03-20 09:43:10 -0700204}
205
206const char* ConstraintOneOf::GetDictKey() const {
207 return commands::attributes::kOneOf_Enum;
208}
209
Alex Vakulenkoe439a0f2014-05-21 12:26:47 -0700210} // namespace buffet