1818# Copyright (c) OWASP Foundation. All Rights Reserved.
1919
2020import warnings
21- from typing import Optional , Set
21+ from typing import Iterable , Optional , Set
2222from xml .etree import ElementTree
2323
2424from ..model import (
@@ -67,14 +67,17 @@ def generate(self, force_regeneration: bool = False) -> None:
6767 elif self .generated :
6868 return
6969
70+ bom = self .get_bom ()
71+ bom .validate ()
72+
7073 if self .bom_supports_metadata ():
7174 self ._add_metadata_element ()
7275
73- components_element = ElementTree .SubElement (self ._root_bom_element , 'components' )
74-
7576 has_vulnerabilities : bool = False
76- if self .get_bom ().components :
77- for component in self .get_bom ().components :
77+
78+ components_element = ElementTree .SubElement (self ._root_bom_element , 'components' )
79+ if bom .components :
80+ for component in bom .components :
7881 component_element = self ._add_component_element (component = component )
7982 components_element .append (component_element )
8083 if self .bom_supports_vulnerabilities_via_extension () and component .has_vulnerabilities ():
@@ -94,22 +97,35 @@ def generate(self, force_regeneration: bool = False) -> None:
9497 elif component .has_vulnerabilities ():
9598 has_vulnerabilities = True
9699
97- if self .bom_supports_services ():
98- if self .get_bom ().services :
99- services_element = ElementTree .SubElement (self ._root_bom_element , 'services' )
100- for service in self .get_bom ().services :
101- services_element .append (self ._add_service_element (service = service ))
102-
103- if self .bom_supports_external_references ():
104- if self .get_bom ().external_references :
105- self ._add_external_references_to_element (
106- ext_refs = self .get_bom ().external_references ,
107- element = self ._root_bom_element
108- )
100+ if self .bom_supports_services () and bom .services :
101+ services_element = ElementTree .SubElement (self ._root_bom_element , 'services' )
102+ for service in bom .services :
103+ services_element .append (self ._add_service_element (service = service ))
104+
105+ if self .bom_supports_external_references () and bom .external_references :
106+ self ._add_external_references_to_element (
107+ ext_refs = bom .external_references ,
108+ element = self ._root_bom_element
109+ )
110+
111+ if self .bom_supports_dependencies () and (bom .metadata .component or bom .components ):
112+ dep_components : Iterable [Component ] = bom .components
113+ if bom .metadata .component :
114+ dep_components = [bom .metadata .component , * dep_components ]
115+ dependencies_element = ElementTree .SubElement (self ._root_bom_element , 'dependencies' )
116+ for component in dep_components :
117+ dependency_element = ElementTree .SubElement (dependencies_element , 'dependency' , {
118+ 'ref' : str (component .bom_ref )
119+ })
120+ for dependency in component .dependencies :
121+ ElementTree .SubElement (dependency_element , 'dependency' , {
122+ 'ref' : str (dependency )
123+ })
124+ del dep_components
109125
110126 if self .bom_supports_vulnerabilities () and has_vulnerabilities :
111127 vulnerabilities_element = ElementTree .SubElement (self ._root_bom_element , 'vulnerabilities' )
112- for component in self . get_bom () .components :
128+ for component in bom .components :
113129 for vulnerability in component .get_vulnerabilities ():
114130 vulnerabilities_element .append (
115131 self ._get_vulnerability_as_xml_element_post_1_4 (vulnerability = vulnerability )
@@ -126,13 +142,14 @@ def get_target_namespace(self) -> str:
126142
127143 # Builder Methods
128144 def _create_bom_element (self ) -> ElementTree .Element :
145+ bom = self .get_bom ()
129146 root_attributes = {
130147 'xmlns' : self .get_target_namespace (),
131148 'version' : '1' ,
132- 'serialNumber' : self . get_bom () .get_urn_uuid ()
149+ 'serialNumber' : bom .get_urn_uuid ()
133150 }
134151
135- if self .bom_supports_vulnerabilities_via_extension () and self . get_bom () .has_vulnerabilities ():
152+ if self .bom_supports_vulnerabilities_via_extension () and bom .has_vulnerabilities ():
136153 root_attributes ['xmlns:v' ] = Xml .VULNERABILITY_EXTENSION_NAMESPACE
137154 ElementTree .register_namespace ('v' , Xml .VULNERABILITY_EXTENSION_NAMESPACE )
138155
0 commit comments