1 /******************************************************************
3 * Copyright 2016 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 #include "simulator_resource_model_schema.h"
22 #include "simulator_exceptions.h"
24 template <typename TYPE>
25 static AttributeValueVariant buildArrayValue(int depth, AttributeValueVariant &childValue)
29 std::vector<TYPE> arrayValue {boost::get<TYPE>(childValue)};
34 std::vector<std::vector<TYPE>> arrayValue {{boost::get<TYPE>(childValue)}};
38 // This for handling array values of depth 3
39 // NOTE: Caller of this method should validate and pass the depth information.
40 // on invalid depth information this method might throw boost exception.
41 std::vector<std::vector<std::vector<TYPE>>> arrayValue {{{boost::get<TYPE>(childValue)}}};
45 template <typename T, typename=void>
46 struct UniquenessChecker
48 static bool get(const std::vector<T> &/*value*/)
55 struct UniquenessChecker<T, typename std::enable_if<
56 std::is_same<T, int>::value
57 || std::is_same<T, double>::value
58 || std::is_same<T, bool>::value
59 || std::is_same<T, std::string>::value
62 static bool get(const std::vector<T> &value)
64 std::vector<T> valueCopy = value;
65 std::sort(valueCopy.begin(), valueCopy.end());
66 if(valueCopy.end() != std::unique(valueCopy.begin(), valueCopy.end()))
72 class IntegerValidator : public boost::static_visitor<bool>
75 IntegerValidator(const std::shared_ptr<IntegerProperty> &property) :
76 m_property(property) {}
79 bool operator ()(const T &)
84 bool operator ()(const int &value)
86 return m_property->validate(value);
90 std::shared_ptr<IntegerProperty> m_property;
93 class DoubleValidator : public boost::static_visitor<bool>
96 DoubleValidator(const std::shared_ptr<DoubleProperty> &property) :
97 m_property(property) {}
100 bool operator ()(const T &)
105 bool operator ()(const double &value)
107 return m_property->validate(value);
111 std::shared_ptr<DoubleProperty> m_property;
114 class StringValidator : public boost::static_visitor<bool>
117 StringValidator(const std::shared_ptr<StringProperty> &property) :
118 m_property(property) {}
120 template <typename T>
121 bool operator ()(const T &)
126 bool operator ()(const std::string &value)
128 return m_property->validate(value);
132 std::shared_ptr<StringProperty> m_property;
135 class ArrayValidator : public boost::static_visitor<bool>
138 ArrayValidator(const std::shared_ptr<ArrayProperty> &property) :
139 m_property(property) {}
141 template <typename T>
142 bool operator ()(const T &)
147 template <typename T>
148 bool operator ()(const std::vector<T> &value)
150 // Validating length of array
151 if (!checkLength(value))
156 // Validate the uniqueness of elements of array
157 if (!checkUniqueness(value))
162 // Validating elements of array
163 std::shared_ptr<AttributeProperty> elementProperty =
164 m_property->getElementProperty();
167 for (size_t index = 0; index < value.size(); index++)
169 AttributeValueVariant element = value[index];
170 if (!elementProperty->validate(element))
179 template <typename T>
180 bool checkLength(const std::vector<T> &value)
182 if (m_property->hasRange())
184 if (value.size() < m_property->getMinItems()
185 || (value.size() > m_property->getMaxItems() && !m_property->isVariable()))
194 template <typename T>
195 bool checkUniqueness(const std::vector<T> &value)
197 if (m_property->isUnique())
199 return UniquenessChecker<T>::get(value);
205 std::shared_ptr<ArrayProperty> m_property;
208 class ModelValidator : public boost::static_visitor<bool>
211 ModelValidator(const std::shared_ptr<ModelProperty> &property) :
212 m_property(property) {}
214 template <typename T>
215 bool operator ()(const T &)
220 bool operator ()(const SimulatorResourceModel &value)
222 return m_property->validate(value);
226 std::shared_ptr<ModelProperty> m_property;
229 AttributeProperty::AttributeProperty(Type type) : m_type(type) {}
231 AttributeProperty::Type AttributeProperty::getType() const
236 IntegerProperty::IntegerProperty(int defaultValue)
237 : AttributeProperty(AttributeProperty::Type::INTEGER),
238 m_defaultValue(defaultValue),
243 std::shared_ptr<IntegerProperty> IntegerProperty::build(int defaultValue)
245 return std::shared_ptr<IntegerProperty>(new IntegerProperty(defaultValue));
248 bool IntegerProperty::isInteger() const
253 std::shared_ptr<IntegerProperty> IntegerProperty::asInteger()
255 return shared_from_this();
258 bool IntegerProperty::hasRange() const
263 bool IntegerProperty::hasValues() const
265 return m_values.size() > 0;
268 int IntegerProperty::getDefaultValue() const
270 return m_defaultValue;
273 bool IntegerProperty::getRange(int &min, int &max) const
283 bool IntegerProperty::getValues(std::vector<int> &values) const
285 if (!m_values.size())
292 void IntegerProperty::setDefaultValue(int value)
294 if(m_hasRange && !(value >= m_min && value <= m_max))
296 m_defaultValue = m_min;
298 else if(m_values.size() > 0
299 && m_values.end() == std::find(m_values.begin(), m_values.end(), value))
301 m_defaultValue = m_values[0];
304 m_defaultValue = value;
307 void IntegerProperty::setRange(int min, int max)
312 setDefaultValue(m_defaultValue);
315 void IntegerProperty::setValues(const std::vector<int> &values)
318 setDefaultValue(m_defaultValue);
321 bool IntegerProperty::validate(const AttributeValueVariant &value)
323 IntegerValidator integerValidator(shared_from_this());
324 return boost::apply_visitor(integerValidator, value);
327 bool IntegerProperty::validate(const int &value)
329 if (m_hasRange && (value < m_min || value > m_max))
333 else if (m_values.size() > 0)
335 if (m_values.end() == std::find(m_values.begin(), m_values.end(), value))
342 AttributeValueVariant IntegerProperty::buildValue()
344 return m_defaultValue;
347 DoubleProperty::DoubleProperty(double defaultValue)
348 : AttributeProperty(AttributeProperty::Type::DOUBLE),
349 m_defaultValue(defaultValue),
354 std::shared_ptr<DoubleProperty> DoubleProperty::build(double defaultValue)
356 return std::shared_ptr<DoubleProperty>(new DoubleProperty(defaultValue));
359 bool DoubleProperty::isDouble() const
364 std::shared_ptr<DoubleProperty> DoubleProperty::asDouble()
366 return shared_from_this();
369 bool DoubleProperty::hasRange() const
374 bool DoubleProperty::hasValues() const
376 return m_values.size() > 0;
379 double DoubleProperty::getDefaultValue() const
381 return m_defaultValue;
384 bool DoubleProperty::getRange(double &min, double &max) const
394 bool DoubleProperty::getValues(std::vector<double> &values) const
396 if (!m_values.size())
403 void DoubleProperty::setDefaultValue(double value)
405 if(m_hasRange && !(value >= m_min && value <= m_max))
407 m_defaultValue = m_min;
409 else if(m_values.size() > 0
410 && m_values.end() == std::find(m_values.begin(), m_values.end(), value))
412 m_defaultValue = m_values[0];
415 m_defaultValue = value;
418 void DoubleProperty::setRange(double min, double max)
423 setDefaultValue(m_defaultValue);
426 void DoubleProperty::setValues(const std::vector<double> &values)
429 setDefaultValue(m_defaultValue);
432 bool DoubleProperty::validate(const AttributeValueVariant &value)
434 DoubleValidator doubleValidator(shared_from_this());
435 return boost::apply_visitor(doubleValidator, value);
438 bool DoubleProperty::validate(const double &value)
440 if (m_hasRange && (value < m_min || value > m_max))
444 else if (m_values.size() > 0)
446 if (m_values.end() == std::find(m_values.begin(), m_values.end(), value))
453 AttributeValueVariant DoubleProperty::buildValue()
455 return m_defaultValue;
458 BooleanProperty::BooleanProperty(bool defaultValue)
459 : AttributeProperty(AttributeProperty::Type::BOOLEAN),
460 m_defaultValue(defaultValue) {}
462 std::shared_ptr<BooleanProperty> BooleanProperty::build(bool defaultValue)
464 return std::shared_ptr<BooleanProperty>(new BooleanProperty(defaultValue));
467 bool BooleanProperty::isBoolean() const
472 std::shared_ptr<BooleanProperty> BooleanProperty::asBoolean()
474 return shared_from_this();
477 void BooleanProperty::setDefaultValue(bool value)
479 m_defaultValue = value;
482 bool BooleanProperty::getDefaultValue() const
484 return m_defaultValue;
487 bool BooleanProperty::validate(const AttributeValueVariant &)
492 AttributeValueVariant BooleanProperty::buildValue()
494 return m_defaultValue;
497 StringProperty::StringProperty(const std::string &defaultValue)
498 : AttributeProperty(AttributeProperty::Type::STRING),
499 m_defaultValue(defaultValue),
504 std::shared_ptr<StringProperty> StringProperty::build(const std::string &defaultValue)
506 return std::shared_ptr<StringProperty>(new StringProperty(defaultValue));
509 bool StringProperty::isString() const
514 std::shared_ptr<StringProperty> StringProperty::asString()
516 return shared_from_this();
519 bool StringProperty::hasRange() const
524 bool StringProperty::hasValues() const
526 return m_values.size() > 0;
529 std::string StringProperty::getDefaultValue() const
531 return m_defaultValue;
534 bool StringProperty::getRange(size_t &min, size_t &max) const
544 bool StringProperty::getValues(std::vector<std::string> &values) const
546 if (!m_values.size())
553 void StringProperty::setDefaultValue(const std::string &value)
555 if(m_values.size() > 0
556 && m_values.end() == std::find(m_values.begin(), m_values.end(), value))
558 m_defaultValue = m_values[0];
562 if(value.length() >= m_min && value.length() <= m_max)
563 m_defaultValue = value;
565 m_defaultValue.clear();
568 m_defaultValue = value;
571 void StringProperty::setRange(size_t min, size_t max)
576 setDefaultValue(m_defaultValue);
579 void StringProperty::setValues(const std::vector<std::string> &values)
582 setDefaultValue(m_defaultValue);
585 bool StringProperty::validate(const AttributeValueVariant &value)
587 StringValidator stringValidator(shared_from_this());
588 return boost::apply_visitor(stringValidator, value);
591 bool StringProperty::validate(const std::string &value)
593 size_t length = value.length();
594 if (m_hasRange && (length < m_min || length > m_max))
598 else if (m_values.size() > 0)
600 if (m_values.end() == std::find(m_values.begin(), m_values.end(), value))
609 AttributeValueVariant StringProperty::buildValue()
611 return m_defaultValue;
614 ArrayProperty::ArrayProperty()
615 : AttributeProperty(AttributeProperty::Type::ARRAY),
618 m_isVariableSize(false),
622 std::shared_ptr<ArrayProperty> ArrayProperty::build()
624 return std::shared_ptr<ArrayProperty>(new ArrayProperty());
627 bool ArrayProperty::isArray() const
632 std::shared_ptr<ArrayProperty> ArrayProperty::asArray()
634 return shared_from_this();
637 void ArrayProperty::setRange(size_t minItems, size_t maxItems)
644 void ArrayProperty::setVariable(bool state)
646 m_isVariableSize = state;
649 void ArrayProperty::setUnique(bool state)
654 bool ArrayProperty::setElementProperty(const std::shared_ptr<AttributeProperty> &property)
659 m_elementProperty = property;
663 bool ArrayProperty::hasRange() const
668 bool ArrayProperty::isVariable() const
670 return m_isVariableSize;
673 bool ArrayProperty::isUnique() const
678 size_t ArrayProperty::getMinItems() const
683 size_t ArrayProperty::getMaxItems() const
688 std::shared_ptr<AttributeProperty> ArrayProperty::getElementProperty()
690 return m_elementProperty;
693 bool ArrayProperty::validate(const AttributeValueVariant &value)
695 ArrayValidator arrayValidator(shared_from_this());
696 return boost::apply_visitor(arrayValidator, value);
699 AttributeValueVariant ArrayProperty::buildValue()
701 // Find the depth and element property
702 std::shared_ptr<AttributeProperty> elementProperty;
703 int depth = findDepth(elementProperty);
705 if (depth < 1 || depth > 3)
707 throw SimulatorException(SIMULATOR_BAD_SCHEMA,
708 "No support for array of depth more than 3!");
711 AttributeValueVariant elementValue = elementProperty->buildValue();
712 if (elementProperty->isInteger())
714 return buildArrayValue<int>(depth, elementValue);
716 else if (elementProperty->isDouble())
718 return buildArrayValue<double>(depth, elementValue);
720 else if (elementProperty->isBoolean())
722 return buildArrayValue<bool>(depth, elementValue);
724 else if (elementProperty->isString())
726 return buildArrayValue<std::string>(depth, elementValue);
728 else if (elementProperty->isModel())
730 return buildArrayValue<SimulatorResourceModel>(depth, elementValue);
733 throw SimulatorException(SIMULATOR_ERROR,
734 "Failed to build value from property of type array!");
737 int ArrayProperty::findDepth(std::shared_ptr<AttributeProperty> &elementProperty)
739 if (!m_elementProperty)
741 throw SimulatorException(SIMULATOR_BAD_SCHEMA, "Invalid Array property!");
744 if (!m_elementProperty->isArray())
746 elementProperty = m_elementProperty;
750 return (1 + m_elementProperty->asArray()->findDepth(elementProperty));
753 ModelProperty::ModelProperty()
754 : AttributeProperty(AttributeProperty::Type::MODEL) {}
756 std::shared_ptr<ModelProperty> ModelProperty::build()
758 return std::shared_ptr<ModelProperty>(new ModelProperty());
761 bool ModelProperty::isModel() const
766 std::shared_ptr<ModelProperty> ModelProperty::asModel()
768 return shared_from_this();
771 bool ModelProperty::add(const std::string &name,
772 const std::shared_ptr<AttributeProperty> &property, bool required)
774 if (name.empty() || !property)
777 m_childProperties[name] = property;
778 m_requiredAttributes[name] = required;
782 std::shared_ptr<AttributeProperty> ModelProperty::get(
783 const std::string &name)
785 if (m_childProperties.end() != m_childProperties.find(name))
786 return m_childProperties[name];
790 std::unordered_map<std::string, std::shared_ptr<AttributeProperty> >
791 ModelProperty::getChildProperties()
793 return m_childProperties;
796 bool ModelProperty::isRequired(const std::string &name)
798 if (m_requiredAttributes.end() == m_requiredAttributes.find(name))
801 return m_requiredAttributes[name];
804 void ModelProperty::remove(const std::string &name)
806 if (m_requiredAttributes.end() != m_requiredAttributes.find(name))
807 m_requiredAttributes.erase(m_requiredAttributes.find(name));
809 if (m_childProperties.end() != m_childProperties.find(name))
810 m_childProperties.erase(m_childProperties.find(name));
813 void ModelProperty::setRequired(const std::string &name)
815 if (m_requiredAttributes.end() != m_requiredAttributes.find(name))
816 m_requiredAttributes[name] = true;
819 void ModelProperty::unsetRequired(const std::string &name)
821 if (m_requiredAttributes.end() != m_requiredAttributes.find(name))
822 m_requiredAttributes[name] = false;
825 bool ModelProperty::validate(const AttributeValueVariant &value)
827 ModelValidator modelValidator(shared_from_this());
828 return boost::apply_visitor(modelValidator, value);
831 bool ModelProperty::validate(const SimulatorResourceModel &model)
833 for (auto &attributeEntry : model.getAttributeValues())
835 std::shared_ptr<AttributeProperty> childProperty = get(attributeEntry.first);
838 if (!childProperty->validate(attributeEntry.second))
846 AttributeValueVariant ModelProperty::buildValue()
848 return buildResourceModel();
851 SimulatorResourceModel ModelProperty::buildResourceModel()
853 SimulatorResourceModel resourceModel;
854 for (auto &propertyElement : m_childProperties)
856 resourceModel.add(propertyElement.first, (propertyElement.second)->buildValue());
859 return resourceModel;