Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(330)

Side by Side Diff: components/policy/core/common/policy_schema.cc

Issue 24367003: Refactored users of PolicySchema to use the new policy::Schema class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed comments Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium 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 "components/policy/core/common/policy_schema.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "base/stl_util.h"
10 #include "components/json_schema/json_schema_constants.h"
11 #include "components/json_schema/json_schema_validator.h"
12
13 namespace policy {
14
15 namespace {
16
17 const char kJSONSchemaVersion[] = "http://json-schema.org/draft-03/schema#";
18
19 // Describes the properties of a TYPE_DICTIONARY policy schema.
20 class DictionaryPolicySchema : public PolicySchema {
21 public:
22 static scoped_ptr<PolicySchema> Parse(const base::DictionaryValue& schema,
23 std::string* error);
24
25 virtual ~DictionaryPolicySchema();
26
27 virtual const PolicySchemaMap* GetProperties() const OVERRIDE;
28 virtual const PolicySchema* GetSchemaForAdditionalProperties() const OVERRIDE;
29
30 private:
31 DictionaryPolicySchema();
32
33 PolicySchemaMap properties_;
34 scoped_ptr<PolicySchema> additional_properties_;
35
36 DISALLOW_COPY_AND_ASSIGN(DictionaryPolicySchema);
37 };
38
39 // Describes the items of a TYPE_LIST policy schema.
40 class ListPolicySchema : public PolicySchema {
41 public:
42 static scoped_ptr<PolicySchema> Parse(const base::DictionaryValue& schema,
43 std::string* error);
44
45 virtual ~ListPolicySchema();
46
47 virtual const PolicySchema* GetSchemaForItems() const OVERRIDE;
48
49 private:
50 ListPolicySchema();
51
52 scoped_ptr<PolicySchema> items_schema_;
53
54 DISALLOW_COPY_AND_ASSIGN(ListPolicySchema);
55 };
56
57 bool SchemaTypeToValueType(const std::string& type_string,
58 base::Value::Type* type) {
59 // Note: "any" is not an accepted type.
60 static const struct {
61 const char* schema_type;
62 base::Value::Type value_type;
63 } kSchemaToValueTypeMap[] = {
64 { json_schema_constants::kArray, base::Value::TYPE_LIST },
65 { json_schema_constants::kBoolean, base::Value::TYPE_BOOLEAN },
66 { json_schema_constants::kInteger, base::Value::TYPE_INTEGER },
67 { json_schema_constants::kNull, base::Value::TYPE_NULL },
68 { json_schema_constants::kNumber, base::Value::TYPE_DOUBLE },
69 { json_schema_constants::kObject, base::Value::TYPE_DICTIONARY },
70 { json_schema_constants::kString, base::Value::TYPE_STRING },
71 };
72 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kSchemaToValueTypeMap); ++i) {
73 if (kSchemaToValueTypeMap[i].schema_type == type_string) {
74 *type = kSchemaToValueTypeMap[i].value_type;
75 return true;
76 }
77 }
78 return false;
79 }
80
81 scoped_ptr<PolicySchema> ParseSchema(const base::DictionaryValue& schema,
82 std::string* error) {
83 std::string type_string;
84 if (!schema.GetString(json_schema_constants::kType, &type_string)) {
85 *error = "The schema type must be declared.";
86 return scoped_ptr<PolicySchema>();
87 }
88
89 base::Value::Type type = base::Value::TYPE_NULL;
90 if (!SchemaTypeToValueType(type_string, &type)) {
91 *error = "The \"any\" type can't be used.";
92 return scoped_ptr<PolicySchema>();
93 }
94
95 switch (type) {
96 case base::Value::TYPE_DICTIONARY:
97 return DictionaryPolicySchema::Parse(schema, error);
98 case base::Value::TYPE_LIST:
99 return ListPolicySchema::Parse(schema, error);
100 default:
101 return make_scoped_ptr(new PolicySchema(type));
102 }
103 }
104
105 DictionaryPolicySchema::DictionaryPolicySchema()
106 : PolicySchema(base::Value::TYPE_DICTIONARY) {}
107
108 DictionaryPolicySchema::~DictionaryPolicySchema() {
109 STLDeleteValues(&properties_);
110 }
111
112 const PolicySchemaMap* DictionaryPolicySchema::GetProperties() const {
113 return &properties_;
114 }
115
116 const PolicySchema*
117 DictionaryPolicySchema::GetSchemaForAdditionalProperties() const {
118 return additional_properties_.get();
119 }
120
121 // static
122 scoped_ptr<PolicySchema> DictionaryPolicySchema::Parse(
123 const base::DictionaryValue& schema,
124 std::string* error) {
125 scoped_ptr<DictionaryPolicySchema> dict_schema(new DictionaryPolicySchema());
126
127 const base::DictionaryValue* dict = NULL;
128 const base::DictionaryValue* properties = NULL;
129 if (schema.GetDictionary(json_schema_constants::kProperties, &properties)) {
130 for (base::DictionaryValue::Iterator it(*properties);
131 !it.IsAtEnd(); it.Advance()) {
132 // This should have been verified by the JSONSchemaValidator.
133 CHECK(it.value().GetAsDictionary(&dict));
134 scoped_ptr<PolicySchema> sub_schema = ParseSchema(*dict, error);
135 if (!sub_schema)
136 return scoped_ptr<PolicySchema>();
137 dict_schema->properties_[it.key()] = sub_schema.release();
138 }
139 }
140
141 if (schema.GetDictionary(json_schema_constants::kAdditionalProperties,
142 &dict)) {
143 scoped_ptr<PolicySchema> sub_schema = ParseSchema(*dict, error);
144 if (!sub_schema)
145 return scoped_ptr<PolicySchema>();
146 dict_schema->additional_properties_ = sub_schema.Pass();
147 }
148
149 return dict_schema.PassAs<PolicySchema>();
150 }
151
152 ListPolicySchema::ListPolicySchema()
153 : PolicySchema(base::Value::TYPE_LIST) {}
154
155 ListPolicySchema::~ListPolicySchema() {}
156
157 const PolicySchema* ListPolicySchema::GetSchemaForItems() const {
158 return items_schema_.get();
159 }
160
161 scoped_ptr<PolicySchema> ListPolicySchema::Parse(
162 const base::DictionaryValue& schema,
163 std::string* error) {
164 const base::DictionaryValue* dict = NULL;
165 if (!schema.GetDictionary(json_schema_constants::kItems, &dict)) {
166 *error = "Arrays must declare a single schema for their items.";
167 return scoped_ptr<PolicySchema>();
168 }
169 scoped_ptr<PolicySchema> items_schema = ParseSchema(*dict, error);
170 if (!items_schema)
171 return scoped_ptr<PolicySchema>();
172
173 scoped_ptr<ListPolicySchema> list_schema(new ListPolicySchema());
174 list_schema->items_schema_ = items_schema.Pass();
175 return list_schema.PassAs<PolicySchema>();
176 }
177
178 } // namespace
179
180 PolicySchema::PolicySchema(base::Value::Type type)
181 : type_(type) {}
182
183 PolicySchema::~PolicySchema() {}
184
185 const PolicySchemaMap* PolicySchema::GetProperties() const {
186 NOTREACHED();
187 return NULL;
188 }
189
190 const PolicySchema* PolicySchema::GetSchemaForAdditionalProperties() const {
191 NOTREACHED();
192 return NULL;
193 }
194
195 const PolicySchema* PolicySchema::GetSchemaForProperty(
196 const std::string& key) const {
197 const PolicySchemaMap* properties = GetProperties();
198 PolicySchemaMap::const_iterator it = properties->find(key);
199 return it == properties->end() ? GetSchemaForAdditionalProperties()
200 : it->second;
201 }
202
203 const PolicySchema* PolicySchema::GetSchemaForItems() const {
204 NOTREACHED();
205 return NULL;
206 }
207
208 // static
209 scoped_ptr<PolicySchema> PolicySchema::Parse(const std::string& content,
210 std::string* error) {
211 // Validate as a generic JSON schema.
212 scoped_ptr<base::DictionaryValue> dict =
213 JSONSchemaValidator::IsValidSchema(content, error);
214 if (!dict)
215 return scoped_ptr<PolicySchema>();
216
217 // Validate the schema version.
218 std::string string_value;
219 if (!dict->GetString(json_schema_constants::kSchema, &string_value) ||
220 string_value != kJSONSchemaVersion) {
221 *error = "Must declare JSON Schema v3 version in \"$schema\".";
222 return scoped_ptr<PolicySchema>();
223 }
224
225 // Validate the main type.
226 if (!dict->GetString(json_schema_constants::kType, &string_value) ||
227 string_value != json_schema_constants::kObject) {
228 *error =
229 "The main schema must have a type attribute with \"object\" value.";
230 return scoped_ptr<PolicySchema>();
231 }
232
233 // Checks for invalid attributes at the top-level.
234 if (dict->HasKey(json_schema_constants::kAdditionalProperties) ||
235 dict->HasKey(json_schema_constants::kPatternProperties)) {
236 *error = "\"additionalProperties\" and \"patternProperties\" are not "
237 "supported at the main schema.";
238 return scoped_ptr<PolicySchema>();
239 }
240
241 return ParseSchema(*dict, error);
242 }
243
244 } // namespace policy
OLDNEW
« no previous file with comments | « components/policy/core/common/policy_schema.h ('k') | components/policy/core/common/policy_schema_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698