diff options
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.h | 185 |
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_ |