MQTTSuite
Loading...
Searching...
No Matches
nlohmann::json_schema::root_schema Class Reference
Collaboration diagram for nlohmann::json_schema::root_schema:

Classes

struct  schema_file

Public Member Functions

 root_schema (schema_loader &&loader, format_checker &&format, content_checker &&content)
format_checkerformat_check ()
content_checkercontent_check ()
void insert (const json_uri &uri, const std::shared_ptr< schema > &s)
void insert_unknown_keyword (const json_uri &uri, const std::string &key, json &value)
std::shared_ptr< schemaget_or_create_ref (const json_uri &uri)
void set_root_schema (json sch)
void validate (const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e, const json_uri &initial) const
 root_schema (schema_loader &&loader, format_checker &&format, content_checker &&content)
format_checkerformat_check ()
content_checkercontent_check ()
void insert (const json_uri &uri, const std::shared_ptr< schema > &s)
void insert_unknown_keyword (const json_uri &uri, const std::string &key, json &value)
std::shared_ptr< schemaget_or_create_ref (const json_uri &uri)
void set_root_schema (json sch)
void validate (const json::json_pointer &ptr, const json &instance, json_patch &patch, error_handler &e, const json_uri &initial) const

Private Member Functions

schema_fileget_or_create_file (const std::string &loc)
schema_fileget_or_create_file (const std::string &loc)

Private Attributes

schema_loader loader_
format_checker format_check_
content_checker content_check_
std::shared_ptr< schemaroot_
std::map< std::string, schema_filefiles_

Detailed Description

Definition at line 142 of file json-validator.cpp.

Constructor & Destructor Documentation

◆ root_schema() [1/2]

nlohmann::json_schema::root_schema::root_schema ( schema_loader && loader,
format_checker && format,
content_checker && content )
inline

Definition at line 169 of file json-validator.cpp.

173 : loader_(std::move(loader)),
174 format_check_(std::move(format)),
175 content_check_(std::move(content))
176 {
177 }
static void content(const std::string &contentEncoding, const std::string &contentMediaType, const json &instance)
static void loader(const json_uri &uri, json &schema)

References content_check_, format_check_, and loader_.

Referenced by nlohmann::json_schema::json_validator::json_validator().

Here is the caller graph for this function:

◆ root_schema() [2/2]

nlohmann::json_schema::root_schema::root_schema ( schema_loader && loader,
format_checker && format,
content_checker && content )
inline

Definition at line 169 of file json-validator.cpp.

173 : loader_(std::move(loader)),
174 format_check_(std::move(format)),
175 content_check_(std::move(content))
176 {
177 }

Member Function Documentation

◆ content_check() [1/2]

content_checker & nlohmann::json_schema::root_schema::content_check ( )
inline

Definition at line 180 of file json-validator.cpp.

180{ return content_check_; }

References content_check_.

Referenced by anonymous_namespace{json-validator.cpp}::string::string(), and anonymous_namespace{json-validator.cpp}::string::validate().

Here is the caller graph for this function:

◆ content_check() [2/2]

content_checker & nlohmann::json_schema::root_schema::content_check ( )
inline

Definition at line 180 of file json-validator.cpp.

180{ return content_check_; }

◆ format_check() [1/2]

format_checker & nlohmann::json_schema::root_schema::format_check ( )
inline

Definition at line 179 of file json-validator.cpp.

179{ return format_check_; }

References format_check_.

Referenced by anonymous_namespace{json-validator.cpp}::string::string(), and anonymous_namespace{json-validator.cpp}::string::validate().

Here is the caller graph for this function:

◆ format_check() [2/2]

format_checker & nlohmann::json_schema::root_schema::format_check ( )
inline

Definition at line 179 of file json-validator.cpp.

179{ return format_check_; }

◆ get_or_create_file() [1/2]

schema_file & nlohmann::json_schema::root_schema::get_or_create_file ( const std::string & loc)
inlineprivate

Definition at line 159 of file json-validator.cpp.

160 {
161 auto file = files_.lower_bound(loc);
162 if (file != files_.end() && !(files_.key_comp()(loc, file->first)))
163 return file->second;
164 else
165 return files_.insert(file, {loc, {}})->second;
166 }
std::map< std::string, schema_file > files_

References files_.

Referenced by get_or_create_ref(), insert(), and insert_unknown_keyword().

Here is the caller graph for this function:

◆ get_or_create_file() [2/2]

schema_file & nlohmann::json_schema::root_schema::get_or_create_file ( const std::string & loc)
inlineprivate

Definition at line 159 of file json-validator.cpp.

160 {
161 auto file = files_.lower_bound(loc);
162 if (file != files_.end() && !(files_.key_comp()(loc, file->first)))
163 return file->second;
164 else
165 return files_.insert(file, {loc, {}})->second;
166 }

◆ get_or_create_ref() [1/2]

std::shared_ptr< schema > nlohmann::json_schema::root_schema::get_or_create_ref ( const json_uri & uri)
inline

Definition at line 244 of file json-validator.cpp.

245 {
246 auto &file = get_or_create_file(uri.location());
247
248 // existing schema
249 auto sch = file.schemas.find(uri.fragment());
250 if (sch != file.schemas.end())
251 return sch->second;
252
253 // referencing an unknown keyword, turn it into schema
254 //
255 // an unknown keyword can only be referenced by a json-pointer,
256 // not by a plain name fragment
257 if (!uri.pointer().to_string().empty()) {
258 bool contains_pointer = file.unknown_keywords.contains(uri.pointer());
259 if (contains_pointer) {
260 auto &subschema = file.unknown_keywords.at(uri.pointer());
261 auto s = schema::make(subschema, this, {}, {{uri}});
262 if (s) { // if schema is valid (non-null)
263 file.unknown_keywords.erase(uri.fragment());
264 return s;
265 }
266 }
267 }
268
269 // get or create a schema_ref
270 auto r = file.unresolved.lower_bound(uri.fragment());
271 if (r != file.unresolved.end() && !(file.unresolved.key_comp()(uri.fragment(), r->first))) {
272 return r->second; // unresolved, already seen previously - use existing reference
273 } else {
274 return file.unresolved.insert(r,
275 {uri.fragment(), std::make_shared<schema_ref>(uri.to_string(), this)})
276 ->second; // unresolved, create reference
277 }
278 }
static std::shared_ptr< schema > make(json &schema, root_schema *root, const std::vector< std::string > &key, std::vector< nlohmann::json_uri > uris)
schema_file & get_or_create_file(const std::string &loc)
std::string fragment() const
std::string to_string() const
Definition json-uri.cpp:118
std::string location() const
Definition json-uri.cpp:102
const json::json_pointer & pointer() const

References nlohmann::json_uri::fragment(), get_or_create_file(), nlohmann::json_uri::location(), anonymous_namespace{json-validator.cpp}::schema::make(), nlohmann::json_uri::pointer(), nlohmann::json_schema::root_schema::schema_file::schemas, nlohmann::json_uri::to_string(), nlohmann::json_schema::root_schema::schema_file::unknown_keywords, and nlohmann::json_schema::root_schema::schema_file::unresolved.

Referenced by anonymous_namespace{json-validator.cpp}::schema::make().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_or_create_ref() [2/2]

std::shared_ptr< schema > nlohmann::json_schema::root_schema::get_or_create_ref ( const json_uri & uri)
inline

Definition at line 244 of file json-validator.cpp.

245 {
246 auto &file = get_or_create_file(uri.location());
247
248 // existing schema
249 auto sch = file.schemas.find(uri.fragment());
250 if (sch != file.schemas.end())
251 return sch->second;
252
253 // referencing an unknown keyword, turn it into schema
254 //
255 // an unknown keyword can only be referenced by a json-pointer,
256 // not by a plain name fragment
257 if (!uri.pointer().to_string().empty()) {
258 bool contains_pointer = file.unknown_keywords.contains(uri.pointer());
259 if (contains_pointer) {
260 auto &subschema = file.unknown_keywords.at(uri.pointer());
261 auto s = schema::make(subschema, this, {}, {{uri}});
262 if (s) { // if schema is valid (non-null)
263 file.unknown_keywords.erase(uri.fragment());
264 return s;
265 }
266 }
267 }
268
269 // get or create a schema_ref
270 auto r = file.unresolved.lower_bound(uri.fragment());
271 if (r != file.unresolved.end() && !(file.unresolved.key_comp()(uri.fragment(), r->first))) {
272 return r->second; // unresolved, already seen previously - use existing reference
273 } else {
274 return file.unresolved.insert(r,
275 {uri.fragment(), std::make_shared<schema_ref>(uri.to_string(), this)})
276 ->second; // unresolved, create reference
277 }
278 }

◆ insert() [1/2]

void nlohmann::json_schema::root_schema::insert ( const json_uri & uri,
const std::shared_ptr< schema > & s )
inline

Definition at line 182 of file json-validator.cpp.

183 {
184 auto &file = get_or_create_file(uri.location());
185 auto sch = file.schemas.lower_bound(uri.fragment());
186 if (sch != file.schemas.end() && !(file.schemas.key_comp()(uri.fragment(), sch->first))) {
187 throw std::invalid_argument("schema with " + uri.to_string() + " already inserted");
188 return;
189 }
190
191 file.schemas.insert({uri.fragment(), s});
192
193 // was someone referencing this newly inserted schema?
194 auto unresolved = file.unresolved.find(uri.fragment());
195 if (unresolved != file.unresolved.end()) {
196 unresolved->second->set_target(s);
197 file.unresolved.erase(unresolved);
198 }
199 }

References nlohmann::json_uri::fragment(), get_or_create_file(), nlohmann::json_uri::location(), nlohmann::json_schema::root_schema::schema_file::schemas, anonymous_namespace{json-validator.cpp}::schema_ref::set_target(), nlohmann::json_uri::to_string(), and nlohmann::json_schema::root_schema::schema_file::unresolved.

Referenced by anonymous_namespace{json-validator.cpp}::schema::make().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert() [2/2]

void nlohmann::json_schema::root_schema::insert ( const json_uri & uri,
const std::shared_ptr< schema > & s )
inline

Definition at line 182 of file json-validator.cpp.

183 {
184 auto &file = get_or_create_file(uri.location());
185 auto sch = file.schemas.lower_bound(uri.fragment());
186 if (sch != file.schemas.end() && !(file.schemas.key_comp()(uri.fragment(), sch->first))) {
187 throw std::invalid_argument("schema with " + uri.to_string() + " already inserted");
188 return;
189 }
190
191 file.schemas.insert({uri.fragment(), s});
192
193 // was someone referencing this newly inserted schema?
194 auto unresolved = file.unresolved.find(uri.fragment());
195 if (unresolved != file.unresolved.end()) {
196 unresolved->second->set_target(s);
197 file.unresolved.erase(unresolved);
198 }
199 }

◆ insert_unknown_keyword() [1/2]

void nlohmann::json_schema::root_schema::insert_unknown_keyword ( const json_uri & uri,
const std::string & key,
json & value )
inline

Definition at line 201 of file json-validator.cpp.

202 {
203 auto &file = get_or_create_file(uri.location());
204 auto new_uri = uri.append(key);
205 auto fragment = new_uri.pointer();
206
207 // is there a reference looking for this unknown-keyword, which is thus no longer a unknown keyword but a schema
208 auto unresolved = file.unresolved.find(fragment.to_string());
209 if (unresolved != file.unresolved.end())
210 schema::make(value, this, {}, {{new_uri}});
211 else { // no, nothing ref'd it, keep for later
212
213 // need to create an object for each reference-token in the
214 // JSON-Pointer When not existing, a stringified integer reference
215 // token (e.g. "123") in the middle of the pointer will be
216 // interpreted a an array-index and an array will be created.
217
218 // json_pointer's reference_tokens is private - get them
219 std::deque<std::string> ref_tokens;
220 auto uri_pointer = uri.pointer();
221 while (!uri_pointer.empty()) {
222 ref_tokens.push_front(uri_pointer.back());
223 uri_pointer.pop_back();
224 }
225
226 // for each token create an object, if not already existing
227 auto unk_kw = &file.unknown_keywords;
228 for (auto &rt : ref_tokens) {
229 // create a json_pointer from rt as rt can be an stringified integer doing find on an array won't work
230 json::json_pointer rt_ptr{"/" + rt};
231 if (unk_kw->contains(rt_ptr) == false)
232 (*unk_kw)[rt] = json::object();
233 unk_kw = &(*unk_kw)[rt_ptr];
234 }
235 (*unk_kw)[key] = value;
236 }
237
238 // recursively add possible subschemas of unknown keywords
239 if (value.type() == json::value_t::object)
240 for (auto &subsch : value.items())
241 insert_unknown_keyword(new_uri, subsch.key(), subsch.value());
242 }
void insert_unknown_keyword(const json_uri &uri, const std::string &key, json &value)
json_uri append(const std::string &field) const

References nlohmann::json_uri::append(), get_or_create_file(), insert_unknown_keyword(), nlohmann::json_uri::location(), anonymous_namespace{json-validator.cpp}::schema::make(), nlohmann::json_uri::pointer(), nlohmann::json_schema::root_schema::schema_file::unknown_keywords, and nlohmann::json_schema::root_schema::schema_file::unresolved.

Referenced by insert_unknown_keyword(), and anonymous_namespace{json-validator.cpp}::schema::make().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ insert_unknown_keyword() [2/2]

void nlohmann::json_schema::root_schema::insert_unknown_keyword ( const json_uri & uri,
const std::string & key,
json & value )
inline

Definition at line 201 of file json-validator.cpp.

202 {
203 auto &file = get_or_create_file(uri.location());
204 auto new_uri = uri.append(key);
205 auto fragment = new_uri.pointer();
206
207 // is there a reference looking for this unknown-keyword, which is thus no longer a unknown keyword but a schema
208 auto unresolved = file.unresolved.find(fragment.to_string());
209 if (unresolved != file.unresolved.end())
210 schema::make(value, this, {}, {{new_uri}});
211 else { // no, nothing ref'd it, keep for later
212
213 // need to create an object for each reference-token in the
214 // JSON-Pointer When not existing, a stringified integer reference
215 // token (e.g. "123") in the middle of the pointer will be
216 // interpreted a an array-index and an array will be created.
217
218 // json_pointer's reference_tokens is private - get them
219 std::deque<std::string> ref_tokens;
220 auto uri_pointer = uri.pointer();
221 while (!uri_pointer.empty()) {
222 ref_tokens.push_front(uri_pointer.back());
223 uri_pointer.pop_back();
224 }
225
226 // for each token create an object, if not already existing
227 auto unk_kw = &file.unknown_keywords;
228 for (auto &rt : ref_tokens) {
229 // create a json_pointer from rt as rt can be an stringified integer doing find on an array won't work
230 json::json_pointer rt_ptr{"/" + rt};
231 if (unk_kw->contains(rt_ptr) == false)
232 (*unk_kw)[rt] = json::object();
233 unk_kw = &(*unk_kw)[rt_ptr];
234 }
235 (*unk_kw)[key] = value;
236 }
237
238 // recursively add possible subschemas of unknown keywords
239 if (value.type() == json::value_t::object)
240 for (auto &subsch : value.items())
241 insert_unknown_keyword(new_uri, subsch.key(), subsch.value());
242 }

◆ set_root_schema() [1/2]

void nlohmann::json_schema::root_schema::set_root_schema ( json sch)
inline

Definition at line 280 of file json-validator.cpp.

281 {
282 files_.clear();
283 root_ = schema::make(sch, this, {}, {{"#"}});
284
285 // load all files which have not yet been loaded
286 do {
287 bool new_schema_loaded = false;
288
289 // files_ is modified during parsing, iterators are invalidated
290 std::vector<std::string> locations;
291 for (auto &file : files_)
292 locations.push_back(file.first);
293
294 for (auto &loc : locations) {
295 if (files_[loc].schemas.size() == 0) { // nothing has been loaded for this file
296 if (loader_) {
297 json loaded_schema;
298
299 loader_(loc, loaded_schema);
300
301 schema::make(loaded_schema, this, {}, {{loc}});
302 new_schema_loaded = true;
303 } else {
304 throw std::invalid_argument("external schema reference '" + loc + "' needs loading, but no loader callback given");
305 }
306 }
307 }
308
309 if (!new_schema_loaded) // if no new schema loaded, no need to try again
310 break;
311 } while (1);
312
313 for (const auto &file : files_) {
314 if (file.second.unresolved.size() != 0) {
315 // Build a representation of the undefined
316 // references as a list of comma-separated strings.
317 auto n_urefs = file.second.unresolved.size();
318 std::string urefs = "[";
319
320 decltype(n_urefs) counter = 0;
321 for (const auto &p : file.second.unresolved) {
322 urefs += p.first;
323
324 if (counter != n_urefs - 1u) {
325 urefs += ", ";
326 }
327
328 ++counter;
329 }
330
331 urefs += "]";
332
333 throw std::invalid_argument("after all files have been parsed, '" +
334 (file.first == "" ? "<root>" : file.first) +
335 "' has still the following undefined references: " + urefs);
336 }
337 }
338 }
nlohmann::json json
std::shared_ptr< schema > root_

References files_, loader_, anonymous_namespace{json-validator.cpp}::schema::make(), root_, nlohmann::json_schema::root_schema::schema_file::schemas, and nlohmann::json_schema::root_schema::schema_file::unresolved.

Referenced by nlohmann::json_schema::json_validator::set_root_schema(), and nlohmann::json_schema::json_validator::set_root_schema().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_root_schema() [2/2]

void nlohmann::json_schema::root_schema::set_root_schema ( json sch)
inline

Definition at line 280 of file json-validator.cpp.

281 {
282 files_.clear();
283 root_ = schema::make(sch, this, {}, {{"#"}});
284
285 // load all files which have not yet been loaded
286 do {
287 bool new_schema_loaded = false;
288
289 // files_ is modified during parsing, iterators are invalidated
290 std::vector<std::string> locations;
291 for (auto &file : files_)
292 locations.push_back(file.first);
293
294 for (auto &loc : locations) {
295 if (files_[loc].schemas.size() == 0) { // nothing has been loaded for this file
296 if (loader_) {
297 json loaded_schema;
298
299 loader_(loc, loaded_schema);
300
301 schema::make(loaded_schema, this, {}, {{loc}});
302 new_schema_loaded = true;
303 } else {
304 throw std::invalid_argument("external schema reference '" + loc + "' needs loading, but no loader callback given");
305 }
306 }
307 }
308
309 if (!new_schema_loaded) // if no new schema loaded, no need to try again
310 break;
311 } while (1);
312
313 for (const auto &file : files_) {
314 if (file.second.unresolved.size() != 0) {
315 // Build a representation of the undefined
316 // references as a list of comma-separated strings.
317 auto n_urefs = file.second.unresolved.size();
318 std::string urefs = "[";
319
320 decltype(n_urefs) counter = 0;
321 for (const auto &p : file.second.unresolved) {
322 urefs += p.first;
323
324 if (counter != n_urefs - 1u) {
325 urefs += ", ";
326 }
327
328 ++counter;
329 }
330
331 urefs += "]";
332
333 throw std::invalid_argument("after all files have been parsed, '" +
334 (file.first == "" ? "<root>" : file.first) +
335 "' has still the following undefined references: " + urefs);
336 }
337 }
338 }

◆ validate() [1/2]

void nlohmann::json_schema::root_schema::validate ( const json::json_pointer & ptr,
const json & instance,
json_patch & patch,
error_handler & e,
const json_uri & initial ) const
inline

Definition at line 340 of file json-validator.cpp.

345 {
346 if (!root_) {
347 e.error(ptr, "", "no root schema has yet been set for validating an instance");
348 return;
349 }
350
351 auto file_entry = files_.find(initial.location());
352 if (file_entry == files_.end()) {
353 e.error(ptr, "", "no file found serving requested root-URI. " + initial.location());
354 return;
355 }
356
357 auto &file = file_entry->second;
358 auto sch = file.schemas.find(initial.fragment());
359 if (sch == file.schemas.end()) {
360 e.error(ptr, "", "no schema find for request initial URI: " + initial.to_string());
361 return;
362 }
363
364 sch->second->validate(ptr, instance, patch, e);
365 }
virtual void error(const json::json_pointer &, const json &, const std::string &)=0
static const auto instance
Definition issue-93.cpp:14

References nlohmann::json_schema::error_handler::error(), files_, nlohmann::json_uri::fragment(), nlohmann::json_uri::location(), root_, nlohmann::json_schema::root_schema::schema_file::schemas, nlohmann::json_uri::to_string(), and anonymous_namespace{json-validator.cpp}::schema::validate().

Referenced by nlohmann::json_schema::json_validator::validate().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ validate() [2/2]

void nlohmann::json_schema::root_schema::validate ( const json::json_pointer & ptr,
const json & instance,
json_patch & patch,
error_handler & e,
const json_uri & initial ) const
inline

Definition at line 340 of file json-validator.cpp.

345 {
346 if (!root_) {
347 e.error(ptr, "", "no root schema has yet been set for validating an instance");
348 return;
349 }
350
351 auto file_entry = files_.find(initial.location());
352 if (file_entry == files_.end()) {
353 e.error(ptr, "", "no file found serving requested root-URI. " + initial.location());
354 return;
355 }
356
357 auto &file = file_entry->second;
358 auto sch = file.schemas.find(initial.fragment());
359 if (sch == file.schemas.end()) {
360 e.error(ptr, "", "no schema find for request initial URI: " + initial.to_string());
361 return;
362 }
363
364 sch->second->validate(ptr, instance, patch, e);
365 }

Member Data Documentation

◆ content_check_

content_checker nlohmann::json_schema::root_schema::content_check_
private

Definition at line 146 of file json-validator.cpp.

Referenced by content_check(), and root_schema().

◆ files_

std::map< std::string, schema_file > nlohmann::json_schema::root_schema::files_
private

Definition at line 157 of file json-validator.cpp.

Referenced by get_or_create_file(), set_root_schema(), and validate().

◆ format_check_

format_checker nlohmann::json_schema::root_schema::format_check_
private

Definition at line 145 of file json-validator.cpp.

Referenced by format_check(), and root_schema().

◆ loader_

schema_loader nlohmann::json_schema::root_schema::loader_
private

Definition at line 144 of file json-validator.cpp.

Referenced by root_schema(), and set_root_schema().

◆ root_

std::shared_ptr< schema > nlohmann::json_schema::root_schema::root_
private

Definition at line 148 of file json-validator.cpp.

Referenced by set_root_schema(), and validate().


The documentation for this class was generated from the following file: