Mantid
Loading...
Searching...
No Matches
PropertyManager.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
7//----------------------------------------------------------------------
8// Includes
9//----------------------------------------------------------------------
11#include "MantidJson/Json.h"
18
19#include <json/json.h>
20
21namespace Mantid::Kernel {
22
23using std::string;
24
25namespace {
26// static logger reference
27Logger g_log("PropertyManager");
28
34const std::string createKey(const std::string &name) {
35 std::string key = name;
36 std::transform(key.begin(), key.end(), key.begin(), toupper);
37 return key;
38}
39} // namespace
40
41const std::string PropertyManager::INVALID_VALUES_SUFFIX = "_invalid_values";
43std::string PropertyManager::getInvalidValuesFilterLogName(const std::string &logName) {
45}
46std::string PropertyManager::getLogNameFromInvalidValuesFilter(const std::string &logName) {
47 std::string retVal = "";
49 retVal = logName.substr(0, logName.size() - PropertyManager::INVALID_VALUES_SUFFIX.size());
50 }
51 return retVal;
52}
53
55bool PropertyManager::isAnInvalidValuesFilterLog(const std::string &logName) {
57 if (logName.length() >= ending.length()) {
58 return (0 == logName.compare(logName.length() - ending.length(), ending.length(), ending));
59 } else {
60 return false;
61 }
62}
63//-----------------------------------------------------------------------------------------------
65PropertyManager::PropertyManager() : m_properties(), m_orderedProperties() {}
66
67//-----------------------------------------------------------------------------------------------
71 : m_properties(), m_orderedProperties(other.m_orderedProperties.size()) {
72 // We need to do a deep copy of the property pointers here
73 for (unsigned int i = 0; i < m_orderedProperties.size(); ++i) {
74 auto p = std::unique_ptr<Property>(other.m_orderedProperties[i]->clone());
75 this->m_orderedProperties[i] = p.get();
76 this->m_properties[createKey(p->name())] = std::move(p);
77 }
78}
79
80//-----------------------------------------------------------------------------------------------
85 // We need to do a deep copy here
86 if (this != &other) {
87 this->m_properties.clear();
88 this->m_orderedProperties.resize(other.m_orderedProperties.size());
89 for (unsigned int i = 0; i < m_orderedProperties.size(); ++i) {
90 auto p = std::unique_ptr<Property>(other.m_orderedProperties[i]->clone());
91 this->m_orderedProperties[i] = p.get();
92 this->m_properties[createKey(p->name())] = std::move(p);
93 }
94 }
95 return *this;
96}
97
98//-----------------------------------------------------------------------------------------------
101
102//-----------------------------------------------------------------------------------------------
109 // Iterate through all properties on the RHS
110 PropertyMap::const_iterator it;
111 for (it = rhs.m_properties.begin(); it != rhs.m_properties.end(); ++it) {
112 // The name on the rhs
113 string rhs_name = it->first;
114 try {
115 Property *lhs_prop = this->getPointerToProperty(rhs_name);
116 // Use the property's += operator to add THAT. Isn't abstraction fun?!
117 (*lhs_prop) += it->second.get();
118 } catch (Exception::NotFoundError &) {
119 // The property isnt on the lhs.
120 // Let's copy it
121 auto copy = std::unique_ptr<Property>(it->second->clone());
122 // And we add a copy of that property to *this
123 this->declareProperty(std::move(copy), "");
124 }
125 }
126
127 return *this;
128}
129
130//-----------------------------------------------------------------------------------------------
139 const std::vector<std::string> &excludedFromFiltering) {
140 auto filter = logFilter->filter();
141 for (auto &orderedProperty : m_orderedProperties) {
142 auto const propName = orderedProperty->name();
143 if (std::find(excludedFromFiltering.cbegin(), excludedFromFiltering.cend(), propName) !=
144 excludedFromFiltering.cend()) {
145 // this log should be excluded from filtering
146 continue;
147 }
148
149 if (auto doubleSeries = dynamic_cast<TimeSeriesProperty<double> *>(orderedProperty)) {
150 // don't filter the invalid values filters
152 break;
153 std::unique_ptr<Property> filtered(nullptr);
155
156 // add the filter to the passed in filters
158 auto const *tspFilterProp = dynamic_cast<TimeSeriesProperty<bool> const *>(filterProp);
159 if (!tspFilterProp)
160 break;
161 logFilter->addFilter(*tspFilterProp);
162
163 filtered = std::make_unique<FilteredTimeSeriesProperty<double>>(doubleSeries, *logFilter->filter());
164 } else if (filter->size() > 0) {
165 // attach the filter to the TimeSeriesProperty, thus creating the FilteredTimeSeriesProperty<double>
166 filtered = std::make_unique<FilteredTimeSeriesProperty<double>>(doubleSeries, *filter);
167 }
168 if (filtered) {
169 // Now replace in the map
170 orderedProperty = filtered.get();
171 this->m_properties[createKey(propName)] = std::move(filtered);
172 }
173 }
174 }
175}
176
186 PropertyManager *newMgr = new PropertyManager();
187 newMgr->m_orderedProperties.reserve(m_orderedProperties.size());
188 // We need to do a deep copy of the property pointers here
189 for (auto const *prop : m_orderedProperties) {
190 std::unique_ptr<Property> newProp;
191 if (auto const *tsp = dynamic_cast<ITimeSeriesProperty const *>(prop))
192 newProp = std::unique_ptr<Property>(tsp->cloneInTimeROI(timeROI));
193 else
194 newProp = std::unique_ptr<Property>(prop->clone());
195 newMgr->m_orderedProperties.emplace_back(newProp.get());
196 newMgr->m_properties[createKey(newProp->name())] = std::move(newProp);
197 }
198 return newMgr;
199}
200
207 for (auto prop : m_orderedProperties) {
208 if (auto tsp = dynamic_cast<ITimeSeriesProperty *>(prop))
209 tsp->removeDataOutsideTimeROI(timeROI);
210 }
211}
212
213//-----------------------------------------------------------------------------------------------
221void PropertyManager::declareProperty(std::unique_ptr<Property> p, const std::string &doc) {
222 p->setDocumentation(doc);
223
224 const std::string key = createKey(p->name());
225 auto existing = m_properties.find(key);
226 if (existing == m_properties.end()) {
227 m_orderedProperties.emplace_back(p.get());
228 m_properties[key] = std::move(p);
229 } else {
230 // Don't error if this is actually the same property object!
231 if (existing->second != p) {
232 throw Exception::ExistsError("Property with given name already exists", key);
233 }
234 }
235}
236
242void PropertyManager::declareOrReplaceProperty(std::unique_ptr<Property> p, const std::string &doc) {
243 p->setDocumentation(doc);
244
245 const std::string key = createKey(p->name());
246 auto existing = m_properties.find(key);
247 if (existing != std::end(m_properties)) {
248 // replace it in the same position
249 auto oldPropPtr = existing->second.get();
250 auto ordereredPropPos = std::find(std::begin(m_orderedProperties), std::end(m_orderedProperties), oldPropPtr);
251 // if the property exists it should be guaranteed to be in the ordered list
252 // by declareProperty
253 assert(ordereredPropPos != std::end(m_orderedProperties));
254 *ordereredPropPos = p.get();
255 } else {
256 m_orderedProperties.emplace_back(p.get());
257 }
258 m_properties[key] = std::move(p);
259}
260
264 for (auto &prop : getProperties()) {
265 if (!prop->isDefault())
266 prop->setValue(prop->getDefault());
267 }
268}
269
270//-----------------------------------------------------------------------------------------------
282void PropertyManager::setProperties(const std::string &propertiesJson,
283 const std::unordered_set<std::string> &ignoreProperties, bool createMissing) {
284 setProperties(propertiesJson, this, ignoreProperties, createMissing);
285}
286//-----------------------------------------------------------------------------------------------
300void PropertyManager::setProperties(const std::string &propertiesJson, IPropertyManager *targetPropertyManager,
301 const std::unordered_set<std::string> &ignoreProperties, bool createMissing) {
302 ::Json::Value jsonValue;
303
304 if (Mantid::JsonHelpers::parse(propertiesJson, &jsonValue)) {
305 setProperties(jsonValue, targetPropertyManager, ignoreProperties, createMissing);
306 } else {
307 throw std::invalid_argument("propertiesArray was not valid json");
308 }
309}
310//-----------------------------------------------------------------------------------------------
318void PropertyManager::setProperties(const ::Json::Value &jsonValue,
319 const std::unordered_set<std::string> &ignoreProperties, bool createMissing) {
320 setProperties(jsonValue, this, ignoreProperties, createMissing);
321}
322
323//-----------------------------------------------------------------------------------------------
333void PropertyManager::setProperties(const ::Json::Value &jsonValue, IPropertyManager *targetPropertyManager,
334 const std::unordered_set<std::string> &ignoreProperties, bool createMissing) {
335 if (jsonValue.type() != ::Json::ValueType::objectValue)
336 return;
337
338 // Some algorithms require Filename to be set first do that here
339 static const std::string propFilename = "Filename";
340 const ::Json::Value &filenameValue = jsonValue[propFilename];
341 if (!filenameValue.isNull()) {
342 const std::string value = filenameValue.asString();
343 // Set it
344 targetPropertyManager->setPropertyValue(propFilename, value);
345 }
346 const auto memberNames = jsonValue.getMemberNames();
347 for (::Json::ArrayIndex i = 0; i < jsonValue.size(); i++) {
348 const auto &propName = memberNames[i];
349 if ((propFilename == propName) || (ignoreProperties.find(propName) != ignoreProperties.end())) {
350 continue;
351 }
352 const ::Json::Value &propValue = jsonValue[propName];
353 if (createMissing) {
354 targetPropertyManager->declareOrReplaceProperty(decodeAsProperty(propName, propValue));
355 } else {
356 targetPropertyManager->setPropertyValueFromJson(propName, propValue);
357 }
358 }
359}
360
367void PropertyManager::setPropertiesWithString(const std::string &propertiesString,
368 const std::unordered_set<std::string> &ignoreProperties) {
369 if (propertiesString.empty()) {
370 return;
371 }
372 auto firstSymbol = propertiesString.find_first_not_of(" \n\t");
373 if (firstSymbol == std::string::npos) {
374 return;
375 }
376 if (propertiesString[firstSymbol] == '{') {
377 setPropertiesWithJSONString(propertiesString, ignoreProperties);
378 } else {
379 setPropertiesWithSimpleString(propertiesString, ignoreProperties);
380 }
381}
382
388void PropertyManager::setPropertiesWithJSONString(const std::string &propertiesString,
389 const std::unordered_set<std::string> &ignoreProperties) {
390 ::Json::Value propertyJson;
391
392 if (Mantid::JsonHelpers::parse(propertiesString, &propertyJson)) {
393 setProperties(propertyJson, ignoreProperties);
394 } else {
395 throw std::invalid_argument("Could not parse JSON string when trying to set a property from: " + propertiesString);
396 }
397}
398
405void PropertyManager::setPropertiesWithSimpleString(const std::string &propertiesString,
406 const std::unordered_set<std::string> &ignoreProperties) {
407 ::Json::Value propertyJson;
408 // Split up comma-separated properties
410
411 boost::char_separator<char> sep(";");
412 tokenizer propPairs(propertiesString, ";", Mantid::Kernel::StringTokenizer::TOK_TRIM);
413 // Iterate over the properties
414 for (const auto &pair : propPairs) {
415 size_t n = pair.find('=');
416 if (n != std::string::npos) {
417 // Normal "PropertyName=value" string.
418 std::string propName;
419 std::string value;
420
421 // Extract the value string
422 if (n < pair.size() - 1) {
423 propName = pair.substr(0, n);
424 value = pair.substr(n + 1, pair.size() - n - 1);
425 } else {
426 // String is "PropertyName="
427 propName = pair.substr(0, n);
428 value = "";
429 }
430 // Set it
431 propertyJson[propName] = value;
432 }
433 }
434 setProperties(propertyJson, ignoreProperties);
435}
436
437//-----------------------------------------------------------------------------------------------
446void PropertyManager::setPropertyValue(const std::string &name, const std::string &value) {
447 auto *prop = getPointerToProperty(name);
448 auto helpMsg = prop->setValue(value);
450 if (!helpMsg.empty()) {
451 helpMsg = "Invalid value for property " + prop->name() + " (" + prop->type() + ") from string \"" + value +
452 "\": " + helpMsg;
453 throw std::invalid_argument(helpMsg);
454 }
455}
456
464void PropertyManager::setPropertyValueFromJson(const std::string &name, const Json::Value &value) {
465 auto *prop = getPointerToProperty(name);
466 auto helpMsg = prop->setValueFromJson(value);
468 if (!helpMsg.empty()) {
469 helpMsg = "Invalid value for property " + prop->name() + " (" + prop->type() + ") from Json \"" +
470 value.toStyledString() + "\": " + helpMsg;
471 throw std::invalid_argument(helpMsg);
472 }
473}
474
475//-----------------------------------------------------------------------------------------------
484void PropertyManager::setPropertyOrdinal(const int &index, const std::string &value) {
485 Property *p = getPointerToPropertyOrdinal(index); // throws runtime_error if property not in vector
486 std::string errorMsg = p->setValue(value);
487 this->afterPropertySet(p->name());
488 if (!errorMsg.empty()) {
489 errorMsg = "Invalid value for property " + p->name() + " (" + p->type() + ") \"" + value + "\" : " + errorMsg;
490 throw std::invalid_argument(errorMsg);
491 }
492}
493
494//-----------------------------------------------------------------------------------------------
500bool PropertyManager::existsProperty(const std::string &name) const {
501 const std::string key = createKey(name);
502 auto it = m_properties.find(key);
503 return (it != m_properties.end());
504}
505
506//-----------------------------------------------------------------------------------------------
511 bool allValid = true;
512 for (const auto &property : m_properties) {
513 // check for errors in each property
514 std::string error = property.second->isValid();
515 //"" means no error
516 if (!error.empty()) {
517 g_log.error() << "Property \"" << property.first << "\" is not set to a valid value: \"" << error << "\".\n";
518 allValid = false;
519 }
520 }
521 return allValid;
522}
523
524//-----------------------------------------------------------------------------------------------
530
531//-----------------------------------------------------------------------------------------------
537std::string PropertyManager::getPropertyValue(const std::string &name) const {
538 Property const *p = getPointerToProperty(name); // throws NotFoundError if property not in vector
539 return p->value();
540}
541
542//-----------------------------------------------------------------------------------------------
550std::string PropertyManager::asString(bool withDefaultValues) const {
551 Json::StreamWriterBuilder builder;
552 builder.settings_["indentation"] = "";
553 const string output = Json::writeString(builder, asJson(withDefaultValues));
554
555 return output;
556}
557
558//-----------------------------------------------------------------------------------------------
564::Json::Value PropertyManager::asJson(bool withDefaultValues) const {
565 ::Json::Value jsonMap;
566 const auto count = static_cast<int>(propertyCount());
567 for (int i = 0; i < count; ++i) {
569 bool is_enabled = true;
570 if (p->getSettings()) {
571 is_enabled = p->getSettings()->isEnabled(this);
572 }
573 if (p->isValueSerializable() && (withDefaultValues || !p->isDefault()) && is_enabled) {
574 jsonMap[p->name()] = p->valueAsJson();
575 }
576 }
577
578 return jsonMap;
579}
580
582 if (other.m_properties.size() != m_properties.size())
583 return false;
584 for (const auto &[key, value] : m_properties) {
585 if (other.m_properties.count(key) != 1)
586 return false;
587 if (*other.m_properties.at(key) != *value)
588 return false;
589 }
590 return true;
591}
592
593bool PropertyManager::operator!=(const PropertyManager &other) const { return !this->operator==(other); }
594
595//-----------------------------------------------------------------------------------------------
602 const std::string key = createKey(name);
603 auto it = m_properties.find(key);
604 if (it != m_properties.end()) {
605 return it->second.get();
606 }
607 throw Exception::NotFoundError("Unknown property", name);
608}
609
610//-----------------------------------------------------------------------------------------------
616 const std::string key = createKey(name);
617 auto it = m_properties.find(key);
618 if (it != m_properties.end()) {
619 return it->second.get();
620 }
621 return nullptr;
622}
623
624//-----------------------------------------------------------------------------------------------
631
632 if (index < static_cast<int>(m_orderedProperties.size())) {
634 }
635 throw std::runtime_error("Property index too high");
636}
637
638//-----------------------------------------------------------------------------------------------
643const std::vector<Property *> &PropertyManager::getProperties() const { return m_orderedProperties; }
644
645//-----------------------------------------------------------------------------------------------
650std::vector<std::string> PropertyManager::getDeclaredPropertyNames() const noexcept {
651 std::vector<std::string> names;
652 const auto &props = getProperties();
653 names.reserve(props.size());
654 std::transform(props.cbegin(), props.cend(), std::back_inserter(names),
655 [](auto &propPtr) { return propPtr->name(); });
656 return names;
657}
658
659//-----------------------------------------------------------------------------------------------
677 return TypedValue(*this, name);
678}
679
680//-----------------------------------------------------------------------------------------------
685void PropertyManager::removeProperty(const std::string &name, const bool delproperty) {
686 if (existsProperty(name)) {
687 // remove it
689 const std::string key = createKey(name);
690 m_properties.erase(key);
691 std::vector<Property *>::iterator itr;
692 itr = find(m_orderedProperties.begin(), m_orderedProperties.end(), prop);
693 m_orderedProperties.erase(itr);
694 (void)delproperty; // not used
695 }
696}
697
703std::unique_ptr<Property> PropertyManager::takeProperty(const size_t index) {
704 try {
705 auto const *property = m_orderedProperties[index];
706 const std::string key = createKey(property->name());
707 auto propertyPtr = std::move(m_properties[key]);
708 m_properties.erase(key);
710 return propertyPtr;
711 } catch (const std::out_of_range &) {
712 return NULL;
713 }
714}
715
716//-----------------------------------------------------------------------------------------------
721 m_orderedProperties.clear();
722 m_properties.clear();
723}
724
725//-----------------------------------------------------------------------------------------------
731Json::Value encodeAsJson(const PropertyManager &propMgr) { return propMgr.asJson(true); }
732
733} // namespace Mantid::Kernel
std::string name
Definition Run.cpp:60
const std::vector< double > & rhs
double value
The value of the point.
Definition FitMW.cpp:51
double error
std::map< DeltaEMode::Type, std::string > index
int count
counter
Definition Matrix.cpp:37
Exception for when an item is already in a collection.
Definition Exception.h:164
Exception for when an item is not found in a collection.
Definition Exception.h:145
Interface to PropertyManager.
virtual void setPropertyValue(const std::string &name, const std::string &value)=0
Sets property value from a string.
virtual void declareOrReplaceProperty(std::unique_ptr< Property > p, const std::string &doc="")=0
Function to declare properties (i.e. store them)
virtual void afterPropertySet(const std::string &)
Override this method to perform a custom action right after a property was set.
virtual void setPropertyValueFromJson(const std::string &name, const Json::Value &value)=0
Sets property value from a Json::Value.
virtual bool isEnabled(const IPropertyManager *algo) const
Is the property to be shown as "enabled" in the GUI.
A non-templated interface to a TimeSeriesProperty.
This class is for filtering TimeSeriesProperty data.
Definition LogFilter.h:32
const TimeSeriesProperty< bool > * filter() const
Returns a reference to the filter.
Definition LogFilter.h:55
void addFilter(const TimeSeriesProperty< bool > &filter)
Adds a filter using boolean AND.
Definition LogFilter.cpp:55
void error(const std::string &msg)
Logs at error level.
Definition Logger.cpp:108
Property manager helper class.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void clear() override final
Clears the whole property map.
bool operator!=(const PropertyManager &other) const
void setPropertyValue(const std::string &name, const std::string &value) override
Set the value of a property by string N.B.
bool validateProperties() const override
Validates all the properties in the collection.
void removeProperty(const std::string &name, const bool delproperty=true) override
removes the property from properties map
void setPropertyOrdinal(const int &index, const std::string &value) override
Set the value of a property by an index N.B.
void declareOrReplaceProperty(std::unique_ptr< Property > p, const std::string &doc="") override
Add or replace a property in the list of managed properties.
size_t propertyCount() const override
Count the number of properties under management.
PropertyManager & operator+=(const PropertyManager &rhs)
Addition operator.
PropertyManager()
Default constructor.
void resetProperties() override
Reset property values back to initial values (blank or default values)
Property * getPointerToProperty(const std::string &name) const override
Get a property by name.
bool existsProperty(const std::string &name) const override
Checks whether the named property is already in the list of managed property.
void setProperties(const std::string &propertiesJson, const std::unordered_set< std::string > &ignoreProperties=std::unordered_set< std::string >(), bool createMissing=false) override
Set the ordered list of properties by one string of values, separated by semicolons.
void setPropertiesWithString(const std::string &propertiesString, const std::unordered_set< std::string > &ignoreProperties=std::unordered_set< std::string >()) override
Sets all the declared properties from a string.
PropertyMap m_properties
The properties under management.
void removeDataOutsideTimeROI(const Kernel::TimeROI &timeROI)
For time series properties, remove time values outside of TimeROI regions, each defined as [roi_begin...
std::string asString(bool withDefaultValues=false) const override
Return the property manager serialized as a string.
void setPropertiesWithJSONString(const std::string &propertiesString, const std::unordered_set< std::string > &ignoreProperties)
Sets all the declared properties from a string.
static bool isAnInvalidValuesFilterLog(const std::string &logName)
Determine if the log's name has a substring indicating it should not be filtered.
void setPropertiesWithSimpleString(const std::string &propertiesString, const std::unordered_set< std::string > &ignoreProperties)
Sets all the declared properties from a string.
static std::string getInvalidValuesFilterLogName(const std::string &logName)
Gets the correct log name for the matching invalid values log for a given log name.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
std::unique_ptr< Property > takeProperty(const size_t index) override
removes the property from the properties map and returns a pointer to it
static std::string getLogNameFromInvalidValuesFilter(const std::string &logName)
void filterByProperty(Mantid::Kernel::LogFilter *logFilter, const std::vector< std::string > &excludedFromFiltering=std::vector< std::string >()) override
Filter the managed properties by the given boolean property mask.
Property * getPointerToPropertyOrdinal(const int &index) const override
Get a property by an index.
::Json::Value asJson(bool withDefaultValues=false) const override
Return the property manager serialized as a json object.
Property * getPointerToPropertyOrNull(const std::string &name) const
Get a property by name.
std::vector< Property * > m_orderedProperties
Stores the order in which the properties were declared.
void declareProperty(std::unique_ptr< Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
PropertyManager & operator=(const PropertyManager &)
Assignment operator - performs a deep copy.
bool operator==(const PropertyManager &other) const
void setPropertyValueFromJson(const std::string &name, const Json::Value &value) override
Set the value of a property by Json::Value.
static const std::string INVALID_VALUES_SUFFIX
const std::vector< Property * > & getProperties() const override
Get the list of managed properties.
PropertyManager * cloneInTimeROI(const Kernel::TimeROI &timeROI)
Create a partial copy of this object such that every time series property is cloned according to the ...
virtual ~PropertyManager() override
Virtual destructor.
std::vector< std::string > getDeclaredPropertyNames() const noexcept override
Return the list of declared property names.
Base class for properties.
Definition Property.h:94
const IPropertySettings * getSettings() const
Definition Property.cpp:109
virtual std::string setValue(const std::string &)=0
Set the value of the property via a string.
virtual bool isDefault() const =0
Overriden function that returns if property has the same value that it was initialised with,...
const std::string & name() const
Get the property's name.
Definition Property.cpp:61
const std::string type() const
Returns the type of the property as a string.
Definition Property.cpp:87
virtual Json::Value valueAsJson() const =0
Returns the value of the property as a Json::Value.
virtual std::string value() const =0
Returns the value of the property as a string.
virtual bool isValueSerializable() const
Whether the string returned by value() can be used for serialization.
Definition Property.h:143
@ TOK_TRIM
remove leading and trailing whitespace from tokens
TimeROI : Object that holds information about when the time measurement was active.
Definition TimeROI.h:18
A specialised Property class for holding a series of time-value pairs.
MANTID_KERNEL_DLL std::unique_ptr< Property > decodeAsProperty(const std::string &name, const Json::Value &value)
Attempt to create a Property of the most appropriate type from a string name and Json value object.
MANTID_KERNEL_DLL::Json::Value encodeAsJson(const OptionalBool &)
Encode an OptionalBool as a Json::Value.
Utility class that enables the getProperty() method to effectively be templated on the return type.