OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/policy/core/common/schema.h" | 5 #include "components/policy/core/common/schema.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <map> | 8 #include <map> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 // Contains the internal data representation of a Schema. This can either wrap | 81 // Contains the internal data representation of a Schema. This can either wrap |
82 // a SchemaData owned elsewhere (currently used to wrap the Chrome schema, which | 82 // a SchemaData owned elsewhere (currently used to wrap the Chrome schema, which |
83 // is generated at compile time), or it can own its own SchemaData. | 83 // is generated at compile time), or it can own its own SchemaData. |
84 class Schema::InternalStorage | 84 class Schema::InternalStorage |
85 : public base::RefCountedThreadSafe<InternalStorage> { | 85 : public base::RefCountedThreadSafe<InternalStorage> { |
86 public: | 86 public: |
87 static scoped_refptr<const InternalStorage> Wrap(const SchemaData* data); | 87 static scoped_refptr<const InternalStorage> Wrap(const SchemaData* data); |
88 | 88 |
89 static scoped_refptr<const InternalStorage> ParseSchema( | 89 static scoped_refptr<const InternalStorage> ParseSchema( |
90 const base::DictionaryValue& schema, | 90 const base::DictionaryValue& schema, |
91 std::string* error); | 91 std::string* error, |
| 92 bool with_backwards_compatibility); |
92 | 93 |
93 const SchemaData* data() const { return &schema_data_; } | 94 const SchemaData* data() const { return &schema_data_; } |
94 | 95 |
95 const SchemaNode* root_node() const { | 96 const SchemaNode* root_node() const { |
96 return schema(0); | 97 return schema(0); |
97 } | 98 } |
98 | 99 |
99 const SchemaNode* schema(int index) const { | 100 const SchemaNode* schema(int index) const { |
100 return schema_data_.schema_nodes + index; | 101 return schema_data_.schema_nodes + index; |
101 } | 102 } |
102 | 103 |
103 const PropertiesNode* properties(int index) const { | 104 const PropertiesNode* properties(int index) const { |
104 return schema_data_.properties_nodes + index; | 105 return schema_data_.properties_nodes + index; |
105 } | 106 } |
106 | 107 |
107 const PropertyNode* property(int index) const { | 108 const PropertyNode* property(int index) const { |
108 return schema_data_.property_nodes + index; | 109 return schema_data_.property_nodes + index; |
109 } | 110 } |
110 | 111 |
111 private: | 112 private: |
112 friend class base::RefCountedThreadSafe<InternalStorage>; | 113 friend class base::RefCountedThreadSafe<InternalStorage>; |
113 | 114 |
114 InternalStorage(); | 115 InternalStorage(); |
115 ~InternalStorage(); | 116 ~InternalStorage(); |
116 | 117 |
117 // Determines the expected |sizes| of the storage for the representation | 118 // Determines the expected |sizes| of the storage for the representation |
118 // of |schema|. | 119 // of |schema|. |
119 static void DetermineStorageSizes(const base::DictionaryValue& schema, | 120 static void DetermineStorageSizes(const base::DictionaryValue& schema, |
120 StorageSizes* sizes); | 121 StorageSizes* sizes, |
| 122 bool with_backwards_compatibility); |
121 | 123 |
122 // Parses the JSON schema in |schema|. | 124 // Parses the JSON schema in |schema|. |
123 // | 125 // |
124 // If |schema| has a "$ref" attribute then a pending reference is appended | 126 // If |schema| has a "$ref" attribute then a pending reference is appended |
125 // to the |reference_list|, and nothing else is done. | 127 // to the |reference_list|, and nothing else is done. |
126 // | 128 // |
127 // Otherwise, |index| gets assigned the index of the corresponding SchemaNode | 129 // Otherwise, |index| gets assigned the index of the corresponding SchemaNode |
128 // in |schema_nodes_|. If the |schema| contains an "id" then that ID is mapped | 130 // in |schema_nodes_|. If the |schema| contains an "id" then that ID is mapped |
129 // to the |index| in the |id_map|. | 131 // to the |index| in the |id_map|. |
130 // | 132 // |
131 // If |schema| is invalid then |error| gets the error reason and false is | 133 // If |schema| is invalid then |error| gets the error reason and false is |
132 // returned. Otherwise returns true. | 134 // returned. Otherwise returns true. |
133 bool Parse(const base::DictionaryValue& schema, | 135 bool Parse(const base::DictionaryValue& schema, |
134 int* index, | 136 int* index, |
135 IdMap* id_map, | 137 IdMap* id_map, |
136 ReferenceList* reference_list, | 138 ReferenceList* reference_list, |
137 std::string* error); | 139 std::string* error, |
| 140 bool with_backwards_compatibility); |
138 | 141 |
139 // Helper for Parse() that gets an already assigned |schema_node| instead of | 142 // Helper for Parse() that gets an already assigned |schema_node| instead of |
140 // an |index| pointer. | 143 // an |index| pointer. |
141 bool ParseDictionary(const base::DictionaryValue& schema, | 144 bool ParseDictionary(const base::DictionaryValue& schema, |
142 SchemaNode* schema_node, | 145 SchemaNode* schema_node, |
143 IdMap* id_map, | 146 IdMap* id_map, |
144 ReferenceList* reference_list, | 147 ReferenceList* reference_list, |
145 std::string* error); | 148 std::string* error, |
| 149 bool with_backwards_compatibility); |
146 | 150 |
147 // Helper for Parse() that gets an already assigned |schema_node| instead of | 151 // Helper for Parse() that gets an already assigned |schema_node| instead of |
148 // an |index| pointer. | 152 // an |index| pointer. |
149 bool ParseList(const base::DictionaryValue& schema, | 153 bool ParseList(const base::DictionaryValue& schema, |
150 SchemaNode* schema_node, | 154 SchemaNode* schema_node, |
151 IdMap* id_map, | 155 IdMap* id_map, |
152 ReferenceList* reference_list, | 156 ReferenceList* reference_list, |
153 std::string* error); | 157 std::string* error, |
| 158 bool with_backwards_compatibility); |
154 | 159 |
155 // Assigns the IDs in |id_map| to the pending references in the | 160 // Assigns the IDs in |id_map| to the pending references in the |
156 // |reference_list|. If an ID is missing then |error| is set and false is | 161 // |reference_list|. If an ID is missing then |error| is set and false is |
157 // returned; otherwise returns true. | 162 // returned; otherwise returns true. |
158 static bool ResolveReferences(const IdMap& id_map, | 163 static bool ResolveReferences(const IdMap& id_map, |
159 const ReferenceList& reference_list, | 164 const ReferenceList& reference_list, |
160 std::string* error); | 165 std::string* error); |
161 | 166 |
162 SchemaData schema_data_; | 167 SchemaData schema_data_; |
163 std::vector<std::string> strings_; | 168 std::vector<std::string> strings_; |
(...skipping 14 matching lines...) Expand all Loading... |
178 InternalStorage* storage = new InternalStorage(); | 183 InternalStorage* storage = new InternalStorage(); |
179 storage->schema_data_.schema_nodes = data->schema_nodes; | 184 storage->schema_data_.schema_nodes = data->schema_nodes; |
180 storage->schema_data_.property_nodes = data->property_nodes; | 185 storage->schema_data_.property_nodes = data->property_nodes; |
181 storage->schema_data_.properties_nodes = data->properties_nodes; | 186 storage->schema_data_.properties_nodes = data->properties_nodes; |
182 return storage; | 187 return storage; |
183 } | 188 } |
184 | 189 |
185 // static | 190 // static |
186 scoped_refptr<const Schema::InternalStorage> | 191 scoped_refptr<const Schema::InternalStorage> |
187 Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, | 192 Schema::InternalStorage::ParseSchema(const base::DictionaryValue& schema, |
188 std::string* error) { | 193 std::string* error, |
| 194 bool with_backwards_compatibility) { |
189 // Determine the sizes of the storage arrays and reserve the capacity before | 195 // Determine the sizes of the storage arrays and reserve the capacity before |
190 // starting to append nodes and strings. This is important to prevent the | 196 // starting to append nodes and strings. This is important to prevent the |
191 // arrays from being reallocated, which would invalidate the c_str() pointers | 197 // arrays from being reallocated, which would invalidate the c_str() pointers |
192 // and the addresses of indices to fix. | 198 // and the addresses of indices to fix. |
193 StorageSizes sizes; | 199 StorageSizes sizes; |
194 DetermineStorageSizes(schema, &sizes); | 200 DetermineStorageSizes(schema, &sizes, with_backwards_compatibility); |
195 | 201 |
196 scoped_refptr<InternalStorage> storage = new InternalStorage(); | 202 scoped_refptr<InternalStorage> storage = new InternalStorage(); |
197 storage->strings_.reserve(sizes.strings); | 203 storage->strings_.reserve(sizes.strings); |
198 storage->schema_nodes_.reserve(sizes.schema_nodes); | 204 storage->schema_nodes_.reserve(sizes.schema_nodes); |
199 storage->property_nodes_.reserve(sizes.property_nodes); | 205 storage->property_nodes_.reserve(sizes.property_nodes); |
200 storage->properties_nodes_.reserve(sizes.properties_nodes); | 206 storage->properties_nodes_.reserve(sizes.properties_nodes); |
201 | 207 |
202 int root_index = kInvalid; | 208 int root_index = kInvalid; |
203 IdMap id_map; | 209 IdMap id_map; |
204 ReferenceList reference_list; | 210 ReferenceList reference_list; |
205 if (!storage->Parse(schema, &root_index, &id_map, &reference_list, error)) | 211 if (!storage->Parse(schema, &root_index, &id_map, &reference_list, error, |
| 212 with_backwards_compatibility)) { |
206 return NULL; | 213 return NULL; |
| 214 } |
207 | 215 |
208 if (root_index == kInvalid) { | 216 if (root_index == kInvalid) { |
209 *error = "The main schema can't have a $ref"; | 217 *error = "The main schema can't have a $ref"; |
210 return NULL; | 218 return NULL; |
211 } | 219 } |
212 | 220 |
213 // None of this should ever happen without having been already detected. | 221 // None of this should ever happen without having been already detected. |
214 // But, if it does happen, then it will lead to corrupted memory; drop | 222 // But, if it does happen, then it will lead to corrupted memory; drop |
215 // everything in that case. | 223 // everything in that case. |
216 if (root_index != 0 || | 224 if (root_index != 0 || |
(...skipping 12 matching lines...) Expand all Loading... |
229 SchemaData* data = &storage->schema_data_; | 237 SchemaData* data = &storage->schema_data_; |
230 data->schema_nodes = vector_as_array(&storage->schema_nodes_); | 238 data->schema_nodes = vector_as_array(&storage->schema_nodes_); |
231 data->property_nodes = vector_as_array(&storage->property_nodes_); | 239 data->property_nodes = vector_as_array(&storage->property_nodes_); |
232 data->properties_nodes = vector_as_array(&storage->properties_nodes_); | 240 data->properties_nodes = vector_as_array(&storage->properties_nodes_); |
233 return storage; | 241 return storage; |
234 } | 242 } |
235 | 243 |
236 // static | 244 // static |
237 void Schema::InternalStorage::DetermineStorageSizes( | 245 void Schema::InternalStorage::DetermineStorageSizes( |
238 const base::DictionaryValue& schema, | 246 const base::DictionaryValue& schema, |
239 StorageSizes* sizes) { | 247 StorageSizes* sizes, |
| 248 bool with_backwards_compatibility) { |
240 std::string ref_string; | 249 std::string ref_string; |
241 if (schema.GetString(schema::kRef, &ref_string)) { | 250 if (schema.GetString(schema::kRef, &ref_string)) { |
242 // Schemas with a "$ref" attribute don't take additional storage. | 251 // Schemas with a "$ref" attribute don't take additional storage. |
243 return; | 252 return; |
244 } | 253 } |
245 | 254 |
246 std::string type_string; | 255 std::string type_string; |
247 base::Value::Type type = base::Value::TYPE_NULL; | 256 base::Value::Type type = base::Value::TYPE_NULL; |
248 if (!schema.GetString(schema::kType, &type_string) || | 257 if (!schema.GetString(schema::kType, &type_string) || |
249 !SchemaTypeToValueType(type_string, &type)) { | 258 !SchemaTypeToValueType(type_string, &type)) { |
250 // This schema is invalid. | 259 // This schema is invalid. |
251 return; | 260 return; |
252 } | 261 } |
253 | 262 |
254 sizes->schema_nodes++; | 263 sizes->schema_nodes++; |
255 | 264 |
256 if (type == base::Value::TYPE_LIST) { | 265 if (type == base::Value::TYPE_LIST) { |
257 const base::DictionaryValue* items = NULL; | 266 const base::DictionaryValue* items = NULL; |
258 if (schema.GetDictionary(schema::kItems, &items)) | 267 if (schema.GetDictionary(schema::kItems, &items)) { |
259 DetermineStorageSizes(*items, sizes); | 268 DetermineStorageSizes(*items, sizes, with_backwards_compatibility); |
| 269 } else if (with_backwards_compatibility) { |
| 270 // TODO(joaodasilva): remove this. http://crbug.com/325349 |
| 271 base::DictionaryValue items_schema; |
| 272 items_schema.SetString("type", "string"); |
| 273 DetermineStorageSizes(items_schema, sizes, true); |
| 274 } |
260 } else if (type == base::Value::TYPE_DICTIONARY) { | 275 } else if (type == base::Value::TYPE_DICTIONARY) { |
261 sizes->properties_nodes++; | 276 sizes->properties_nodes++; |
262 | 277 |
263 const base::DictionaryValue* dict = NULL; | 278 const base::DictionaryValue* dict = NULL; |
264 if (schema.GetDictionary(schema::kAdditionalProperties, &dict)) | 279 if (schema.GetDictionary(schema::kAdditionalProperties, &dict)) |
265 DetermineStorageSizes(*dict, sizes); | 280 DetermineStorageSizes(*dict, sizes, with_backwards_compatibility); |
266 | 281 |
267 const base::DictionaryValue* properties = NULL; | 282 const base::DictionaryValue* properties = NULL; |
268 if (schema.GetDictionary(schema::kProperties, &properties)) { | 283 if (schema.GetDictionary(schema::kProperties, &properties)) { |
269 for (base::DictionaryValue::Iterator it(*properties); | 284 for (base::DictionaryValue::Iterator it(*properties); |
270 !it.IsAtEnd(); it.Advance()) { | 285 !it.IsAtEnd(); it.Advance()) { |
271 // This should have been verified by the JSONSchemaValidator. | 286 // This should have been verified by the JSONSchemaValidator. |
272 CHECK(it.value().GetAsDictionary(&dict)); | 287 CHECK(it.value().GetAsDictionary(&dict)); |
273 DetermineStorageSizes(*dict, sizes); | 288 DetermineStorageSizes(*dict, sizes, with_backwards_compatibility); |
274 sizes->strings++; | 289 sizes->strings++; |
275 sizes->property_nodes++; | 290 sizes->property_nodes++; |
276 } | 291 } |
277 } | 292 } |
278 } | 293 } |
279 } | 294 } |
280 | 295 |
281 bool Schema::InternalStorage::Parse(const base::DictionaryValue& schema, | 296 bool Schema::InternalStorage::Parse(const base::DictionaryValue& schema, |
282 int* index, | 297 int* index, |
283 IdMap* id_map, | 298 IdMap* id_map, |
284 ReferenceList* reference_list, | 299 ReferenceList* reference_list, |
285 std::string* error) { | 300 std::string* error, |
| 301 bool with_backwards_compatibility) { |
286 std::string ref_string; | 302 std::string ref_string; |
287 if (schema.GetString(schema::kRef, &ref_string)) { | 303 if (schema.GetString(schema::kRef, &ref_string)) { |
288 std::string id_string; | 304 std::string id_string; |
289 if (schema.GetString(schema::kId, &id_string)) { | 305 if (schema.GetString(schema::kId, &id_string)) { |
290 *error = "Schemas with a $ref can't have an id"; | 306 *error = "Schemas with a $ref can't have an id"; |
291 return false; | 307 return false; |
292 } | 308 } |
293 reference_list->push_back(std::make_pair(ref_string, index)); | 309 reference_list->push_back(std::make_pair(ref_string, index)); |
294 return true; | 310 return true; |
295 } | 311 } |
(...skipping 10 matching lines...) Expand all Loading... |
306 return false; | 322 return false; |
307 } | 323 } |
308 | 324 |
309 *index = static_cast<int>(schema_nodes_.size()); | 325 *index = static_cast<int>(schema_nodes_.size()); |
310 schema_nodes_.push_back(SchemaNode()); | 326 schema_nodes_.push_back(SchemaNode()); |
311 SchemaNode* schema_node = &schema_nodes_.back(); | 327 SchemaNode* schema_node = &schema_nodes_.back(); |
312 schema_node->type = type; | 328 schema_node->type = type; |
313 schema_node->extra = kInvalid; | 329 schema_node->extra = kInvalid; |
314 | 330 |
315 if (type == base::Value::TYPE_DICTIONARY) { | 331 if (type == base::Value::TYPE_DICTIONARY) { |
316 if (!ParseDictionary(schema, schema_node, id_map, reference_list, error)) | 332 if (!ParseDictionary(schema, schema_node, id_map, reference_list, error, |
| 333 with_backwards_compatibility)) { |
317 return false; | 334 return false; |
| 335 } |
318 } else if (type == base::Value::TYPE_LIST) { | 336 } else if (type == base::Value::TYPE_LIST) { |
319 if (!ParseList(schema, schema_node, id_map, reference_list, error)) | 337 if (!ParseList(schema, schema_node, id_map, reference_list, error, |
| 338 with_backwards_compatibility)) { |
320 return false; | 339 return false; |
| 340 } |
321 } | 341 } |
322 | 342 |
323 std::string id_string; | 343 std::string id_string; |
324 if (schema.GetString(schema::kId, &id_string)) { | 344 if (schema.GetString(schema::kId, &id_string)) { |
325 if (ContainsKey(*id_map, id_string)) { | 345 if (ContainsKey(*id_map, id_string)) { |
326 *error = "Duplicated id: " + id_string; | 346 *error = "Duplicated id: " + id_string; |
327 return false; | 347 return false; |
328 } | 348 } |
329 (*id_map)[id_string] = *index; | 349 (*id_map)[id_string] = *index; |
330 } | 350 } |
331 | 351 |
332 return true; | 352 return true; |
333 } | 353 } |
334 | 354 |
335 bool Schema::InternalStorage::ParseDictionary( | 355 bool Schema::InternalStorage::ParseDictionary( |
336 const base::DictionaryValue& schema, | 356 const base::DictionaryValue& schema, |
337 SchemaNode* schema_node, | 357 SchemaNode* schema_node, |
338 IdMap* id_map, | 358 IdMap* id_map, |
339 ReferenceList* reference_list, | 359 ReferenceList* reference_list, |
340 std::string* error) { | 360 std::string* error, |
| 361 bool with_backwards_compatibility) { |
341 int extra = static_cast<int>(properties_nodes_.size()); | 362 int extra = static_cast<int>(properties_nodes_.size()); |
342 properties_nodes_.push_back(PropertiesNode()); | 363 properties_nodes_.push_back(PropertiesNode()); |
343 properties_nodes_[extra].begin = kInvalid; | 364 properties_nodes_[extra].begin = kInvalid; |
344 properties_nodes_[extra].end = kInvalid; | 365 properties_nodes_[extra].end = kInvalid; |
345 properties_nodes_[extra].additional = kInvalid; | 366 properties_nodes_[extra].additional = kInvalid; |
346 schema_node->extra = extra; | 367 schema_node->extra = extra; |
347 | 368 |
348 const base::DictionaryValue* dict = NULL; | 369 const base::DictionaryValue* dict = NULL; |
349 if (schema.GetDictionary(schema::kAdditionalProperties, &dict)) { | 370 if (schema.GetDictionary(schema::kAdditionalProperties, &dict)) { |
350 if (!Parse(*dict, &properties_nodes_[extra].additional, | 371 if (!Parse(*dict, &properties_nodes_[extra].additional, |
351 id_map, reference_list, error)) { | 372 id_map, reference_list, error, with_backwards_compatibility)) { |
352 return false; | 373 return false; |
353 } | 374 } |
354 } | 375 } |
355 | 376 |
356 const base::DictionaryValue* properties = NULL; | 377 const base::DictionaryValue* properties = NULL; |
357 if (schema.GetDictionary(schema::kProperties, &properties)) { | 378 if (schema.GetDictionary(schema::kProperties, &properties)) { |
358 int base_index = static_cast<int>(property_nodes_.size()); | 379 int base_index = static_cast<int>(property_nodes_.size()); |
359 // This reserves nodes for all of the |properties|, and makes sure they | 380 // This reserves nodes for all of the |properties|, and makes sure they |
360 // are contiguous. Recursive calls to Parse() will append after these | 381 // are contiguous. Recursive calls to Parse() will append after these |
361 // elements. | 382 // elements. |
362 property_nodes_.resize(base_index + properties->size()); | 383 property_nodes_.resize(base_index + properties->size()); |
363 | 384 |
364 int index = base_index; | 385 int index = base_index; |
365 for (base::DictionaryValue::Iterator it(*properties); | 386 for (base::DictionaryValue::Iterator it(*properties); |
366 !it.IsAtEnd(); it.Advance(), ++index) { | 387 !it.IsAtEnd(); it.Advance(), ++index) { |
367 // This should have been verified by the JSONSchemaValidator. | 388 // This should have been verified by the JSONSchemaValidator. |
368 CHECK(it.value().GetAsDictionary(&dict)); | 389 CHECK(it.value().GetAsDictionary(&dict)); |
369 strings_.push_back(it.key()); | 390 strings_.push_back(it.key()); |
370 property_nodes_[index].key = strings_.back().c_str(); | 391 property_nodes_[index].key = strings_.back().c_str(); |
371 if (!Parse(*dict, &property_nodes_[index].schema, | 392 if (!Parse(*dict, &property_nodes_[index].schema, |
372 id_map, reference_list, error)) { | 393 id_map, reference_list, error, with_backwards_compatibility)) { |
373 return false; | 394 return false; |
374 } | 395 } |
375 } | 396 } |
376 CHECK_EQ(static_cast<int>(properties->size()), index - base_index); | 397 CHECK_EQ(static_cast<int>(properties->size()), index - base_index); |
377 properties_nodes_[extra].begin = base_index; | 398 properties_nodes_[extra].begin = base_index; |
378 properties_nodes_[extra].end = index; | 399 properties_nodes_[extra].end = index; |
379 } | 400 } |
380 | 401 |
381 return true; | 402 return true; |
382 } | 403 } |
383 | 404 |
384 bool Schema::InternalStorage::ParseList(const base::DictionaryValue& schema, | 405 bool Schema::InternalStorage::ParseList(const base::DictionaryValue& schema, |
385 SchemaNode* schema_node, | 406 SchemaNode* schema_node, |
386 IdMap* id_map, | 407 IdMap* id_map, |
387 ReferenceList* reference_list, | 408 ReferenceList* reference_list, |
388 std::string* error) { | 409 std::string* error, |
| 410 bool with_backwards_compatibility) { |
| 411 // TODO(joaodasilva): remove this. http://crbug.com/325349 |
| 412 base::DictionaryValue items; |
| 413 items.SetString("type", "string"); |
| 414 |
389 const base::DictionaryValue* dict = NULL; | 415 const base::DictionaryValue* dict = NULL; |
390 if (!schema.GetDictionary(schema::kItems, &dict)) { | 416 if (!schema.GetDictionary(schema::kItems, &dict)) { |
391 *error = "Arrays must declare a single schema for their items."; | 417 if (with_backwards_compatibility) { |
392 return false; | 418 dict = &items; |
| 419 } else { |
| 420 *error = "Arrays must declare a single schema for their items."; |
| 421 return false; |
| 422 } |
393 } | 423 } |
394 return Parse(*dict, &schema_node->extra, id_map, reference_list, error); | 424 |
| 425 return Parse(*dict, &schema_node->extra, id_map, reference_list, error, |
| 426 with_backwards_compatibility); |
395 } | 427 } |
396 | 428 |
397 // static | 429 // static |
398 bool Schema::InternalStorage::ResolveReferences( | 430 bool Schema::InternalStorage::ResolveReferences( |
399 const IdMap& id_map, | 431 const IdMap& id_map, |
400 const ReferenceList& reference_list, | 432 const ReferenceList& reference_list, |
401 std::string* error) { | 433 std::string* error) { |
402 for (ReferenceList::const_iterator ref = reference_list.begin(); | 434 for (ReferenceList::const_iterator ref = reference_list.begin(); |
403 ref != reference_list.end(); ++ref) { | 435 ref != reference_list.end(); ++ref) { |
404 IdMap::const_iterator id = id_map.find(ref->first); | 436 IdMap::const_iterator id = id_map.find(ref->first); |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 if (!*it || !GetItems().Validate(**it)) | 525 if (!*it || !GetItems().Validate(**it)) |
494 return false; | 526 return false; |
495 } | 527 } |
496 } | 528 } |
497 | 529 |
498 return true; | 530 return true; |
499 } | 531 } |
500 | 532 |
501 // static | 533 // static |
502 Schema Schema::Parse(const std::string& content, std::string* error) { | 534 Schema Schema::Parse(const std::string& content, std::string* error) { |
| 535 return ParseWithBackwardsCompatibility(content, error, false); |
| 536 } |
| 537 |
| 538 // static |
| 539 Schema Schema::ParseWithBackwardsCompatibility( |
| 540 const std::string& content, |
| 541 std::string* error, |
| 542 bool with_backwards_compatibility) { |
503 // Validate as a generic JSON schema. | 543 // Validate as a generic JSON schema. |
504 scoped_ptr<base::DictionaryValue> dict = | 544 scoped_ptr<base::DictionaryValue> dict = |
505 JSONSchemaValidator::IsValidSchema(content, error); | 545 JSONSchemaValidator::IsValidSchema(content, error); |
506 if (!dict) | 546 if (!dict) |
507 return Schema(); | 547 return Schema(); |
508 | 548 |
509 // Validate the main type. | 549 // Validate the main type. |
510 std::string string_value; | 550 std::string string_value; |
511 if (!dict->GetString(schema::kType, &string_value) || | 551 if (!dict->GetString(schema::kType, &string_value) || |
512 string_value != schema::kObject) { | 552 string_value != schema::kObject) { |
513 *error = | 553 *error = |
514 "The main schema must have a type attribute with \"object\" value."; | 554 "The main schema must have a type attribute with \"object\" value."; |
515 return Schema(); | 555 return Schema(); |
516 } | 556 } |
517 | 557 |
518 // Checks for invalid attributes at the top-level. | 558 // Checks for invalid attributes at the top-level. |
519 if (dict->HasKey(schema::kAdditionalProperties) || | 559 if (dict->HasKey(schema::kAdditionalProperties) || |
520 dict->HasKey(schema::kPatternProperties)) { | 560 dict->HasKey(schema::kPatternProperties)) { |
521 *error = "\"additionalProperties\" and \"patternProperties\" are not " | 561 *error = "\"additionalProperties\" and \"patternProperties\" are not " |
522 "supported at the main schema."; | 562 "supported at the main schema."; |
523 return Schema(); | 563 return Schema(); |
524 } | 564 } |
525 | 565 |
526 scoped_refptr<const InternalStorage> storage = | 566 scoped_refptr<const InternalStorage> storage = |
527 InternalStorage::ParseSchema(*dict, error); | 567 InternalStorage::ParseSchema(*dict, error, with_backwards_compatibility); |
528 if (!storage) | 568 if (!storage) |
529 return Schema(); | 569 return Schema(); |
530 return Schema(storage, storage->root_node()); | 570 return Schema(storage, storage->root_node()); |
531 } | 571 } |
532 | 572 |
533 base::Value::Type Schema::type() const { | 573 base::Value::Type Schema::type() const { |
534 CHECK(valid()); | 574 CHECK(valid()); |
535 return node_->type; | 575 return node_->type; |
536 } | 576 } |
537 | 577 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 | 617 |
578 Schema Schema::GetItems() const { | 618 Schema Schema::GetItems() const { |
579 CHECK(valid()); | 619 CHECK(valid()); |
580 CHECK_EQ(base::Value::TYPE_LIST, type()); | 620 CHECK_EQ(base::Value::TYPE_LIST, type()); |
581 if (node_->extra == kInvalid) | 621 if (node_->extra == kInvalid) |
582 return Schema(); | 622 return Schema(); |
583 return Schema(storage_, storage_->schema(node_->extra)); | 623 return Schema(storage_, storage_->schema(node_->extra)); |
584 } | 624 } |
585 | 625 |
586 } // namespace policy | 626 } // namespace policy |
OLD | NEW |