/**
* @file artis/builder/Builder.hpp
* @author See the AUTHORS file
*/
/*
* Copyright (C) 2012-2019 ULCO http://www.univ-littoral.fr
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef ARTIS_BUILDER_BUILDER_HPP
#define ARTIS_BUILDER_BUILDER_HPP
#include
#include
#include
#include
#include
namespace artis {
namespace builder {
template
class Builder {
public:
Builder(const std::string& json)
{
std::stringstream ss;
ss << json;
boost::property_tree::read_json(ss, tree);
}
virtual ~Builder() { }
T* build() { return dynamic_cast < T* >(build_model(tree)); }
private:
kernel::AbstractModel* build_model(boost::property_tree::ptree const& pt)
{
using boost::property_tree::ptree;
kernel::AbstractModel* model = nullptr;
kernel::AbstractModels submodels;
std::string name;
ptree::const_iterator it_type = pt.end();
ptree::const_iterator it_name = pt.end();
ptree::const_iterator it_states = pt.end();
ptree::const_iterator it_internals = pt.end();
ptree::const_iterator it_externals = pt.end();
ptree::const_iterator it_submodels = pt.end();
for (ptree::const_iterator it = pt.begin(); it != pt.end(); ++it) {
if (it->first == "type") {
it_type = it;
} else if (it->first == "name") {
it_name = it;
} else if (it->first == "states") {
it_states = it;
} else if (it->first == "internals") {
it_internals = it;
} else if (it->first == "externals") {
it_externals = it;
} else if (it->first == "submodels") {
it_submodels = it;
}
}
// name
if (it_name != pt.end()) {
name = it_type->second.get_value();
}
// submodels
if (it_submodels != pt.end()) {
for (ptree::const_iterator itm = it_submodels->second.begin();
itm != it_submodels->second.end(); ++itm) {
submodels.push_back(build_model(itm->second));
}
}
// states
if (it_states != pt.end()) {
build_states(it_states->second, model);
}
// internals
if (it_internals != pt.end()) {
build_internals(it_internals->second, model);
}
// externals
if (it_externals != pt.end()) {
build_externals(it_externals->second, model);
}
// type
if (it_type != pt.end()) {
model = F::factory().create(
it_type->second.get_value(), submodels);
}
return model;
}
void build_internals(boost::property_tree::ptree const& pt, kernel::AbstractModel* model)
{
using boost::property_tree::ptree;
for (ptree::const_iterator it = pt.begin(); it != pt.end(); ++it) {
build_variable(it->second, model);
}
}
void build_externals(boost::property_tree::ptree const& pt, kernel::AbstractModel* model)
{
using boost::property_tree::ptree;
for (ptree::const_iterator it = pt.begin(); it != pt.end(); ++it) {
build_variable(it->second, model);
}
}
void build_states(boost::property_tree::ptree const& pt, kernel::AbstractModel* model)
{
using boost::property_tree::ptree;
for (ptree::const_iterator it = pt.begin(); it != pt.end(); ++it) {
build_variable(it->second, model);
}
}
void build_variable(boost::property_tree::ptree const& pt, kernel::AbstractModel* /* model */)
{
using boost::property_tree::ptree;
std::string name;
std::string type;
for (ptree::const_iterator it = pt.begin(); it != pt.end(); ++it) {
if (it->first == "name") {
name = it->second.get_value();
} else if (it->first == "type") {
type = it->second.get_value();
}
}
std::cout << name << ": " << type << std::endl;
}
boost::property_tree::ptree tree;
};
}
}
#endif