Open Lighting Architecture  0.9.4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SchemaParseContext.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15  *
16  * SchemaParseContext.h
17  * Stores the state required as we walk the JSON schema document.
18  * Copyright (C) 2014 Simon Newton
19  */
20 
21 #ifndef COMMON_WEB_SCHEMAPARSECONTEXT_H_
22 #define COMMON_WEB_SCHEMAPARSECONTEXT_H_
23 
24 #include <ola/base/Macro.h>
25 
26 #include <map>
27 #include <memory>
28 #include <set>
29 #include <string>
30 #include <vector>
31 
32 #include "common/web/PointerTracker.h"
33 #include "common/web/SchemaErrorLogger.h"
34 #include "common/web/SchemaKeywords.h"
35 #include "common/web/OptionalItem.h"
36 #include "ola/web/JsonSchema.h"
37 #include "ola/web/JsonParser.h"
38 
39 namespace ola {
40 namespace web {
41 
42 class ArrayOfSchemaContext;
43 class ArrayOfStringsContext;
44 class DefinitionsParseContext;
45 class DependencyParseContext;
46 class JsonValueContext;
47 class PropertiesParseContext;
48 class SchemaParseContext;
49 
54  public:
56  virtual ~SchemaParseContextInterface() {}
57 
58  virtual void String(SchemaErrorLogger *logger, const std::string &value) = 0;
59  virtual void Number(SchemaErrorLogger *logger, uint32_t value) = 0;
60  virtual void Number(SchemaErrorLogger *logger, int32_t value) = 0;
61  virtual void Number(SchemaErrorLogger *logger, uint64_t value) = 0;
62  virtual void Number(SchemaErrorLogger *logger, int64_t value) = 0;
63  virtual void Number(SchemaErrorLogger *logger, double value) = 0;
64  virtual void Bool(SchemaErrorLogger *logger, bool value) = 0;
65  virtual void Null(SchemaErrorLogger *logger) = 0;
66  virtual SchemaParseContextInterface* OpenArray(SchemaErrorLogger *logger) = 0;
67  virtual void CloseArray(SchemaErrorLogger *logger) = 0;
68  virtual SchemaParseContextInterface* OpenObject(
69  SchemaErrorLogger *logger) = 0;
70  virtual void ObjectKey(SchemaErrorLogger *logger, const std::string &key) = 0;
71  virtual void CloseObject(SchemaErrorLogger *logger) = 0;
72 };
73 
79  public:
81 
85  void ObjectKey(SchemaErrorLogger*, const std::string &keyword) {
86  m_keyword.Set(keyword);
87  }
88 
89  protected:
93  std::string TakeKeyword() {
94  std::string keyword = m_keyword.Value();
95  m_keyword.Reset();
96  return keyword;
97  }
98 
102  const std::string& Keyword() const { return m_keyword.Value(); }
103 
104  private:
105  OptionalItem<std::string> m_keyword;
106 };
107 
115  public:
117 
118  void String(SchemaErrorLogger *logger, const std::string &value);
119  void Number(SchemaErrorLogger *logger, uint32_t value);
120  void Number(SchemaErrorLogger *logger, int32_t value);
121  void Number(SchemaErrorLogger *logger, uint64_t value);
122  void Number(SchemaErrorLogger *logger, int64_t value);
123  void Number(SchemaErrorLogger *logger, double value);
124  void Bool(SchemaErrorLogger *logger, bool value);
125  void Null(SchemaErrorLogger *logger);
127  void CloseArray(SchemaErrorLogger *logger);
128  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
129  void CloseObject(SchemaErrorLogger *logger);
130 
131  private:
132  void ReportErrorForType(SchemaErrorLogger *logger, JsonType type);
133 
134  DISALLOW_COPY_AND_ASSIGN(StrictTypedParseContext);
135 };
136 
144  public:
154  m_schema_defs(definitions) {
155  }
156 
157  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
158  void CloseObject(SchemaErrorLogger *logger);
159 
160  private:
161  SchemaDefinitions *m_schema_defs;
162  std::auto_ptr<SchemaParseContext> m_current_schema;
163 
164  DISALLOW_COPY_AND_ASSIGN(DefinitionsParseContext);
165 };
166 
171  public:
177  explicit SchemaParseContext(SchemaDefinitions *definitions)
178  : m_schema_defs(definitions),
179  m_keyword(SCHEMA_UNKNOWN),
180  m_type(JSON_UNDEFINED) {
181  }
182 
191 
192  void ObjectKey(SchemaErrorLogger *logger, const std::string &keyword);
193 
194  void String(SchemaErrorLogger *logger, const std::string &value);
195  void Number(SchemaErrorLogger *logger, uint32_t value);
196  void Number(SchemaErrorLogger *logger, int32_t value);
197  void Number(SchemaErrorLogger *logger, uint64_t value);
198  void Number(SchemaErrorLogger *logger, int64_t value);
199  void Number(SchemaErrorLogger *logger, double value);
200  void Bool(SchemaErrorLogger *logger, bool value);
201  void Null(SchemaErrorLogger *logger);
203  void CloseArray(SchemaErrorLogger *logger);
204  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
205  void CloseObject(SchemaErrorLogger *logger);
206 
207  private:
208  SchemaDefinitions *m_schema_defs;
209  // Set to the last keyword reported to ObjectKey()
210  SchemaKeyword m_keyword;
211 
212  // Members are arranged according to the order in which they appear in the
213  // draft standard.
214 
215  // Common keywords
217  OptionalItem<std::string> m_schema;
218 
219  // 5.1 Number / integer keywords
220  OptionalItem<bool> m_exclusive_maximum;
221  OptionalItem<bool> m_exclusive_minimum;
222  std::auto_ptr<JsonNumber> m_maximum;
223  std::auto_ptr<JsonNumber> m_minimum;
224  std::auto_ptr<JsonNumber> m_multiple_of;
225 
226  // 5.2 String keywords
227  // TODO(simon): Implement pattern support?
228  OptionalItem<std::string> m_pattern;
229  OptionalItem<uint64_t> m_max_length;
230  OptionalItem<uint64_t> m_min_length;
231 
232  // 5.3 Array keywords
233  // 'additionalItems' can be either a bool or a schema
234  OptionalItem<bool> m_additional_items;
235  std::auto_ptr<SchemaParseContext> m_additional_items_context;
236 
237  // 'items' can be either a json schema, or an array of json schema.
238  std::auto_ptr<SchemaParseContext> m_items_single_context;
239  std::auto_ptr<ArrayOfSchemaContext> m_items_context_array;
240 
241  OptionalItem<uint64_t> m_max_items;
242  OptionalItem<uint64_t> m_min_items;
243  OptionalItem<bool> m_unique_items;
244 
245  // 5.4 Object keywords
246  OptionalItem<uint64_t> m_max_properties;
247  OptionalItem<uint64_t> m_min_properties;
248  std::auto_ptr<ArrayOfStringsContext> m_required_items;
249  std::auto_ptr<DependencyParseContext> m_dependency_context;
250 
251  // 5.5 Keywords for multiple instance types
252  JsonType m_type;
253  std::auto_ptr<class ArrayOfJsonValuesContext> m_enum_context;
254  std::auto_ptr<class ArrayOfSchemaContext> m_allof_context;
255  std::auto_ptr<class ArrayOfSchemaContext> m_anyof_context;
256  std::auto_ptr<class ArrayOfSchemaContext> m_oneof_context;
257  std::auto_ptr<class SchemaParseContext> m_not_context;
258 
259  // 6. Metadata keywords
260  OptionalItem<std::string> m_description;
262  std::auto_ptr<const JsonValue> m_default_value;
263  std::auto_ptr<JsonValueContext> m_default_value_context;
264 
265  OptionalItem<std::string> m_ref_schema;
266 
267  // TODO(simon): Implement format support?
268  OptionalItem<std::string> m_format;
269 
270  std::auto_ptr<DefinitionsParseContext> m_definitions_context;
271  std::auto_ptr<PropertiesParseContext> m_properties_context;
272  OptionalItem<bool> m_additional_properties;
273  std::auto_ptr<SchemaParseContext> m_additional_properties_context;
274 
275  void ProcessPositiveInt(SchemaErrorLogger *logger, uint64_t value);
276 
277  template <typename T>
278  void ProcessInt(SchemaErrorLogger *logger, T t);
279 
280  bool AddNumberConstraints(IntegerValidator *validator,
281  SchemaErrorLogger *logger);
282 
283  BaseValidator* BuildArrayValidator(SchemaErrorLogger *logger);
284  BaseValidator* BuildObjectValidator(SchemaErrorLogger *logger);
285  BaseValidator* BuildStringValidator(SchemaErrorLogger *logger);
286 
287  static bool ValidTypeForKeyword(SchemaErrorLogger *logger,
288  SchemaKeyword keyword,
289  JsonType type);
290 
291  // Verify that type == expected_type. If it doesn't report an error to the
292  // logger.
293  static bool CheckTypeAndLog(SchemaErrorLogger *logger, SchemaKeyword keyword,
294  JsonType type, JsonType expected_type);
295  // Same as above but the type can be either expected_type1 or expected_type2
296  static bool CheckTypeAndLog(SchemaErrorLogger *logger, SchemaKeyword keyword,
297  JsonType type, JsonType expected_type1,
298  JsonType expected_type2);
299 
300  DISALLOW_COPY_AND_ASSIGN(SchemaParseContext);
301 };
302 
303 
308  public:
309  explicit PropertiesParseContext(SchemaDefinitions *definitions)
311  m_schema_defs(definitions) {
312  }
314 
315  void AddPropertyValidators(ObjectValidator *object_validator,
316  SchemaErrorLogger *logger);
317 
318  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
319 
320  private:
321  typedef std::map<std::string, SchemaParseContext*> SchemaMap;
322 
323  SchemaDefinitions *m_schema_defs;
324  SchemaMap m_property_contexts;
325 
326  DISALLOW_COPY_AND_ASSIGN(PropertiesParseContext);
327 };
328 
329 
334  public:
335  explicit ArrayOfSchemaContext(SchemaDefinitions *definitions)
336  : m_schema_defs(definitions) {
337  }
338 
340 
347  void GetValidators(SchemaErrorLogger *logger,
349 
350  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
351 
352  private:
353  typedef std::vector<SchemaParseContext*> ItemSchemas;
354 
355  SchemaDefinitions *m_schema_defs;
356  ItemSchemas m_item_schemas;
357 
358  DISALLOW_COPY_AND_ASSIGN(ArrayOfSchemaContext);
359 };
360 
361 
368  public:
369  typedef std::set<std::string> StringSet;
370 
372 
376  void GetStringSet(StringSet *stringd);
377 
378  void String(SchemaErrorLogger *logger, const std::string &value);
379 
380  private:
381  StringSet m_items;
382 
383  DISALLOW_COPY_AND_ASSIGN(ArrayOfStringsContext);
384 };
385 
394  public:
396 
397  const JsonValue* ClaimValue(SchemaErrorLogger *logger);
398 
399  void String(SchemaErrorLogger *logger, const std::string &value);
400  void Number(SchemaErrorLogger *logger, uint32_t value);
401  void Number(SchemaErrorLogger *logger, int32_t value);
402  void Number(SchemaErrorLogger *logger, uint64_t value);
403  void Number(SchemaErrorLogger *logger, int64_t value);
404  void Number(SchemaErrorLogger *logger, double value);
405  void Bool(SchemaErrorLogger *logger, bool value);
406  void Null(SchemaErrorLogger *logger);
408  void CloseArray(SchemaErrorLogger *logger);
409  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
410  void ObjectKey(SchemaErrorLogger *logger, const std::string &key);
411  void CloseObject(SchemaErrorLogger *logger);
412 
413  private:
414  JsonParser m_parser;
415 
416  DISALLOW_COPY_AND_ASSIGN(JsonValueContext);
417 };
418 
425  public:
428 
429  void AddEnumsToValidator(BaseValidator *validator);
430 
431  void String(SchemaErrorLogger *logger, const std::string &value);
432  void Number(SchemaErrorLogger *logger, uint32_t value);
433  void Number(SchemaErrorLogger *logger, int32_t value);
434  void Number(SchemaErrorLogger *logger, uint64_t value);
435  void Number(SchemaErrorLogger *logger, int64_t value);
436  void Number(SchemaErrorLogger *logger, double value);
437  void Bool(SchemaErrorLogger *logger, bool value);
438  void Null(SchemaErrorLogger *logger);
440  void CloseArray(SchemaErrorLogger *logger);
441  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
442  void ObjectKey(SchemaErrorLogger*, const std::string &) {}
443  void CloseObject(SchemaErrorLogger *logger);
444 
445  bool Empty() const { return m_enums.empty(); }
446 
447  private:
448  std::vector<const JsonValue*> m_enums;
449  std::auto_ptr<JsonValueContext> m_value_context;
450 
451  void CheckForDuplicateAndAdd(SchemaErrorLogger *logger,
452  const JsonValue *value);
453 
454  DISALLOW_COPY_AND_ASSIGN(ArrayOfJsonValuesContext);
455 };
456 
457 
466  public:
467  explicit DependencyParseContext(SchemaDefinitions *definitions)
468  : m_schema_defs(definitions) {}
470 
471  void AddDependenciesToValidator(ObjectValidator *validator);
472 
474  void CloseArray(SchemaErrorLogger *logger);
475  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
476  void CloseObject(SchemaErrorLogger *logger);
477 
478  private:
479  typedef std::set<std::string> StringSet;
480  typedef std::map<std::string, ValidatorInterface*> SchemaDependencies;
481  typedef std::map<std::string, StringSet> PropertyDependencies;
482 
483  SchemaDefinitions *m_schema_defs;
484 
485  std::auto_ptr<ArrayOfStringsContext> m_property_context;
486  std::auto_ptr<SchemaParseContext> m_schema_context;
487 
488  PropertyDependencies m_property_dependencies;
489  SchemaDependencies m_schema_dependencies;
490 
491  DISALLOW_COPY_AND_ASSIGN(DependencyParseContext);
492 };
493 } // namespace web
494 } // namespace ola
495 #endif // COMMON_WEB_SCHEMAPARSECONTEXT_H_