Skip to content

Commit 0a491c6

Browse files
committed
Add manufacturer information
1 parent db2a35b commit 0a491c6

File tree

4 files changed

+394
-0
lines changed

4 files changed

+394
-0
lines changed

src/main/java/org/cyclonedx/maven/BaseCycloneDxMojo.java

+91
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,10 @@
4242
import org.cyclonedx.model.LifecycleChoice;
4343
import org.cyclonedx.model.Lifecycles;
4444
import org.cyclonedx.model.Metadata;
45+
import org.cyclonedx.model.OrganizationalContact;
46+
import org.cyclonedx.model.OrganizationalEntity;
4547
import org.cyclonedx.model.Property;
48+
import org.cyclonedx.model.organization.PostalAddress;
4649
import org.cyclonedx.parsers.JsonParser;
4750
import org.cyclonedx.parsers.Parser;
4851
import org.cyclonedx.parsers.XmlParser;
@@ -57,6 +60,7 @@
5760
import java.util.LinkedHashSet;
5861
import java.util.List;
5962
import java.util.Map;
63+
import java.util.Objects;
6064
import java.util.Set;
6165
import java.util.UUID;
6266

@@ -247,6 +251,13 @@ public abstract class BaseCycloneDxMojo extends AbstractMojo {
247251
@Parameter
248252
private ExternalReference[] externalReferences;
249253

254+
/**
255+
* Manufacturer information for automatic creator information
256+
* @since 2.9.1
257+
*/
258+
@Parameter(property = "cyclonedx.manufacturer", required = false)
259+
private OrganizationalEntity manufacturer = null;
260+
250261
@org.apache.maven.plugins.annotations.Component
251262
private MavenProjectHelper mavenProjectHelper;
252263

@@ -351,6 +362,10 @@ public void execute() throws MojoExecutionException {
351362
if (detectUnusedForOptionalScope) {
352363
metadata.addProperty(newProperty("maven.optional.unused", Boolean.toString(detectUnusedForOptionalScope)));
353364
}
365+
366+
if (hasManufacturerInformation()) {
367+
metadata.setManufacturer(manufacturer);
368+
}
354369
}
355370

356371
final Component rootComponent = metadata.getComponent();
@@ -362,6 +377,82 @@ public void execute() throws MojoExecutionException {
362377
}
363378
}
364379

380+
/**
381+
* Check the mojo configuration for the optional manufacturer contents.
382+
*
383+
* @return {@code true} if there is any manufacturer information configured.
384+
*/
385+
boolean hasManufacturerInformation() {
386+
if (manufacturer == null) {
387+
return false;
388+
}
389+
390+
return isNotNullOrEmpty(manufacturer.getAddress()) ||
391+
isNotNullOrEmpty(manufacturer.getName()) ||
392+
isNotNullOrEmptyContacts(manufacturer.getContacts()) ||
393+
isNotNullOrEmptyString(manufacturer.getUrls());
394+
}
395+
396+
/**
397+
* @param text Some text
398+
* @return {@code true} if there is any text
399+
*/
400+
boolean isNotNullOrEmpty(String text) {
401+
return text != null && !text.trim().isEmpty();
402+
}
403+
404+
/**
405+
* @param list A list of text
406+
* @return {@code true} if there is any element has a text value
407+
*/
408+
boolean isNotNullOrEmptyString(List<String> list) {
409+
if (list != null && !list.isEmpty()) {
410+
return list.stream().filter(Objects::nonNull).anyMatch(this::isNotNullOrEmpty);
411+
}
412+
return false;
413+
}
414+
415+
/**
416+
* @param list A list of contacts
417+
* @return {@code true} if there is any contact has something configured
418+
*/
419+
boolean isNotNullOrEmptyContacts(List<OrganizationalContact> list) {
420+
if (list != null && !list.isEmpty()) {
421+
return list.stream().filter(Objects::nonNull).anyMatch(this::isNotNullOrEmpty);
422+
423+
}
424+
return false;
425+
}
426+
427+
/**
428+
* @param address A postal address entry
429+
* @return {@code true} if there is any postal address information exists
430+
*/
431+
boolean isNotNullOrEmpty(PostalAddress address) {
432+
if (address == null) {
433+
return false;
434+
}
435+
return isNotNullOrEmpty(address.getStreetAddress()) ||
436+
isNotNullOrEmpty(address.getCountry()) ||
437+
isNotNullOrEmpty(address.getPostalCode()) ||
438+
isNotNullOrEmpty(address.getLocality()) ||
439+
isNotNullOrEmpty(address.getPostOfficeBoxNumber()) ||
440+
isNotNullOrEmpty(address.getRegion());
441+
}
442+
443+
/**
444+
* @param contact A contact entry
445+
* @return {@code true} if there is any contact information exists
446+
*/
447+
boolean isNotNullOrEmpty(OrganizationalContact contact) {
448+
if (null == contact) {
449+
return false;
450+
}
451+
return isNotNullOrEmpty(contact.getName()) ||
452+
isNotNullOrEmpty(contact.getEmail()) ||
453+
isNotNullOrEmpty(contact.getPhone());
454+
}
455+
365456
private Property newProperty(String name, String value) {
366457
Property property = new Property();
367458
property.setName(name);

src/site/markdown/manufacturer.md

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# Manufacturer
2+
Manufacturer is common in BOMs created through automated processes.
3+
4+
When creating a number of BOMs for several projects within one organization
5+
or company, it is convenient to attach this information at one place.
6+
7+
This will also conform to upcoming EU regulation that all SBOM files shall
8+
9+
>At minimum, the product with digital elements shall be accompanied by:
10+
>1. the name, registered trade name or registered trademark of the manufacturer, and the
11+
> postal address, the email address or other digital contact as well as, where
12+
> available, the website at which the manufacturer can be contacted;
13+
>2. the single point of contact where information about vulnerabilities of the product
14+
> with digital elements can be reported and received, and where the manufacturer’s
15+
> policy on coordinated vulnerability disclosure can be found
16+
>3. name and type and any additional information enabling the unique identification
17+
> of the product with digital elements
18+
>4. the intended purpose of the product with digital elements, including the security
19+
> environment provided by the manufacturer, as well as the product’s essential
20+
> functionalities and information about the security properties
21+
22+
## Configuration
23+
The configuration is optional. If none is specified, the manufacturer information is not visible.
24+
See https://cyclonedx.org/docs/latest/json/#metadata_manufacturer for more information.
25+
26+
### name
27+
The name of the organization,
28+
29+
### address
30+
The physical address (location) of the organization.
31+
##### country
32+
The country name or the two-letter ISO 3166-1 country code.
33+
##### region
34+
The region or state in the country.
35+
##### locality
36+
The locality or city within the country.
37+
##### postOfficeBoxNumber
38+
The post office box number.
39+
##### postalCode
40+
The postal code.
41+
##### streetAddress
42+
The street address.
43+
44+
### url
45+
The URL of the organization. Multiple URLs are allowed.
46+
47+
# contact
48+
A contact at the organization. Multiple contacts are allowed.
49+
50+
##### name
51+
The name of a contact
52+
##### email
53+
The email address of the contact.
54+
##### phone
55+
The phone number of the contact.
56+
57+
## Example of configuration
58+
59+
```xml
60+
<build>
61+
<pluginManagement>
62+
<plugins>
63+
<plugin>
64+
<groupId>org.cyclonedx</groupId>
65+
<artifactId>cyclonedx-maven-plugin</artifactId>
66+
<version>${cyclonedx-maven-plugin.version}</version>
67+
<configuration>
68+
<manufacturer>
69+
<name>Example Company</name>
70+
<url>https://www.example.com/contact</url>
71+
<contact>
72+
<contact>
73+
<name>Steve Springett</name>
74+
<email>[email protected]</email>
75+
</contact>
76+
<contact>
77+
<name>Another contact</name>
78+
<phone>1-800-555-1111</phone>
79+
</contact>
80+
</contact>
81+
</manufacturer>
82+
</configuration>
83+
</plugin>
84+
</plugins>
85+
</pluginManagement>
86+
</build>
87+
```
88+
89+
This configuration will add the following to the BOM file (JSON format):
90+
```json
91+
"manufacturer" : {
92+
"name" : "Example Company",
93+
"url" : [
94+
"https://www.example.com/contact"
95+
],
96+
"contact" : [
97+
{
98+
"name" : "Steve Springett",
99+
"email" : "[email protected]"
100+
},
101+
{
102+
"name" : "Another contact",
103+
"phone" : "1-800-555-1111"
104+
}
105+
]
106+
}
107+
```
108+
109+
## Links
110+
- [EU regulation proposal about SBOM generation.](https://www.europarl.europa.eu/doceo/document/TA-9-2024-0130_EN.pdf)
111+

src/site/site.xml

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
<item name="CycloneDX" href="https://www.cyclonedx.org/" />
2727
<item name="Tool Center" href="https://cyclonedx.org/tool-center/" />
2828
<item name="CycloneDX Maven Plugin" href="index.html" />
29+
<item name="Manufacture References" href="manufacturer.html"/>
2930
</breadcrumbs>
3031
<links>
3132
<item name="Sources" href="https://www.github.com/CycloneDX/cyclonedx-maven-plugin"/>

0 commit comments

Comments
 (0)