Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

make id_shorts optional #130

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions basyx/aas/adapter/json/json_deserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,8 @@ def _amend_abstract_attributes(cls, obj: object, dct: Dict[str, object]) -> None
:param dct: The object's dict representation from JSON
"""
if isinstance(obj, model.Referable):
if 'idShort' in dct:
obj.id_short = _get_ts(dct, 'idShort', str)
if 'category' in dct:
obj.category = _get_ts(dct, 'category', str)
if 'displayName' in dct:
Expand All @@ -242,8 +244,6 @@ def _amend_abstract_attributes(cls, obj: object, dct: Dict[str, object]) -> None
obj.description = cls._construct_lang_string_set(_get_ts(dct, 'description', list),
model.MultiLanguageTextType)
if isinstance(obj, model.Identifiable):
if 'idShort' in dct:
obj.id_short = _get_ts(dct, 'idShort', str)
if 'administration' in dct:
obj.administration = cls._construct_administrative_information(_get_ts(dct, 'administration', dict))
if isinstance(obj, model.HasSemantics):
Expand Down Expand Up @@ -536,7 +536,7 @@ def _construct_entity(cls, dct: Dict[str, object], object_class=model.Entity) ->
if 'specificAssetIds' in dct:
specific_asset_id = cls._construct_specific_asset_id(_get_ts(dct, 'specificAssetIds', dict))

ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
entity_type=ENTITY_TYPES_INVERSE[_get_ts(dct, "entityType", str)],
global_asset_id=global_asset_id,
specific_asset_id=specific_asset_id)
Expand Down Expand Up @@ -586,7 +586,7 @@ def _construct_submodel(cls, dct: Dict[str, object], object_class=model.Submodel

@classmethod
def _construct_capability(cls, dct: Dict[str, object], object_class=model.Capability) -> model.Capability:
ret = object_class(id_short=_get_ts(dct, "idShort", str))
ret = object_class(id_short=None)
cls._amend_abstract_attributes(ret, dct)
return ret

Expand All @@ -595,7 +595,7 @@ def _construct_basic_event_element(cls, dct: Dict[str, object], object_class=mod
-> model.BasicEventElement:
# TODO: remove the following type: ignore comments when mypy supports abstract types for Type[T]
# see https://github.com/python/mypy/issues/5374
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
observed=cls._construct_model_reference(_get_ts(dct, 'observed', dict),
model.Referable), # type: ignore
direction=DIRECTION_INVERSE[_get_ts(dct, "direction", str)],
Expand All @@ -615,7 +615,7 @@ def _construct_basic_event_element(cls, dct: Dict[str, object], object_class=mod

@classmethod
def _construct_operation(cls, dct: Dict[str, object], object_class=model.Operation) -> model.Operation:
ret = object_class(_get_ts(dct, "idShort", str))
ret = object_class(None)
cls._amend_abstract_attributes(ret, dct)

# Deserialize variables (they are not Referable, thus we don't
Expand All @@ -640,7 +640,7 @@ def _construct_relationship_element(
cls, dct: Dict[str, object], object_class=model.RelationshipElement) -> model.RelationshipElement:
# TODO: remove the following type: ignore comments when mypy supports abstract types for Type[T]
# see https://github.com/python/mypy/issues/5374
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
first=cls._construct_reference(_get_ts(dct, 'first', dict)),
second=cls._construct_reference(_get_ts(dct, 'second', dict)))
cls._amend_abstract_attributes(ret, dct)
Expand All @@ -653,7 +653,7 @@ def _construct_annotated_relationship_element(
# TODO: remove the following type: ignore comments when mypy supports abstract types for Type[T]
# see https://github.com/python/mypy/issues/5374
ret = object_class(
id_short=_get_ts(dct, "idShort", str),
id_short=None,
first=cls._construct_reference(_get_ts(dct, 'first', dict)),
second=cls._construct_reference(_get_ts(dct, 'second', dict)))
cls._amend_abstract_attributes(ret, dct)
Expand All @@ -667,7 +667,7 @@ def _construct_annotated_relationship_element(
def _construct_submodel_element_collection(cls, dct: Dict[str, object],
object_class=model.SubmodelElementCollection)\
-> model.SubmodelElementCollection:
ret = object_class(id_short=_get_ts(dct, "idShort", str))
ret = object_class(id_short=None)
cls._amend_abstract_attributes(ret, dct)
if not cls.stripped and 'value' in dct:
for element in _get_ts(dct, "value", list):
Expand All @@ -688,7 +688,7 @@ def _construct_submodel_element_list(cls, dct: Dict[str, object], object_class=m
if 'semanticIdListElement' in dct else None
value_type_list_element = model.datatypes.XSD_TYPE_CLASSES[_get_ts(dct, 'valueTypeListElement', str)]\
if 'valueTypeListElement' in dct else None
ret = object_class(id_short=_get_ts(dct, 'idShort', str),
ret = object_class(id_short=None,
type_value_list_element=type_value_list_element,
order_relevant=order_relevant,
semantic_id_list_element=semantic_id_list_element,
Expand All @@ -702,7 +702,7 @@ def _construct_submodel_element_list(cls, dct: Dict[str, object], object_class=m

@classmethod
def _construct_blob(cls, dct: Dict[str, object], object_class=model.Blob) -> model.Blob:
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
content_type=_get_ts(dct, "contentType", str))
cls._amend_abstract_attributes(ret, dct)
if 'value' in dct:
Expand All @@ -711,7 +711,7 @@ def _construct_blob(cls, dct: Dict[str, object], object_class=model.Blob) -> mod

@classmethod
def _construct_file(cls, dct: Dict[str, object], object_class=model.File) -> model.File:
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
value=None,
content_type=_get_ts(dct, "contentType", str))
cls._amend_abstract_attributes(ret, dct)
Expand All @@ -730,7 +730,7 @@ def _construct_resource(cls, dct: Dict[str, object], object_class=model.Resource
@classmethod
def _construct_multi_language_property(
cls, dct: Dict[str, object], object_class=model.MultiLanguageProperty) -> model.MultiLanguageProperty:
ret = object_class(id_short=_get_ts(dct, "idShort", str))
ret = object_class(id_short=None)
cls._amend_abstract_attributes(ret, dct)
if 'value' in dct and dct['value'] is not None:
ret.value = cls._construct_lang_string_set(_get_ts(dct, 'value', list), model.MultiLanguageTextType)
Expand All @@ -740,7 +740,7 @@ def _construct_multi_language_property(

@classmethod
def _construct_property(cls, dct: Dict[str, object], object_class=model.Property) -> model.Property:
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
value_type=model.datatypes.XSD_TYPE_CLASSES[_get_ts(dct, 'valueType', str)],)
cls._amend_abstract_attributes(ret, dct)
if 'value' in dct and dct['value'] is not None:
Expand All @@ -751,7 +751,7 @@ def _construct_property(cls, dct: Dict[str, object], object_class=model.Property

@classmethod
def _construct_range(cls, dct: Dict[str, object], object_class=model.Range) -> model.Range:
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
value_type=model.datatypes.XSD_TYPE_CLASSES[_get_ts(dct, 'valueType', str)],)
cls._amend_abstract_attributes(ret, dct)
if 'min' in dct and dct['min'] is not None:
Expand All @@ -763,7 +763,7 @@ def _construct_range(cls, dct: Dict[str, object], object_class=model.Range) -> m
@classmethod
def _construct_reference_element(
cls, dct: Dict[str, object], object_class=model.ReferenceElement) -> model.ReferenceElement:
ret = object_class(id_short=_get_ts(dct, "idShort", str),
ret = object_class(id_short=None,
value=None)
cls._amend_abstract_attributes(ret, dct)
if 'value' in dct and dct['value'] is not None:
Expand Down
42 changes: 16 additions & 26 deletions basyx/aas/adapter/xml/xml_deserialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,9 @@ def _amend_abstract_attributes(cls, obj: object, element: etree.Element) -> None
:return: None
"""
if isinstance(obj, model.Referable):
id_short = _get_text_or_none(element.find(NS_AAS + "idShort"))
if id_short is not None:
obj.id_short = id_short
category = _get_text_or_none(element.find(NS_AAS + "category"))
display_name = _failsafe_construct(element.find(NS_AAS + "displayName"),
cls.construct_multi_language_name_type, cls.failsafe)
Expand All @@ -448,9 +451,6 @@ def _amend_abstract_attributes(cls, obj: object, element: etree.Element) -> None
if description is not None:
obj.description = description
if isinstance(obj, model.Identifiable):
id_short = _get_text_or_none(element.find(NS_AAS + "idShort"))
if id_short is not None:
obj.id_short = id_short
administration = _failsafe_construct(element.find(NS_AAS + "administration"),
cls.construct_administrative_information, cls.failsafe)
if administration:
Expand Down Expand Up @@ -491,7 +491,7 @@ def _construct_relationship_element_internal(cls, element: etree.Element, object
to reduce duplicate code
"""
relationship_element = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
_child_construct_mandatory(element, NS_AAS + "first", cls.construct_reference),
_child_construct_mandatory(element, NS_AAS + "second", cls.construct_reference)
)
Expand Down Expand Up @@ -752,7 +752,7 @@ def construct_annotated_relationship_element(cls, element: etree.Element,
def construct_basic_event_element(cls, element: etree.Element, object_class=model.BasicEventElement,
**_kwargs: Any) -> model.BasicEventElement:
basic_event_element = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
_child_construct_mandatory(element, NS_AAS + "observed", cls._construct_referable_reference),
_child_text_mandatory_mapped(element, NS_AAS + "direction", DIRECTION_INVERSE),
_child_text_mandatory_mapped(element, NS_AAS + "state", STATE_OF_EVENT_INVERSE)
Expand All @@ -779,7 +779,7 @@ def construct_basic_event_element(cls, element: etree.Element, object_class=mode
@classmethod
def construct_blob(cls, element: etree.Element, object_class=model.Blob, **_kwargs: Any) -> model.Blob:
blob = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
_child_text_mandatory(element, NS_AAS + "contentType")
)
value = _get_text_or_none(element.find(NS_AAS + "value"))
Expand All @@ -791,9 +791,7 @@ def construct_blob(cls, element: etree.Element, object_class=model.Blob, **_kwar
@classmethod
def construct_capability(cls, element: etree.Element, object_class=model.Capability, **_kwargs: Any) \
-> model.Capability:
capability = object_class(
_child_text_mandatory(element, NS_AAS + "idShort")
)
capability = object_class(None)
cls._amend_abstract_attributes(capability, element)
return capability

Expand All @@ -803,7 +801,7 @@ def construct_entity(cls, element: etree.Element, object_class=model.Entity, **_
specific_asset_id = _failsafe_construct(element.find(NS_AAS + "specificAssetId"),
cls.construct_specific_asset_id, cls.failsafe)
entity = object_class(
id_short=_child_text_mandatory(element, NS_AAS + "idShort"),
id_short=None,
entity_type=_child_text_mandatory_mapped(element, NS_AAS + "entityType", ENTITY_TYPES_INVERSE),
global_asset_id=global_asset_id,
specific_asset_id=specific_asset_id)
Expand All @@ -820,7 +818,7 @@ def construct_entity(cls, element: etree.Element, object_class=model.Entity, **_
@classmethod
def construct_file(cls, element: etree.Element, object_class=model.File, **_kwargs: Any) -> model.File:
file = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
_child_text_mandatory(element, NS_AAS + "contentType")
)
value = _get_text_or_none(element.find(NS_AAS + "value"))
Expand All @@ -843,9 +841,7 @@ def construct_resource(cls, element: etree.Element, object_class=model.Resource,
@classmethod
def construct_multi_language_property(cls, element: etree.Element, object_class=model.MultiLanguageProperty,
**_kwargs: Any) -> model.MultiLanguageProperty:
multi_language_property = object_class(
_child_text_mandatory(element, NS_AAS + "idShort")
)
multi_language_property = object_class(None)
value = _failsafe_construct(element.find(NS_AAS + "value"), cls.construct_multi_language_text_type,
cls.failsafe)
if value is not None:
Expand All @@ -859,9 +855,7 @@ def construct_multi_language_property(cls, element: etree.Element, object_class=
@classmethod
def construct_operation(cls, element: etree.Element, object_class=model.Operation, **_kwargs: Any) \
-> model.Operation:
operation = object_class(
_child_text_mandatory(element, NS_AAS + "idShort")
)
operation = object_class(None)
input_variables = element.find(NS_AAS + "inputVariables")
if input_variables is not None:
for input_variable in _child_construct_multiple(input_variables, NS_AAS + "operationVariable",
Expand All @@ -883,7 +877,7 @@ def construct_operation(cls, element: etree.Element, object_class=model.Operatio
@classmethod
def construct_property(cls, element: etree.Element, object_class=model.Property, **_kwargs: Any) -> model.Property:
property_ = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
value_type=_child_text_mandatory_mapped(element, NS_AAS + "valueType", model.datatypes.XSD_TYPE_CLASSES)
)
value = _get_text_or_none(element.find(NS_AAS + "value"))
Expand All @@ -898,7 +892,7 @@ def construct_property(cls, element: etree.Element, object_class=model.Property,
@classmethod
def construct_range(cls, element: etree.Element, object_class=model.Range, **_kwargs: Any) -> model.Range:
range_ = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
value_type=_child_text_mandatory_mapped(element, NS_AAS + "valueType", model.datatypes.XSD_TYPE_CLASSES)
)
max_ = _get_text_or_none(element.find(NS_AAS + "max"))
Expand All @@ -913,9 +907,7 @@ def construct_range(cls, element: etree.Element, object_class=model.Range, **_kw
@classmethod
def construct_reference_element(cls, element: etree.Element, object_class=model.ReferenceElement, **_kwargs: Any) \
-> model.ReferenceElement:
reference_element = object_class(
_child_text_mandatory(element, NS_AAS + "idShort")
)
reference_element = object_class(None)
value = _failsafe_construct(element.find(NS_AAS + "value"), cls.construct_reference, cls.failsafe)
if value is not None:
reference_element.value = value
Expand All @@ -930,9 +922,7 @@ def construct_relationship_element(cls, element: etree.Element, object_class=mod
@classmethod
def construct_submodel_element_collection(cls, element: etree.Element, object_class=model.SubmodelElementCollection,
**_kwargs: Any) -> model.SubmodelElementCollection:
collection = object_class(
_child_text_mandatory(element, NS_AAS + "idShort")
)
collection = object_class(None)
if not cls.stripped:
value = element.find(NS_AAS + "value")
if value is not None:
Expand All @@ -952,7 +942,7 @@ def construct_submodel_element_list(cls, element: etree.Element, object_class=mo
f"{model.SubmodelElement}, got {type_value_list_element}!")
order_relevant = element.find(NS_AAS + "orderRelevant")
list_ = object_class(
_child_text_mandatory(element, NS_AAS + "idShort"),
None,
type_value_list_element,
semantic_id_list_element=_failsafe_construct(element.find(NS_AAS + "semanticIdListElement"),
cls.construct_reference, cls.failsafe),
Expand Down
3 changes: 2 additions & 1 deletion basyx/aas/adapter/xml/xml_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ def abstract_classes_to_xml(tag: str, obj: object) -> etree.Element:
if isinstance(obj, model.Referable):
if obj.category:
elm.append(_generate_element(name=NS_AAS + "category", text=obj.category))
elm.append(_generate_element(name=NS_AAS + "idShort", text=obj.id_short))
if obj.id_short:
elm.append(_generate_element(name=NS_AAS + "idShort", text=obj.id_short))
if obj.display_name:
elm.append(lang_string_set_to_xml(obj.display_name, tag=NS_AAS + "displayName"))
if obj.description:
Expand Down
Loading
Loading