summaryrefslogtreecommitdiff
path: root/src/components/smart_objects/include/smart_objects/enum_schema_item.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/smart_objects/include/smart_objects/enum_schema_item.h')
-rw-r--r--src/components/smart_objects/include/smart_objects/enum_schema_item.h185
1 files changed, 156 insertions, 29 deletions
diff --git a/src/components/smart_objects/include/smart_objects/enum_schema_item.h b/src/components/smart_objects/include/smart_objects/enum_schema_item.h
index 524d966188..cbba5bd7cd 100644
--- a/src/components/smart_objects/include/smart_objects/enum_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/enum_schema_item.h
@@ -39,11 +39,36 @@
#include <set>
#include <string>
-#include "utils/shared_ptr.h"
#include "smart_objects/default_shema_item.h"
-namespace NsSmartDeviceLink {
-namespace NsSmartObjects {
+#include "utils/semantic_version.h"
+#include <boost/optional.hpp>
+
+namespace ns_smart_device_link {
+namespace ns_smart_objects {
+
+struct ElementSignature {
+ boost::optional<utils::SemanticVersion> mSince;
+ boost::optional<utils::SemanticVersion> mUntil;
+ bool mRemoved;
+
+ ElementSignature(std::string since = "",
+ std::string until = "",
+ bool removed = false) {
+ utils::SemanticVersion since_struct(since);
+ utils::SemanticVersion until_struct(until);
+
+ if (since_struct.isValid()) {
+ mSince = since_struct;
+ }
+
+ if (until_struct.isValid()) {
+ mUntil = until_struct;
+ }
+
+ mRemoved = removed;
+ }
+};
template <typename EnumType>
class EnumConversionHelper;
@@ -60,25 +85,44 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
* @param DefaultValue Default value.
* @return Shared pointer to a new schema item.
**/
- static utils::SharedPtr<TEnumSchemaItem> create(
+ static std::shared_ptr<TEnumSchemaItem> create(
const std::set<EnumType>& AllowedElements,
const TSchemaItemParameter<EnumType>& DefaultValue =
TSchemaItemParameter<EnumType>());
+
/**
- * @deprecated
- * @brief Validate smart object.
- * @param Object Object to validate.
- * @return NsSmartObjects::Errors::eType
+ * @brief Create a new schema item.
+ * @param AllowedElements Set of allowed enumeration elements.
+ * @param DefaultValue Default value.
+ * @return Shared pointer to a new schema item.
**/
- Errors::eType validate(const SmartObject& Object) OVERRIDE;
+ static std::shared_ptr<TEnumSchemaItem> createWithSignatures(
+ const std::set<EnumType>& AllowedElements,
+ const std::map<EnumType, std::vector<ElementSignature> >&
+ ElementSignatures,
+ const TSchemaItemParameter<EnumType>& DefaultValue =
+ TSchemaItemParameter<EnumType>());
+
/**
* @brief Validate smart object.
* @param Object Object to validate.
* @param report__ object for reporting errors during validation
- * @return NsSmartObjects::Errors::eType
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return ns_smart_objects::errors::eType
**/
- Errors::eType validate(const SmartObject& Object,
- rpc::ValidationReport* report__) OVERRIDE;
+ errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__,
+ const utils::SemanticVersion& MessageVersion =
+ utils::SemanticVersion()) OVERRIDE;
+ /**
+ * @brief Return the correct history signature based on message version.
+ * @param signatures Vector reference of enums history items.
+ * @param MessageVersion RPC Version of mobile app.
+ **/
+ const ElementSignature getSignature(
+ const std::vector<ElementSignature>& signatures,
+ const utils::SemanticVersion& MessageVersion);
+
/**
* @brief Apply schema.
* This implementation checks if enumeration is represented as string
@@ -89,7 +133,9 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
* from smart object otherwise contains false.
**/
void applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) OVERRIDE;
+ const bool RemoveFakeParameters,
+ const utils::SemanticVersion& MessageVersion =
+ utils::SemanticVersion()) OVERRIDE;
/**
* @brief Unapply schema.
* @param Object Object to unapply schema.
@@ -104,12 +150,18 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
**/
TEnumSchemaItem(const std::set<EnumType>& AllowedElements,
const TSchemaItemParameter<EnumType>& DefaultValue);
+
+ TEnumSchemaItem(const std::set<EnumType>& AllowedElements,
+ const TSchemaItemParameter<EnumType>& DefaultValue,
+ const std::map<EnumType, std::vector<ElementSignature> >&
+ ElementSignatures);
SmartType getSmartType() const OVERRIDE;
EnumType getDefaultValue() const OVERRIDE;
/**
* @brief Set of allowed enumeration elements.
**/
const std::set<EnumType> mAllowedElements;
+ std::map<EnumType, std::vector<ElementSignature> > mElementSignatures;
/**
* @brief Default value.
**/
@@ -208,21 +260,54 @@ class EnumConversionHelper {
};
template <typename EnumType>
-utils::SharedPtr<TEnumSchemaItem<EnumType> > TEnumSchemaItem<EnumType>::create(
+std::shared_ptr<TEnumSchemaItem<EnumType> > TEnumSchemaItem<EnumType>::create(
const std::set<EnumType>& AllowedElements,
const TSchemaItemParameter<EnumType>& DefaultValue) {
- return new TEnumSchemaItem<EnumType>(AllowedElements, DefaultValue);
+ return std::shared_ptr<TEnumSchemaItem<EnumType> >(
+ new TEnumSchemaItem<EnumType>(AllowedElements, DefaultValue));
}
template <typename EnumType>
-Errors::eType TEnumSchemaItem<EnumType>::validate(const SmartObject& Object) {
- rpc::ValidationReport report("RPC");
- return validate(Object, &report);
+std::shared_ptr<TEnumSchemaItem<EnumType> >
+TEnumSchemaItem<EnumType>::createWithSignatures(
+ const std::set<EnumType>& AllowedElements,
+ const std::map<EnumType, std::vector<ElementSignature> >& ElementSignatures,
+ const TSchemaItemParameter<EnumType>& DefaultValue) {
+ return std::shared_ptr<TEnumSchemaItem<EnumType> >(
+ new TEnumSchemaItem<EnumType>(
+ AllowedElements, DefaultValue, ElementSignatures));
+}
+
+template <typename EnumType>
+const ElementSignature TEnumSchemaItem<EnumType>::getSignature(
+ const std::vector<ElementSignature>& signatures,
+ const utils::SemanticVersion& MessageVersion) {
+ for (uint i = 0; i < signatures.size(); i++) {
+ ElementSignature signature = signatures[i];
+ // Check if signature matches message version
+ if (signature.mSince != boost::none &&
+ MessageVersion < signature.mSince.get()) {
+ // Msg version predates 'since' field, check next entry
+ continue;
+ }
+ if (signature.mUntil != boost::none &&
+ (MessageVersion >= signature.mUntil.get())) {
+ continue; // Msg version newer than `until` field, check next entry
+ }
+ // Found correct signature
+ return signature;
+ }
+
+ // Could not match msg version to element siganture
+ ElementSignature ret;
+ return ret;
}
template <typename EnumType>
-Errors::eType TEnumSchemaItem<EnumType>::validate(
- const SmartObject& Object, rpc::ValidationReport* report__) {
+errors::eType TEnumSchemaItem<EnumType>::validate(
+ const SmartObject& Object,
+ rpc::ValidationReport* report__,
+ const utils::SemanticVersion& MessageVersion) {
if (SmartType_Integer != Object.getType()) {
std::string validation_info;
if (SmartType_String == Object.getType()) {
@@ -234,22 +319,55 @@ Errors::eType TEnumSchemaItem<EnumType>::validate(
SmartObject::typeToString(Object.getType());
}
report__->set_validation_info(validation_info);
- return Errors::INVALID_VALUE;
+ return errors::INVALID_VALUE;
}
- if (mAllowedElements.find(static_cast<EnumType>(Object.asInt())) ==
- mAllowedElements.end()) {
+
+ auto elements_it =
+ mAllowedElements.find(static_cast<EnumType>(Object.asInt()));
+
+ if (elements_it == mAllowedElements.end()) {
std::stringstream stream;
stream << "Invalid enum value: " << Object.asInt();
std::string validation_info = stream.str();
report__->set_validation_info(validation_info);
- return Errors::OUT_OF_RANGE;
+ return errors::OUT_OF_RANGE;
+ }
+
+ // Element exists in schema. Check if version is also valid.
+ if (MessageVersion.isValid()) {
+ EnumType value = *elements_it;
+ auto signatures_it = mElementSignatures.find(value);
+ if (signatures_it != mElementSignatures.end()) {
+ if (!signatures_it->second.empty()) {
+ ElementSignature signature =
+ getSignature(signatures_it->second, MessageVersion);
+ if (signature.mRemoved) {
+ // Element was removed for this version
+ std::string validation_info = "Enum value : " + Object.asString() +
+ " removed for SyncMsgVersion " +
+ MessageVersion.toString();
+ report__->set_validation_info(validation_info);
+ return errors::INVALID_VALUE;
+ } else if (signature.mSince == boost::none &&
+ signature.mUntil == boost::none) {
+ // Element does not exist for this version
+ std::string validation_info = "Enum value : " + Object.asString() +
+ " does not exist for SyncMsgVersion " +
+ MessageVersion.toString();
+ report__->set_validation_info(validation_info);
+ return errors::INVALID_VALUE;
+ }
+ }
+ }
}
- return Errors::OK;
+ return errors::OK;
}
template <typename EnumType>
-void TEnumSchemaItem<EnumType>::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) {
+void TEnumSchemaItem<EnumType>::applySchema(
+ SmartObject& Object,
+ const bool RemoveFakeParameters,
+ const utils::SemanticVersion& MessageVersion) {
if (SmartType_String == Object.getType()) {
EnumType enum_val = static_cast<EnumType>(-1);
if (ConversionHelper::StringToEnum(Object.asString(), &enum_val)) {
@@ -285,6 +403,15 @@ TEnumSchemaItem<EnumType>::TEnumSchemaItem(
: CDefaultSchemaItem<EnumType>(DefaultValue)
, mAllowedElements(AllowedElements) {}
-} // namespace NsSmartObjects
-} // namespace NsSmartDeviceLink
+template <typename EnumType>
+TEnumSchemaItem<EnumType>::TEnumSchemaItem(
+ const std::set<EnumType>& AllowedElements,
+ const TSchemaItemParameter<EnumType>& DefaultValue,
+ const std::map<EnumType, std::vector<ElementSignature> >& ElementSignatures)
+ : CDefaultSchemaItem<EnumType>(DefaultValue)
+ , mAllowedElements(AllowedElements)
+ , mElementSignatures(ElementSignatures) {}
+
+} // namespace ns_smart_objects
+} // namespace ns_smart_device_link
#endif // SRC_COMPONENTS_SMART_OBJECTS_INCLUDE_SMART_OBJECTS_ENUM_SCHEMA_ITEM_H_