summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackLivio <jack@livio.io>2018-08-01 14:06:34 -0400
committerJackLivio <jack@livio.io>2018-08-01 14:06:34 -0400
commitea4a1731986b7f420c31f978edc7219edde448be (patch)
tree15fb0a6a4543c58f04cd3bc180b1e6e7834cc8ed
parent9727cd2cd185d2ea3ea028aab89cb419d1ad4a87 (diff)
downloadsdl_core-ea4a1731986b7f420c31f978edc7219edde448be.tar.gz
Add support for mandatory and removed versioning
-rw-r--r--src/components/application_manager/include/application_manager/application.h3
-rw-r--r--src/components/application_manager/include/application_manager/application_data_impl.h4
-rw-r--r--src/components/application_manager/include/application_manager/rpc_handler_impl.h1
-rw-r--r--src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc14
-rw-r--r--src/components/application_manager/src/application_data_impl.cc13
-rw-r--r--src/components/application_manager/src/rpc_handler_impl.cc16
-rw-r--r--src/components/formatters/include/formatters/CSmartFactory.h12
-rw-r--r--src/components/formatters/src/CSmartFactory.cc1
-rw-r--r--src/components/include/utils/semantic_version.h135
-rw-r--r--src/components/smart_objects/include/smart_objects/always_false_schema_item.h9
-rw-r--r--src/components/smart_objects/include/smart_objects/always_true_schema_item.h10
-rw-r--r--src/components/smart_objects/include/smart_objects/array_schema_item.h13
-rw-r--r--src/components/smart_objects/include/smart_objects/default_shema_item.h16
-rw-r--r--src/components/smart_objects/include/smart_objects/enum_schema_item.h22
-rw-r--r--src/components/smart_objects/include/smart_objects/number_schema_item.h16
-rw-r--r--src/components/smart_objects/include/smart_objects/object_schema_item.h42
-rw-r--r--src/components/smart_objects/include/smart_objects/schema_item.h15
-rw-r--r--src/components/smart_objects/include/smart_objects/smart_object.h9
-rw-r--r--src/components/smart_objects/include/smart_objects/smart_schema.h13
-rw-r--r--src/components/smart_objects/include/smart_objects/string_schema_item.h10
-rw-r--r--src/components/smart_objects/src/always_false_schema_item.cc7
-rw-r--r--src/components/smart_objects/src/always_true_schema_item.cc5
-rw-r--r--src/components/smart_objects/src/array_schema_item.cc46
-rw-r--r--src/components/smart_objects/src/object_schema_item.cc122
-rw-r--r--src/components/smart_objects/src/schema_item.cc8
-rw-r--r--src/components/smart_objects/src/smart_object.cc4
-rw-r--r--src/components/smart_objects/src/smart_schema.cc9
-rw-r--r--src/components/smart_objects/src/string_schema_item.cc5
-rw-r--r--tools/InterfaceGenerator/MsgVersionGenerate.py34
-rwxr-xr-xtools/InterfaceGenerator/generator/Model.py50
-rwxr-xr-xtools/InterfaceGenerator/generator/generators/SmartFactoryBase.py45
-rwxr-xr-xtools/InterfaceGenerator/generator/parsers/RPCBase.py119
32 files changed, 775 insertions, 53 deletions
diff --git a/src/components/application_manager/include/application_manager/application.h b/src/components/application_manager/include/application_manager/application.h
index 844b08071b..c5dec86eee 100644
--- a/src/components/application_manager/include/application_manager/application.h
+++ b/src/components/application_manager/include/application_manager/application.h
@@ -51,6 +51,7 @@
#include "protocol_handler/protocol_handler.h"
#include "smart_objects/smart_object.h"
#include "utils/macro.h"
+#include "utils/semantic_version.h"
namespace application_manager {
@@ -115,6 +116,7 @@ class InitialApplicationData {
virtual const smart_objects::SmartObject* ngn_media_screen_name() const = 0;
virtual const mobile_api::Language::eType& language() const = 0;
virtual const mobile_api::Language::eType& ui_language() const = 0;
+ virtual const utils::SemanticVersion& msg_version() const = 0;
virtual void set_app_types(const smart_objects::SmartObject& app_types) = 0;
virtual void set_vr_synonyms(
const smart_objects::SmartObject& vr_synonyms) = 0;
@@ -125,6 +127,7 @@ class InitialApplicationData {
virtual void set_language(const mobile_api::Language::eType& language) = 0;
virtual void set_ui_language(
const mobile_api::Language::eType& ui_language) = 0;
+ virtual void set_msg_version(const uint16_t major, const uint16_t minor, const uint16_t patch) = 0;
};
/*
diff --git a/src/components/application_manager/include/application_manager/application_data_impl.h b/src/components/application_manager/include/application_manager/application_data_impl.h
index 8da8dec8f1..71d2c53d5b 100644
--- a/src/components/application_manager/include/application_manager/application_data_impl.h
+++ b/src/components/application_manager/include/application_manager/application_data_impl.h
@@ -35,6 +35,7 @@
#include <string>
#include "utils/lock.h"
+#include "utils/semantic_version.h"
#include "smart_objects/smart_object.h"
#include "application_manager/application.h"
#include "interfaces/MOBILE_API.h"
@@ -55,6 +56,7 @@ class InitialApplicationDataImpl : public virtual Application {
const smart_objects::SmartObject* ngn_media_screen_name() const;
const mobile_api::Language::eType& language() const;
const mobile_api::Language::eType& ui_language() const;
+ const utils::SemanticVersion& msg_version() const;
void set_app_types(const smart_objects::SmartObject& app_types);
void set_vr_synonyms(const smart_objects::SmartObject& vr_synonyms);
@@ -63,6 +65,7 @@ class InitialApplicationDataImpl : public virtual Application {
void set_ngn_media_screen_name(const smart_objects::SmartObject& ngn_name);
void set_language(const mobile_api::Language::eType& language);
void set_ui_language(const mobile_api::Language::eType& ui_language);
+ void set_msg_version(const uint16_t major, const uint16_t minor, const uint16_t patch);
void set_perform_interaction_layout(
mobile_api::LayoutMode::eType layout) OVERRIDE;
@@ -77,6 +80,7 @@ class InitialApplicationDataImpl : public virtual Application {
mobile_api::Language::eType language_;
mobile_api::Language::eType ui_language_;
mobile_apis::LayoutMode::eType perform_interaction_layout_;
+ utils::SemanticVersion msg_version_;
private:
DISALLOW_COPY_AND_ASSIGN(InitialApplicationDataImpl);
diff --git a/src/components/application_manager/include/application_manager/rpc_handler_impl.h b/src/components/application_manager/include/application_manager/rpc_handler_impl.h
index 44954d41f7..7f61c7b034 100644
--- a/src/components/application_manager/include/application_manager/rpc_handler_impl.h
+++ b/src/components/application_manager/include/application_manager/rpc_handler_impl.h
@@ -57,6 +57,7 @@
#include "interfaces/v4_protocol_v1_2_no_extra_schema.h"
#include "utils/threads/message_loop_thread.h"
+#include "utils/semantic_version.h"
namespace application_manager {
namespace rpc_handler {
diff --git a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc
index 78a92d360a..672864c422 100644
--- a/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc
+++ b/src/components/application_manager/rpc_plugins/sdl_rpc_plugin/src/commands/mobile/register_app_interface_request.cc
@@ -293,12 +293,26 @@ void RegisterAppInterfaceRequest::Run() {
return;
}
+ uint16_t major = msg_params[strings::sync_msg_version][strings::major_version].asUInt();
+ uint16_t minor = msg_params[strings::sync_msg_version][strings::minor_version].asUInt();
+ uint16_t patch = 0;
+ if(msg_params[strings::sync_msg_version].keyExists(strings::patch_version)) {
+ patch = msg_params[strings::sync_msg_version][strings::patch_version].asUInt();
+ }
+ if (major < minimum_major_version || (major == minimum_major_version && minor < minimum_minor_version)
+ || (major == minimum_major_version && minor == minimum_minor_version && patch < minimum_patch_version)) {
+ SendResponse(false, mobile_apis::Result::REJECTED);
+ }
+
application = application_manager_.RegisterApplication(message_);
if (!application) {
LOG4CXX_ERROR(logger_, "Application hasn't been registered!");
return;
}
+
+ application->set_msg_version(major, minor, patch);
+
// For resuming application need to restore hmi_app_id from resumeCtrl
resumption::ResumeCtrl& resumer = application_manager_.resume_controller();
const std::string& device_mac = application->mac_address();
diff --git a/src/components/application_manager/src/application_data_impl.cc b/src/components/application_manager/src/application_data_impl.cc
index f271b7ff6a..4f26ce5ef5 100644
--- a/src/components/application_manager/src/application_data_impl.cc
+++ b/src/components/application_manager/src/application_data_impl.cc
@@ -103,6 +103,12 @@ const mobile_api::Language::eType& InitialApplicationDataImpl::ui_language()
return ui_language_;
}
+const utils::SemanticVersion& InitialApplicationDataImpl::msg_version()
+ const {
+ return msg_version_;
+}
+
+
void InitialApplicationDataImpl::set_app_types(
const smart_objects::SmartObject& app_types) {
if (app_types_) {
@@ -153,6 +159,13 @@ void InitialApplicationDataImpl::set_ui_language(
ui_language_ = ui_language;
}
+void InitialApplicationDataImpl::set_msg_version(
+ const uint16_t major, const uint16_t minor, const uint16_t patch) {
+ msg_version_.major_version = major;
+ msg_version_.minor_version = minor;
+ msg_version_.patch_version = patch;
+}
+
void InitialApplicationDataImpl::set_perform_interaction_layout(
mobile_apis::LayoutMode::eType layout) {
perform_interaction_layout_ = layout;
diff --git a/src/components/application_manager/src/rpc_handler_impl.cc b/src/components/application_manager/src/rpc_handler_impl.cc
index b374147968..7b3645ddf1 100644
--- a/src/components/application_manager/src/rpc_handler_impl.cc
+++ b/src/components/application_manager/src/rpc_handler_impl.cc
@@ -218,9 +218,23 @@ bool RPCHandlerImpl::ConvertMessageToSO(
rpc::ValidationReport report("RPC");
+ //Attach RPC version to SmartObject if it does not exist yet.
+ auto app_ptr = app_manager_.application(message.connection_key());
+ utils::SemanticVersion msg_version(2, 0, 0);
+ if (app_ptr && (output[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS].keyExists(NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION) == false)) {
+ printf("Getting app msg version\n");
+ msg_version = app_ptr->msg_version();
+ output[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS][NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION] = msg_version.toString();
+ } else if (mobile_apis::FunctionID::RegisterAppInterfaceID == static_cast<mobile_apis::FunctionID::eType>(output[strings::params][strings::function_id].asInt())) {
+ //Assume default version 1.0.0 until properly set in RAI
+ printf("Setting default msg version\n");
+ output[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS][NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION] = msg_version.toString();
+ printf("%s\n", output[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS][NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION].asString().c_str());
+ }
+
if (!conversion_result ||
!mobile_so_factory().attachSchema(output, true) ||
- ((output.validate(&report) != smart_objects::Errors::OK))) {
+ ((output.validate(&report, msg_version) != smart_objects::Errors::OK))) {
LOG4CXX_WARN(logger_,
"Failed to parse string to smart object :"
<< message.json_message());
diff --git a/src/components/formatters/include/formatters/CSmartFactory.h b/src/components/formatters/include/formatters/CSmartFactory.h
index 9fed89253b..c2037e7adc 100644
--- a/src/components/formatters/include/formatters/CSmartFactory.h
+++ b/src/components/formatters/include/formatters/CSmartFactory.h
@@ -82,6 +82,10 @@ extern const std::string S_PROTOCOL_TYPE;
extern const std::string S_CORRELATION_ID;
/**
+ * @brief String constant for RPC_MSG_VERSION.
+ */
+extern const std::string S_RPC_MSG_VERSION;
+/**
* @brief String constant for "code" param name.
*/
extern const std::string kCode;
@@ -295,7 +299,13 @@ bool CSmartFactory<FunctionIdEnum, MessageTypeEnum, StructIdEnum>::attachSchema(
}
object.setSchema(schemaIterator->second);
- schemaIterator->second.applySchema(object, RemoveFakeParameters);
+
+ utils::SemanticVersion msg_version;
+ if (object[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS].keyExists(NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION)) {
+ msg_version = object[NsSmartDeviceLink::NsJSONHandler::strings::S_PARAMS][NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION].asString();
+ }
+
+ schemaIterator->second.applySchema(object, RemoveFakeParameters, msg_version);
return true;
}
diff --git a/src/components/formatters/src/CSmartFactory.cc b/src/components/formatters/src/CSmartFactory.cc
index 6b0808fbfa..27e2064fee 100644
--- a/src/components/formatters/src/CSmartFactory.cc
+++ b/src/components/formatters/src/CSmartFactory.cc
@@ -47,6 +47,7 @@ const std::string NsSmartDeviceLink::NsJSONHandler::strings::S_PROTOCOL_TYPE(
"protocol_type");
const std::string NsSmartDeviceLink::NsJSONHandler::strings::S_CORRELATION_ID(
"correlation_id");
+const std::string NsSmartDeviceLink::NsJSONHandler::strings::S_RPC_MSG_VERSION("rpc_msg_version");
const std::string NsSmartDeviceLink::NsJSONHandler::strings::kCode("code");
const std::string NsSmartDeviceLink::NsJSONHandler::strings::kMessage(
"message");
diff --git a/src/components/include/utils/semantic_version.h b/src/components/include/utils/semantic_version.h
new file mode 100644
index 0000000000..aca61f4810
--- /dev/null
+++ b/src/components/include/utils/semantic_version.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2018, Livio
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following
+ * disclaimer in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * Neither the name of the Ford Motor Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SRC_COMPONENTS_INCLUDE_UTILS_SEMANTIC_VERSION_H_
+#define SRC_COMPONENTS_INCLUDE_UTILS_SEMANTIC_VERSION_H_
+
+#include <boost/algorithm/string.hpp>
+
+namespace utils {
+
+struct SemanticVersion {
+
+ SemanticVersion(uint16_t major = 0, uint16_t minor = 0, uint16_t patch = 0) {
+ major_version = major;
+ minor_version = minor;
+ patch_version = patch;
+ }
+
+ SemanticVersion(const std::string& str_version) {
+ std::vector<std::string> str_array;
+ boost::split(str_array, str_version, boost::is_any_of("."));
+ if(str_array.size() == 3) {
+ major_version = atoi(str_array[0].c_str());
+ minor_version = atoi(str_array[1].c_str());
+ patch_version = atoi(str_array[2].c_str());
+ } else {
+ exit(1);
+ }
+ }
+
+ bool operator==(const SemanticVersion& version) const {
+ if (major_version == version.major_version && minor_version == version.minor_version && patch_version == version.patch_version) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool operator<(const SemanticVersion& version) const {
+ if(major_version < version.major_version) {
+ return true;
+ } else if (minor_version < version.minor_version) {
+ return true;
+ } else if (patch_version < version.patch_version) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool operator<=(const SemanticVersion& version) const {
+ if (this->operator==(version)) {
+ return true;
+ } else if (this->operator<(version)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool operator>(const SemanticVersion& version) const {
+ if(major_version > version.major_version) {
+ return true;
+ } else if (minor_version > version.minor_version) {
+ return true;
+ } else if (patch_version > version.patch_version) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ bool operator>=(const SemanticVersion& version) const {
+ if (this->operator==(version)) {
+ return true;
+ } else if (this->operator>(version)) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ const std::string toString() {
+ std::string result = "";
+ result += std::to_string(major_version);
+ result += ".";
+ result += std::to_string(minor_version);
+ result += ".";
+ result += std::to_string(patch_version);
+ printf("toString Result!!!: %s\n", result.c_str());
+ return result;
+ }
+
+ bool isValid() const{
+ return major_version > 0 || minor_version > 0 || patch_version > 0;
+ }
+
+ uint16_t major_version = 0;
+ uint16_t minor_version = 0;
+ uint16_t patch_version = 0;
+
+};
+
+}
+
+#endif // SRC_COMPONENTS_INCLUDE_UTILS_CALLABLE_H \ No newline at end of file
diff --git a/src/components/smart_objects/include/smart_objects/always_false_schema_item.h b/src/components/smart_objects/include/smart_objects/always_false_schema_item.h
index 4510f2292a..3a8a309b8d 100644
--- a/src/components/smart_objects/include/smart_objects/always_false_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/always_false_schema_item.h
@@ -62,6 +62,15 @@ class CAlwaysFalseSchemaItem : public ISchemaItem {
**/
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
+ /**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
private:
CAlwaysFalseSchemaItem();
diff --git a/src/components/smart_objects/include/smart_objects/always_true_schema_item.h b/src/components/smart_objects/include/smart_objects/always_true_schema_item.h
index 8a211339ba..9fe7878811 100644
--- a/src/components/smart_objects/include/smart_objects/always_true_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/always_true_schema_item.h
@@ -63,6 +63,16 @@ class CAlwaysTrueSchemaItem : public ISchemaItem {
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
+ /**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
+
private:
CAlwaysTrueSchemaItem();
DISALLOW_COPY_AND_ASSIGN(CAlwaysTrueSchemaItem);
diff --git a/src/components/smart_objects/include/smart_objects/array_schema_item.h b/src/components/smart_objects/include/smart_objects/array_schema_item.h
index 3e8be98ee0..af21dd9b65 100644
--- a/src/components/smart_objects/include/smart_objects/array_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/array_schema_item.h
@@ -38,6 +38,8 @@
#include "smart_objects/always_true_schema_item.h"
#include "smart_objects/schema_item_parameter.h"
+#include "utils/semantic_version.h"
+
namespace NsSmartDeviceLink {
namespace NsSmartObjects {
/**
@@ -83,6 +85,15 @@ class CArraySchemaItem : public ISchemaItem {
**/
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
+ /**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
/**
* @brief Apply schema.
@@ -93,7 +104,7 @@ class CArraySchemaItem : public ISchemaItem {
* 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.
diff --git a/src/components/smart_objects/include/smart_objects/default_shema_item.h b/src/components/smart_objects/include/smart_objects/default_shema_item.h
index fdac77d029..75dbcaf67d 100644
--- a/src/components/smart_objects/include/smart_objects/default_shema_item.h
+++ b/src/components/smart_objects/include/smart_objects/default_shema_item.h
@@ -65,6 +65,16 @@ class CDefaultSchemaItem : public ISchemaItem {
rpc::ValidationReport* report__) OVERRIDE;
/**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
+
+ /**
* @brief Set default value to an object.
* @param Object Object to set default value.
* @return true if default value was successfully set, false otherwise.
@@ -127,6 +137,12 @@ Errors::eType CDefaultSchemaItem<Type>::validate(
}
template <typename Type>
+Errors::eType CDefaultSchemaItem<Type>::validate(
+ const SmartObject& Object, rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ return validate(Object, report__);
+}
+
+template <typename Type>
bool CDefaultSchemaItem<Type>::setDefaultValue(SmartObject& Object) {
Type value;
if (mDefaultValue.getValue(value)) {
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 450bbc6c40..787960659f 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
@@ -41,6 +41,8 @@
#include "smart_objects/default_shema_item.h"
+#include "utils/semantic_version.h"
+
namespace NsSmartDeviceLink {
namespace NsSmartObjects {
@@ -78,6 +80,16 @@ class TEnumSchemaItem : public CDefaultSchemaItem<EnumType> {
**/
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
+
+ /**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
/**
* @brief Apply schema.
* This implementation checks if enumeration is represented as string
@@ -88,7 +100,7 @@ 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.
@@ -248,8 +260,14 @@ Errors::eType TEnumSchemaItem<EnumType>::validate(
}
template <typename EnumType>
+Errors::eType TEnumSchemaItem<EnumType>::validate(
+ const SmartObject& Object, rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ return validate(Object, report__);
+}
+
+template <typename EnumType>
void TEnumSchemaItem<EnumType>::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) {
+ 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)) {
diff --git a/src/components/smart_objects/include/smart_objects/number_schema_item.h b/src/components/smart_objects/include/smart_objects/number_schema_item.h
index 2c64538953..e1d294779d 100644
--- a/src/components/smart_objects/include/smart_objects/number_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/number_schema_item.h
@@ -81,6 +81,16 @@ class TNumberSchemaItem : public CDefaultSchemaItem<NumberType> {
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
+ /**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
+
private:
/**
* @brief Get smart type for this NumberType.
@@ -194,6 +204,12 @@ Errors::eType TNumberSchemaItem<NumberType>::validate(
}
template <typename NumberType>
+Errors::eType TNumberSchemaItem<NumberType>::validate(
+ const SmartObject& Object, rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ return validate(Object, report__);
+}
+
+template <typename NumberType>
TNumberSchemaItem<NumberType>::TNumberSchemaItem(
const TSchemaItemParameter<NumberType>& MinValue,
const TSchemaItemParameter<NumberType>& MaxValue,
diff --git a/src/components/smart_objects/include/smart_objects/object_schema_item.h b/src/components/smart_objects/include/smart_objects/object_schema_item.h
index 4c0def558b..df5a34a25a 100644
--- a/src/components/smart_objects/include/smart_objects/object_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/object_schema_item.h
@@ -37,6 +37,8 @@
#include <set>
#include "utils/macro.h"
+#include "utils/semantic_version.h"
+#include <boost/optional.hpp>
#include "smart_objects/schema_item.h"
#include "smart_objects/schema_item_parameter.h"
@@ -62,7 +64,20 @@ class CObjectSchemaItem : public ISchemaItem {
* @param IsMandatory true if member is mandatory, false
* otherwise. Defaults to true.
**/
- SMember(const ISchemaItemPtr SchemaItem, const bool IsMandatory = true);
+ //SMember(const ISchemaItemPtr SchemaItem, const bool IsMandatory = true);
+
+ SMember(const ISchemaItemPtr SchemaItem,
+ const bool IsMandatory = true,
+ const std::string& Since = "",
+ const std::string& Until = "",
+ const bool IsDeprecated = false,
+ const bool IsRemoved = false);
+ /**
+ * @brief Checks the version a parameter was removed (until)
+ * If the mobile's msg version is greater than or
+ **/
+ bool CheckHistoryFieldVersion(const utils::SemanticVersion& MessageVersion) const;
+
/**
* @brief Member schema item.
**/
@@ -71,6 +86,11 @@ class CObjectSchemaItem : public ISchemaItem {
* @brief true if member is mandatory, false otherwise.
**/
bool mIsMandatory;
+ boost::optional<utils::SemanticVersion> mSince;
+ boost::optional<utils::SemanticVersion> mUntil;
+ bool mIsDeprecated;
+ bool mIsRemoved;
+
};
typedef std::map<std::string, SMember> Members;
/**
@@ -98,13 +118,22 @@ class CObjectSchemaItem : public ISchemaItem {
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
/**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
+ /**
* @brief Apply schema.
* @param Object Object to apply schema.
* @param RemoveFakeParameters contains true if need to remove fake parameters
* 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.
@@ -136,7 +165,14 @@ class CObjectSchemaItem : public ISchemaItem {
* @brief Removes fake parameters from object.
* @param Object Object to remove fake parameters.
**/
- void RemoveFakeParams(SmartObject& Object);
+ void RemoveFakeParams(SmartObject& Object, const utils::SemanticVersion& MessageVersion);
+
+ /**
+ * @brief Checks mandatory and version fields to see
+ * if a member is required.
+ * @param Object Object to remove fake parameters.
+ **/
+ bool IsMandatory(const SMember& member);
/**
* @brief Map of member name to SMember structure describing the object
diff --git a/src/components/smart_objects/include/smart_objects/schema_item.h b/src/components/smart_objects/include/smart_objects/schema_item.h
index 2b15a1d47a..4e126b2bec 100644
--- a/src/components/smart_objects/include/smart_objects/schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/schema_item.h
@@ -40,6 +40,7 @@
#include <memory>
#include "utils/macro.h"
+#include "utils/semantic_version.h"
namespace NsSmartDeviceLink {
namespace NsSmartObjects {
@@ -74,6 +75,18 @@ class ISchemaItem {
rpc::ValidationReport* report__);
/**
+ * @brief Validate smart object.
+ *
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * message if an error occurs
+ * @param MessageVersion to check mobile RPC version against RPC Spec Histor
+ * @return NsSmartObjects::Errors::eType
+ **/
+ virtual Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion);
+
+ /**
* @brief Set default value to an object.
*
* @param Object Object to set default value.
@@ -100,7 +113,7 @@ class ISchemaItem {
**/
virtual void applySchema(
NsSmartDeviceLink::NsSmartObjects::SmartObject& Object,
- const bool RemoveFakeParameters);
+ const bool RemoveFakeParameters, const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
/**
* @brief Unapply schema.
diff --git a/src/components/smart_objects/include/smart_objects/smart_object.h b/src/components/smart_objects/include/smart_objects/smart_object.h
index 6a2cbdb911..5853c9bb3f 100644
--- a/src/components/smart_objects/include/smart_objects/smart_object.h
+++ b/src/components/smart_objects/include/smart_objects/smart_object.h
@@ -687,6 +687,15 @@ class SmartObject FINAL {
Errors::eType validate(rpc::ValidationReport* report__);
/**
+ * @brief Validates object according to attached schema.
+ *
+ * @param report__ object for reporting errors during validation
+ * @param messageVersion of the mobile app to check against RPC Spec Schema
+ * @return Result of validation.
+ */
+ Errors::eType validate(rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion);
+
+ /**
* @brief Sets new schema
*
* @param schema Schema for object validation
diff --git a/src/components/smart_objects/include/smart_objects/smart_schema.h b/src/components/smart_objects/include/smart_objects/smart_schema.h
index ada5646043..08595d311c 100644
--- a/src/components/smart_objects/include/smart_objects/smart_schema.h
+++ b/src/components/smart_objects/include/smart_objects/smart_schema.h
@@ -83,6 +83,17 @@ class CSmartSchema FINAL {
rpc::ValidationReport* report__) const;
/**
+ * @brief Validate smart object.
+ *
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& messageVersion) const;
+
+ /**
* @brief Set new root schema item.
*
* @param SchemaItem Root schema item.
@@ -97,7 +108,7 @@ class CSmartSchema FINAL {
* @param RemoveFakeParameters contains true if need to remove fake parameters
* from smart object otherwise contains false.
**/
- void applySchema(SmartObject& Object, const bool RemoveFakeParameters);
+ void applySchema(SmartObject& Object, const bool RemoveFakeParameters, const utils::SemanticVersion& MessageVersion = utils::SemanticVersion());
/**
* @brief The reverse SmartObject conversion using schema.
diff --git a/src/components/smart_objects/include/smart_objects/string_schema_item.h b/src/components/smart_objects/include/smart_objects/string_schema_item.h
index 50418debc0..0bf21a6449 100644
--- a/src/components/smart_objects/include/smart_objects/string_schema_item.h
+++ b/src/components/smart_objects/include/smart_objects/string_schema_item.h
@@ -74,7 +74,15 @@ class CStringSchemaItem : public CDefaultSchemaItem<std::string> {
**/
Errors::eType validate(const SmartObject& Object,
rpc::ValidationReport* report__) OVERRIDE;
-
+ /**
+ * @brief Validate smart object.
+ * @param Object Object to validate.
+ * @param report__ object for reporting errors during validation
+ * @param MessageVersion to check mobile RPC version against RPC Spec History
+ * @return NsSmartObjects::Errors::eType
+ **/
+ Errors::eType validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) OVERRIDE;
private:
/**
* @brief Constructor.
diff --git a/src/components/smart_objects/src/always_false_schema_item.cc b/src/components/smart_objects/src/always_false_schema_item.cc
index 203ae11236..18d0d36323 100644
--- a/src/components/smart_objects/src/always_false_schema_item.cc
+++ b/src/components/smart_objects/src/always_false_schema_item.cc
@@ -51,5 +51,12 @@ Errors::eType CAlwaysFalseSchemaItem::validate(
report__->set_validation_info("Generic error");
return Errors::ERROR;
}
+
+Errors::eType CAlwaysFalseSchemaItem::validate(
+ const SmartObject& Object, rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ report__->set_validation_info("Generic error");
+ return Errors::ERROR;
+}
+
} // namespace NsSmartObjects
} // namespace NsSmartDeviceLink
diff --git a/src/components/smart_objects/src/always_true_schema_item.cc b/src/components/smart_objects/src/always_true_schema_item.cc
index 774bcea121..0402fa0d10 100644
--- a/src/components/smart_objects/src/always_true_schema_item.cc
+++ b/src/components/smart_objects/src/always_true_schema_item.cc
@@ -48,5 +48,10 @@ Errors::eType CAlwaysTrueSchemaItem::validate(const SmartObject& object,
return Errors::OK;
}
+Errors::eType CAlwaysTrueSchemaItem::validate(
+ const SmartObject& Object, rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ return Errors::OK;
+}
+
} // namespace NsSmartObjects
} // namespace NsSmartDeviceLink
diff --git a/src/components/smart_objects/src/array_schema_item.cc b/src/components/smart_objects/src/array_schema_item.cc
index f006267f10..78619050e0 100644
--- a/src/components/smart_objects/src/array_schema_item.cc
+++ b/src/components/smart_objects/src/array_schema_item.cc
@@ -89,11 +89,53 @@ Errors::eType CArraySchemaItem::validate(const SmartObject& Object,
return Errors::OK;
}
+Errors::eType CArraySchemaItem::validate(const SmartObject& Object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ if (SmartType_Array != Object.getType()) {
+ std::string validation_info = "Incorrect type, expected: " +
+ SmartObject::typeToString(SmartType_Array) +
+ ", got: " +
+ SmartObject::typeToString(Object.getType());
+ report__->set_validation_info(validation_info);
+ return Errors::INVALID_VALUE;
+ }
+ size_t sizeLimit;
+ const size_t array_len = Object.length();
+
+ if (mMinSize.getValue(sizeLimit) && (array_len < sizeLimit)) {
+ std::stringstream stream;
+ stream << "Got array of size: " << array_len
+ << ", minimum allowed: " << sizeLimit;
+ std::string validation_info = stream.str();
+ report__->set_validation_info(validation_info);
+ return Errors::OUT_OF_RANGE;
+ }
+ if (mMaxSize.getValue(sizeLimit) && (array_len > sizeLimit)) {
+ std::stringstream stream;
+ stream << "Got array of size: " << array_len
+ << ", maximum allowed: " << sizeLimit;
+ std::string validation_info = stream.str();
+ report__->set_validation_info(validation_info);
+ return Errors::OUT_OF_RANGE;
+ }
+
+ for (size_t i = 0u; i < array_len; ++i) {
+ std::stringstream strVal;
+ strVal << i;
+ const Errors::eType result = mElementSchemaItem->validate(
+ Object.getElement(i), &report__->ReportSubobject(strVal.str()), MessageVersion);
+ if (Errors::OK != result) {
+ return result;
+ }
+ }
+ return Errors::OK;
+}
+
void CArraySchemaItem::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) {
+ const bool RemoveFakeParameters, const utils::SemanticVersion& MessageVersion) {
if (SmartType_Array == Object.getType()) {
for (size_t i = 0U; i < Object.length(); ++i) {
- mElementSchemaItem->applySchema(Object[i], RemoveFakeParameters);
+ mElementSchemaItem->applySchema(Object[i], RemoveFakeParameters, MessageVersion);
}
}
}
diff --git a/src/components/smart_objects/src/object_schema_item.cc b/src/components/smart_objects/src/object_schema_item.cc
index c79b97689d..bab952411b 100644
--- a/src/components/smart_objects/src/object_schema_item.cc
+++ b/src/components/smart_objects/src/object_schema_item.cc
@@ -33,6 +33,8 @@
#include <algorithm>
+#include <boost/algorithm/string.hpp>
+
#include "smart_objects/always_false_schema_item.h"
#include "smart_objects/smart_object.h"
@@ -48,8 +50,66 @@ CObjectSchemaItem::SMember::SMember()
: mSchemaItem(CAlwaysFalseSchemaItem::create()), mIsMandatory(true) {}
CObjectSchemaItem::SMember::SMember(const ISchemaItemPtr SchemaItem,
- const bool IsMandatory)
- : mSchemaItem(SchemaItem), mIsMandatory(IsMandatory) {}
+ const bool IsMandatory,
+ const std::string& Since,
+ const std::string& Until,
+ const bool IsDeprecated,
+ const bool IsRemoved)
+ : mSchemaItem(SchemaItem), mIsMandatory(IsMandatory) {
+
+ if (Since.size() > 0) {
+ utils::SemanticVersion since_struct;
+ std::vector<std::string> since_fields;
+ boost::split(since_fields, Since, boost::is_any_of("."));
+ if(since_fields.size() == 3) {
+ since_struct.major_version = atoi(since_fields[0].c_str());
+ since_struct.minor_version = atoi(since_fields[1].c_str());
+ since_struct.patch_version = atoi(since_fields[2].c_str());
+ mSince = since_struct;
+ }
+ }
+
+ if (Until.size() > 0) {
+ utils::SemanticVersion until_struct;
+ std::vector<std::string> until_fields;
+ boost::split(until_fields, Until, boost::is_any_of("."));
+ if(until_fields.size() == 3) {
+ until_struct.major_version = atoi(until_fields[0].c_str());
+ until_struct.minor_version = atoi(until_fields[1].c_str());
+ until_struct.patch_version = atoi(until_fields[2].c_str());
+ mUntil = until_struct;
+ }
+ }
+
+ mIsDeprecated = IsDeprecated;
+ mIsRemoved = IsRemoved;
+
+ }
+
+bool CObjectSchemaItem::SMember::CheckHistoryFieldVersion(const utils::SemanticVersion& MessageVersion) const {
+ if (MessageVersion.isValid()) {
+ if (mSince.is_initialized()) {
+ if (MessageVersion < mSince.get()) {
+ return false; //Msg version predates `since` field
+ } else {
+ if (mUntil.is_initialized() && (MessageVersion >= mUntil.get())) {
+ return false; //Msg version newer than `until` field
+ } else {
+ return true; //Mobile msg version falls within specified version range
+ }
+ }
+ }
+
+ if (mUntil.is_initialized() && (MessageVersion >= mUntil.get())) {
+ return false; //Msg version newer than `until` field
+ } else {
+ return true; //Mobile msg version falls within specified version range
+ }
+ }
+
+ printf("Final true of check history version\n");
+ return true; //Not enough version information. Default true.
+}
std::shared_ptr<CObjectSchemaItem> CObjectSchemaItem::create(
const Members& members) {
@@ -99,14 +159,52 @@ Errors::eType CObjectSchemaItem::validate(const SmartObject& object,
return Errors::OK;
}
+Errors::eType CObjectSchemaItem::validate(const SmartObject& object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ if (SmartType_Map != object.getType()) {
+ std::string validation_info = "Incorrect type, expected: " +
+ SmartObject::typeToString(SmartType_Map) +
+ ", got: " +
+ SmartObject::typeToString(object.getType());
+ report__->set_validation_info(validation_info);
+ return Errors::INVALID_VALUE;
+ }
+
+ std::set<std::string> object_keys = object.enumerate();
+
+ for (Members::const_iterator it = mMembers.begin(); it != mMembers.end();
+ ++it) {
+ const std::string& key = it->first;
+ const SMember& member = it->second;
+ printf("key: %s\n", key.c_str());
+ std::set<std::string>::const_iterator key_it = object_keys.find(key);
+ if (object_keys.end() == key_it) {
+ if (member.mIsMandatory && member.CheckHistoryFieldVersion(MessageVersion)) {
+ std::string validation_info = "Missing mandatory parameter: " + key;
+ report__->set_validation_info(validation_info);
+ return Errors::MISSING_MANDATORY_PARAMETER;
+ }
+ continue;
+ }
+ const SmartObject& field = object.getElement(key);
+ const Errors::eType result =
+ member.mSchemaItem->validate(field, &report__->ReportSubobject(key), MessageVersion);
+ if (Errors::OK != result) {
+ return result;
+ }
+ object_keys.erase(key_it);
+ }
+ return Errors::OK;
+}
+
void CObjectSchemaItem::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) {
+ const bool RemoveFakeParameters, const utils::SemanticVersion& MessageVersion) {
if (SmartType_Map != Object.getType()) {
return;
}
if (RemoveFakeParameters) {
- RemoveFakeParams(Object);
+ RemoveFakeParams(Object, MessageVersion);
}
SmartObject default_value;
@@ -117,10 +215,10 @@ void CObjectSchemaItem::applySchema(SmartObject& Object,
if (!Object.keyExists(key)) {
if (member.mSchemaItem->setDefaultValue(default_value)) {
Object[key] = default_value;
- member.mSchemaItem->applySchema(Object[key], RemoveFakeParameters);
+ member.mSchemaItem->applySchema(Object[key], RemoveFakeParameters, MessageVersion);
}
} else {
- member.mSchemaItem->applySchema(Object[key], RemoveFakeParameters);
+ member.mSchemaItem->applySchema(Object[key], RemoveFakeParameters, MessageVersion);
}
}
}
@@ -173,22 +271,30 @@ size_t CObjectSchemaItem::GetMemberSize() {
CObjectSchemaItem::CObjectSchemaItem(const Members& members)
: mMembers(members) {}
-void CObjectSchemaItem::RemoveFakeParams(SmartObject& Object) {
+void CObjectSchemaItem::RemoveFakeParams(SmartObject& Object, const utils::SemanticVersion& MessageVersion) {
for (SmartMap::const_iterator it = Object.map_begin();
it != Object.map_end();) {
const std::string& key = it->first;
- if (mMembers.end() == mMembers.find(key)
+ std::map<std::string, SMember>::const_iterator members_it = mMembers.find(key);
+ if (mMembers.end() == members_it
// FIXME(EZamakhov): Remove illegal usage of filed in AM
&&
key.compare(connection_key) != 0 && key.compare(binary_data) != 0 &&
key.compare(app_id) != 0) {
++it;
Object.erase(key);
+ } else if (members_it->second.mIsRemoved && members_it->second.CheckHistoryFieldVersion(MessageVersion)) {
+ ++it;
+ Object.erase(key);
} else {
it++;
}
}
}
+bool CObjectSchemaItem::IsMandatory(const SMember& member) {
+ return true;
+}
+
} // namespace NsSmartObjects
} // namespace NsSmartDeviceLink
diff --git a/src/components/smart_objects/src/schema_item.cc b/src/components/smart_objects/src/schema_item.cc
index 22735d40d5..685cd3a79f 100644
--- a/src/components/smart_objects/src/schema_item.cc
+++ b/src/components/smart_objects/src/schema_item.cc
@@ -44,6 +44,12 @@ Errors::eType ISchemaItem::validate(const SmartObject& object,
return Errors::ERROR;
}
+Errors::eType ISchemaItem::validate(const SmartObject& object,
+ rpc::ValidationReport* report__,
+ const utils::SemanticVersion& MessageVersion) {
+ return Errors::ERROR;
+}
+
bool ISchemaItem::setDefaultValue(SmartObject& Object) {
return false;
}
@@ -53,7 +59,7 @@ bool ISchemaItem::hasDefaultValue(SmartObject& Object) {
}
void ISchemaItem::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) {}
+ const bool RemoveFakeParameters, const utils::SemanticVersion& MessageVersion) {}
void ISchemaItem::unapplySchema(SmartObject& Object) {}
diff --git a/src/components/smart_objects/src/smart_object.cc b/src/components/smart_objects/src/smart_object.cc
index a0925eef05..a1d769dff7 100644
--- a/src/components/smart_objects/src/smart_object.cc
+++ b/src/components/smart_objects/src/smart_object.cc
@@ -882,6 +882,10 @@ Errors::eType SmartObject::validate(rpc::ValidationReport* report__) {
return m_schema.validate(*this, report__);
}
+Errors::eType SmartObject::validate(rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ return m_schema.validate(*this, report__, MessageVersion);
+}
+
void SmartObject::setSchema(const CSmartSchema& schema) {
m_schema = schema;
}
diff --git a/src/components/smart_objects/src/smart_schema.cc b/src/components/smart_objects/src/smart_schema.cc
index 7509ea80f1..7e2aaed974 100644
--- a/src/components/smart_objects/src/smart_schema.cc
+++ b/src/components/smart_objects/src/smart_schema.cc
@@ -50,13 +50,18 @@ Errors::eType CSmartSchema::validate(const SmartObject& object,
return mSchemaItem->validate(object, report__);
}
+Errors::eType CSmartSchema::validate(const SmartObject& object,
+ rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) const {
+ return mSchemaItem->validate(object, report__, MessageVersion);
+}
+
void CSmartSchema::setSchemaItem(const ISchemaItemPtr schemaItem) {
mSchemaItem = schemaItem;
}
void CSmartSchema::applySchema(SmartObject& Object,
- const bool RemoveFakeParameters) {
- mSchemaItem->applySchema(Object, RemoveFakeParameters);
+ const bool RemoveFakeParameters, const utils::SemanticVersion& MessageVersion) {
+ mSchemaItem->applySchema(Object, RemoveFakeParameters, MessageVersion);
}
void CSmartSchema::unapplySchema(SmartObject& Object) {
diff --git a/src/components/smart_objects/src/string_schema_item.cc b/src/components/smart_objects/src/string_schema_item.cc
index b403607ede..05ed196717 100644
--- a/src/components/smart_objects/src/string_schema_item.cc
+++ b/src/components/smart_objects/src/string_schema_item.cc
@@ -84,6 +84,11 @@ Errors::eType CStringSchemaItem::validate(const SmartObject& Object,
return Errors::OK;
}
+Errors::eType CStringSchemaItem::validate(
+ const SmartObject& Object, rpc::ValidationReport* report__, const utils::SemanticVersion& MessageVersion) {
+ return validate(Object, report__);
+}
+
SmartType CStringSchemaItem::getSmartType() const {
return SmartType_String;
}
diff --git a/tools/InterfaceGenerator/MsgVersionGenerate.py b/tools/InterfaceGenerator/MsgVersionGenerate.py
index 86251cd419..4a24a3239f 100644
--- a/tools/InterfaceGenerator/MsgVersionGenerate.py
+++ b/tools/InterfaceGenerator/MsgVersionGenerate.py
@@ -12,14 +12,25 @@ def generate_msg_version(file_name, path_to_storage):
"""
tree = xml.etree.ElementTree.parse(file_name)
root = tree.getroot()
- if (root.tag == "interface" and "version" in root.attrib):
+ if (root.tag == "interface" and "version" and "minVersion" in root.attrib):
check_version_format(root.attrib["version"])
array = (root.attrib["version"]).split(".")
major_version = array[0]
minor_version = array[1]
patch_version = array[2]
- if (major_version.isdigit() and minor_version.isdigit() and patch_version.isdigit):
- data_for_storage = prepare_data_for_storage(major_version, minor_version, patch_version)
+
+ check_minimum_version_format(root.attrib["minVersion"])
+ minimum_version_array = (root.attrib["minVersion"]).split(".")
+ if (len(minimum_version_array) == 2):
+ minimum_version_array.append("0")
+ minimum_major_version = minimum_version_array[0]
+ minimum_minor_version = minimum_version_array[1]
+ minimum_patch_version = minimum_version_array[2]
+
+ if (major_version.isdigit() and minor_version.isdigit() and patch_version.isdigit() and
+ minimum_major_version.isdigit() and minimum_minor_version.isdigit() and minimum_patch_version.isdigit()):
+ data_for_storage = prepare_data_for_storage(major_version, minor_version, patch_version,
+ minimum_major_version, minimum_minor_version, minimum_patch_version)
store_data_to_file(path_to_storage, data_for_storage)
else:
raise RPCBase.ParseError("Attribute version has incorect value in MOBILE_API.xml")
@@ -45,7 +56,16 @@ def check_version_format(version):
raise RPCBase.ParseError("Incorrect format of version please check MOBILE_API.xml. "
"Need format of version major_version.minor_version.patch_version")
-def prepare_data_for_storage(major_version, minor_version, patch_version):
+
+def check_minimum_version_format(version):
+ """Checks correctness of format of version
+ """
+ p = re.compile('\d+\\.\d+\\.\d+|\d+\\.\d+')
+ result = p.match(version)
+ if result == None or (result.end() != len(version)):
+ raise RPCBase.ParseError("Incorrect format of version please check MOBILE_API.xml. "
+ "Need format of minVersion major_version.minor_version or major_version.minor_version.patch_version")
+def prepare_data_for_storage(major_version, minor_version, patch_version, minimum_major_version, minimum_minor_version, minimum_patch_version):
"""Prepares data to store to file.
"""
temp = Template(
@@ -80,8 +100,12 @@ def prepare_data_for_storage(major_version, minor_version, patch_version):
u'''const uint16_t major_version = $m_version;\n'''
u'''const uint16_t minor_version = $min_version;\n'''
u'''const uint16_t patch_version = $p_version;\n'''
+ u'''const uint16_t minimum_major_version = $min_major_version;\n'''
+ u'''const uint16_t minimum_minor_version = $min_minor_version;\n'''
+ u'''const uint16_t minimum_patch_version = $min_patch_version;\n'''
u'''} // namespace application_manager\n'''
u'''#endif // GENERATED_MSG_VERSION_H''')
- data_to_file = temp.substitute(m_version = major_version, min_version = minor_version, p_version = patch_version)
+ data_to_file = temp.substitute(m_version = major_version, min_version = minor_version, p_version = patch_version,
+ min_major_version = minimum_major_version, min_minor_version = minimum_minor_version, min_patch_version = minimum_patch_version)
return data_to_file
diff --git a/tools/InterfaceGenerator/generator/Model.py b/tools/InterfaceGenerator/generator/Model.py
index ee458d934a..c4d2eca0bd 100755
--- a/tools/InterfaceGenerator/generator/Model.py
+++ b/tools/InterfaceGenerator/generator/Model.py
@@ -124,7 +124,8 @@ class InterfaceItemBase(object):
"""
def __init__(self, name, description=None, design_description=None,
- issues=None, todos=None, platform=None, default_value=None, scope=None):
+ issues=None, todos=None, platform=None, default_value=None, scope=None,
+ since=None, until=None, deprecated=None, removed=None):
self.name = name
self.description = description if description is not None else []
self.design_description = \
@@ -134,6 +135,10 @@ class InterfaceItemBase(object):
self.platform = platform
self.default_value = default_value
self.scope = scope
+ self.since = since
+ self.until = until
+ self.deprecated = deprecated
+ self.removed = removed
class EnumElement(InterfaceItemBase):
@@ -149,13 +154,18 @@ class EnumElement(InterfaceItemBase):
def __init__(self, name, description=None, design_description=None,
issues=None, todos=None, platform=None, internal_name=None,
- value=None):
+ value=None, since=None, until=None, deprecated=None, removed=None):
super(EnumElement, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
platform=platform)
self.internal_name = internal_name
self.value = value
+ self.since = since
+ self.until = until
+ self.deprecated = deprecated
+ self.removed = removed
+
@property
def primary_name(self):
@@ -180,7 +190,7 @@ class Enum(InterfaceItemBase):
def __init__(self, name, description=None, design_description=None,
issues=None, todos=None, platform=None, internal_scope=None,
- elements=None, scope=None):
+ elements=None, scope=None, since=None, until=None, deprecated=None, removed=None):
super(Enum, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
@@ -189,6 +199,10 @@ class Enum(InterfaceItemBase):
self.internal_scope = internal_scope
self.elements = \
elements if elements is not None else collections.OrderedDict()
+ self.since = since
+ self.until = until
+ self.deprecated = deprecated
+ self.removed = removed
class EnumSubset(InterfaceItemBase):
@@ -204,7 +218,7 @@ class EnumSubset(InterfaceItemBase):
def __init__(self, name, enum, description=None, design_description=None,
issues=None, todos=None, platform=None,
- allowed_elements=None):
+ allowed_elements=None, since=None, until=None, deprecated=None, removed=None):
super(EnumSubset, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
@@ -213,6 +227,10 @@ class EnumSubset(InterfaceItemBase):
self.enum = enum
self.allowed_elements = \
allowed_elements if allowed_elements is not None else {}
+ self.since = since
+ self.until = until
+ self.deprecated = deprecated
+ self.removed = removed
class Param(InterfaceItemBase):
@@ -229,7 +247,8 @@ class Param(InterfaceItemBase):
def __init__(self, name, param_type, description=None,
design_description=None, issues=None, todos=None,
- platform=None, is_mandatory=True, default_value=None, scope=None):
+ platform=None, is_mandatory=True, default_value=None, scope=None,
+ since=None, until=None, deprecated=None, removed=None):
super(Param, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
@@ -238,6 +257,10 @@ class Param(InterfaceItemBase):
self.is_mandatory = is_mandatory
self.param_type = param_type
self.default_value = default_value
+ self.since = since
+ self.until = until
+ self.deprecated = deprecated
+ self.removed=removed
class FunctionParam(Param):
@@ -251,11 +274,13 @@ class FunctionParam(Param):
def __init__(self, name, param_type, description=None,
design_description=None, issues=None, todos=None,
- platform=None, is_mandatory=True, default_value=None, scope=None):
+ platform=None, is_mandatory=True, default_value=None, scope=None,
+ since=None, until=None, deprecated=None, removed=None):
super(FunctionParam, self).__init__(
name, param_type=param_type, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform, is_mandatory=is_mandatory, default_value=default_value, scope=scope)
+ platform=platform, is_mandatory=is_mandatory, default_value=default_value,
+ scope=scope, since=since, until=until, deprecated=deprecated, removed=removed)
self.default_value = default_value
@@ -270,12 +295,15 @@ class Struct(InterfaceItemBase):
"""
def __init__(self, name, description=None, design_description=None,
- issues=None, todos=None, platform=None, members=None, scope=None):
+ issues=None, todos=None, platform=None, members=None, scope=None,
+ since=None, until=None, deprecated=None, removed=None):
super(Struct, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform, scope=scope)
+ platform=platform, scope=scope, since=since, until=until,
+ deprecated=deprecated, removed=removed)
+ print since
self.members = \
members if members is not None else collections.OrderedDict()
@@ -293,11 +321,11 @@ class Function(InterfaceItemBase):
def __init__(self, name, function_id, message_type, description=None,
design_description=None, issues=None, todos=None,
- platform=None, params=None, scope=None):
+ platform=None, params=None, scope=None, since=None, until=None, deprecated=None, removed=None):
super(Function, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform, scope=scope)
+ platform=platform, scope=scope, since=None, until=None, deprecated=None, removed=None)
self.function_id = function_id
self.message_type = message_type
diff --git a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
index 0c500dee8e..05dd939ad0 100755
--- a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
+++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
@@ -505,7 +505,8 @@ class CodeGenerator(object):
String with structs implementation source code.
"""
-
+ #print struct.name
+ #print struct.since
processed_enums = []
return self._struct_impl_template.substitute(
namespace=namespace,
@@ -518,7 +519,7 @@ class CodeGenerator(object):
schema_items_decl=self._gen_schema_items_decls(
struct.members.values()),
schema_item_fill=self._gen_schema_items_fill(
- struct.members.values())),
+ struct.members.values(), struct.since, struct.until, struct.deprecated, struct.removed)),
1))
def _gen_schema_loc_decls(self, members, processed_enums):
@@ -746,7 +747,7 @@ class CodeGenerator(object):
return result
- def _gen_schema_items_fill(self, members):
+ def _gen_schema_items_fill(self, members=None, since=None, until=None, deprecated=None, removed=None):
"""Generate schema items fill code.
Generates source code that fills new schema with items.
@@ -760,7 +761,7 @@ class CodeGenerator(object):
"""
result = u"\n".join(
- [self._gen_schema_item_fill(x) for x in members])
+ [self._gen_schema_item_fill(x, since, until, deprecated, removed) for x in members])
return u"".join([result, u"\n\n"]) if result else u""
@@ -781,7 +782,7 @@ class CodeGenerator(object):
raise GenerateError("Unexpected call to the unimplemented function.")
- def _gen_schema_item_fill(self, member):
+ def _gen_schema_item_fill(self, member, since, until, deprecated, removed):
"""Generate schema item fill code.
Generates source code that fills new schema with item.
@@ -793,11 +794,29 @@ class CodeGenerator(object):
String with schema item fill code.
"""
-
- return self._impl_code_item_fill_template.substitute(
- name=member.name,
- var_name=self._gen_schema_item_var_name(member),
- is_mandatory=u"true" if member.is_mandatory is True else u"false")
+ #print(member.since)
+ #print member.name
+ if (since is not None or
+ until is not None or
+ deprecated is not None or
+ removed is not None or
+ member.since is not None or
+ member.until is not None or
+ member.deprecated is not None or
+ member.removed is not None):
+ return self._impl_code_item_fill_template_with_version.substitute(
+ name=member.name,
+ var_name=self._gen_schema_item_var_name(member),
+ is_mandatory=u"true" if member.is_mandatory is True else u"false",
+ since=member.since if member.since is not None else since if since is not None else "",
+ until=member.until if member.until is not None else until if until is not None else "",
+ deprecated=member.deprecated if member.deprecated is not None else deprecated if deprecated is not None else u"false",
+ removed=member.removed if member.removed is not None else removed if removed is not None else u"false")
+ else:
+ return self._impl_code_item_fill_template.substitute(
+ name=member.name,
+ var_name=self._gen_schema_item_var_name(member),
+ is_mandatory=u"true" if member.is_mandatory is True else u"false")
@staticmethod
def _gen_schema_item_var_name(member):
@@ -899,7 +918,7 @@ class CodeGenerator(object):
schema_items_decl=self._gen_schema_items_decls(
function.params.values()),
schema_item_fill=self._gen_schema_items_fill(
- function.params.values()),
+ function.params.values(), function.since, function.until, function.deprecated, function.removed),
schema_params_fill=self._gen_schema_params_fill(
function.message_type.name)),
1))
@@ -1531,6 +1550,10 @@ class CodeGenerator(object):
u'''schema_members["${name}"] = CObjectSchemaItem::'''
u'''SMember(${var_name}, ${is_mandatory});''')
+ _impl_code_item_fill_template_with_version = string.Template(
+ u'''schema_members["${name}"] = CObjectSchemaItem::'''
+ u'''SMember(${var_name}, ${is_mandatory}, "${since}", "${until}", ${deprecated}, ${removed});''')
+
_function_impl_template = string.Template(
u'''CSmartSchema $namespace::$class_name::'''
u'''InitFunction_${function_id}_${message_type}(\n'''
diff --git a/tools/InterfaceGenerator/generator/parsers/RPCBase.py b/tools/InterfaceGenerator/generator/parsers/RPCBase.py
index 4853916dad..d3e103ce7a 100755
--- a/tools/InterfaceGenerator/generator/parsers/RPCBase.py
+++ b/tools/InterfaceGenerator/generator/parsers/RPCBase.py
@@ -6,7 +6,7 @@ Contains base parser for SDLRPC v1/v2 and JSON RPC XML format.
import collections
import xml.etree.ElementTree
-
+import re
from generator import Model
@@ -203,16 +203,35 @@ class Parser(object):
internal_scope = None
scope = None
+ since = None
+ until = None
+ deprecated = None
+ removed = None
+ result = None
for attribute in attributes:
if attribute == "internal_scope":
internal_scope = attributes[attribute]
elif attribute == "scope":
scope = attributes[attribute]
+ elif attribute == "since":
+ result = self._parse_version(attributes[attribute])
+ since = result
+ elif attribute == "until":
+ result = self._parse_version(attributes[attribute])
+ until = result
+ elif attribute == "deprecated":
+ deprecated = attributes[attribute]
+ elif attribute == "removed":
+ removed = attributes[attribute]
else:
raise ParseError("Unexpected attribute '" + attribute +
"' in enum '" + params["name"] + "'")
params["internal_scope"] = internal_scope
params["scope"] = scope
+ params["since"] = since
+ params["until"] = until
+ params["deprecated"] = deprecated
+ params["removed"] = removed
elements = collections.OrderedDict()
for subelement in subelements:
@@ -236,13 +255,32 @@ class Parser(object):
params, subelements, attrib = self._parse_base_item(element, prefix)
scope = None
+ since = None
+ until = None
+ deprecated = None
+ removed = None
+ result = None
for attribute in attrib:
if attribute == "scope":
scope = attrib[attribute]
+ elif attribute == "since":
+ result = self._parse_version(attrib[attribute])
+ since = result
+ elif attribute == "until":
+ result = self._parse_version(attrib[attribute])
+ until = result
+ elif attribute == "deprecated":
+ deprecated = attributes[attribute]
+ elif attribute == "removed":
+ removed = attrib[attribute]
else:
raise ParseError("Unexpected attribute '" + attribute +
"' in struct '" + params["name"] + "'")
params["scope"] = scope
+ params["since"] = since
+ params["until"] = until
+ params["deprecated"] = deprecated
+ params["removed"] = removed
members = collections.OrderedDict()
for subelement in subelements:
@@ -271,13 +309,32 @@ class Parser(object):
attributes)
scope = None
+ since = None
+ until = None
+ deprecated = None
+ removed = None
+ result = None
for attribute in attributes:
if attribute == "scope":
scope = attributes[attribute]
+ elif attribute == "since":
+ result = self._parse_version(attributes[attribute])
+ since = result
+ elif attribute == "until":
+ result = self._parse_version(attributes[attribute])
+ until = result
+ elif attribute == "deprecated":
+ deprecated = attributes[attribute]
+ elif attribute == "removed":
+ removed = attributes[attribute]
params["function_id"] = function_id
params["message_type"] = message_type
params["scope"] = scope
+ params["since"] = since
+ params["until"] = until
+ params["deprecated"] = deprecated
+ params["removed"] = removed
function_params = collections.OrderedDict()
for subelement in subelements:
@@ -443,6 +500,11 @@ class Parser(object):
internal_name = None
value = None
+ since = None
+ until = None
+ deprecated = None
+ removed = None
+ result = None
for attribute in attributes:
if attribute == "internal_name":
internal_name = attributes[attribute]
@@ -452,9 +514,22 @@ class Parser(object):
except:
raise ParseError("Invalid value for enum element: '" +
attributes[attribute] + "'")
+ elif attribute == "since":
+ result = self._parse_version(attributes[attribute])
+ since = result
+ elif attribute == "until":
+ result = self._parse_version(attributes[attribute])
+ until = result
+ elif attribute == "deprecated":
+ deprecated = attributes[attribute]
+ elif attribute == "removed":
+ removed = attributes[attribute]
params["internal_name"] = internal_name
params["value"] = value
-
+ params["since"] = since
+ params["until"] = until
+ params["deprecated"] = deprecated
+ params["removed"] = removed
# Magic usage is correct
# pylint: disable=W0142
return Model.EnumElement(**params)
@@ -548,6 +623,27 @@ class Parser(object):
"""
params, subelements, attrib = self._parse_base_item(element, "")
+ since_version = self._extract_attrib(attrib, "since")
+ if since_version is not None:
+ result = self._parse_version(since_version)
+ params["since"] = result
+
+ until_version = self._extract_attrib(attrib, "until")
+ if until_version is not None:
+ result = self._parse_version(until_version)
+ params["until"] = result
+
+ deprecated = self._extract_attrib(attrib, "deprecated")
+ if deprecated is not None:
+ params["deprecated"] = deprecated
+
+ removed = self._extract_attrib(attrib, "removed")
+ if removed is not None:
+ params["removed"] = removed
+ print("FOUND REMOVED!!!!!")
+ print(params["name"])
+
+
is_mandatory = self._extract_attrib(attrib, "mandatory")
if is_mandatory is None:
raise ParseError("'mandatory' is not specified for parameter '" +
@@ -765,3 +861,22 @@ class Parser(object):
print ("Ignoring attribute '" +
name + "'")
return True
+
+ def _parse_version(self, version):
+ """
+ Validates if a version supplied is in the correct
+ format of Major.Minor.Patch. If Major.Minor format
+ is supplied, a patch version of 0 will be added to
+ the end.
+ """
+ p = re.compile('\d+\\.\d+\\.\d+|\d+\\.\d+')
+ result = p.match(version)
+ if result == None or (result.end() != len(version)):
+ raise RPCBase.ParseError("Incorrect format of version please check MOBILE_API.xml. "
+ "Need format of major_version.minor_version or major_version.minor_version.patch_version")
+
+ version_array = version.split(".")
+ if (len(version_array) == 2):
+ version_array.append("0")
+ dot_str = "."
+ return dot_str.join(version_array)