12#include <system_error>
16namespace fs = std::filesystem;
18bool same_mapping_file(
const std::string& lhs,
const std::string& rhs)
25 const fs::path lhs_path(lhs);
26 const fs::path rhs_path(rhs);
28 if (fs::exists(lhs_path, ec) && fs::exists(rhs_path, ec)) {
30 if (fs::equivalent(lhs_path, rhs_path, ec) && !ec) {
35 return fs::absolute(lhs_path).lexically_normal() == fs::absolute(rhs_path).lexically_normal();
40 const std::string& modelName,
41 const std::string& modelJsonPath,
42 const std::string& smJsonPath)
44 if (same_mapping_file(modelJsonPath, smJsonPath)) {
49 const auto modelParams = modelDB.
getParams();
51 for (
const auto& [name, _] : modelParams) {
52 if (smParams.contains(name)) {
53 std::ostringstream oss;
54 oss <<
"MARTY mapping collision for key '" <<
name <<
"' while loading model '"
55 << modelName <<
"'. The key exists in both the read-only SM mapping '"
56 << smJsonPath <<
"' and the user/model mapping '" << modelJsonPath
57 <<
"'. Rename the BSM key or remove the duplicate entry.";
58 throw std::runtime_error(oss.str());
63std::string resolve_sm_mapping_path(
const std::string& modelName,
64 const std::string& modelJsonPath,
65 const std::string& smJsonPath)
67 if (modelName ==
"SM" || !same_mapping_file(modelJsonPath, smJsonPath)) {
77 const fs::path candidate = fs::path(modelJsonPath).parent_path() /
"sm.json";
78 if (fs::exists(candidate, ec) && !ec && !same_mapping_file(candidate.string(), modelJsonPath)) {
79 return candidate.string();
88 std::shared_ptr<IMappingAdapterFactory> adapterFactory,
89 std::shared_ptr<IParamMappingSource> loader
91: adapterFactory_(
std::move(adapterFactory))
92, loader_(
std::move(loader))
95std::unique_ptr<IParameterResolver>
97 const std::string& modelJsonPath,
98 const std::string& smJsonPath)
const
100 std::shared_ptr<IMappingAdapterFactory> adapter =
101 adapterFactory_ ? adapterFactory_
102 : std::make_shared<DefaultMappingAdapterFactory>();
104 std::shared_ptr<IParamMappingSource> src =
106 : std::make_shared<JsonParamMappingAdapter>(std::make_shared<JSONParser>());
108 const std::string resolvedSmJsonPath = resolve_sm_mapping_path(modelName, modelJsonPath, smJsonPath);
113 validate_no_mapping_collision(*smDB, *modelDB, modelName, modelJsonPath, resolvedSmJsonPath);
115 return std::make_unique<ParameterResolverProxy>(smDB, modelDB);
Declares the default factory for interpreter ports.
Factory for creating default mapping database adapters.
Adapter to load parameter mappings from a JSON/YAML-like DBNode tree.
Lightweight JSON parser/serializer for DBNode trees.
Declares a proxy implementation of IMappingDatabasePort.
Declares a proxy implementation of IParameterResolver.
DefaultInterpreterPortsFactory(std::shared_ptr< IMappingAdapterFactory > adapterFactory=nullptr, std::shared_ptr< IParamMappingSource > loader=nullptr)
std::unique_ptr< IParameterResolver > makeResolver(const std::string &modelName, const std::string &modelJsonPath, const std::string &smJsonPath) const override
Creates a new IParameterResolver for the given model.
Interface for accessing a parameter-mapping database.
virtual std::unordered_map< std::string, InterpretedParam > getParams() const =0
Returns all parameters stored in the database.
static std::shared_ptr< MappingDatabaseProxy > fromFactory(const IMappingAdapterFactory &factory, const std::string &instanceName, const std::string &jsonFilePath, std::shared_ptr< IParamMappingSource > loader=nullptr)
Factory helper to create a proxy with a given adapter factory.
Hash specialization for SymbolId<Tag>.