13#include <boost/algorithm/string.hpp>
19#include <Poco/Notification.h>
20#include <Poco/NotificationCenter.h>
24#define strcasecmp _stricmp
43 return strcasecmp(lhs.c_str(),
rhs.c_str()) < 0;
63 using svc_it =
typename svcmap::iterator;
89 const std::shared_ptr<T> &
object()
const {
return m_object; }
118 const std::shared_ptr<T> &
newObject()
const {
return m_newObject; }
119 const std::shared_ptr<T> &
oldObject()
const {
return m_oldObject; }
190 virtual void add(
const std::string &name,
const std::shared_ptr<T> &Tobject) {
191 checkForEmptyName(name);
192 checkForNullPointer(Tobject);
194 bool success =
false;
197 std::lock_guard<std::recursive_mutex> lock(m_mutex);
202 success = datamap.insert(std::make_pair(name, Tobject)).second;
205 std::string
error =
" add : Unable to insert Data Object : '" + name +
"'";
207 throw std::runtime_error(
error);
209 g_log.
debug() <<
"Add Data Object " << name <<
" successful\n";
210 notificationCenter.postNotification(
new AddNotification(name, Tobject));
222 virtual void addOrReplace(
const std::string &name,
const std::shared_ptr<T> &Tobject) {
223 checkForNullPointer(Tobject);
226 std::unique_lock<std::recursive_mutex> lock(m_mutex);
229 auto it = datamap.find(name);
230 if (it != datamap.end()) {
232 g_log.
debug(
"Data Object '" + name +
"' replaced in data service.\n");
237 it->second = Tobject;
244 DataService::add(name, Tobject);
253 std::unique_lock<std::recursive_mutex> lock(m_mutex);
255 auto it = datamap.find(name);
256 if (it == datamap.end()) {
258 g_log.
debug(
" remove '" + name +
"' cannot be found");
264 auto data = std::move(it->second);
272 g_log.
debug(
"Data Object '" + name +
"' deleted from data service.");
281 void rename(
const std::string &oldName,
const std::string &newName) {
282 checkForEmptyName(newName);
284 if (oldName == newName) {
285 g_log.
warning(
"Rename: The existing name matches the new name");
290 std::unique_lock<std::recursive_mutex> lock(m_mutex);
292 auto existingNameIter = datamap.find(oldName);
293 if (existingNameIter == datamap.end()) {
295 g_log.
warning(
" rename '" + oldName +
"' cannot be found");
299 auto existingNameObject = std::move(existingNameIter->second);
300 auto targetNameIter = datamap.find(newName);
303 if (targetNameIter != datamap.end()) {
304 auto targetNameObject = targetNameIter->second;
311 datamap.erase(existingNameIter);
313 if (targetNameIter != datamap.end()) {
314 targetNameIter->second = std::move(existingNameObject);
318 if (!(datamap.emplace(newName, std::move(existingNameObject)).second)) {
321 std::string
error =
" add : Unable to insert Data Object : '" + newName +
"'";
323 throw std::runtime_error(
error);
328 g_log.
debug(
"Data Object '" + oldName +
"' renamed to '" + newName +
"'");
337 std::lock_guard<std::recursive_mutex> lock(m_mutex);
341 g_log.
debug() <<
typeid(
this).name() <<
" cleared.\n";
350 std::shared_ptr<T>
retrieve(
const std::string &name)
const {
352 std::lock_guard<std::recursive_mutex> _lock(m_mutex);
354 auto it = datamap.find(name);
355 if (it != datamap.end()) {
365 return std::all_of(listOfNames.cbegin(), listOfNames.cend(),
366 [
this](
auto const &name) { return this->doesExist(name); });
372 std::lock_guard<std::recursive_mutex> _lock(m_mutex);
373 auto it = datamap.find(name);
374 return it != datamap.end();
379 std::lock_guard<std::recursive_mutex> _lock(m_mutex);
381 if (showingHiddenObjects()) {
382 return datamap.size();
384 return std::count_if(datamap.cbegin(), datamap.cend(),
385 [](
const auto &it) { return !isHiddenDataServiceObject(it.first); });
400 const std::string &contain =
"")
const {
402 std::vector<std::string> foundNames;
405 if (hiddenState == DataServiceHidden::Auto) {
406 if (showingHiddenObjects()) {
407 hiddenState = DataServiceHidden::Include;
409 hiddenState = DataServiceHidden::Exclude;
414 if (hiddenState == DataServiceHidden::Include) {
416 std::lock_guard<std::recursive_mutex> _lock(m_mutex);
417 foundNames.reserve(datamap.size());
418 for (
const auto &item : datamap) {
419 if (contain.empty()) {
420 foundNames.emplace_back(item.first);
421 }
else if (item.first.find(contain) != std::string::npos) {
422 foundNames.emplace_back(item.first);
427 std::lock_guard<std::recursive_mutex> _lock(m_mutex);
428 foundNames.reserve(datamap.size());
429 for (
const auto &item : datamap) {
430 if (!isHiddenDataServiceObject(item.first)) {
432 if (contain.empty()) {
433 foundNames.emplace_back(item.first);
434 }
else if (item.first.find(contain) != std::string::npos) {
435 foundNames.emplace_back(item.first);
443 if (sortState == DataServiceSort::Sorted) {
444 std::sort(foundNames.begin(), foundNames.end());
452 std::lock_guard<std::recursive_mutex> _lock(m_mutex);
454 const bool alwaysIncludeHidden = includeHidden == DataServiceHidden::Include;
455 const bool usingAuto = includeHidden == DataServiceHidden::Auto && showingHiddenObjects();
457 const bool showingHidden = alwaysIncludeHidden || usingAuto;
459 std::vector<std::shared_ptr<T>> objects;
460 objects.reserve(datamap.size());
461 for (
const auto &it : datamap) {
462 if (showingHidden || !isHiddenDataServiceObject(it.first)) {
463 objects.emplace_back(it.second);
472 return boost::starts_with(name, prefixToHide());
476 auto showingHiddenFlag = ConfigService::Instance().getValue<
bool>(
"MantidOptions.InvisibleWorkspaces");
477 return showingHiddenFlag.get_value_or(
false);
498 const std::string
error =
"Add Data Object with empty name";
500 throw std::runtime_error(
error);
506 const std::string
error =
"Attempt to add empty shared pointer";
508 throw std::runtime_error(
error);
const std::vector< double > & rhs
#define DLLExport
Definitions of the DLLImport compiler directives for MSVC.
double obj
the value of the quadratic function
AddNotification is sent after an new object is added to the data service.
AddNotification(const std::string &name, const std::shared_ptr< T > &obj)
Constructor.
AfterReplaceNotification is sent after an object is replaced in the addOrReplace() function.
AfterReplaceNotification(const std::string &name, const std::shared_ptr< T > &newObj)
Constructor.
BeforeReplaceNotification is sent before an object is replaced in the addOrReplace() function.
std::shared_ptr< T > m_oldObject
const std::shared_ptr< T > & oldObject() const
BeforeReplaceNotification(const std::string &name, const std::shared_ptr< T > &obj, const std::shared_ptr< T > &newObj)
Constructor.
const std::shared_ptr< T > & newObject() const
Returns the pointer to the new object.
std::shared_ptr< T > m_newObject
shared pointer to the object
Clear notification is sent when the service is cleared.
ClearNotification()
Constructor.
Base class for DataService notifications that also stores a pointer to the object.
DataServiceNotification(const std::string &name, const std::shared_ptr< T > &obj)
Constructor.
const std::shared_ptr< T > & object() const
Returns the const pointer to the object concerned or 0 if it is a general notification.
std::shared_ptr< T > m_object
shared pointer to the object
Class for named object notifications.
NamedObjectNotification(const std::string &name)
std::string m_name
object's name
const std::string & objectName() const
Returns the name of the object.
PostDeleteNotification is sent after an object is deleted from the data service.
PostDeleteNotification(const std::string &name)
Constructor.
PreDeleteNotification is sent before an object is deleted from the data service.
PreDeleteNotification(const std::string &name, const std::shared_ptr< T > &obj)
Constructor.
Rename notification is sent when the rename method is called.
std::string m_newName
New object name.
const std::string & newObjectName() const
New name for the object.
RenameNotification(const std::string &name, const std::string &newName)
Constructor.
DataService stores instances of a given type.
virtual void add(const std::string &name, const std::shared_ptr< T > &Tobject)
Add an object to the service.
static std::string prefixToHide()
bool doesExist(const std::string &name) const
Check to see if a data object exists in the store.
void checkForNullPointer(const std::shared_ptr< T > &Tobject)
void rename(const std::string &oldName, const std::string &newName)
Rename an object within the service.
std::vector< std::string > getObjectNames(DataServiceSort sortState=DataServiceSort::Unsorted, DataServiceHidden hiddenState=DataServiceHidden::Auto, const std::string &contain="") const
Returns a vector of strings containing all object names in the ADS.
Logger g_log
Logger for this DataService.
svcmap datamap
Map of objects in the data service.
const std::string svcName
DataService name.
virtual void shutdown()
Prepare for shutdown.
std::shared_ptr< T > retrieve(const std::string &name) const
Get a shared pointer to a stored data object.
void checkForEmptyName(const std::string &name)
DataService & operator=(const DataService &)=delete
Deleted copy assignment operator.
size_t size() const
Return the number of objects stored by the data service.
std::map< std::string, std::shared_ptr< T >, CaseInsensitiveCmp > svcmap
Typedef for the map holding the names of and pointers to the data objects.
static bool showingHiddenObjects()
virtual ~DataService()=default
std::recursive_mutex m_mutex
Recursive mutex to avoid simultaneous access or notifications.
typename svcmap::const_iterator svc_constit
Const iterator for the data store map.
bool doAllWsExist(const std::vector< std::string > &listOfNames)
Checks all elements within the specified vector exist in the ADS.
virtual void addOrReplace(const std::string &name, const std::shared_ptr< T > &Tobject)
Add or replace an object to the service.
typename svcmap::iterator svc_it
Iterator for the data store map.
Poco::NotificationCenter notificationCenter
Sends notifications to observers.
DataService(const std::string &name)
Protected constructor (singleton)
std::vector< std::shared_ptr< T > > getObjects(DataServiceHidden includeHidden=DataServiceHidden::Auto) const
Get a vector of the pointers to the data objects stored by the service.
void remove(const std::string &name)
Remove an object from the service.
static bool isHiddenDataServiceObject(const std::string &name)
void clear()
Empty the service.
DataService(const DataService &)=delete
Deleted copy constructor.
Exception for when an item is not found in a collection.
The Logger class is in charge of the publishing messages from the framework through various channels.
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.
Kernel::Logger g_log("ExperimentInfo")
static logger object
DataServiceSort
Flag for whether to sort items before returning.
DataServiceHidden
Flag for whether to include hidden items when returning, Auto queries the class to determine this beh...
Helper class which provides the Collimation Length for SANS instruments.
bool operator()(const std::string &lhs, const std::string &rhs) const