summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJackLivio <jack@livio.io>2018-08-03 15:01:42 -0400
committerJackLivio <jack@livio.io>2018-08-03 15:01:42 -0400
commitcbb261bb92c6b8e156bdcf690ee77ee00bd0adf9 (patch)
tree23d406f36bfa889c4ff95d6ae35f5022218e1ef0
parentfb751ab2cfd3c41c92c81af677756ebc75a7c1c8 (diff)
downloadsdl_core-cbb261bb92c6b8e156bdcf690ee77ee00bd0adf9.tar.gz
Add support for struct param history
-rw-r--r--src/components/smart_objects/include/smart_objects/object_schema_item.h4
-rw-r--r--src/components/smart_objects/src/object_schema_item.cc46
-rwxr-xr-xtools/InterfaceGenerator/generator/Model.py31
-rwxr-xr-xtools/InterfaceGenerator/generator/generators/SmartFactoryBase.py118
-rwxr-xr-xtools/InterfaceGenerator/generator/parsers/RPCBase.py42
5 files changed, 202 insertions, 39 deletions
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 df5a34a25a..8ff51d302a 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
@@ -71,7 +71,8 @@ class CObjectSchemaItem : public ISchemaItem {
const std::string& Since = "",
const std::string& Until = "",
const bool IsDeprecated = false,
- const bool IsRemoved = false);
+ const bool IsRemoved = false,
+ const std::vector<CObjectSchemaItem::SMember>& history_vector = {});
/**
* @brief Checks the version a parameter was removed (until)
* If the mobile's msg version is greater than or
@@ -90,6 +91,7 @@ class CObjectSchemaItem : public ISchemaItem {
boost::optional<utils::SemanticVersion> mUntil;
bool mIsDeprecated;
bool mIsRemoved;
+ std::vector<CObjectSchemaItem::SMember> mHistoryVector;
};
typedef std::map<std::string, SMember> Members;
diff --git a/src/components/smart_objects/src/object_schema_item.cc b/src/components/smart_objects/src/object_schema_item.cc
index bab952411b..c17a2221db 100644
--- a/src/components/smart_objects/src/object_schema_item.cc
+++ b/src/components/smart_objects/src/object_schema_item.cc
@@ -54,7 +54,8 @@ CObjectSchemaItem::SMember::SMember(const ISchemaItemPtr SchemaItem,
const std::string& Since,
const std::string& Until,
const bool IsDeprecated,
- const bool IsRemoved)
+ const bool IsRemoved,
+ const std::vector<CObjectSchemaItem::SMember>& history_vector)
: mSchemaItem(SchemaItem), mIsMandatory(IsMandatory) {
if (Since.size() > 0) {
@@ -83,6 +84,7 @@ CObjectSchemaItem::SMember::SMember(const ISchemaItemPtr SchemaItem,
mIsDeprecated = IsDeprecated;
mIsRemoved = IsRemoved;
+ mHistoryVector = history_vector;
}
@@ -107,7 +109,6 @@ bool CObjectSchemaItem::SMember::CheckHistoryFieldVersion(const utils::SemanticV
}
}
- printf("Final true of check history version\n");
return true; //Not enough version information. Default true.
}
@@ -176,10 +177,33 @@ Errors::eType CObjectSchemaItem::validate(const SmartObject& object,
++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)) {
+ if(member.mSince.is_initialized() && MessageVersion < member.mSince.get() && member.mHistoryVector.size() > 0) {
+ //Message version predates parameter and a history vector exists.
+ for (uint i=0; i<member.mHistoryVector.size(); i++) {
+ if (member.mHistoryVector[i].mSince.is_initialized() && MessageVersion >= member.mHistoryVector[i].mSince.get()) {
+ if (member.mHistoryVector[i].mUntil.is_initialized() && MessageVersion >= member.mHistoryVector[i].mUntil.get()) {
+ //MessageVersion is newer than the specified "Until" version
+ continue;
+ } else {
+ if (member.mHistoryVector[i].mIsMandatory == true && (member.mHistoryVector[i].mIsRemoved == false)) {
+ std::string validation_info = "Missing mandatory parameter since and until: " + key;
+ report__->set_validation_info(validation_info);
+ return Errors::MISSING_MANDATORY_PARAMETER;
+ }
+ break;
+ }
+ } else if (member.mHistoryVector[i].mSince.is_initialized() == false && member.mHistoryVector[i].mUntil.is_initialized() && MessageVersion < member.mHistoryVector[i].mUntil.get()){
+ if (member.mHistoryVector[i].mIsMandatory == true && (member.mHistoryVector[i].mIsRemoved == false)) {
+ std::string validation_info = "Missing mandatory parameter until: " + key;
+ report__->set_validation_info(validation_info);
+ return Errors::MISSING_MANDATORY_PARAMETER;
+ }
+ break;
+ }
+ }
+ } else if (member.mIsMandatory && member.CheckHistoryFieldVersion(MessageVersion) && (member.mIsMandatory == false)) {
std::string validation_info = "Missing mandatory parameter: " + key;
report__->set_validation_info(validation_info);
return Errors::MISSING_MANDATORY_PARAMETER;
@@ -286,8 +310,18 @@ void CObjectSchemaItem::RemoveFakeParams(SmartObject& Object, const utils::Seman
} else if (members_it->second.mIsRemoved && members_it->second.CheckHistoryFieldVersion(MessageVersion)) {
++it;
Object.erase(key);
- } else {
- it++;
+ } else if (members_it->second.mHistoryVector.size() > 0) {
+ for (uint i=0; i<members_it->second.mHistoryVector.size(); i++) {
+ if (members_it->second.mHistoryVector[i].CheckHistoryFieldVersion(MessageVersion) && members_it->second.mHistoryVector[i].mIsRemoved) {
+ ++it;
+ Object.erase(key);
+ break;
+ }
+ }
+ ++it;
+ }
+ else {
+ ++it;
}
}
}
diff --git a/tools/InterfaceGenerator/generator/Model.py b/tools/InterfaceGenerator/generator/Model.py
index c4d2eca0bd..827553bda2 100755
--- a/tools/InterfaceGenerator/generator/Model.py
+++ b/tools/InterfaceGenerator/generator/Model.py
@@ -125,7 +125,7 @@ class InterfaceItemBase(object):
def __init__(self, name, description=None, design_description=None,
issues=None, todos=None, platform=None, default_value=None, scope=None,
- since=None, until=None, deprecated=None, removed=None):
+ since=None, until=None, deprecated=None, removed=None, history=None):
self.name = name
self.description = description if description is not None else []
self.design_description = \
@@ -139,6 +139,7 @@ class InterfaceItemBase(object):
self.until = until
self.deprecated = deprecated
self.removed = removed
+ self.history = history
class EnumElement(InterfaceItemBase):
@@ -154,11 +155,11 @@ class EnumElement(InterfaceItemBase):
def __init__(self, name, description=None, design_description=None,
issues=None, todos=None, platform=None, internal_name=None,
- value=None, since=None, until=None, deprecated=None, removed=None):
+ value=None, since=None, until=None, deprecated=None, removed=None, history=None):
super(EnumElement, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform)
+ platform=platform, history=history)
self.internal_name = internal_name
self.value = value
self.since = since
@@ -190,11 +191,11 @@ 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, since=None, until=None, deprecated=None, removed=None):
+ elements=None, scope=None, since=None, until=None, deprecated=None, removed=None, history=None):
super(Enum, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform, scope=scope)
+ platform=platform, scope=scope, history=history)
self.internal_scope = internal_scope
self.elements = \
@@ -218,11 +219,11 @@ class EnumSubset(InterfaceItemBase):
def __init__(self, name, enum, description=None, design_description=None,
issues=None, todos=None, platform=None,
- allowed_elements=None, since=None, until=None, deprecated=None, removed=None):
+ allowed_elements=None, since=None, until=None, deprecated=None, removed=None, history=None):
super(EnumSubset, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform)
+ platform=platform, history=history)
self.enum = enum
self.allowed_elements = \
@@ -248,11 +249,11 @@ 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,
- since=None, until=None, deprecated=None, removed=None):
+ since=None, until=None, deprecated=None, removed=None, history=None):
super(Param, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform, default_value=default_value, scope=scope)
+ platform=platform, default_value=default_value, scope=scope, history=history)
self.is_mandatory = is_mandatory
self.param_type = param_type
@@ -275,12 +276,12 @@ 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,
- since=None, until=None, deprecated=None, removed=None):
+ since=None, until=None, deprecated=None, removed=None, history=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, since=since, until=until, deprecated=deprecated, removed=removed)
+ scope=scope, since=since, until=until, deprecated=deprecated, removed=removed, history=history)
self.default_value = default_value
@@ -296,12 +297,12 @@ class Struct(InterfaceItemBase):
def __init__(self, name, description=None, design_description=None,
issues=None, todos=None, platform=None, members=None, scope=None,
- since=None, until=None, deprecated=None, removed=None):
+ since=None, until=None, deprecated=None, removed=None, history=None):
super(Struct, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
platform=platform, scope=scope, since=since, until=until,
- deprecated=deprecated, removed=removed)
+ deprecated=deprecated, removed=removed, history=history)
print since
self.members = \
@@ -321,11 +322,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, since=None, until=None, deprecated=None, removed=None):
+ platform=None, params=None, scope=None, since=None, until=None, deprecated=None, removed=None, history=None):
super(Function, self).__init__(
name, description=description,
design_description=design_description, issues=issues, todos=todos,
- platform=platform, scope=scope, since=None, until=None, deprecated=None, removed=None)
+ platform=platform, scope=scope, since=since, until=until, deprecated=deprecated, removed=removed, history=history)
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 05dd939ad0..65359fe54e 100755
--- a/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
+++ b/tools/InterfaceGenerator/generator/generators/SmartFactoryBase.py
@@ -600,10 +600,43 @@ class CodeGenerator(object):
"""
- result = u"\n\n".join(
- [self._gen_schema_item_decl(x) for x in members])
+ result_array = []
+ for x in members:
+ result_array.append(self._gen_schema_item_decl(x))
+ count = 0
+ if x.history is not None:
+ history_list = x.history
+ for item in history_list:
+ item.name += "_history_v" + str(len(history_list)-count)
+ result_array.append(self._gen_schema_item_decl(item))
+ count += 1
+ result_array.append(self._gen_history_vector_decl(history_list, x.name))
+
+ result = u"\n\n".join(result_array)
+ return result
+
+ def _gen_history_vector_decl(self, history_list, name):
+ """Generate History Vector Declaration.
+
+ Generates the declaration and initialization
+ of a vector of schema items
+
+ Arguments:
+ history_list -> list of history items
+ name -> name of parent parameter name
+
+ Returns:
+ String with history array code.
+ """
+ result_array = []
+ result_array.append(self._impl_code_shared_ptr_vector_template.substitute(var_name = name))
+ '''for item in history_list:
+ result_array.append(self._impl_code_append_history_vector_template.substitute(vector_name=name, item_name=item.name))
+'''
+ result = u"\n".join(result_array)
+ return result
+
- return u"".join([result, u"\n\n"]) if result else u""
def _gen_schema_item_decl(self, member):
"""Generate schema item declaration.
@@ -759,10 +792,16 @@ class CodeGenerator(object):
String with function schema items fill code.
"""
-
- result = u"\n".join(
- [self._gen_schema_item_fill(x, since, until, deprecated, removed) for x in members])
-
+ result_array = []
+ for x in members:
+ #If history, create Smember History vector first
+ if x.history is not None:
+ history_list = x.history
+ for item in history_list:
+ result_array.append(self._gen_history_vector_item_fill(item, x.name))
+ result_array.append(self._gen_schema_item_fill(x, since, until, deprecated, removed))
+
+ result = u"\n".join(result_array)
return u"".join([result, u"\n\n"]) if result else u""
def _gen_schema_params_fill(self, message_type_name):
@@ -804,20 +843,59 @@ class CodeGenerator(object):
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")
+ if member.history is not None:
+ return self._impl_code_item_fill_template_with_version_and_history_vector.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",
+ vector_name=member.name)
+ else:
+ 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")
+ def _gen_history_vector_item_fill(self, member, vector_name):
+ """Generate schema item fill code.
+
+ Generates source code that fills history vector with item.
+
+ Keyword arguments:
+ member -- struct member/function parameter to process.
+
+ Returns:
+ String with schema item fill code.
+
+ """
+
+ if (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_append_history_vector_template.substitute(
+ vector_name=vector_name,
+ name=member.name,
+ mandatory=u"true" if member.is_mandatory is True else u"false",
+ since=member.since if member.since is not None else "",
+ until=member.until if member.until is not None else "",
+ deprecated=member.deprecated if member.deprecated is not None else u"false",
+ removed=member.removed if member.removed is not None else u"false")
+ else:
+ print "Warning! History item does not have any version history. Omitting %s" % member.name
+
@staticmethod
def _gen_schema_item_var_name(member):
"""Generate schema item variable name.
@@ -1524,6 +1602,12 @@ class CodeGenerator(object):
u'''${comment}'''
u'''std::shared_ptr<ISchemaItem> ${var_name} = ${item_decl};''')
+ _impl_code_shared_ptr_vector_template = string.Template(
+ u'''std::vector<CObjectSchemaItem::SMember> ${var_name}_history_vector;''')
+
+ _impl_code_append_history_vector_template = string.Template(
+ u'''${vector_name}_history_vector.push_back(CObjectSchemaItem::SMember(${name}_SchemaItem, ${mandatory}, "${since}", "${until}", ${deprecated}, ${removed}));''')
+
_impl_code_integer_item_template = string.Template(
u'''TNumberSchemaItem<${type}>::create(${params})''')
@@ -1554,6 +1638,10 @@ class CodeGenerator(object):
u'''schema_members["${name}"] = CObjectSchemaItem::'''
u'''SMember(${var_name}, ${is_mandatory}, "${since}", "${until}", ${deprecated}, ${removed});''')
+ _impl_code_item_fill_template_with_version_and_history_vector = string.Template(
+ u'''schema_members["${name}"] = CObjectSchemaItem::'''
+ u'''SMember(${var_name}, ${is_mandatory}, "${since}", "${until}", ${deprecated}, ${removed}, ${vector_name}_history_vector);''')
+
_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 d3e103ce7a..c587a97b3a 100755
--- a/tools/InterfaceGenerator/generator/parsers/RPCBase.py
+++ b/tools/InterfaceGenerator/generator/parsers/RPCBase.py
@@ -416,6 +416,8 @@ class Parser(object):
issues = []
todos = []
subelements = []
+ history = None
+ warnings = []
if "name" not in element.attrib:
raise ParseError("Name is not specified for " + element.tag)
@@ -436,6 +438,12 @@ class Parser(object):
todos.append(self._parse_simple_element(subelement))
elif subelement.tag == "issue":
issues.append(self._parse_issue(subelement))
+ elif subelement.tag == "history":
+ if history is not None:
+ raise ParseError("Elements can only have one history tag: " + element.tag)
+ history = self._parse_history(subelement, prefix, element)
+ elif subelement.tag == "warning":
+ warnings.append(self._parse_warning(subelement))
else:
subelements.append(subelement)
@@ -443,6 +451,7 @@ class Parser(object):
params["design_description"] = design_description
params["issues"] = issues
params["todos"] = todos
+ params["history"] = history
return params, subelements, attrib
@@ -640,8 +649,6 @@ class Parser(object):
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")
@@ -880,3 +887,34 @@ class Parser(object):
version_array.append("0")
dot_str = "."
return dot_str.join(version_array)
+
+ def _parse_history(self, history, prefix, parent):
+ print "Pare History of Size: %d" % len(history)
+ if history.tag != "history":
+ raise ParseError("Invalid history tag: " + interface.tag)
+
+ items = []
+
+ for subelement in history:
+ if subelement.tag == "enum" and parent.tag == "enum":
+ items.append(self._parse_enum(subelement, prefix))
+ elif subelement.tag == "element" and parent.tag == "element":
+ items.append(self._parse_enum_element(subelement))
+ elif subelement.tag == "description" and parent.tag == "description":
+ items.append(self._parse_simple_element(subelement))
+ elif subelement.tag == "struct" and parent.tag == "struct":
+ items.append(self._parse_struct(subelement, prefix))
+ elif subelement.tag == "param" and parent.tag == "param":
+ items.append(self._parse_function_param(subelement, prefix))
+ elif subelement.tag == "function" and parent.tag == "function":
+ items.append(self.__parse_function(subelement, prefix))
+ else:
+ print subelement.tag
+ print parent.tag
+ raise ParseError("A history tag must be nested within the element it notes the history for. Fix item: '" +
+ parent.attrib["name"] + "'")
+
+ return items
+ def _parse_warning(self, warning):
+ print "Parse warning"
+