Line data Source code
1 : //* This file is part of the MOOSE framework 2 : //* https://mooseframework.inl.gov 3 : //* 4 : //* All rights reserved, see COPYRIGHT for full restrictions 5 : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT 6 : //* 7 : //* Licensed under LGPL 2.1, please see LICENSE for details 8 : //* https://www.gnu.org/licenses/lgpl-2.1.html 9 : 10 : #pragma once 11 : 12 : #include <string> 13 : #include <map> 14 : #include <type_traits> 15 : 16 : #include "MooseError.h" 17 : 18 : #include "minijson/minijson.h" 19 : 20 : class WebServerControl; 21 : 22 : namespace Moose 23 : { 24 : /** 25 : * A static registry used to register and build values of different types for the WebServerControl 26 : * 27 : * Needed due to the complexities of parsing parameter types from generic JSON received 28 : * by the web server. 29 : */ 30 : class WebServerControlTypeRegistry 31 : { 32 : public: 33 : /** 34 : * @return The WebServerControlTypeRegistry singleton 35 : */ 36 : static WebServerControlTypeRegistry & getRegistry(); 37 : 38 : /** 39 : * The base class for a value that is produced by this registry. 40 : */ 41 : class ValueBase 42 : { 43 : public: 44 : /** 45 : * Constructor. 46 : * @param name The name that the value is for (typically a controllable path) 47 : * @param type The string representationg of the type 48 : */ 49 168 : ValueBase(const std::string & name, const std::string & type) : _name(name), _type(type) {} 50 168 : virtual ~ValueBase() {} 51 : 52 : /** 53 : * @return The name that the value is for 54 : */ 55 280 : const std::string & name() const { return _name; } 56 : /** 57 : * @return The string representation of the type 58 : */ 59 112 : const std::string & type() const { return _type; } 60 : 61 : /** 62 : * Sets the controllable value given the name and type via the controllable 63 : * interface in \p control. 64 : * 65 : * Will broadcast the value for setting it. 66 : */ 67 : virtual void setControllableValue(WebServerControl & control) = 0; 68 : 69 : /** 70 : * Common exception for parsing related errors in converting JSON to a value. 71 : */ 72 : struct Exception : public std::exception 73 : { 74 : public: 75 0 : Exception(const std::string & message) : _message(message) {} 76 0 : virtual const char * what() const noexcept override final { return _message.c_str(); } 77 : 78 : private: 79 : const std::string _message; 80 : }; 81 : 82 : private: 83 : /// The name that the value is for 84 : const std::string _name; 85 : /// The string representation of the type 86 : const std::string _type; 87 : }; 88 : 89 : /** 90 : * Registers a type with string name \p type_name and the given derived type. 91 : */ 92 : template <typename DerivedValueType> 93 359632 : static char add(const std::string & type_name) 94 : { 95 : static_assert(std::is_base_of_v<ValueBase, DerivedValueType>, "Is not derived from ValueBase"); 96 359632 : getRegistry()._types.emplace(type_name, std::make_unique<Type<DerivedValueType>>(type_name)); 97 359632 : return 0; 98 : } 99 : 100 : /** 101 : * @return Whether or not the type \p type is registered. 102 : */ 103 112 : static bool isRegistered(const std::string & type) { return getRegistry()._types.count(type); } 104 : 105 : /** 106 : * Builds a value with the type \p type, name \p name, and a default value. 107 : */ 108 56 : static std::unique_ptr<ValueBase> build(const std::string & type, const std::string & name) 109 : { 110 56 : return get(type).build(name); 111 : } 112 : /** 113 : * Builds a value with the type \p type, name \p name, and a value parsed from \p json_value. 114 : * 115 : * Will throw ValueBase::Exception on a parsing error. 116 : */ 117 : static std::unique_ptr<ValueBase> 118 112 : build(const std::string & type, const std::string & name, const miniJson::Json & json_value) 119 : { 120 112 : return get(type).build(name, json_value); 121 : } 122 : 123 : private: 124 : /** 125 : * Base registry class for a type that is used to build values. 126 : */ 127 : class TypeBase 128 : { 129 : public: 130 359632 : TypeBase(const std::string & type) : _type(type) {} 131 0 : virtual ~TypeBase() {} 132 : 133 : /** 134 : * @return The string representation of the type 135 : */ 136 168 : const std::string & type() const { return _type; } 137 : /** 138 : * Builds a value with the given type, name \p name, and JSON value \p json_value. 139 : * 140 : * This will parse the JSON value into the underlying type and will be called 141 : * on only rank 0 where server listens. 142 : */ 143 : virtual std::unique_ptr<ValueBase> build(const std::string & name, 144 : const miniJson::Json & json_value) const = 0; 145 : /** 146 : * Builds a value with the given type, name \p name, and a default value. 147 : * 148 : * This will be called on processors that are not rank 0 for cloning. 149 : */ 150 : virtual std::unique_ptr<ValueBase> build(const std::string & name) const = 0; 151 : 152 : private: 153 : /// The string representation of the underlying type 154 : const std::string _type; 155 : }; 156 : 157 : template <class DerivedValueType> 158 : struct Type : public TypeBase 159 : { 160 359632 : Type(const std::string & type) : TypeBase(type) {} 161 : 162 56 : virtual std::unique_ptr<ValueBase> build(const std::string & name) const override final 163 : { 164 56 : return std::make_unique<DerivedValueType>(name, type()); 165 : } 166 112 : virtual std::unique_ptr<ValueBase> build(const std::string & name, 167 : const miniJson::Json & json_value) const override final 168 : { 169 112 : return std::make_unique<DerivedValueType>(name, type(), json_value); 170 : } 171 : }; 172 : 173 : /** 174 : * Internal getter for the registration object for type \p type. 175 : */ 176 168 : static const TypeBase & get(const std::string & type) 177 : { 178 168 : auto & registry = getRegistry(); 179 168 : const auto it = registry._types.find(type); 180 168 : if (it == registry._types.end()) 181 0 : mooseError("WebServerControlTypeRegistry: The type '", type, "' is not registered"); 182 336 : return *it->second; 183 : } 184 : 185 : /// The registration data 186 : std::map<std::string, std::unique_ptr<TypeBase>> _types; 187 : }; 188 : }