Open Lighting Architecture  0.9.1
 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_type(JSON_UNDEFINED) {
180  }
181 
190 
191  void ObjectKey(SchemaErrorLogger *logger, const std::string &keyword);
192 
193  void String(SchemaErrorLogger *logger, const std::string &value);
194  void Number(SchemaErrorLogger *logger, uint32_t value);
195  void Number(SchemaErrorLogger *logger, int32_t value);
196  void Number(SchemaErrorLogger *logger, uint64_t value);
197  void Number(SchemaErrorLogger *logger, int64_t value);
198  void Number(SchemaErrorLogger *logger, double value);
199  void Bool(SchemaErrorLogger *logger, bool value);
200  void Null(SchemaErrorLogger *logger);
202  void CloseArray(SchemaErrorLogger *logger);
203  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
204  void CloseObject(SchemaErrorLogger *logger);
205 
206  private:
207  SchemaDefinitions *m_schema_defs;
208  // Set to the last keyword reported to ObjectKey()
209  SchemaKeyword m_keyword;
210 
211  // Members are arranged according to the order in which they appear in the
212  // draft standard.
213 
214  // Common keywords
216  OptionalItem<std::string> m_schema;
217 
218  // 5.1 Number / integer keywords
219  OptionalItem<bool> m_exclusive_maximum;
220  OptionalItem<bool> m_exclusive_minimum;
221  std::auto_ptr<JsonNumber> m_maximum;
222  std::auto_ptr<JsonNumber> m_minimum;
223  std::auto_ptr<JsonNumber> m_multiple_of;
224 
225  // 5.2 String keywords
226  // TODO(simon): Implement pattern support?
227  OptionalItem<std::string> m_pattern;
228  OptionalItem<uint64_t> m_max_length;
229  OptionalItem<uint64_t> m_min_length;
230 
231  // 5.3 Array keywords
232  // 'additionalItems' can be either a bool or a schema
233  OptionalItem<bool> m_additional_items;
234  std::auto_ptr<SchemaParseContext> m_additional_items_context;
235 
236  // 'items' can be either a json schema, or an array of json schema.
237  std::auto_ptr<SchemaParseContext> m_items_single_context;
238  std::auto_ptr<ArrayOfSchemaContext> m_items_context_array;
239 
240  OptionalItem<uint64_t> m_max_items;
241  OptionalItem<uint64_t> m_min_items;
242  OptionalItem<bool> m_unique_items;
243 
244  // 5.4 Object keywords
245  OptionalItem<uint64_t> m_max_properties;
246  OptionalItem<uint64_t> m_min_properties;
247  std::auto_ptr<ArrayOfStringsContext> m_required_items;
248  std::auto_ptr<DependencyParseContext> m_dependency_context;
249 
250  // 5.5 Keywords for multiple instance types
251  JsonType m_type;
252  std::auto_ptr<class ArrayOfJsonValuesContext> m_enum_context;
253  std::auto_ptr<class ArrayOfSchemaContext> m_allof_context;
254  std::auto_ptr<class ArrayOfSchemaContext> m_anyof_context;
255  std::auto_ptr<class ArrayOfSchemaContext> m_oneof_context;
256  std::auto_ptr<class SchemaParseContext> m_not_context;
257 
258  // 6. Metadata keywords
259  OptionalItem<std::string> m_description;
261  std::auto_ptr<const JsonValue> m_default_value;
262  std::auto_ptr<JsonValueContext> m_default_value_context;
263 
264  OptionalItem<std::string> m_ref_schema;
265 
266  // TODO(simon): Implement format support?
267  OptionalItem<std::string> m_format;
268 
269  std::auto_ptr<DefinitionsParseContext> m_definitions_context;
270  std::auto_ptr<PropertiesParseContext> m_properties_context;
271  OptionalItem<bool> m_additional_properties;
272  std::auto_ptr<SchemaParseContext> m_additional_properties_context;
273 
274  void ProcessPositiveInt(SchemaErrorLogger *logger, uint64_t value);
275 
276  template <typename T>
277  void ProcessInt(SchemaErrorLogger *logger, T t);
278 
279  bool AddNumberConstraints(IntegerValidator *validator,
280  SchemaErrorLogger *logger);
281 
282  BaseValidator* BuildArrayValidator(SchemaErrorLogger *logger);
283  BaseValidator* BuildObjectValidator(SchemaErrorLogger *logger);
284  BaseValidator* BuildStringValidator(SchemaErrorLogger *logger);
285 
286  static bool ValidTypeForKeyword(SchemaErrorLogger *logger,
287  SchemaKeyword keyword,
288  JsonType type);
289 
290  // Verify that type == expected_type. If it doesn't report an error to the
291  // logger.
292  static bool CheckTypeAndLog(SchemaErrorLogger *logger, SchemaKeyword keyword,
293  JsonType type, JsonType expected_type);
294  // Same as above but the type can be either expected_type1 or expected_type2
295  static bool CheckTypeAndLog(SchemaErrorLogger *logger, SchemaKeyword keyword,
296  JsonType type, JsonType expected_type1,
297  JsonType expected_type2);
298 
299  DISALLOW_COPY_AND_ASSIGN(SchemaParseContext);
300 };
301 
302 
307  public:
308  explicit PropertiesParseContext(SchemaDefinitions *definitions)
310  m_schema_defs(definitions) {
311  }
313 
314  void AddPropertyValidators(ObjectValidator *object_validator,
315  SchemaErrorLogger *logger);
316 
317  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
318 
319  private:
320  typedef std::map<std::string, SchemaParseContext*> SchemaMap;
321 
322  SchemaDefinitions *m_schema_defs;
323  SchemaMap m_property_contexts;
324 
325  DISALLOW_COPY_AND_ASSIGN(PropertiesParseContext);
326 };
327 
328 
333  public:
334  explicit ArrayOfSchemaContext(SchemaDefinitions *definitions)
335  : m_schema_defs(definitions) {
336  }
337 
339 
346  void GetValidators(SchemaErrorLogger *logger,
348 
349  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
350 
351  private:
352  typedef std::vector<SchemaParseContext*> ItemSchemas;
353 
354  SchemaDefinitions *m_schema_defs;
355  ItemSchemas m_item_schemas;
356 
357  DISALLOW_COPY_AND_ASSIGN(ArrayOfSchemaContext);
358 };
359 
360 
367  public:
368  typedef std::set<std::string> StringSet;
369 
371 
375  void GetStringSet(StringSet *stringd);
376 
377  void String(SchemaErrorLogger *logger, const std::string &value);
378 
379  private:
380  StringSet m_items;
381 
382  DISALLOW_COPY_AND_ASSIGN(ArrayOfStringsContext);
383 };
384 
393  public:
395 
396  const JsonValue* ClaimValue(SchemaErrorLogger *logger);
397 
398  void String(SchemaErrorLogger *logger, const std::string &value);
399  void Number(SchemaErrorLogger *logger, uint32_t value);
400  void Number(SchemaErrorLogger *logger, int32_t value);
401  void Number(SchemaErrorLogger *logger, uint64_t value);
402  void Number(SchemaErrorLogger *logger, int64_t value);
403  void Number(SchemaErrorLogger *logger, double value);
404  void Bool(SchemaErrorLogger *logger, bool value);
405  void Null(SchemaErrorLogger *logger);
407  void CloseArray(SchemaErrorLogger *logger);
408  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
409  void ObjectKey(SchemaErrorLogger *logger, const std::string &key);
410  void CloseObject(SchemaErrorLogger *logger);
411 
412  private:
413  JsonParser m_parser;
414 
415  DISALLOW_COPY_AND_ASSIGN(JsonValueContext);
416 };
417 
424  public:
427 
428  void AddEnumsToValidator(BaseValidator *validator);
429 
430  void String(SchemaErrorLogger *logger, const std::string &value);
431  void Number(SchemaErrorLogger *logger, uint32_t value);
432  void Number(SchemaErrorLogger *logger, int32_t value);
433  void Number(SchemaErrorLogger *logger, uint64_t value);
434  void Number(SchemaErrorLogger *logger, int64_t value);
435  void Number(SchemaErrorLogger *logger, double value);
436  void Bool(SchemaErrorLogger *logger, bool value);
437  void Null(SchemaErrorLogger *logger);
439  void CloseArray(SchemaErrorLogger *logger);
440  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
441  void ObjectKey(SchemaErrorLogger*, const std::string &) {}
442  void CloseObject(SchemaErrorLogger *logger);
443 
444  bool Empty() const { return m_enums.empty(); }
445 
446  private:
447  std::vector<const JsonValue*> m_enums;
448  std::auto_ptr<JsonValueContext> m_value_context;
449 
450  void CheckForDuplicateAndAdd(SchemaErrorLogger *logger,
451  const JsonValue *value);
452 
453  DISALLOW_COPY_AND_ASSIGN(ArrayOfJsonValuesContext);
454 };
455 
456 
465  public:
466  explicit DependencyParseContext(SchemaDefinitions *definitions)
467  : m_schema_defs(definitions) {}
469 
470  void AddDependenciesToValidator(ObjectValidator *validator);
471 
473  void CloseArray(SchemaErrorLogger *logger);
474  SchemaParseContextInterface* OpenObject(SchemaErrorLogger *logger);
475  void CloseObject(SchemaErrorLogger *logger);
476 
477  private:
478  typedef std::set<std::string> StringSet;
479  typedef std::map<std::string, ValidatorInterface*> SchemaDependencies;
480  typedef std::map<std::string, StringSet> PropertyDependencies;
481 
482  SchemaDefinitions *m_schema_defs;
483 
484  std::auto_ptr<ArrayOfStringsContext> m_property_context;
485  std::auto_ptr<SchemaParseContext> m_schema_context;
486 
487  PropertyDependencies m_property_dependencies;
488  SchemaDependencies m_schema_dependencies;
489 
490  DISALLOW_COPY_AND_ASSIGN(DependencyParseContext);
491 };
492 } // namespace web
493 } // namespace ola
494 #endif // COMMON_WEB_SCHEMAPARSECONTEXT_H_