@@ -819,6 +819,81 @@ def is_bom_link(self) -> bool:
819819 return self ._uri .startswith (_BOM_LINK_PREFIX )
820820
821821
822+ @serializable .serializable_class (ignore_unknown_during_deserialization = True )
823+ class Property :
824+ """
825+ This is our internal representation of `propertyType` complex type that can be used in multiple places within
826+ a CycloneDX BOM document.
827+
828+ .. note::
829+ See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.7/xml/#type_propertyType
830+
831+ Specifies an individual property with a name and value.
832+ """
833+
834+ def __init__ (
835+ self , * ,
836+ name : str ,
837+ value : Optional [str ] = None ,
838+ ) -> None :
839+ self .name = name
840+ self .value = value
841+
842+ @property
843+ @serializable .xml_attribute ()
844+ def name (self ) -> str :
845+ """
846+ The name of the property.
847+
848+ Duplicate names are allowed, each potentially having a different value.
849+
850+ Returns:
851+ `str`
852+ """
853+ return self ._name
854+
855+ @name .setter
856+ def name (self , name : str ) -> None :
857+ self ._name = name
858+
859+ @property
860+ @serializable .xml_name ('.' )
861+ @serializable .xml_string (serializable .XmlStringSerializationType .NORMALIZED_STRING )
862+ def value (self ) -> Optional [str ]:
863+ """
864+ Value of this Property.
865+
866+ Returns:
867+ `str`
868+ """
869+ return self ._value
870+
871+ @value .setter
872+ def value (self , value : Optional [str ]) -> None :
873+ self ._value = value
874+
875+ def __comparable_tuple (self ) -> _ComparableTuple :
876+ return _ComparableTuple ((
877+ self .name , self .value
878+ ))
879+
880+ def __eq__ (self , other : object ) -> bool :
881+ if isinstance (other , Property ):
882+ return self .__comparable_tuple () == other .__comparable_tuple ()
883+ return False
884+
885+ def __lt__ (self , other : Any ) -> bool :
886+ if isinstance (other , Property ):
887+ return self .__comparable_tuple () < other .__comparable_tuple ()
888+ return NotImplemented
889+
890+ def __hash__ (self ) -> int :
891+ return hash (self .__comparable_tuple ())
892+
893+ def __repr__ (self ) -> str :
894+ return f'<Property name={ self .name } >'
895+
896+
822897@serializable .serializable_class (ignore_unknown_during_deserialization = True )
823898class ExternalReference :
824899 """
@@ -835,11 +910,13 @@ def __init__(
835910 url : XsUri ,
836911 comment : Optional [str ] = None ,
837912 hashes : Optional [Iterable [HashType ]] = None ,
913+ properties : Optional [Iterable [Property ]] = None ,
838914 ) -> None :
839915 self .url = url
840916 self .comment = comment
841917 self .type = type
842918 self .hashes = hashes or []
919+ self .properties = properties or []
843920
844921 @property
845922 @serializable .xml_sequence (1 )
@@ -909,102 +986,44 @@ def hashes(self) -> 'SortedSet[HashType]':
909986 def hashes (self , hashes : Iterable [HashType ]) -> None :
910987 self ._hashes = SortedSet (hashes )
911988
912- def __comparable_tuple (self ) -> _ComparableTuple :
913- return _ComparableTuple ((
914- self ._type , self ._url , self ._comment ,
915- _ComparableTuple (self ._hashes )
916- ))
917-
918- def __eq__ (self , other : object ) -> bool :
919- if isinstance (other , ExternalReference ):
920- return self .__comparable_tuple () == other .__comparable_tuple ()
921- return False
922-
923- def __lt__ (self , other : Any ) -> bool :
924- if isinstance (other , ExternalReference ):
925- return self .__comparable_tuple () < other .__comparable_tuple ()
926- return NotImplemented
927-
928- def __hash__ (self ) -> int :
929- return hash (self .__comparable_tuple ())
930-
931- def __repr__ (self ) -> str :
932- return f'<ExternalReference { self .type .name } , { self .url } >'
933-
934-
935- @serializable .serializable_class (ignore_unknown_during_deserialization = True )
936- class Property :
937- """
938- This is our internal representation of `propertyType` complex type that can be used in multiple places within
939- a CycloneDX BOM document.
940-
941- .. note::
942- See the CycloneDX Schema definition: https://cyclonedx.org/docs/1.7/xml/#type_propertyType
943-
944- Specifies an individual property with a name and value.
945- """
946-
947- def __init__ (
948- self , * ,
949- name : str ,
950- value : Optional [str ] = None ,
951- ) -> None :
952- self .name = name
953- self .value = value
954-
955- @property
956- @serializable .xml_attribute ()
957- def name (self ) -> str :
958- """
959- The name of the property.
960-
961- Duplicate names are allowed, each potentially having a different value.
962-
963- Returns:
964- `str`
965- """
966- return self ._name
967-
968- @name .setter
969- def name (self , name : str ) -> None :
970- self ._name = name
971-
972989 @property
973- @serializable .xml_name ( '.' )
974- @serializable .xml_string (serializable .XmlStringSerializationType . NORMALIZED_STRING )
975- def value (self ) -> Optional [ str ] :
990+ @serializable .view ( SchemaVersion1Dot7 )
991+ @serializable .xml_array (serializable .XmlArraySerializationType . NESTED , 'property' )
992+ def properties (self ) -> 'SortedSet[Property]' :
976993 """
977- Value of this Property.
994+ Provides the ability to document properties in a key/value store. This provides flexibility to include data not
995+ officially supported in the standard without having to use additional namespaces or create extensions.
978996
979- Returns :
980- `str `
997+ Return :
998+ Set of `Property `
981999 """
982- return self ._value
1000+ return self ._properties
9831001
984- @value .setter
985- def value (self , value : Optional [ str ]) -> None :
986- self ._value = value
1002+ @properties .setter
1003+ def properties (self , properties : Iterable [ Property ]) -> None :
1004+ self ._properties = SortedSet ( properties )
9871005
9881006 def __comparable_tuple (self ) -> _ComparableTuple :
9891007 return _ComparableTuple ((
990- self .name , self .value
1008+ self ._type , self ._url , self ._comment ,
1009+ _ComparableTuple (self ._hashes ), _ComparableTuple (self .properties ),
9911010 ))
9921011
9931012 def __eq__ (self , other : object ) -> bool :
994- if isinstance (other , Property ):
1013+ if isinstance (other , ExternalReference ):
9951014 return self .__comparable_tuple () == other .__comparable_tuple ()
9961015 return False
9971016
9981017 def __lt__ (self , other : Any ) -> bool :
999- if isinstance (other , Property ):
1018+ if isinstance (other , ExternalReference ):
10001019 return self .__comparable_tuple () < other .__comparable_tuple ()
10011020 return NotImplemented
10021021
10031022 def __hash__ (self ) -> int :
10041023 return hash (self .__comparable_tuple ())
10051024
10061025 def __repr__ (self ) -> str :
1007- return f'<Property name= { self .name } >'
1026+ return f'<ExternalReference { self .type . name } , { self . url } >'
10081027
10091028
10101029@serializable .serializable_class (ignore_unknown_during_deserialization = True )
0 commit comments