15#include <boost/algorithm/string.hpp>
24Kernel::Logger
g_log(
"AlgorithmFactory");
32 g_log.
debug() <<
"Algorithm Factory created.\n";
43 int local_version = version;
62 alg->calledByAlias =
true;
69 g_log.
error() <<
"algorithm " << name <<
" version " << version <<
" is not registered \n";
70 g_log.
error() <<
"the latest registered version is " << hVersion <<
'\n';
71 throw std::runtime_error(
"algorithm not registered " +
createName(name, local_version));
74 throw std::runtime_error(
"algorithm not registered " + name);
85 std::string key = this->
createName(algorithmName, version);
89 auto it =
m_vmap.find(algorithmName);
91 int highest_version = it->second;
92 if (highest_version > 1 && version == highest_version)
96 m_vmap.erase(algorithmName);
99 g_log.
warning() <<
"Error unsubscribing algorithm " << algorithmName <<
" version " << version
100 <<
". Nothing registered with this name and version.";
115 std::string key = this->
createName(algorithmName, version);
126 std::ostringstream oss;
127 oss << name <<
"|" << version;
136 std::string::size_type seperatorPosition = mangledName.find(
'|');
137 if (seperatorPosition == std::string::npos) {
138 throw std::invalid_argument(
"Cannot decode a Name string without a \"|\" (bar) character ");
140 std::string name = mangledName.substr(0, seperatorPosition);
142 std::istringstream ss(mangledName.substr(seperatorPosition + 1));
145 g_log.
debug() <<
"mangled string:" << mangledName <<
" name:" << name <<
" version:" << version <<
'\n';
146 return std::pair<std::string, int>(name, version);
179 std::unordered_set<std::string> hiddenCategories;
183 std::vector<std::string> validNames;
184 std::vector<std::string>::const_iterator itr_end = names.end();
185 for (std::vector<std::string>::const_iterator itr = names.begin(); itr != itr_end; ++itr) {
186 std::string name = *itr;
188 std::pair<std::string, int> namePair =
decodeName(name);
189 std::shared_ptr<IAlgorithm> alg =
create(namePair.first, namePair.second);
190 std::vector<std::string> categories = alg->categories();
191 bool toBeRemoved =
true;
194 std::vector<std::string>::const_iterator itCategoriesEnd = categories.end();
195 for (std::vector<std::string>::const_iterator itCategories = categories.begin(); itCategories != itCategoriesEnd;
198 if (hiddenCategories.find(*itCategories) == hiddenCategories.end()) {
206 validNames.emplace_back(name);
218 auto a_it = m_amap.find(alias);
219 if (a_it == m_amap.end())
231 auto viter =
m_vmap.find(algorithmName);
232 if (viter !=
m_vmap.end())
233 return viter->second;
238 if (realName != boost::none) {
239 viter =
m_vmap.find(realName.get());
241 if (viter !=
m_vmap.end())
242 return viter->second;
244 throw std::runtime_error(
"AlgorithmFactory::highestVersion() - Unknown algorithm '" + algorithmName +
"'");
257 std::map<std::string, bool> resultCategories;
260 std::unordered_set<std::string> hiddenCategories;
265 std::vector<std::string> names =
getKeys(
true);
267 std::vector<std::string>::const_iterator itr_end = names.end();
269 for (std::vector<std::string>::const_iterator itr = names.begin(); itr != itr_end; ++itr) {
270 std::string name = *itr;
272 std::pair<std::string, int> namePair =
decodeName(name);
273 std::shared_ptr<IAlgorithm> alg =
create(namePair.first, namePair.second);
275 std::vector<std::string> categories = alg->categories();
278 std::vector<std::string>::const_iterator itCategoriesEnd = categories.end();
279 for (std::vector<std::string>::const_iterator itCategories = categories.begin(); itCategories != itCategoriesEnd;
281 bool isHidden =
true;
283 if (hiddenCategories.find(*itCategories) == hiddenCategories.end()) {
286 resultCategories[*itCategories] = isHidden;
289 return resultCategories;
301 std::unordered_set<std::string> validCategories;
307 for (
auto const &category : categoryMap) {
308 bool isHidden = (category).second;
309 if (includeHidden || (!isHidden)) {
310 validCategories.insert((category).first);
314 return validCategories;
333 std::unordered_set<std::string> hiddenCategories;
334 if (!includeHidden) {
339 std::vector<AlgorithmDescriptor> res;
341 for (
const auto &s : sv) {
345 size_t i = s.find(
'|');
346 if (i == std::string::npos) {
350 desc.
name = s.substr(0, i);
351 std::string vers = s.substr(i + 1);
352 desc.
version = vers.empty() ? 1 : std::stoi(vers);
357 auto categories = alg->categories();
358 desc.
alias = alg->alias();
361 auto itCategoriesEnd = categories.end();
362 for (
auto itCategories = categories.begin(); itCategories != itCategoriesEnd; ++itCategories) {
366 bool categoryIsHidden =
false;
369 std::vector<std::string> categoryLayers;
370 boost::split(categoryLayers, desc.
category, boost::is_any_of(
"\\"));
373 std::string currentLayer;
374 for (
auto &categoryLayer : categoryLayers) {
375 currentLayer.append(categoryLayer);
377 if (hiddenCategories.find(currentLayer) != hiddenCategories.end()) {
379 categoryIsHidden =
true;
384 currentLayer.append(
"\\");
387 if (!categoryIsHidden) {
388 res.emplace_back(desc);
390 if (!desc.
alias.empty() && includeAliases) {
392 std::string lowerCaseName = desc.
name;
393 std::transform(desc.
name.cbegin(), desc.
name.cend(), lowerCaseName.begin(),
394 [](
unsigned char c) { return std::tolower(c); });
395 if (lowerCaseName != desc.
alias) {
VersionMap m_vmap
The map holding the registered class names and their highest versions.
bool exists(const std::string &algorithmName, const int version=-1)
Does an algorithm of the given name and version exist.
std::string createName(const std::string &, const int &) const
creates an algorithm name convolved from an name and version
std::shared_ptr< Algorithm > createAlgorithm(const std::string &name, const int version) const
Create an algorithm object with the specified name.
const std::unordered_set< std::string > getCategories(bool includeHidden=false) const
Get the algorithm categories.
boost::optional< std::string > getRealNameFromAlias(const std::string &alias) const noexcept
Get an algorithms name from the alias map.
void fillHiddenCategories(std::unordered_set< std::string > *categorySet) const
fills a set with the hidden categories
int highestVersion(const std::string &algorithmName) const
Returns the highest version of the algorithm currently registered.
std::vector< AlgorithmDescriptor > getDescriptors(bool includeHidden=false, bool includeAliases=false) const
Returns algorithm descriptors.
void unsubscribe(const std::string &algorithmName, const int version)
Unsubscribe the given algorithm.
AlgorithmFactoryImpl()
Private Constructor for singleton class.
const std::string extractAlgName(const std::shared_ptr< IAlgorithm > &alg) const
Extract the name of an algorithm.
std::pair< std::string, int > decodeName(const std::string &mangledName) const
unmangles the names used as keys into the name and version
int extractAlgVersion(const std::shared_ptr< IAlgorithm > &alg) const
Extract the version of an algorithm.
~AlgorithmFactoryImpl() override
Private Destructor.
const std::string extractAlgAlias(const std::shared_ptr< IAlgorithm > &alg) const
Extract the alias of an algorithm.
const std::vector< std::string > getKeys() const override
Get the algorithm names and version - mangled use decodeName to separate.
std::shared_ptr< Algorithm > create(const std::string &, const int &) const
Creates an instance of an algorithm.
const std::map< std::string, bool > getCategoriesWithState() const
Get the algorithm categories.
Base class from which all concrete algorithm classes should be derived.
The dynamic factory is a base dynamic factory for serving up objects in response to requests from oth...
void unsubscribe(const std::string &className)
Unregisters the given class and deletes the instantiator for the class.
virtual std::shared_ptr< Base > create(const std::string &className) const
Creates a new instance of the class with the given name.
virtual const std::vector< std::string > getKeys() const
Returns the keys in the map.
bool exists(const std::string &className) const
Returns true if the given class is currently registered.
Exception for when an item is not found in a collection.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
Iterator begin()
Iterator referring to first element in the container.
@ TOK_IGNORE_EMPTY
ignore empty tokens
@ TOK_TRIM
remove leading and trailing whitespace from tokens
Iterator end()
Iterator referring to the past-the-end element in the container.
Kernel::Logger g_log("ExperimentInfo")
static logger object
Mantid::Kernel::StringTokenizer tokenizer
Structure uniquely describing an algorithm with its name, category and version.
std::string category
category
std::string name
Algorithm Name.