This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ant-antlibs-cyclonedx.git

commit e1a1b317709237322253ad999bf1234b3011ce25
Author: Stefan Bodewig <[email protected]>
AuthorDate: Fri May 1 22:24:39 2026 +0200

    supplier seems important to some validators
---
 examples/bom.json                                | 42 ++++++++++++++----------
 examples/bom.xml                                 | 40 ++++++++++++----------
 src/main/org/apache/ant/cyclonedx/Component.java | 39 +++++++++++++++++++---
 src/main/org/apache/ant/cyclonedx/ToolData.java  |  3 +-
 src/tests/antunit/componentbom-test.xml          |  8 +++++
 5 files changed, 90 insertions(+), 42 deletions(-)

diff --git a/examples/bom.json b/examples/bom.json
index b858f16..3887657 100644
--- a/examples/bom.json
+++ b/examples/bom.json
@@ -1,10 +1,10 @@
 {
   "bomFormat" : "CycloneDX",
   "specVersion" : "1.6",
-  "serialNumber" : "urn:uuid:8cfe0788-fca0-491e-a48c-920ac2b05566",
+  "serialNumber" : "urn:uuid:9473c08b-477c-4087-9fb9-965d51f6b87b",
   "version" : 1,
   "metadata" : {
-    "timestamp" : "2026-05-01T19:53:39Z",
+    "timestamp" : "2026-05-01T20:20:09Z",
     "lifecycles" : [
       {
         "phase" : "build"
@@ -14,6 +14,12 @@
       "components" : [
         {
           "type" : "library",
+          "supplier" : {
+            "name" : "Apache Ant Development Team",
+            "url" : [
+              "https://ant.apache.org/";
+            ]
+          },
           "manufacturer" : {
             "name" : "Apache Ant Development Team",
             "url" : [
@@ -27,35 +33,35 @@
           "hashes" : [
             {
               "alg" : "MD5",
-              "content" : "a30e1771f4376fc5444a0eff34c57f35"
+              "content" : "8f400c4cf1c0fced3eb9e0bfd5d18485"
             },
             {
               "alg" : "SHA-1",
-              "content" : "91174b265156be460602e86dd20456e1b1f3783f"
+              "content" : "9d6e76799441f34d56b39aca6415a36d510b463c"
             },
             {
               "alg" : "SHA-256",
-              "content" : 
"938be9e478e3134df97d0ae0710d77ebbf39e3916e5f307db99bf131ddd39bb3"
+              "content" : 
"0b12ba1c7c6ae24a49581810c7495b92df933c150eddebf94522f5fdb19902d8"
             },
             {
               "alg" : "SHA-512",
-              "content" : 
"be0b34697f1954938c3875ef857341d6e7fd276b083bd92ce904651c109911995db8d8420608734e348d54c45bcf72c5213223b84a8c88efbebb62a99edbfe90"
+              "content" : 
"7eb05a92293ead979a82953f4ac2eb560f7414b7d52a6caa651f2d71d95bee8c5deb1e85235ede013497400f005a938d7ce3647396a9f2c7859afaa5e1991102"
             },
             {
               "alg" : "SHA3-256",
-              "content" : 
"d9a03b56538c8eb3531a333b3727c88e84e51255ddbcfcf324027f0cf5863182"
+              "content" : 
"18e97fdcdfb34cad170895bf01da95fdc83a77639ca32451bd7dcd3a313dbc47"
             },
             {
               "alg" : "SHA3-512",
-              "content" : 
"a4653e504cb66e18f0629ed3b21ceb2aebf203ba7848bc96593011fc647435d6a2ae2f3ebe21df72413dd4b2a6ed690b2689cb24b4be3f90d3427f0b1111631d"
+              "content" : 
"dd80e9505830bcd1381ac41b5fb68f9eec5413c9eca02740bdcd2dcdb28a3dce2480a61da1f61fe1b5e27d5f50f95f46dabbb28fa05015140a34245eafd86e3b"
             },
             {
               "alg" : "SHA-384",
-              "content" : 
"b94ebd288e066eb3663583b576d28abece610be66343db9e1a76145b0fa468f97b96a10f5aa24074d844586c048de6ce"
+              "content" : 
"e64ab7365de5350211165f5f1334d5bcd399d5e918a40791122b529f5f81b5200e83b1d62789b062a40671b45e2b7946"
             },
             {
               "alg" : "SHA3-384",
-              "content" : 
"7262084714b890624a731ba65af3ae6b4ffe61bed2d6b6647114f52faa9b15d5a53e77a1f463c36bc5fb2b11e430687d"
+              "content" : 
"9a632d33939e993910ae7eedafb383a1ac6786b72e4e36a88f5873a3be8690577becd66cddc7875e97fcc98455c11bb3"
             }
           ],
           "licenses" : [
@@ -91,35 +97,35 @@
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "a30e1771f4376fc5444a0eff34c57f35"
+          "content" : "8f400c4cf1c0fced3eb9e0bfd5d18485"
         },
         {
           "alg" : "SHA-1",
-          "content" : "91174b265156be460602e86dd20456e1b1f3783f"
+          "content" : "9d6e76799441f34d56b39aca6415a36d510b463c"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"938be9e478e3134df97d0ae0710d77ebbf39e3916e5f307db99bf131ddd39bb3"
+          "content" : 
"0b12ba1c7c6ae24a49581810c7495b92df933c150eddebf94522f5fdb19902d8"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"be0b34697f1954938c3875ef857341d6e7fd276b083bd92ce904651c109911995db8d8420608734e348d54c45bcf72c5213223b84a8c88efbebb62a99edbfe90"
+          "content" : 
"7eb05a92293ead979a82953f4ac2eb560f7414b7d52a6caa651f2d71d95bee8c5deb1e85235ede013497400f005a938d7ce3647396a9f2c7859afaa5e1991102"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"d9a03b56538c8eb3531a333b3727c88e84e51255ddbcfcf324027f0cf5863182"
+          "content" : 
"18e97fdcdfb34cad170895bf01da95fdc83a77639ca32451bd7dcd3a313dbc47"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"a4653e504cb66e18f0629ed3b21ceb2aebf203ba7848bc96593011fc647435d6a2ae2f3ebe21df72413dd4b2a6ed690b2689cb24b4be3f90d3427f0b1111631d"
+          "content" : 
"dd80e9505830bcd1381ac41b5fb68f9eec5413c9eca02740bdcd2dcdb28a3dce2480a61da1f61fe1b5e27d5f50f95f46dabbb28fa05015140a34245eafd86e3b"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"b94ebd288e066eb3663583b576d28abece610be66343db9e1a76145b0fa468f97b96a10f5aa24074d844586c048de6ce"
+          "content" : 
"e64ab7365de5350211165f5f1334d5bcd399d5e918a40791122b529f5f81b5200e83b1d62789b062a40671b45e2b7946"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"7262084714b890624a731ba65af3ae6b4ffe61bed2d6b6647114f52faa9b15d5a53e77a1f463c36bc5fb2b11e430687d"
+          "content" : 
"9a632d33939e993910ae7eedafb383a1ac6786b72e4e36a88f5873a3be8690577becd66cddc7875e97fcc98455c11bb3"
         }
       ],
       "licenses" : [
diff --git a/examples/bom.xml b/examples/bom.xml
index b882d5b..82404a3 100644
--- a/examples/bom.xml
+++ b/examples/bom.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<bom serialNumber="urn:uuid:b09e9df9-cc7f-4de4-a61d-489046a4358c" version="1" 
xmlns="http://cyclonedx.org/schema/bom/1.6";>
+<bom serialNumber="urn:uuid:fdd9f10c-e0ba-4971-acdb-7dfe4f3c274d" version="1" 
xmlns="http://cyclonedx.org/schema/bom/1.6";>
   <metadata>
-    <timestamp>2026-05-01T19:53:39Z</timestamp>
+    <timestamp>2026-05-01T20:20:09Z</timestamp>
     <lifecycles>
       <lifecycle>
         <phase>build</phase>
@@ -10,6 +10,10 @@
     <tools>
       <components>
         <component type="library">
+          <supplier>
+            <name>Apache Ant Development Team</name>
+            <url>https://ant.apache.org/</url>
+          </supplier>
           <manufacturer>
             <name>Apache Ant Development Team</name>
             <url>https://ant.apache.org/</url>
@@ -19,14 +23,14 @@
           <version>0.1alpha</version>
           <description>Apache CycloneDX Antlib</description>
           <hashes>
-            <hash alg="MD5">a30e1771f4376fc5444a0eff34c57f35</hash>
-            <hash alg="SHA-1">91174b265156be460602e86dd20456e1b1f3783f</hash>
-            <hash 
alg="SHA-256">938be9e478e3134df97d0ae0710d77ebbf39e3916e5f307db99bf131ddd39bb3</hash>
-            <hash 
alg="SHA-512">be0b34697f1954938c3875ef857341d6e7fd276b083bd92ce904651c109911995db8d8420608734e348d54c45bcf72c5213223b84a8c88efbebb62a99edbfe90</hash>
-            <hash 
alg="SHA3-256">d9a03b56538c8eb3531a333b3727c88e84e51255ddbcfcf324027f0cf5863182</hash>
-            <hash 
alg="SHA3-512">a4653e504cb66e18f0629ed3b21ceb2aebf203ba7848bc96593011fc647435d6a2ae2f3ebe21df72413dd4b2a6ed690b2689cb24b4be3f90d3427f0b1111631d</hash>
-            <hash 
alg="SHA-384">b94ebd288e066eb3663583b576d28abece610be66343db9e1a76145b0fa468f97b96a10f5aa24074d844586c048de6ce</hash>
-            <hash 
alg="SHA3-384">7262084714b890624a731ba65af3ae6b4ffe61bed2d6b6647114f52faa9b15d5a53e77a1f463c36bc5fb2b11e430687d</hash>
+            <hash alg="MD5">8f400c4cf1c0fced3eb9e0bfd5d18485</hash>
+            <hash alg="SHA-1">9d6e76799441f34d56b39aca6415a36d510b463c</hash>
+            <hash 
alg="SHA-256">0b12ba1c7c6ae24a49581810c7495b92df933c150eddebf94522f5fdb19902d8</hash>
+            <hash 
alg="SHA-512">7eb05a92293ead979a82953f4ac2eb560f7414b7d52a6caa651f2d71d95bee8c5deb1e85235ede013497400f005a938d7ce3647396a9f2c7859afaa5e1991102</hash>
+            <hash 
alg="SHA3-256">18e97fdcdfb34cad170895bf01da95fdc83a77639ca32451bd7dcd3a313dbc47</hash>
+            <hash 
alg="SHA3-512">dd80e9505830bcd1381ac41b5fb68f9eec5413c9eca02740bdcd2dcdb28a3dce2480a61da1f61fe1b5e27d5f50f95f46dabbb28fa05015140a34245eafd86e3b</hash>
+            <hash 
alg="SHA-384">e64ab7365de5350211165f5f1334d5bcd399d5e918a40791122b529f5f81b5200e83b1d62789b062a40671b45e2b7946</hash>
+            <hash 
alg="SHA3-384">9a632d33939e993910ae7eedafb383a1ac6786b72e4e36a88f5873a3be8690577becd66cddc7875e97fcc98455c11bb3</hash>
           </hashes>
           <licenses>
             <license>
@@ -52,14 +56,14 @@
       <version>0.1alpha</version>
       <description>Apache CycloneDX Antlib</description>
       <hashes>
-        <hash alg="MD5">a30e1771f4376fc5444a0eff34c57f35</hash>
-        <hash alg="SHA-1">91174b265156be460602e86dd20456e1b1f3783f</hash>
-        <hash 
alg="SHA-256">938be9e478e3134df97d0ae0710d77ebbf39e3916e5f307db99bf131ddd39bb3</hash>
-        <hash 
alg="SHA-512">be0b34697f1954938c3875ef857341d6e7fd276b083bd92ce904651c109911995db8d8420608734e348d54c45bcf72c5213223b84a8c88efbebb62a99edbfe90</hash>
-        <hash 
alg="SHA3-256">d9a03b56538c8eb3531a333b3727c88e84e51255ddbcfcf324027f0cf5863182</hash>
-        <hash 
alg="SHA3-512">a4653e504cb66e18f0629ed3b21ceb2aebf203ba7848bc96593011fc647435d6a2ae2f3ebe21df72413dd4b2a6ed690b2689cb24b4be3f90d3427f0b1111631d</hash>
-        <hash 
alg="SHA-384">b94ebd288e066eb3663583b576d28abece610be66343db9e1a76145b0fa468f97b96a10f5aa24074d844586c048de6ce</hash>
-        <hash 
alg="SHA3-384">7262084714b890624a731ba65af3ae6b4ffe61bed2d6b6647114f52faa9b15d5a53e77a1f463c36bc5fb2b11e430687d</hash>
+        <hash alg="MD5">8f400c4cf1c0fced3eb9e0bfd5d18485</hash>
+        <hash alg="SHA-1">9d6e76799441f34d56b39aca6415a36d510b463c</hash>
+        <hash 
alg="SHA-256">0b12ba1c7c6ae24a49581810c7495b92df933c150eddebf94522f5fdb19902d8</hash>
+        <hash 
alg="SHA-512">7eb05a92293ead979a82953f4ac2eb560f7414b7d52a6caa651f2d71d95bee8c5deb1e85235ede013497400f005a938d7ce3647396a9f2c7859afaa5e1991102</hash>
+        <hash 
alg="SHA3-256">18e97fdcdfb34cad170895bf01da95fdc83a77639ca32451bd7dcd3a313dbc47</hash>
+        <hash 
alg="SHA3-512">dd80e9505830bcd1381ac41b5fb68f9eec5413c9eca02740bdcd2dcdb28a3dce2480a61da1f61fe1b5e27d5f50f95f46dabbb28fa05015140a34245eafd86e3b</hash>
+        <hash 
alg="SHA-384">e64ab7365de5350211165f5f1334d5bcd399d5e918a40791122b529f5f81b5200e83b1d62789b062a40671b45e2b7946</hash>
+        <hash 
alg="SHA3-384">9a632d33939e993910ae7eedafb383a1ac6786b72e4e36a88f5873a3be8690577becd66cddc7875e97fcc98455c11bb3</hash>
       </hashes>
       <licenses>
         <license>
diff --git a/src/main/org/apache/ant/cyclonedx/Component.java 
b/src/main/org/apache/ant/cyclonedx/Component.java
index 26d3fb5..6813699 100644
--- a/src/main/org/apache/ant/cyclonedx/Component.java
+++ b/src/main/org/apache/ant/cyclonedx/Component.java
@@ -23,7 +23,9 @@ public class Component {
     private String group;
     private String version;
     private String description;
-    private Manufacturer manufacturer = null;
+    private Organization manufacturer = null;
+    private Organization supplier = null;
+    private boolean manufacturerIsSupplier = false;
     private List<org.cyclonedx.model.License> licenses = new ArrayList<>();
     private String purl;
     private String bomRef;
@@ -60,14 +62,26 @@ public class Component {
         this.description = description;
     }
 
-    public Manufacturer createManufacturer() {
+    public Organization createManufacturer() {
         if (manufacturer != null) {
             throw new BuildException("component can only have one 
manufacturer");
         }
-        manufacturer = new Manufacturer();
+        manufacturer = new Organization();
         return manufacturer;
     }
 
+    public Organization createSupplier() {
+        if (supplier != null) {
+            throw new BuildException("component can only have one supplier");
+        }
+        supplier = new Organization();
+        return supplier;
+    }
+
+    public void setManufacturerIsSupplier(boolean manufacturerIsSupplier) {
+        this.manufacturerIsSupplier = manufacturerIsSupplier;
+    }
+
     public void addConfiguredLicense(License l) {
         licenses.add(l.toCycloneDxLicense());
     }
@@ -147,6 +161,14 @@ public class Component {
         if (name == null) {
             throw new BuildException("component name is required");
         }
+        if (manufacturerIsSupplier) {
+            if (manufacturer == null) {
+                throw new BuildException("component without manufacturer can't 
use manufacturer as supplier");
+            }
+            if (supplier != null) {
+                throw new BuildException("component with supplier can't use 
manufacturer as supplier");
+            }
+        }
 
         org.cyclonedx.model.Component component = new 
org.cyclonedx.model.Component();
 
@@ -162,7 +184,14 @@ public class Component {
             component.setDescription(description);
         }
         if (manufacturer != null) {
-            component.setManufacturer(manufacturer.toOrganizationalEntity());
+            OrganizationalEntity oe = manufacturer.toOrganizationalEntity();
+            component.setManufacturer(oe);
+            if (manufacturerIsSupplier) {
+                component.setSupplier(oe);
+            }
+        }
+        if (supplier != null) {
+            component.setSupplier(supplier.toOrganizationalEntity());
         }
         if (!licenses.isEmpty()) {
             LicenseChoice lc = new LicenseChoice();
@@ -209,7 +238,7 @@ public class Component {
         component.setHashes(BomUtils.calculateHashes(file, bomVersion));
     }
 
-    public static class Manufacturer {
+    public static class Organization {
         private String name;
         private List<String> urls = new ArrayList<>();
 
diff --git a/src/main/org/apache/ant/cyclonedx/ToolData.java 
b/src/main/org/apache/ant/cyclonedx/ToolData.java
index b686206..1894538 100644
--- a/src/main/org/apache/ant/cyclonedx/ToolData.java
+++ b/src/main/org/apache/ant/cyclonedx/ToolData.java
@@ -38,9 +38,10 @@ public class ToolData {
         antlibComponent.setVersion(getVersion());
         antlibComponent.setDescription("Apache CycloneDX Antlib");
 
-        Component.Manufacturer manufacturer = 
antlibComponent.createManufacturer();
+        Component.Organization manufacturer = 
antlibComponent.createManufacturer();
         manufacturer.setName("Apache Ant Development Team");
         manufacturer.addConfiguredUrl(new 
URLResource("https://ant.apache.org/";));
+        antlibComponent.setManufacturerIsSupplier(true);
 
         Component.License license = new Component.License();
         license.setLicenseId("Apache-2.0");
diff --git a/src/tests/antunit/componentbom-test.xml 
b/src/tests/antunit/componentbom-test.xml
index ae48f41..fa3559f 100644
--- a/src/tests/antunit/componentbom-test.xml
+++ b/src/tests/antunit/componentbom-test.xml
@@ -96,6 +96,14 @@
         xmlns:au="antlib:org.apache.ant.antunit"
         name="bom.metadata.tools.components.component.manufacturer.url"
         value="https://ant.apache.org/"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.metadata.tools.components.component.supplier.name"
+        value="Apache Ant Development Team"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.metadata.tools.components.component.supplier.url"
+        value="https://ant.apache.org/"/>
     <au:assertPropertyEquals
         xmlns:au="antlib:org.apache.ant.antunit"
         name="bom.metadata.tools.components.component.licenses.license.id"

Reply via email to