Update SchemaParser to pass optional resolution scope with recursive fn calls

This commit is contained in:
Tristan Penman 2015-12-13 13:09:12 +11:00
parent 79267593f3
commit cdabbe5549

View File

@ -94,6 +94,7 @@ private:
* document
* @param node Reference to node to parse
* @param schema Reference to Schema to populate
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param parentSchema Optional pointer to the parent schema, used to
* support required keyword in Draft 3.
@ -105,6 +106,7 @@ private:
const AdapterType &rootNode,
const AdapterType &node,
Schema &schema,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type>
fetchDoc = boost::none,
Schema *parentSchema = NULL,
@ -127,7 +129,7 @@ private:
}
const std::string &jsonRef = itr->second.asString();
populateSchemaUsingJsonReference(jsonRef, rootNode, node,
schema, fetchDoc, parentSchema, ownName);
schema, currentScope, fetchDoc, parentSchema, ownName);
return;
}
}
@ -143,17 +145,17 @@ private:
if ((itr = object.find("allOf")) != object.end()) {
schema.addConstraint(makeAllOfConstraint(rootNode, itr->second,
fetchDoc));
currentScope, fetchDoc));
}
if ((itr = object.find("anyOf")) != object.end()) {
schema.addConstraint(makeAnyOfConstraint(rootNode, itr->second,
fetchDoc));
currentScope, fetchDoc));
}
if ((itr = object.find("dependencies")) != object.end()) {
schema.addConstraint(makeDependenciesConstraint(rootNode,
itr->second, fetchDoc));
itr->second, currentScope, fetchDoc));
}
if ((itr = object.find("description")) != object.end()) {
@ -188,7 +190,7 @@ private:
schema.addConstraint(makeItemsConstraint(rootNode,
itemsItr != object.end() ? &itemsItr->second : NULL,
additionalitemsItr != object.end() ? &additionalitemsItr->second : NULL,
fetchDoc));
currentScope, fetchDoc));
}
}
@ -248,12 +250,12 @@ private:
if ((itr = object.find("not")) != object.end()) {
schema.addConstraint(makeNotConstraint(rootNode, itr->second,
fetchDoc));
currentScope, fetchDoc));
}
if ((itr = object.find("oneOf")) != object.end()) {
schema.addConstraint(makeOneOfConstraint(rootNode, itr->second,
fetchDoc));
currentScope, fetchDoc));
}
if ((itr = object.find("pattern")) != object.end()) {
@ -274,7 +276,7 @@ private:
propertiesItr != object.end() ? &propertiesItr->second : NULL,
patternPropertiesItr != object.end() ? &patternPropertiesItr->second : NULL,
additionalPropertiesItr != object.end() ? &additionalPropertiesItr->second : NULL,
fetchDoc, &schema));
currentScope, fetchDoc, &schema));
}
}
@ -303,7 +305,7 @@ private:
if ((itr = object.find("type")) != object.end()) {
schema.addConstraint(makeTypeConstraint(rootNode, itr->second,
fetchDoc));
currentScope, fetchDoc));
}
if ((itr = object.find("uniqueItems")) != object.end()) {
@ -326,6 +328,7 @@ private:
* document; used for recursive parsing of schemas
* @param node Reference to node to parse
* @param schema Reference to Schema to populate
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param parentSchema Optional pointer to the parent schema, used to
* support required keyword in Draft 3.
@ -338,6 +341,7 @@ private:
const AdapterType &rootNode,
const AdapterType &node,
Schema &schema,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type>
fetchDoc,
Schema *parentSchema = NULL,
@ -375,27 +379,28 @@ private:
*docPtr, jsonPointer);
// Resolve reference against retrieved document
populateSchema<AdapterType>(ref, schema, fetchDoc, parentSchema,
ownName);
populateSchema<AdapterType>(ref, ref, schema, currentScope,
fetchDoc, parentSchema, ownName);
} else {
const AdapterType &ref = internal::json_pointer::resolveJsonPointer(
rootNode, jsonPointer);
// Resolve reference against current document
populateSchema<AdapterType>(rootNode, ref, schema, fetchDoc,
parentSchema, ownName);
populateSchema<AdapterType>(rootNode, ref, schema, currentScope,
fetchDoc, parentSchema, ownName);
}
}
/**
* @brief Make a new AllOfConstraint object
*
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an array of child schemas
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an array of child schemas
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
*
* @return pointer to a new AllOfConstraint object that belongs to the
* caller
@ -404,6 +409,7 @@ private:
constraints::AllOfConstraint* makeAllOfConstraint(
const AdapterType &rootNode,
const AdapterType &node,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type > fetchDoc)
{
if (!node.maybeArray()) {
@ -415,7 +421,7 @@ private:
if (schemaNode.maybeObject()) {
childSchemas.push_back(new Schema);
populateSchema<AdapterType>(rootNode, schemaNode,
childSchemas.back(), fetchDoc);
childSchemas.back(), currentScope, fetchDoc);
} else {
throw std::runtime_error("Expected array element to be an object value in 'allOf' constraint.");
}
@ -428,11 +434,12 @@ private:
/**
* @brief Make a new AnyOfConstraint object
*
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an array of child schemas
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an array of child schemas
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
*
* @return pointer to a new AnyOfConstraint object that belongs to the
* caller
@ -441,6 +448,7 @@ private:
constraints::AnyOfConstraint* makeAnyOfConstraint(
const AdapterType &rootNode,
const AdapterType &node,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type > fetchDoc)
{
if (!node.maybeArray()) {
@ -452,7 +460,7 @@ private:
if (schemaNode.maybeObject()) {
childSchemas.push_back(new Schema);
populateSchema<AdapterType>(rootNode, schemaNode,
childSchemas.back(), fetchDoc);
childSchemas.back(), currentScope, fetchDoc);
} else {
throw std::runtime_error("Expected array element to be an object value in 'anyOf' constraint.");
}
@ -482,12 +490,13 @@ private:
* If the format of any part of the the dependency node does not match one
* of these formats, an exception will be thrown.
*
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an object that defines a mapping
* of properties to their dependencies.
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an object that defines a
* mapping of properties to their dependencies.
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
*
* @return pointer to a new DependencyConstraint that belongs to the
* caller
@ -496,6 +505,7 @@ private:
constraints::DependenciesConstraint* makeDependenciesConstraint(
const AdapterType &rootNode,
const AdapterType &node,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type >
fetchDoc)
{
@ -538,7 +548,7 @@ private:
// Parse dependent subschema
Schema &childSchema = pdsm[member.first];
populateSchema<AdapterType>(rootNode, member.second,
childSchema, fetchDoc);
childSchema, currentScope, fetchDoc);
// If we're supposed to be parsing a Draft3 schema, then the value
// of the dependency mapping can also be a string containing the
@ -592,6 +602,7 @@ private:
* @param additionalItems Optional pointer to a JSON node containing
* an additional properties schema or a boolean
* value.
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents
* (optional)
*
@ -602,6 +613,7 @@ private:
const AdapterType &rootNode,
const AdapterType *items,
const AdapterType *additionalItems,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type >
fetchDoc)
{
@ -622,7 +634,7 @@ private:
// used to validate additional array items.
additionalItemsSchema.reset(new Schema());
populateSchema<AdapterType>(rootNode, *additionalItems,
*additionalItemsSchema, fetchDoc);
*additionalItemsSchema, currentScope, fetchDoc);
} else {
// Any other format for the additionalItems property will result
// in an exception being thrown.
@ -650,7 +662,7 @@ private:
itemSchemas.push_back(new Schema());
Schema &childSchema = itemSchemas.back();
populateSchema<AdapterType>(rootNode, v, childSchema,
fetchDoc);
currentScope, fetchDoc);
}
// Create an ItemsConstraint object using the appropriate
@ -668,7 +680,7 @@ private:
// additionalItems constraint will be ignored.
Schema childSchema;
populateSchema<AdapterType>(rootNode, *items, childSchema,
fetchDoc);
currentScope, fetchDoc);
if (additionalItemsSchema) {
return new constraints::ItemsConstraint(childSchema, *additionalItemsSchema);
} else {
@ -934,10 +946,12 @@ private:
/**
* @brief Make a new NotConstraint object
*
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing a schema
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing a schema
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
*
* @return pointer to a new NotConstraint object that belongs to the caller
*/
@ -945,11 +959,13 @@ private:
constraints::NotConstraint* makeNotConstraint(
const AdapterType &rootNode,
const AdapterType &node,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type > fetchDoc)
{
if (node.maybeObject()) {
Schema childSchema;
populateSchema<AdapterType>(rootNode, node, childSchema, fetchDoc);
populateSchema<AdapterType>(rootNode, node, childSchema,
currentScope, fetchDoc);
return new constraints::NotConstraint(childSchema);
}
@ -959,12 +975,12 @@ private:
/**
* @brief Make a new OneOfConstraint object
*
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an array of child schemas
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node JSON node containing an array of child schemas
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
*
* @return pointer to a new OneOfConstraint that belongs to the caller
*/
@ -972,6 +988,7 @@ private:
constraints::OneOfConstraint* makeOneOfConstraint(
const AdapterType &rootNode,
const AdapterType &node,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type >
fetchDoc)
{
@ -979,7 +996,7 @@ private:
BOOST_FOREACH ( const AdapterType schemaNode, node.getArray() ) {
childSchemas.push_back(new Schema);
populateSchema<AdapterType>(rootNode, schemaNode,
childSchemas.back(), fetchDoc);
childSchemas.back(), currentScope, fetchDoc);
}
/// @todo: bypass deep copy of the child schemas
@ -1017,6 +1034,7 @@ private:
* @param additionalProperties Optional pointer to a JSON node containing
* an additional properties schema or a
* boolean value.
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents
* (optional)
* @param parentSchema Optional pointer to the Schema of the
@ -1031,6 +1049,7 @@ private:
const AdapterType *properties,
const AdapterType *patternProperties,
const AdapterType *additionalProperties,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type >
fetchDoc,
Schema *parentSchema)
@ -1046,8 +1065,8 @@ private:
const std::string &propertyName = m.first;
Schema &childSchema = propertySchemas[propertyName];
populateSchema<AdapterType>(
rootNode, m.second, childSchema, // Required
fetchDoc, parentSchema, &propertyName); // Optional
rootNode, m.second, childSchema, currentScope, fetchDoc,
parentSchema, &propertyName);
}
}
@ -1059,8 +1078,8 @@ private:
const std::string &propertyName = m.first;
Schema &childSchema = patternPropertySchemas[propertyName];
populateSchema<AdapterType>(
rootNode, m.second, childSchema, // Required
fetchDoc, parentSchema, &propertyName); // Optional
rootNode, m.second, childSchema, currentScope, fetchDoc,
parentSchema, &propertyName);
}
}
@ -1086,7 +1105,7 @@ private:
// a child schema.
additionalPropertiesSchema.reset(new Schema());
populateSchema<AdapterType>(rootNode, *additionalProperties,
*additionalPropertiesSchema, fetchDoc);
*additionalPropertiesSchema, currentScope, fetchDoc);
} else {
// All other types are invalid
throw std::runtime_error("Invalid type for 'additionalProperties' constraint.");
@ -1168,11 +1187,12 @@ private:
/**
* @brief Make a new TypeConstraint object
*
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node Node containing the name of a JSON type
* @param fetchDoc Function to fetch remote JSON documents (optional)
* @param rootNode Reference to the node from which JSON References
* will be resolved when they refer to the current
* document; used for recursive parsing of schemas
* @param node Node containing the name of a JSON type
* @param currentScope URI for current resolution scope
* @param fetchDoc Function to fetch remote JSON documents (optional)
*
* @return pointer to a new TypeConstraint object.
@ -1181,6 +1201,7 @@ private:
constraints::TypeConstraint* makeTypeConstraint(
const AdapterType &rootNode,
const AdapterType &node,
boost::optional<std::string> currentScope,
boost::optional<typename FetchDocumentFunction<AdapterType>::Type >
fetchDoc)
{
@ -1208,7 +1229,7 @@ private:
// Schema!
schemas.push_back(new Schema());
populateSchema<AdapterType>(rootNode, v, schemas.back(),
fetchDoc);
currentScope, fetchDoc);
} else {
throw std::runtime_error("Type name should be a string.");
}
@ -1216,7 +1237,7 @@ private:
} else if (node.isObject() && version == kDraft3) {
schemas.push_back(new Schema());
populateSchema<AdapterType>(rootNode, node, schemas.back(),
fetchDoc);
currentScope, fetchDoc);
} else {
throw std::runtime_error("Type name should be a string.");
}