Update document fetch interface to use underlying document type rather than Adapter

This commit is contained in:
Tristan Penman 2016-02-14 11:10:21 -08:00
parent bee57e1f90
commit 193c58da02
2 changed files with 33 additions and 32 deletions

View File

@ -64,10 +64,10 @@ public:
DocumentType;
/// Templated function pointer type for fetching remote documents
typedef const AdapterType * (*FetchDoc)(const std::string &uri);
typedef const DocumentType * (*FetchDoc)(const std::string &uri);
/// Templated function pointer type for freeing fetched documents
typedef void (*FreeDoc)(const AdapterType *);
typedef void (*FreeDoc)(const DocumentType *);
};
/**
@ -116,7 +116,7 @@ private:
typedef typename adapters::AdapterTraits<AdapterType>::DocumentType
DocumentType;
typedef std::map<std::string, const AdapterType*> Type;
typedef std::map<std::string, const DocumentType*> Type;
};
typedef std::map<std::string, const Subschema *> SchemaCache;
@ -395,7 +395,7 @@ private:
}
if (actualDocumentUri) {
const AdapterType *newDoc = NULL;
const typename FunctionPtrs<AdapterType>::DocumentType *newDoc = NULL;
// Have we seen this document before?
typename DocumentCache<AdapterType>::Type::iterator docCacheItr =
@ -429,16 +429,18 @@ private:
newDoc = docCacheItr->second;
}
const AdapterType newRootNode(*newDoc);
// Find where we need to be in the document
const AdapterType &referencedAdapter =
internal::json_pointer::resolveJsonPointer(*newDoc,
internal::json_pointer::resolveJsonPointer(newRootNode,
actualJsonPointer);
newCacheKeys.push_back(queryKey);
// Populate the schema, starting from the referenced node, with
// nested JSON References resolved relative to the new root node
return makeOrReuseSchema(rootSchema, *newDoc, referencedAdapter,
return makeOrReuseSchema(rootSchema, newRootNode, referencedAdapter,
currentScope, actualJsonPointer, fetchDoc, parentSubschema,
ownName, docCache, schemaCache, newCacheKeys);
@ -885,7 +887,8 @@ private:
"Fetching of remote JSON References not enabled.");
}
const AdapterType *newDoc = fetchDoc(*documentUri);
const typename DocumentCache<AdapterType>::DocumentType *newDoc =
fetchDoc(*documentUri);
// Can't proceed without the remote document
if (!newDoc) {
@ -900,14 +903,16 @@ private:
docCache.insert(DocCacheValueType(*documentUri, newDoc));
const AdapterType newRootNode(*newDoc);
const AdapterType &referencedAdapter =
internal::json_pointer::resolveJsonPointer(
*newDoc, actualJsonPointer);
newRootNode, actualJsonPointer);
// TODO: Need to detect degenerate circular references
resolveThenPopulateSchema(rootSchema, *newDoc, referencedAdapter,
schema, boost::none, actualJsonPointer, fetchDoc,
parentSchema, ownName, docCache, schemaCache);
resolveThenPopulateSchema(rootSchema, newRootNode,
referencedAdapter, schema, boost::none, actualJsonPointer,
fetchDoc, parentSchema, ownName, docCache, schemaCache);
} else {
const AdapterType &referencedAdapter =

View File

@ -13,43 +13,38 @@ using valijson::SchemaParser;
using valijson::adapters::RapidJsonAdapter;
using valijson::Validator;
namespace {
static rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> allocator;
static rapidjson::Value fetchedRoot;
static RapidJsonAdapter fetchedRootAdapter;
}
class TestFetchDocumentCallback : public ::testing::Test
{
};
const RapidJsonAdapter * fetchDocument(const std::string &uri)
const rapidjson::Document * fetchDocument(const std::string &uri)
{
EXPECT_STREQ("http://localhost:1234/", uri.c_str());
rapidjson::Document *fetchedRoot = new rapidjson::Document();
fetchedRoot->SetObject();
rapidjson::Value valueOfTypeAttribute;
valueOfTypeAttribute.SetString("string", allocator);
valueOfTypeAttribute.SetString("string", fetchedRoot->GetAllocator());
rapidjson::Value schemaOfTestProperty;
schemaOfTestProperty.SetObject();
schemaOfTestProperty.AddMember("type", valueOfTypeAttribute, allocator);
schemaOfTestProperty.AddMember("type", valueOfTypeAttribute,
fetchedRoot->GetAllocator());
rapidjson::Value propertiesConstraint;
propertiesConstraint.SetObject();
propertiesConstraint.AddMember("test", schemaOfTestProperty, allocator);
propertiesConstraint.AddMember("test", schemaOfTestProperty,
fetchedRoot->GetAllocator());
fetchedRoot.SetObject();
fetchedRoot.AddMember("properties", propertiesConstraint, allocator);
fetchedRoot->AddMember("properties", propertiesConstraint,
fetchedRoot->GetAllocator());
// Have to ensure that fetchedRoot exists for at least as long as the
// shared pointer that we return here
return new RapidJsonAdapter(fetchedRoot);
return fetchedRoot;
}
void freeDocument(const RapidJsonAdapter *adapter)
void freeDocument(const rapidjson::Document *adapter)
{
delete adapter;
}
@ -60,7 +55,8 @@ TEST_F(TestFetchDocumentCallback, Basics)
rapidjson::Document schemaDocument;
RapidJsonAdapter schemaDocumentAdapter(schemaDocument);
schemaDocument.SetObject();
schemaDocument.AddMember("$ref", "http://localhost:1234/#/", allocator);
schemaDocument.AddMember("$ref", "http://localhost:1234/#/",
schemaDocument.GetAllocator());
// Parse schema document
Schema schema;
@ -71,7 +67,7 @@ TEST_F(TestFetchDocumentCallback, Basics)
// Test resulting schema with a valid document
rapidjson::Document validDocument;
validDocument.SetObject();
validDocument.AddMember("test", "valid", allocator);
validDocument.AddMember("test", "valid", schemaDocument.GetAllocator());
Validator validator;
EXPECT_TRUE(validator.validate(schema, RapidJsonAdapter(validDocument),
NULL));
@ -79,7 +75,7 @@ TEST_F(TestFetchDocumentCallback, Basics)
// Test resulting schema with an invalid document
rapidjson::Document invalidDocument;
invalidDocument.SetObject();
invalidDocument.AddMember("test", 123, allocator);
invalidDocument.AddMember("test", 123, schemaDocument.GetAllocator());
EXPECT_FALSE(validator.validate(schema, RapidJsonAdapter(invalidDocument),
NULL));
}