https://mooseframework.inl.gov
Loading...
Searching...
No Matches
Registry.C
Go to the documentation of this file.
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#include "InputParameters.h"
11#include "Registry.h"
12#include "Factory.h"
13#include "ActionFactory.h"
14#include "MooseUtils.h"
15#include "Capabilities.h"
16
17#include "libmesh/libmesh_common.h"
18
19#include <memory>
20#include <filesystem>
21#include <regex>
22
25{
26 // We need a naked new here (_not_ a smart pointer or object instance) due to what seems like a
27 // bug in clang's static object destruction when using dynamic library loading.
28 static Registry * registry_singleton = nullptr;
29 if (!registry_singleton)
30 registry_singleton = new Registry();
31 return *registry_singleton;
32}
33
34void
35Registry::registerObjectsTo(Factory & f, const std::set<std::string> & labels)
36{
37 auto & r = getRegistry();
38
39 for (const auto & label : labels)
40 {
41 r._known_labels.insert(label);
42 if (r._per_label_objects.count(label) == 0)
43 continue;
44
45 for (const auto & obj : r._per_label_objects[label])
46 {
47 const auto name = obj->name();
48 r._name_to_entry[name] = obj;
49
50 f.reg(obj);
51 if (!obj->_alias.empty())
52 f.associateNameToClass(name, obj->_classname);
53 }
54 }
55}
56
58Registry::objData(const std::string & name)
59{
60 auto & r = getRegistry();
61
62 if (const auto it = r._name_to_entry.find(name); it != r._name_to_entry.end())
63 return *it->second;
64 else
65 mooseError("Object ", name, " is not registered yet");
66}
67
68void
69Registry::registerActionsTo(ActionFactory & f, const std::set<std::string> & labels)
70{
71 auto & r = getRegistry();
72
73 for (const auto & label : labels)
74 {
75 r._known_labels.insert(label);
76 if (r._per_label_actions.count(label) == 0)
77 continue;
78
79 for (const auto & obj : r._per_label_actions[label])
80 f.reg(obj);
81 }
82}
83
84char
85Registry::addKnownLabel(const std::string & label)
86{
87 getRegistry()._known_labels.insert(label);
88 return 0;
89}
90
91void
92Registry::addDataFilePath(const std::string & name,
93 const std::string & in_tree_path,
94 const bool is_app /* = true */,
95 const std::optional<std::string> & info /* = {} */)
96{
98
99 // Enforce that the folder is called "data", because we rely on the installed path
100 // to be within PREFIX/share/<name>/data (see determineDataFilePath())
101 if (is_app)
102 {
103 const std::string folder = std::filesystem::path(in_tree_path).filename().c_str();
104 if (folder != "data")
105 mooseError("While registering data file path '",
106 in_tree_path,
107 "' for '",
108 name,
109 "': The folder must be named 'data' and it is named '",
110 folder,
111 "'");
112 }
113
114 // Find either the installed or in-tree path
115 const auto path = determineDataFilePath(name, in_tree_path);
116
117 auto & dfp = getRegistry()._data_file_paths;
118 const auto it = dfp.find(name);
119 // Not registered yet
120 if (it == dfp.end())
121 {
122 dfp.emplace(name, path);
123 addDataFilePathCapability(name, path, info);
124 }
125 // Registered, but with a different value
126 else if (it->second != path)
127 mooseError("While registering data file path '",
128 path,
129 "' for '",
130 name,
131 "': the path '",
132 it->second,
133 "' is already registered");
134}
135
136void
137Registry::addMissingDataFilePath(const std::string & name, const std::string & info)
138{
140 addDataFilePathCapability(name, {}, info);
141}
142
143void
144Registry::addAppDataFilePath(const std::string & app_name, const std::string & app_path)
145{
146 // split the *App.C filename from its containing directory
147 const auto dir = MooseUtils::splitFileName(app_path).first;
148 // This works for both build/unity_src/ and src/base/ as the *App.C file location,
149 // in case __FILE__ doesn't get overriden in unity build
150 addDataFilePath(app_name, MooseUtils::pathjoin(dir, "../../data"));
151}
152
153void
154Registry::addDeprecatedAppDataFilePath(const std::string & app_path)
155{
156 const auto app_name = appNameFromAppPath(app_path);
157 mooseDeprecated("In ",
158 app_path,
159 ":\nregisterDataFilePath() is deprecated. Use registerAppDataFilePath(\"",
160 app_name,
161 "\") instead.");
162 addAppDataFilePath(app_name, app_path);
163}
164
165std::string
166Registry::getDataFilePath(const std::string & name)
167{
168 const auto & dfps = getRegistry()._data_file_paths;
169 const auto it = dfps.find(name);
170 if (it == dfps.end())
171 mooseError("Registry::getDataFilePath(): A data file path for '", name, "' is not registered");
172 return it->second;
173}
174
175void
176Registry::addRepository(const std::string & repo_name, const std::string & repo_url)
177{
178 auto & repos = getRegistry()._repos;
179 const auto [it, inserted] = repos.emplace(repo_name, repo_url);
180 if (!inserted && it->second != repo_url)
181 mooseError("Registry::registerRepository(): The repository '",
182 repo_name,
183 "' is already registered with a different URL '",
184 it->second,
185 "'.");
186}
187
188const std::string &
189Registry::getRepositoryURL(const std::string & repo_name)
190{
191 const auto & repos = getRegistry()._repos;
192 if (const auto it = repos.find(repo_name); it != repos.end())
193 return it->second;
194 mooseError("Registry::getRepositoryURL(): The repository '", repo_name, "' is not registered.");
195}
196
197void
198Registry::addAppCitation(const std::string & app_name,
199 const std::string & key,
200 const std::string & bibtex)
201{
202 auto & app_citations = getRegistry()._app_citations[app_name];
203 const auto [it, inserted] = app_citations.emplace(key, bibtex);
204 if (!inserted && it->second != bibtex)
206 "Registry: the citation '", key, "' is already registered with different BibTeX text.");
207}
208
209const std::map<std::string, std::string> &
210Registry::getCitations(const std::string & app_name)
211{
212 static const std::map<std::string, std::string> empty;
213 const auto & app_citations = getRegistry()._app_citations;
214 const auto it = app_citations.find(app_name);
215 return it != app_citations.end() ? it->second : empty;
216}
217
218std::string
219Registry::determineDataFilePath(const std::string & name, const std::string & in_tree_path)
220{
221 // TODO: Track whether or not the application is installed in a better way
222 // than this, which will enable us to pick one or the other based on
223 // the install state. This probably also won't work with dynamic loading, where
224 // we can't necessarily get this information from the binary (as there could be
225 // multiple binary paths)
226
227 // Installed data
228 const auto installed_path =
229 MooseUtils::pathjoin(Moose::getExecutablePath(), "..", "share", name, "data");
230 if (MooseUtils::checkFileReadable(installed_path, false, false, false))
231 return MooseUtils::canonicalPath(installed_path);
232
233 // In tree data
234 if (MooseUtils::checkFileReadable(in_tree_path, false, false, false))
235 return MooseUtils::canonicalPath(in_tree_path);
236
237 mooseError("Failed to determine data file path for '",
238 name,
239 "'. Paths searched:\n\n installed: ",
240 installed_path,
241 "\n in-tree: ",
242 in_tree_path);
243}
244
245std::string
246Registry::appNameFromAppPath(const std::string & app_path)
247{
248 // This is for deprecated use only. It assumes that the application name
249 // (binary name) in the build follows our normal naming of FooBarApp -> foo_bar.
250 // We need to convert the application source file to the above, for example:
251 // /path/to/FooBarBazApp.C -> foo_bar_baz
252 // Ideally, we would instead have the user specify this manually so that
253 // there is no ambiguity.
254 std::smatch match;
255 if (std::regex_search(app_path, match, std::regex("\\/([a-zA-Z0-9_]+)App\\.C$")))
256 {
257 std::string name = match[1]; // FooBarBaz
258 name = std::regex_replace(name, std::regex("(?!^)([A-Z])"), "_$1"); // Foo_Bar_Baz
259 name = MooseUtils::toLower(name); // foo_bar_baz
260 return name;
261 }
262
264 "Registry::appNameFromAppPath(): Failed to parse application name from '", app_path, "'");
265}
266
267void
268Registry::checkDataFilePathName(const std::string & name)
269{
270 if (!std::regex_search(name, std::regex("[a-z0-9_]+")))
271 mooseError("Unallowed characters in data file path name '",
272 name,
273 "'; allowed characters = a-z, 0-9, _");
274}
275
276void
277Registry::addDataFilePathCapability(const std::string & name,
278 const std::optional<std::string> & path /* = {} */,
279 const std::optional<std::string> & extra_info /* = {}*/)
280{
281 std::string doc = "Named data path '" + name + "' is ";
282 if (path)
283 doc += "available at '" + *path + "'";
284 else
285 doc += "not available";
286 if (extra_info)
287 doc += "; " + *extra_info;
288 doc += ".";
289
290 auto & capabilities = Moose::internal::Capabilities::getCapabilities({});
291 capabilities.add("data_" + name, bool(path), doc);
292}
void mooseError(Args &&... args)
Emit an error message with the given stringified, concatenated args and terminate the application.
Definition MooseError.h:311
void mooseDeprecated(Args &&... args)
Emit a deprecated code/feature message with the given stringified, concatenated args.
Definition MooseError.h:363
Specialized factory for generic Action System objects.
void reg(std::shared_ptr< RegistryEntryBase > obj)
Generic factory class for build all sorts of objects.
Definition Factory.h:29
void reg(std::shared_ptr< RegistryEntryBase > obj)
Definition Factory.C:23
void associateNameToClass(const std::string &name, const std::string &class_name)
Associates an object name with a class name.
Definition Factory.C:290
static Capabilities & getCapabilities(const GetCapabilitiesPassKey)
Get the singleton Capabilities.
Capability & add(const std::string_view name, const Moose::Capability::Value &value, const std::string_view doc)
Add a capability.
The registry is used as a global singleton to collect information on all available MooseObject and Ac...
Definition Registry.h:179
std::map< std::string, std::string > _repos
Repository name -> repository URL; used for mooseDocumentedError.
Definition Registry.h:371
static const RegistryEntryBase & objData(const std::string &name)
Definition Registry.C:58
static void addDataFilePath(const std::string &name, const std::string &in_tree_path, const bool app=true, const std::optional< std::string > &info={})
register general search paths; "app" is whether or not the path is an app path
Definition Registry.C:92
static void addAppCitation(const std::string &app_name, const std::string &key, const std::string &bibtex)
Register a citation (the full BibTeX bibtex text, identified by key) tied to the app app_name; emitte...
Definition Registry.C:198
static void addAppDataFilePath(const std::string &app_name, const std::string &app_path)
register search paths for an application (path determined relative to app_path); app_path should be p...
Definition Registry.C:144
static std::string appNameFromAppPath(const std::string &app_path)
Internal helper for getting an application name from its path, for example: /path/to/FooBarBazApp....
Definition Registry.C:246
static void checkDataFilePathName(const std::string &name)
Check a data file path for valid characters.
Definition Registry.C:268
static void addDeprecatedAppDataFilePath(const std::string &app_path)
deprecated method; use addAppDataFilePath instead
Definition Registry.C:154
static void addDataFilePathCapability(const std::string &name, const std::optional< std::string > &path={}, const std::optional< std::string > &extra_info={})
Add a data file path capability.
Definition Registry.C:277
std::map< std::string, std::map< std::string, std::string > > _app_citations
App/module name -> (citation key -> BibTeX entry text) for that app.
Definition Registry.h:374
static std::string determineDataFilePath(const std::string &name, const std::string &in_tree_path)
Internal helper for determing a root data file path (in-tree vs installed)
Definition Registry.C:219
static void registerActionsTo(ActionFactory &f, const std::set< std::string > &labels)
This registers all Actions known to the registry that have the given label(s) with the factory f.
Definition Registry.C:69
static Registry & getRegistry()
Get the global Registry singleton.
Definition Registry.C:24
static void registerObjectsTo(Factory &f, const std::set< std::string > &labels)
This registers all MooseObjects known to the registry that have the given label(s) with the factory f...
Definition Registry.C:35
static std::string getDataFilePath(const std::string &name)
Gets a data path for the registered name.
Definition Registry.C:166
static void addMissingDataFilePath(const std::string &name, const std::string &info)
register a data file path as missing, along with info about how it can be added
Definition Registry.C:137
std::set< std::string > _known_labels
Definition Registry.h:367
std::map< std::string, std::string > _data_file_paths
Data file registry; name -> in-tree path.
Definition Registry.h:369
static const std::string & getRepositoryURL(const std::string &repo_name)
Returns the repository URL associated with repo_name.
Definition Registry.C:189
static void addRepository(const std::string &repo_name, const std::string &repo_url)
register a repository
Definition Registry.C:176
static const std::map< std::string, std::map< std::string, std::string > > & getCitations()
Returns the registered citations, keyed by app/module name and then by BibTeX key (app/module name ->...
Definition Registry.h:291
static char addKnownLabel(const std::string &label)
addKnownLabel whitelists a label as valid for purposes of the checkLabels function.
Definition Registry.C:85
std::filesystem::path pathjoin(const std::filesystem::path &p)
Definition MooseUtils.C:70
std::string canonicalPath(const std::string &path)
std::string toLower(std::string name)
Convert supplied string to lower case.
bool checkFileReadable(const std::string &filename, bool check_line_endings, bool throw_on_unreadable, bool check_for_git_lfs_pointer)
Definition MooseUtils.C:265
std::string getExecutablePath()
Gets the directory the running executable is on Mac OS X and linux.