Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bool XmlHandlerConfiguration::is_valid(
{
if (!utils::is_file_accessible(file.c_str(), utils::FileAccessMode::read))
{
error_msg << "File " << file << " has not exist or does not have read access. ";
error_msg << "File " << file << " does not exist or does not have read access. ";
return false;
}
}
Expand Down
41 changes: 39 additions & 2 deletions ddspipe_yaml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,47 @@ project(
# - Configure log depending on LOG_INFO flag and CMake type
configure_project_cpp()

file(
GLOB_RECURSE SOURCE_FILES
"${PROJECT_SOURCE_DIR}/src/cpp/*.c*"
"${PROJECT_SOURCE_DIR}/../thirdparty/nlohmann_json_schema_validator/*.cpp"
)

file(
GLOB_RECURSE INCLUDE_FILES
"${PROJECT_SOURCE_DIR}/include/*.hpp"
"${PROJECT_SOURCE_DIR}/include/testing/*.hpp"
"${PROJECT_SOURCE_DIR}/include/impl/*.ipp"
"${PROJECT_SOURCE_DIR}/../thirdparty/nlohmann_json/nlohmann/*.hpp"
"${PROJECT_SOURCE_DIR}/../thirdparty/nlohmann_json_schema_validator/*.hpp"
"${PROJECT_SOURCE_DIR}/../thirdparty/nlohmann_json_schema_validator/nlohmann/*.hpp"
)

#set(NLOHMANN_JSON_INCLUDE_DIR
# "${PROJECT_SOURCE_DIR}/../thirdparty/nlohmann_json/nlohmann")
#
#set(NLOHMANN_JSON_SCHEMA_INCLUDE_DIR
# "${PROJECT_SOURCE_DIR}/../thirdparty/nlohmann_json_schema_validator/nlohmann")
#
#install(
# DIRECTORY
# "${NLOHMANN_JSON_INCLUDE_DIR}"
# "${NLOHMANN_JSON_SCHEMA_INCLUDE_DIR}"
# DESTINATION
# ${INCLUDE_INSTALL_DIR}
# COMPONENT
# headers
# FILES_MATCHING
# PATTERN "*.h"
# PATTERN "*.hpp"
#)

# Compile C++ library
compile_library(
"${PROJECT_SOURCE_DIR}/src/cpp" # Source directory
"${PROJECT_SOURCE_DIR}/include" # Include directory
"${PROJECT_SOURCE_DIR}/src/cpp" # Source directory (not used because the list in ${SOURCE_FILES} is used instead)
"${PROJECT_SOURCE_DIR}/include" # Include directory (not used because the list in ${INCLUDE_FILES} is used instead)
"${SOURCE_FILES}" # List of source files to compile
"${INCLUDE_FILES}" # List of include files
)

###############################################################################
Expand Down
52 changes: 35 additions & 17 deletions ddspipe_yaml/include/ddspipe_yaml/YamlReader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ enum YamlReaderVersion
* Every method is implemented
*/
class
DDSPIPE_YAML_DllAPI
YamlReader
DDSPIPE_YAML_DllAPI
YamlReader
{
public:

Expand Down Expand Up @@ -167,14 +167,32 @@ class
const Yaml& yml,
const TagType& tag);

//! TODO comment
template <typename T>
/**
* @brief Takes the element \c yml and builds the object \c T
*
* This method takes a yaml node and then builds and return and object of type \c T.
*
* @tparam T type of the object to build
* @param yml base yaml
* @param version configuration version
*/
template<typename T>
static T get(
const Yaml& yml,
const YamlReaderVersion version);

//! Get element inside \c tag
template <typename T>
/**
* @brief Extracts the sub-yaml from the \c tag and then builds the object \c T
*
* This method calls \c get_value_in_tag to extract the sub-yaml from the \c tag and then it calls \c get to build
* the object \c T.
*
* @tparam T type of the object to build
* @param yml base yaml
* @param tag key to yaml containing the object
* @param version configuration version
*/
template<typename T>
static T get(
const Yaml& yml,
const TagType& tag,
Expand All @@ -190,28 +208,28 @@ class
* the default values are initialized with the default constructor, and then are overwritten by the yaml.
* [this problem arises because C++ does not allow different order of parameters in method call]
*/
template <typename T>
template<typename T>
static void fill(
T& object,
const Yaml& yml,
const YamlReaderVersion version);

//! Fill an element given by parameter with the values inside \c tag in \c yml
template <typename T>
template<typename T>
static void fill(
T& object,
const Yaml& yml,
const TagType& tag,
const YamlReaderVersion version);

//! TODO comment
template <typename T>
template<typename T>
static std::list<T> get_list(
const Yaml& yml,
const YamlReaderVersion version);

//! Get list inside \c tag
template <typename T>
template<typename T>
static std::list<T> get_list(
const Yaml& yml,
const TagType& tag,
Expand All @@ -228,19 +246,19 @@ class
* @param version configuration version
* @return set of elements
*/
template <typename T>
template<typename T>
static std::set<T> get_set(
const Yaml& yml,
const TagType& tag,
const YamlReaderVersion version);

//! TODO comment
template <typename T>
template<typename T>
static T get_scalar(
const Yaml& yml);

//! Get scalar value inside \c tag
template <typename T>
template<typename T>
static T get_scalar(
const Yaml& yml,
const TagType& tag);
Expand Down Expand Up @@ -276,26 +294,26 @@ class
const TagType& tag);

//! TODO comment
template <typename T>
template<typename T>
static T get_enumeration(
const Yaml& yml,
const std::map<TagType, T>& enum_values);

//! Get enumeration value inside \c tag
template <typename T>
template<typename T>
static T get_enumeration(
const Yaml& yml,
const TagType& tag,
const std::map<TagType, T>& enum_values);

//! TODO comment
template <typename T>
template<typename T>
static T get_enumeration_from_builder(
const Yaml& yml,
const utils::EnumBuilder<T>& enum_builder);

//! Get enumeration value inside \c tag
template <typename T>
template<typename T>
static T get_enumeration_from_builder(
const Yaml& yml,
const TagType& tag,
Expand Down
136 changes: 136 additions & 0 deletions ddspipe_yaml/include/ddspipe_yaml/YamlValidator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// Copyright 2026 Proyectos y Sistemas de Mantenimiento SL (eProsima).
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <memory>

#include <ddspipe_yaml/library/library_dll.h>
#include <ddspipe_yaml/Yaml.hpp>

namespace nlohmann {
namespace json_schema {
class json_validator;
} // namespace json_schema
} // namespace nlohmann

namespace eprosima {
namespace ddspipe {
namespace yaml {

/**
* @brief Validates YAML objects against a JSON Schema (draft-07).
*
* Loads a schema from a file path or a raw string via \c InputType, then
* validates \c Yaml nodes against it. Custom format checkers (e.g. IPv4/IPv6)
* are applied automatically during validation.
*/
class DDSPIPE_YAML_DllAPI YamlValidator
{
private:

std::unique_ptr<nlohmann::json_schema::json_validator> validator;

protected:

/**
* @brief Custom format checker registered with the JSON Schema validator.
*
* Called automatically during validation when the schema uses the \c format keyword.
* Supported format values are \c "v4" (IPv4) and \c "v6" (IPv6).
*
* @param format Name of the format to check (e.g. \c "v4" or \c "v6").
* @param value Value to validate against the given format.
*
* @throws std::invalid_argument if \c value does not conform to \c format.
*/
static void format_checker(
const std::string& format,
const std::string& value);

public:

enum class InputType
{
FROM_STRING,
FROM_FILE
};

/**
* @brief Default constructor. Creates a \c YamlValidator with no schema loaded.
*
* \c validate_YAML will return \c false until a schema is set via \c set_schema.
*/
YamlValidator();

/**
* @brief Construct a \c YamlValidator and load a JSON Schema (draft-07).
*
* @param input_type Whether \c schema_string is a file path (\c InputType::FROM_FILE)
* or raw JSON content (\c InputType::FROM_STRING).
* @param schema_string File path or raw JSON string of the schema to load.
*
* @throws utils::ConfigurationException if the schema cannot be read, parsed, or is not
* a valid JSON Schema draft-07.
*/
explicit YamlValidator(
InputType input_type,
const std::string& schema_string);

/**
* @brief Default destructor. Needed because \c std::unique_ptr needs the full definition
* of \c nlohmann::json_schema::json_validator when destroying it.
*/
~YamlValidator();

/**
* @brief Move assignment operator. Needed because \c std::unique_ptr needs the full definition
* of \c nlohmann::json_schema::json_validator when move-assigning (the old value is destroyed).
*/
YamlValidator& operator =(
YamlValidator&&);

/**
* @brief Set or replace the root schema of the validator.
*
* @param input_type Whether \c schema_string is a file path (\c InputType::FROM_FILE)
* or raw JSON content (\c InputType::FROM_STRING).
* @param schema_string File path or raw JSON string of the schema to load.
*
* @throws utils::ConfigurationException if the schema cannot be read, parsed, or is not
* a valid JSON Schema draft-07.
*/
void set_schema(
InputType input_type,
const std::string& schema_string);

/**
* @brief Validate a YAML object against the loaded schema.
*
* Returns \c false immediately if no schema has been loaded.
*
* @param yml Yaml object to validate.
* @param display_errors If \c true, prints validation errors to \c stderr.
* @return \c true if \c yml conforms to the schema, \c false otherwise.
*
* @throws utils::ConfigurationException if \c yml cannot be converted to JSON.
*/
bool validate_YAML(
const Yaml& yml,
bool display_errors = true);
};

} /* namespace yaml */
} /* namespace ddspipe */
} /* namespace eprosima */
6 changes: 3 additions & 3 deletions ddspipe_yaml/include/ddspipe_yaml/YamlWriter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Yaml add_tag(
* - native types (int, string, boolean)
* - collections (vector, set, map)
*/
template <typename T>
template<typename T>
void set(
Yaml& yml,
const T& value);
Expand All @@ -78,14 +78,14 @@ void set(
*
* @tparam T type of the value to set in the yaml.
*/
template <typename T>
template<typename T>
void set(
Yaml& yml,
const T& value,
bool is_compact);

//! Set the \c value in a new yaml in \c yml under \c tag .
template <typename T>
template<typename T>
void set_in_tag(
Yaml& yml,
const TagType& tag,
Expand Down
Loading
Loading