Skip to content

Commit

Permalink
Merge pull request #19 from nawaz1991/18-feature-add-support-for-refe…
Browse files Browse the repository at this point in the history
…rence-in-json

Added support to resolve JSON references
  • Loading branch information
nawaz1991 authored Apr 19, 2024
2 parents 39c182d + 7bfd90b commit 9cee64e
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/oas_validator_imp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class OASValidatorImp

ValidationError GetValidators(const std::string& method, const std::string& http_path, ValidatorsStore*& validators, std::string& error_msg,
std::unordered_map<size_t, ParamRange>* param_idxs = nullptr, std::string* query = nullptr);
static std::vector<std::string> Split(const std::string& str, char delimiter);
static rapidjson::Value* ResolvePath(rapidjson::Document& doc, const std::string& path);
void ResolveReferences(rapidjson::Value& value, rapidjson::Document& doc, rapidjson::Document::AllocatorType& allocator);
};

#endif // OAS_VALIDATION_HPP
55 changes: 55 additions & 0 deletions src/oas_validator_imp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "oas_validator_imp.hpp"
#include <fstream>
#include <rapidjson/istreamwrapper.h>
#include <sstream>

OASValidatorImp::OASValidatorImp(const std::string& oas_specs)
{
Expand All @@ -27,6 +28,8 @@ OASValidatorImp::OASValidatorImp(const std::string& oas_specs)
" at offset: " + std::to_string(doc.GetErrorOffset()) + " Error message: " + rapidjson::GetParseError_En(doc.GetParseError()));
}

ResolveReferences(doc, doc, doc.GetAllocator());

const rapidjson::Value& paths = doc["paths"];
std::vector<std::string> ref_keys;
ref_keys.emplace_back("paths");
Expand Down Expand Up @@ -238,6 +241,58 @@ ValidationError OASValidatorImp::GetValidators(const std::string& method, const
return ValidationError::NONE;
}

std::vector<std::string> OASValidatorImp::Split(const std::string& str, char delimiter) {
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(str);
while (getline(tokenStream, token, delimiter)) {
tokens.push_back(token);
}
return tokens;
}

rapidjson::Value* OASValidatorImp::ResolvePath(rapidjson::Document& doc, const std::string& path) {
std::vector<std::string> parts = Split(path, '/');
rapidjson::Value* current = &doc;
for (const std::string& part : parts) {
if (!current->IsObject() || !current->HasMember(part.c_str())) {
throw ValidatorInitExc("Invalid path or missing member:" + part);
}
current = &(*current)[part.c_str()];
}
return current;
}

void OASValidatorImp::ResolveReferences(rapidjson::Value& value, rapidjson::Document& doc, rapidjson::Document::AllocatorType& allocator) {
if (value.IsObject()) {
bool shouldReiterate;
do {
shouldReiterate = false;
for (auto itr = value.MemberBegin(); itr != value.MemberEnd();) {
if (strcmp(itr->name.GetString(), "$ref") == 0 && itr->value.IsString()) {
std::string ref = itr->value.GetString();
if (ref.rfind("#/", 0) == 0) {
ref.erase(0, 2); // Remove '#/'
rapidjson::Value const* refValue = ResolvePath(doc, ref);
if (refValue) {
value.CopyFrom(*refValue, allocator);
shouldReiterate = true; // Signal to reiterate due to structural changes
break; // Exit the loop to avoid invalid iterator use
}
}
} else {
ResolveReferences(itr->value, doc, allocator);
}
++itr;
}
} while (shouldReiterate); // Keep resolving until no more references are found
} else if (value.IsArray()) {
for (rapidjson::SizeType i = 0; i < value.Size(); i++) {
ResolveReferences(value[i], doc, allocator);
}
}
}

const std::unordered_map<std::string, HttpMethod> OASValidatorImp::kStringToMethod = {
{"GET", HttpMethod::GET}, {"POST", HttpMethod::POST}, {"PUT", HttpMethod::PUT}, {"DELETE", HttpMethod::DELETE}, {"HEAD", HttpMethod::HEAD},
{"OPTIONS", HttpMethod::OPTIONS}, {"PATCH", HttpMethod::PATCH}, {"CONNECT", HttpMethod::CONNECT}, {"TRACE", HttpMethod::TRACE}, {"get", HttpMethod::GET},
Expand Down

0 comments on commit 9cee64e

Please sign in to comment.