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

asf-gitbox-commits pushed a commit to branch support-ivy-as-component-source
in repository https://gitbox.apache.org/repos/asf/ant-antlibs-cyclonedx.git

commit f069bfdf98dd018e501c97af573601548a6464b1
Author: Stefan Bodewig <[email protected]>
AuthorDate: Sat Aug 15 20:30:32 2026 +0200

    make it easier to supply additional data to Ivy dependencies
---
 build.xml                                          |   7 +-
 docs/component.html                                | 126 +++++++-
 example/ant-cyclonedx-0.2alpha.cdx.diff            | 333 ++++++++++++++++-----
 example/ant-cyclonedx-0.2alpha.cdx.json            |  92 +++---
 example/ant-cyclonedx-0.2alpha.ivy.cdx.json        | 242 +++++++--------
 src/main/org/apache/ant/cyclonedx/Component.java   |  85 ++++++
 .../ant/cyclonedx/IvyModuleComponentResolver.java  |  11 +-
 src/tests/antunit/component-ivymodule-test.xml     |  94 +++++-
 8 files changed, 722 insertions(+), 268 deletions(-)

diff --git a/build.xml b/build.xml
index b6825ea..15c29b6 100644
--- a/build.xml
+++ b/build.xml
@@ -139,7 +139,10 @@ under the License.
           description="Apache CycloneDX Antlib"
           publisher="The Apache Software Foundation"
           supplierIsManufacturer="true">
-        <ivymodule conf="default,provided" externalConf="provided"/>
+        <ivymodule conf="default,provided" externalConf="provided">
+          <templateComponent refid="ant"/>
+          <templateComponent refid="ant-launcher"/>
+        </ivymodule>
         <file file="${jarname}"/>
         <supplier refid="ant-pmc"/>
         <license refid="apache-2"/>
@@ -147,8 +150,6 @@ under the License.
         <externalReferenceSet refid="antlibs-common-ext-refs"/>
         <externalReferenceSet refid="antlib-ext-refs"/>
       </component>
-      <additionalComponent refid="ant"/>
-      <additionalComponent refid="ant-launcher"/>
       <license refid="apache-2"/>
     </cdx:componentbom>
   </target>
diff --git a/docs/component.html b/docs/component.html
index 307ca8d..a4b2c8a 100644
--- a/docs/component.html
+++ b/docs/component.html
@@ -272,8 +272,15 @@ <h4 id="ivyModule">ivyModule</h4>
 
     <p>Not all parts of an SBOM component you may want to provide are
       part of an Ivy module definition and you may want to provide
-      them explicitly, supplier and manufacturer information, more
-      external references or the publisher for example.</p>
+      them explicitly. Supplier and manufacturer information, more
+      external references or the publisher are missing for
+      example. The <code>type</code> defaults to "library" and
+      the <code>scope</code> to "required". For the component that
+      contains the <code>ivyModule</code> child element itself, you
+      can use the "normal" attributes and nested element of the
+      component to augment data - for the dependencies identified by
+      the Ivy module you can provide extra data
+      as <code>templateComponent</code> child elements.</p>
 
     <p>The <code>sbomLink</code> and <code>ivyModule</code> elements
       can not both be used as nested elements of the same
@@ -328,6 +335,119 @@ <h5>Attributes</h5>
       </tr>
     </table>
 
+    <h5>Nested elements</h5>
+
+    <h6>templateComponent</h6>
+
+    <p>A nested <code>templateComponent</code> element supports all
+      attributes and nested elements of a component, but
+      neither <code>sbomLink</code> nor <code>ivyModule</code> have
+      any effect.</p>
+
+    <p>A <code>templateComponent</code> can be used to enrich a
+      component detected by Ivy as a dependency of the current
+      component. For example by adding more external references or a
+      manufacturer. Template components take precedence over a data
+      detected by Ivy, they are matched to a detected dependency by
+      name and group only, the version is ignored. If
+      the <code>templateComponent</code> has a <code>version</code>
+      attribute, no hashes will be calculated from the resolved
+      file.</p>
+
+    <p>The combination
+      of <code>ivyModule</code>, <code>templateComponent</code> and
+      an <code>additionalComponent</code> specified in
+      a <code>compomentbom</code> may be a bit
+      confusing. An <code>additionalComponent</code> is always added
+      to the generated SBOM and any <code>ivyModule</code> dependency
+      or <code>templateComponent</code> that matches the name and
+      group of an <code>additionalComponent</code> is ignored. Apart
+      from that a <code>templateComponent</code> will only show up in
+      the SBOM if a matching dependency is detected
+      by <code>ivyModule</code>. <code>templateComponent</code> and
+      Ivy module dependencies are merged
+      while <code>additionalComponent</code>s completely replace Ivy
+      module dependencies.</p>
+
+    <p>As an example, assume the <code>ivyModule</code> resolves a
+      module with group "org.example", name "module" and version "1"
+      which has a dependency on a component with group "com.example",
+      name "dependency", version "2" and description "my
+      description".</p>
+
+    <p>The following snippet adds two components to the SBOM with
+      bom-refs "pkg:maven/org.example/module@1?type=jar" and
+      "pkg:maven/com.example/dependency@2?type=jar" where the later has a
+      description of "my description" and hashes if the dependency has
+      been retrieved:</p>
+
+    <pre>
+      &lt;cdx:componentbom
+        &lt;cdx:component>
+          &lt;ivyModule/>
+        &lt;/cdx:component>
+      &lt;/cdx:componentbom>
+    </pre>
+
+    <p>The following snippet adds two components to the SBOM with
+      bom-refs "pkg:maven/org.example/module@1?type=jar" and
+      "pkg:maven/com.example/dependency@3?type=jar" where the later has
+      a no description at all and no hashes either.</p>
+
+    <pre>
+      &lt;cdx:componentbom
+        &lt;cdx:component>
+          &lt;ivyModule/>
+        &lt;/cdx:component>
+        &lt;cdx:additionalComponent
+            name="dependency"
+            group="com.example"
+            version="3"
+          />
+      &lt;/cdx:componentbom>
+    </pre>
+
+    <p>The following snippet adds two components to the SBOM with
+      bom-refs "pkg:maven/org.example/module@1?type=jar" and
+      "pkg:maven/com.example/dependency@2?type=jar" where the later
+      has a description "my description" a publisher "example" and
+      hashes if the dependency has been retrieved.</p>
+
+    <pre>
+      &lt;cdx:componentbom
+        &lt;cdx:component>
+          &lt;ivyModule>
+            &lt;cdx:templateComponent
+                name="dependency"
+                group="com.example"
+                publisher="Example"
+              />
+          &lt;/ivyModule>
+        &lt;/cdx:component>
+      &lt;/cdx:componentbom>
+    </pre>
+
+    <p>The following snippet adds two components to the SBOM with
+      bom-refs "pkg:maven/org.example/module@1?type=jar" and
+      "pkg:maven/com.example/dependency@3?type=jar" where the later has
+      a description "another description" but no hashes (as the
+      version doesn't match).</p>
+
+    <pre>
+      &lt;cdx:componentbom
+        &lt;cdx:component>
+          &lt;ivyModule>
+            &lt;cdx:templateComponent
+                name="dependency"
+                group="com.example"
+                version="3"
+                description="another description"
+              />
+          &lt;/ivyModule>
+        &lt;/cdx:component>
+      &lt;/cdx:componentbom>
+    </pre>
+
     <h4 id="manufacturer">manufacturer</h4>
 
     <p>At most one nested <a href="organization.html">organization</a>
@@ -505,7 +625,7 @@ <h3>Examples</h3>
         &lt;license refid="apache-2"/>
         &lt;externalReferenceSet refid="antlib-ext-refs"/>
         &lt;dependency componentRef="ant"/>
-        &lt;dependency 
bomRef="pkg:maven/org.cyclonedx/[email protected]?type=jar"/>
+        &lt;dependency 
bomRef="pkg:maven/org.cyclonedx/[email protected]?type=jar"/>
       &lt;/cdx:component>
     </pre>
   </body>
diff --git a/example/ant-cyclonedx-0.2alpha.cdx.diff 
b/example/ant-cyclonedx-0.2alpha.cdx.diff
index 2158107..6bf9d08 100644
--- a/example/ant-cyclonedx-0.2alpha.cdx.diff
+++ b/example/ant-cyclonedx-0.2alpha.cdx.diff
@@ -1,18 +1,5 @@
---- ant-cyclonedx-0.2alpha.cdx.json    2026-08-07 16:26:20.482069699 +0200
-+++ ant-cyclonedx-0.2alpha.ivy.cdx.json        2026-08-07 16:26:45.477044844 
+0200
-@@ -1,10 +1,10 @@
- {
-   "bomFormat" : "CycloneDX",
-   "specVersion" : "1.7",
--  "serialNumber" : "urn:uuid:46b215d3-5bd4-4619-92bf-4dd0883c885d",
-+  "serialNumber" : "urn:uuid:2ef84f46-64af-4fb9-b3da-70f4fcb7acd3",
-   "version" : 1,
-   "metadata" : {
--    "timestamp" : "2026-08-07T14:14:06Z",
-+    "timestamp" : "2026-08-07T14:13:23Z",
-     "lifecycles" : [
-       {
-         "phase" : "build"
+--- ant-cyclonedx-0.2alpha.cdx.json    2026-08-15 20:25:55.771468081 +0200
++++ ant-cyclonedx-0.2alpha.ivy.cdx.json        2026-08-15 20:25:49.100344456 
+0200
 @@ -253,36 +253,64 @@
    "components" : [
      {
@@ -259,28 +246,28 @@
 -          "url" : "https://github.com/FasterXML/jackson-dataformat-xml";
 +          "alg" : "SHA-256",
 +          "content" : 
"cc3a0e540791a9a1cbcd7584767b84572ffda0b72823856558f47dea69ae8ed1"
-         },
-         {
--          "type" : "bom",
--          "url" : 
"https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/2.22.1/jackson-dataformat-xml-2.22.1-sbom-cyclonedx.json";
++        },
++        {
 +          "alg" : "SHA-512",
 +          "content" : 
"12398c493aa3b54716813a6297b72104fa52ab324bae54512e41a1285ac756fcbb800084c088f8e9d3aceae2e698ca164bc547421d5fe2fb62ed2dadf1d3d000"
-         },
-         {
--          "type" : "distribution-intake",
--          "url" : "https://central.sonatype.com/api/v1/publisher";
-+          "alg" : "SHA3-256",
-+          "content" : 
"2d33856e0e0aa27571950d57227a66ab78f22c5cecf7c07afc3ad4dbe3b4b4ae"
 +        },
 +        {
++          "alg" : "SHA3-256",
++          "content" : 
"2d33856e0e0aa27571950d57227a66ab78f22c5cecf7c07afc3ad4dbe3b4b4ae"
+         },
+         {
+-          "type" : "bom",
+-          "url" : 
"https://repo1.maven.org/maven2/com/fasterxml/jackson/dataformat/jackson-dataformat-xml/2.22.1/jackson-dataformat-xml-2.22.1-sbom-cyclonedx.json";
 +          "alg" : "SHA3-512",
 +          "content" : 
"47bdf965089a1949286216aed3b286d8990a3b9169dacb15f0a6f36df07ee397d0ecbcc1294228479068cdbff4b1d8a11718ad5efa744952c34eb092e62cf644"
 +        },
 +        {
 +          "alg" : "SHA-384",
 +          "content" : 
"2f20d92e2fc1932406055a055e0602c9d0a96d7c19b75aeb7dca7c19b30e65bd126677a9bb855ef493be8f4be1feaf62"
-+        },
-+        {
+         },
+         {
+-          "type" : "distribution-intake",
+-          "url" : "https://central.sonatype.com/api/v1/publisher";
 +          "alg" : "SHA3-384",
 +          "content" : 
"e0bc342c2bcd8d91b674657a28e0a762d68232729d7a53d0c04ba63807a1f6bc458bfb64c422408f0cb701ce753ff7cd"
 +        }
@@ -360,9 +347,10 @@
 -        }
 -      ],
 -      "purl" : 
"pkg:maven/com.jcraft/[email protected]?type=jar",
--      "externalReferences" : [
--        {
--          "type" : "website",
++      "purl" : 
"pkg:maven/com.github.package-url/[email protected]?type=jar",
+       "externalReferences" : [
+         {
+           "type" : "website",
 -          "url" : "http://www.jcraft.com/";
 -        }
 -      ]
@@ -406,10 +394,9 @@
 -        }
 -      ],
 -      "purl" : "pkg:maven/com.jcraft/[email protected]?type=jar",
-+      "purl" : 
"pkg:maven/com.github.package-url/[email protected]?type=jar",
-       "externalReferences" : [
-         {
-           "type" : "website",
+-      "externalReferences" : [
+-        {
+-          "type" : "website",
 -          "url" : "http://www.jcraft.com/";
 -        }
 -      ]
@@ -460,11 +447,11 @@
      },
      {
        "type" : "library",
-       "bom-ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
+       "bom-ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
 -      "publisher" : "The Apache Software Foundation",
        "group" : "commons-codec",
        "name" : "commons-codec",
-       "version" : "1.22.0",
+       "version" : "1.22.1",
 @@ -861,47 +808,22 @@
        "licenses" : [
          {
@@ -476,7 +463,7 @@
            }
          }
        ],
-       "purl" : "pkg:maven/commons-codec/[email protected]?type=jar",
+       "purl" : "pkg:maven/commons-codec/[email protected]?type=jar",
        "externalReferences" : [
          {
 -          "type" : "vcs",
@@ -492,7 +479,7 @@
 -        },
 -        {
 -          "type" : "bom",
--          "url" : 
"https://repo1.maven.org/maven2/commons-codec/commons-codec/1.22.0/commons-codec-1.22.0-cyclonedx.json";
+-          "url" : 
"https://repo1.maven.org/maven2/commons-codec/commons-codec/1.22.1/commons-codec-1.22.1-cyclonedx.json";
 -        },
 -        {
 -          "type" : "mailing-list",
@@ -558,14 +545,19 @@
          }
        ]
      },
-@@ -1128,24 +1026,7 @@
-     },
-     {
+@@ -984,168 +882,119 @@
        "type" : "library",
--      "bom-ref" : 
"pkg:maven/org.apache.commons/[email protected]?type=jar",
--      "group" : "org.apache.commons",
--      "name" : "commons-codec",
--      "version" : "1.18.0",
+       "bom-ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
+       "isExternal" : true,
+-      "supplier" : {
+-        "name" : "Apache Ant Project Management Committee",
+-        "url" : [
+-          "https://ant.apache.org/";
+-        ]
+-      },
+       "group" : "org.apache.ant",
+       "name" : "ant-launcher",
+       "version" : "1.10.17",
 -      "licenses" : [
 -        {
 -          "license" : {
@@ -574,16 +566,211 @@
 -          }
 -        }
 -      ],
--      "purl" : "pkg:maven/org.apache.commons/[email protected]?type=jar"
+-      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
+-      "externalReferences" : [
+-        {
+-          "type" : "vcs",
+-          "url" : "https://gitbox.apache.org/repos/asf/ant.git";
+-        },
+-        {
+-          "type" : "issue-tracker",
+-          "url" : "https://bz.apache.org/bugzilla/buglist.cgi?product=Ant";
+-        },
+-        {
+-          "type" : "website",
+-          "url" : "https://ant.apache.org/";
+-        },
+-        {
+-          "type" : "advisories",
+-          "url" : 
"https://ant.apache.org/security.html#Apache%20Ant%20Security%20Vulnerabilities";
+-        },
++      "hashes" : [
+         {
+-          "type" : "mailing-list",
+-          "url" : "https://ant.apache.org/mail.html";
++          "alg" : "MD5",
++          "content" : "6f03c0937a15756fd7bc7bb98d6ee360"
+         },
+         {
+-          "type" : "documentation",
+-          "url" : "https://ant.apache.org/manual/";
++          "alg" : "SHA-1",
++          "content" : "a65884e1ff214f724a6e9c089365c71935c488e4"
+         },
+         {
+-          "type" : "source-distribution",
+-          "url" : "https://ant.apache.org/srcdownload.cgi";
++          "alg" : "SHA-256",
++          "content" : 
"f6e3de06dc0ea396638004f1a003f55fdbd20c3e7ccfb9b7a524f49fd0ae8568"
+         },
+         {
+-          "type" : "distribution",
+-          "url" : "https://ant.apache.org/bindownload.cgi";
++          "alg" : "SHA-512",
++          "content" : 
"73fef113f238f6fcfe94e7d58824207ea6557626262f27d3bd20ab3bbba6af848ee5998ad915a7fa3999e0e368bb1f7ae1bf90888295989a15236a73c7d08709"
+         },
+         {
+-          "type" : "license",
+-          "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
++          "alg" : "SHA3-256",
++          "content" : 
"80ef280b77fd566dde6c6438a974f993db7540dc7a99ea89e43557df769a7f17"
+         },
+         {
+-          "type" : "release-notes",
+-          "url" : "https://github.com/apache/ant/blob/master/WHATSNEW";
++          "alg" : "SHA3-512",
++          "content" : 
"b9700c9f92513d503c806ed1ce2fed1d351a79f609ac8b30d4ec27580b0976d67cbecbe040647c7602f549f18ef8ac4fa37cc54d47a577e5046f0f86ff21de39"
+         },
+         {
+-          "type" : "security-contact",
+-          "url" : "https://www.apache.org/security/";
++          "alg" : "SHA-384",
++          "content" : 
"3cfaf78d72581170b94df32d7b069bab2e10fa8ae56d2973de3a750ec45aaeb194d89714dacc77af8f9892802a4a7ec6"
+         },
+         {
+-          "type" : "rfc-9116",
+-          "url" : "https://ant.apache.org/.well-known/security.txt";
++          "alg" : "SHA3-384",
++          "content" : 
"447a649c728ffc652a3676904a3001e41cd10387dafe90df97fa121c8e824822a98a00b9a3de3cbd93b19355ad51d7a7"
+         }
+-      ]
 -    },
 -    {
 -      "type" : "library",
+-      "bom-ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
+-      "isExternal" : true,
+-      "supplier" : {
+-        "name" : "Apache Ant Project Management Committee",
+-        "url" : [
+-          "https://ant.apache.org/";
+-        ]
+-      },
+-      "group" : "org.apache.ant",
+-      "name" : "ant",
+-      "version" : "1.10.17",
++      ],
+       "licenses" : [
+         {
+           "license" : {
+-            "id" : "Apache-2.0",
++            "name" : "The Apache Software License, Version 2.0",
+             "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
+           }
+         }
+       ],
+-      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
++      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
+       "externalReferences" : [
+         {
+-          "type" : "vcs",
+-          "url" : "https://gitbox.apache.org/repos/asf/ant.git";
+-        },
+-        {
+-          "type" : "issue-tracker",
+-          "url" : "https://bz.apache.org/bugzilla/buglist.cgi?product=Ant";
+-        },
+-        {
+           "type" : "website",
+           "url" : "https://ant.apache.org/";
+-        },
+-        {
+-          "type" : "advisories",
+-          "url" : 
"https://ant.apache.org/security.html#Apache%20Ant%20Security%20Vulnerabilities";
+-        },
++        }
++      ]
++    },
++    {
++      "type" : "library",
++      "bom-ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
++      "isExternal" : true,
++      "group" : "org.apache.ant",
++      "name" : "ant",
++      "version" : "1.10.17",
++      "hashes" : [
+         {
+-          "type" : "mailing-list",
+-          "url" : "https://ant.apache.org/mail.html";
++          "alg" : "MD5",
++          "content" : "7deb57aad47476c63e707ea57533e43b"
+         },
+         {
+-          "type" : "documentation",
+-          "url" : "https://ant.apache.org/manual/";
++          "alg" : "SHA-1",
++          "content" : "fa8a13422ac460563171d10a37c3f28340a953f6"
+         },
+         {
+-          "type" : "source-distribution",
+-          "url" : "https://ant.apache.org/srcdownload.cgi";
++          "alg" : "SHA-256",
++          "content" : 
"8be692e02837f41a47a3d21cde6655792142fdf42fe23bcb16d7129cad9b2284"
+         },
+         {
+-          "type" : "distribution",
+-          "url" : "https://ant.apache.org/bindownload.cgi";
++          "alg" : "SHA-512",
++          "content" : 
"f1cc1a82e1abcf613d4ccf080f83fcd51acd7d4a2f1c2841cca90dd1ebaa96fab2df6411abd2cf97e2ec74231b1540a5d15c12117ba777ab1538b61f9f2b5fa9"
+         },
+         {
+-          "type" : "license",
+-          "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
++          "alg" : "SHA3-256",
++          "content" : 
"540a9cc40d8c9c4e004b04bd6af4a590e18d2077e93d441a9dcbdf90798b31b6"
+         },
+         {
+-          "type" : "release-notes",
+-          "url" : "https://github.com/apache/ant/blob/master/WHATSNEW";
++          "alg" : "SHA3-512",
++          "content" : 
"7a65837340a624a8f9eb68a56c78b6891ddf95cd617ccbc227e2fe88b53f59c2cea7d856b4d803898f2bb2317dbc8f8124d3c35154e3cee555d97fe064a8739d"
+         },
+         {
+-          "type" : "security-contact",
+-          "url" : "https://www.apache.org/security/";
++          "alg" : "SHA-384",
++          "content" : 
"2af275805479b9cfcfdae25f19cce911922207bc2fb77c2c44caf8633c56cd7d772ab30134bac68aacf0ea6e444fa50c"
+         },
+         {
+-          "type" : "rfc-9116",
+-          "url" : "https://ant.apache.org/.well-known/security.txt";
++          "alg" : "SHA3-384",
++          "content" : 
"71205d360f909df37fef5b427538c22977e01801108a1cb37387d1f72e784509796a915c2069a12762a78b990d0aa207"
+         }
+-      ]
+-    },
+-    {
+-      "type" : "library",
+-      "bom-ref" : 
"pkg:maven/org.apache.commons/[email protected]?type=jar",
+-      "group" : "org.apache.commons",
+-      "name" : "commons-codec",
+-      "version" : "1.18.0",
++      ],
+       "licenses" : [
+         {
+           "license" : {
+-            "id" : "Apache-2.0",
++            "name" : "The Apache Software License, Version 2.0",
+             "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
+           }
+         }
+       ],
+-      "purl" : "pkg:maven/org.apache.commons/[email protected]?type=jar"
++      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
++      "externalReferences" : [
++        {
++          "type" : "website",
++          "url" : "https://ant.apache.org/";
++        }
++      ]
+     },
+     {
+       "type" : "library",
        "bom-ref" : 
"pkg:maven/org.apache.commons/[email protected]?type=jar",
 -      "publisher" : "The Apache Software Foundation",
        "group" : "org.apache.commons",
        "name" : "commons-collections4",
        "version" : "4.5.0",
-@@ -1187,63 +1068,22 @@
+@@ -1187,63 +1036,22 @@
        "licenses" : [
          {
            "license" : {
@@ -649,7 +836,7 @@
        "group" : "org.apache.commons",
        "name" : "commons-lang3",
        "version" : "3.20.0",
-@@ -1285,95 +1125,26 @@
+@@ -1285,95 +1093,26 @@
        "licenses" : [
          {
            "license" : {
@@ -748,7 +935,7 @@
        "hashes" : [
          {
            "alg" : "MD5",
-@@ -1411,93 +1182,21 @@
+@@ -1411,93 +1150,21 @@
        "licenses" : [
          {
            "license" : {
@@ -845,7 +1032,7 @@
        "bom-ref" : "pkg:maven/org.codehaus.woodstox/[email protected]?type=jar",
        "group" : "org.codehaus.woodstox",
        "name" : "stax2-api",
-@@ -1540,17 +1239,22 @@
+@@ -1540,17 +1207,22 @@
        "licenses" : [
          {
            "license" : {
@@ -866,12 +1053,12 @@
      },
      {
        "type" : "library",
-       "bom-ref" : 
"pkg:maven/org.cyclonedx/[email protected]?type=jar",
+       "bom-ref" : 
"pkg:maven/org.cyclonedx/[email protected]?type=jar",
 -      "publisher" : "OWASP Foundation",
        "group" : "org.cyclonedx",
        "name" : "cyclonedx-core-java",
-       "version" : "13.0.0",
-@@ -1592,62 +1296,146 @@
+       "version" : "13.1.0",
+@@ -1592,62 +1264,146 @@
        "licenses" : [
          {
            "license" : {
@@ -882,7 +1069,7 @@
            }
          }
        ],
-       "purl" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
+       "purl" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
        "externalReferences" : [
          {
 -          "type" : "vcs",
@@ -915,24 +1102,24 @@
 -          "url" : "https://github.com/CycloneDX/cyclonedx-core-java";
 +          "alg" : "SHA-256",
 +          "content" : 
"7b751d952061954d5abfed7181c1f645d336091b679891591d63329c622eb832"
++        },
++        {
++          "alg" : "SHA-512",
++          "content" : 
"9a3e79db6666a6096a3021bb2e1d918f30f589d8de51d6b600f8ebd92515a510ae2d8f87919cc2dfa8365d64f10194cac8dfa0fb950160eef0e9da06f6caaeb9"
++        },
++        {
++          "alg" : "SHA3-256",
++          "content" : 
"00559b4f4066b4917ba4fe2a6f23111eaeada321112d030910d218ced9084b5e"
          },
          {
 -          "type" : "distribution-intake",
 -          "url" : 
"https://oss.sonatype.org/service/local/staging/deploy/maven2/";
-+          "alg" : "SHA-512",
-+          "content" : 
"9a3e79db6666a6096a3021bb2e1d918f30f589d8de51d6b600f8ebd92515a510ae2d8f87919cc2dfa8365d64f10194cac8dfa0fb950160eef0e9da06f6caaeb9"
++          "alg" : "SHA3-512",
++          "content" : 
"9579c2f7e7516e177c2d493ccc9eb8150978cf19f6f09b28d116f6935239fd56dc6af2b62b3336f79b0b462445550cd1fb5377a07001a6f44aaab6a32fa2fa47"
          },
          {
 -          "type" : "build-system",
 -          "url" : "https://github.com/CycloneDX/cyclonedx-core-java/actions";
-+          "alg" : "SHA3-256",
-+          "content" : 
"00559b4f4066b4917ba4fe2a6f23111eaeada321112d030910d218ced9084b5e"
-+        },
-+        {
-+          "alg" : "SHA3-512",
-+          "content" : 
"9579c2f7e7516e177c2d493ccc9eb8150978cf19f6f09b28d116f6935239fd56dc6af2b62b3336f79b0b462445550cd1fb5377a07001a6f44aaab6a32fa2fa47"
-+        },
-+        {
 +          "alg" : "SHA-384",
 +          "content" : 
"6ea24f814a9b6ece428cfd0535e2f3b8927005745ef61006b50fdb5a90126ee5ea05650155382b3b755c5bce38ef3944"
 +        },
@@ -1040,7 +1227,7 @@
      },
      {
        "ref" : 
"pkg:maven/com.fasterxml.jackson.core/[email protected]?type=jar",
-@@ -1667,10 +1455,33 @@
+@@ -1667,10 +1423,33 @@
        ]
      },
      {
@@ -1071,32 +1258,32 @@
 +      ]
 +    },
 +    {
-       "ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
+       "ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
        "dependsOn" : [ ]
      },
-@@ -1681,8 +1492,10 @@
+@@ -1681,8 +1460,10 @@
      {
        "ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
        "dependsOn" : [
-+        "pkg:maven/commons-codec/[email protected]?type=jar",
++        "pkg:maven/commons-codec/[email protected]?type=jar",
          "pkg:maven/org.apache.ant/[email protected]?type=jar",
          "pkg:maven/org.apache.ant/[email protected]?type=jar",
 +        "pkg:maven/org.apache.ivy/[email protected]?type=jar",
-         "pkg:maven/org.cyclonedx/[email protected]?type=jar"
+         "pkg:maven/org.cyclonedx/[email protected]?type=jar"
        ]
      },
-@@ -1698,9 +1511,7 @@
+@@ -1698,9 +1479,7 @@
      },
      {
        "ref" : 
"pkg:maven/org.apache.commons/[email protected]?type=jar",
 -      "dependsOn" : [
--        "pkg:maven/commons-codec/[email protected]?type=jar"
+-        "pkg:maven/commons-codec/[email protected]?type=jar"
 -      ]
 +      "dependsOn" : [ ]
      },
      {
        "ref" : "pkg:maven/org.apache.commons/[email protected]?type=jar",
-@@ -1708,20 +1519,7 @@
+@@ -1708,20 +1487,7 @@
      },
      {
        "ref" : "pkg:maven/org.apache.ivy/[email protected]?type=jar",
@@ -1118,7 +1305,7 @@
      },
      {
        "ref" : "pkg:maven/org.codehaus.woodstox/[email protected]?type=jar",
-@@ -1738,6 +1536,14 @@
+@@ -1738,6 +1504,14 @@
          "pkg:maven/org.apache.commons/[email protected]?type=jar",
          "pkg:maven/org.apache.commons/[email protected]?type=jar"
        ]
diff --git a/example/ant-cyclonedx-0.2alpha.cdx.json 
b/example/ant-cyclonedx-0.2alpha.cdx.json
index 2b4d835..1e8bed0 100644
--- a/example/ant-cyclonedx-0.2alpha.cdx.json
+++ b/example/ant-cyclonedx-0.2alpha.cdx.json
@@ -1,10 +1,10 @@
 {
   "bomFormat" : "CycloneDX",
   "specVersion" : "1.7",
-  "serialNumber" : "urn:uuid:46b215d3-5bd4-4619-92bf-4dd0883c885d",
+  "serialNumber" : "urn:uuid:068b13c8-01a0-1000-9297-150796a001fc",
   "version" : 1,
   "metadata" : {
-    "timestamp" : "2026-08-07T14:14:06Z",
+    "timestamp" : "2026-08-15T17:49:33Z",
     "lifecycles" : [
       {
         "phase" : "build"
@@ -34,35 +34,35 @@
           "hashes" : [
             {
               "alg" : "MD5",
-              "content" : "d325f6c7629142693fd8b9012f4ad22c"
+              "content" : "93377dd0fcea7a2d943bde92bdb2056d"
             },
             {
               "alg" : "SHA-1",
-              "content" : "e96723969081ffd5efbaa87c4378b7545f4fabe2"
+              "content" : "25394ae9ad3888e7e3634099cce4d75b2f2e6862"
             },
             {
               "alg" : "SHA-256",
-              "content" : 
"209f8ba54603780c2f0180494961c33439381dc0e35d3dbf85d55bd4dba93c81"
+              "content" : 
"ddab2702eeda163f45f2171c4ede688e2f009bb3c69491f7a60b7d95d425eaa2"
             },
             {
               "alg" : "SHA-512",
-              "content" : 
"5e40d417a70385d1bf492e24bd0e82d3bf99402a404e5a71634c1a5e0ba4d19ec0a4ff21b87e31ce42a0960af51b091dcfd44b2b9e2ceffb07e7f91a3403bd96"
+              "content" : 
"4fe694b6825907a148eff248d8610fb11ce6458104c7d5b734d9143a01df86fea019209ed8197850bdb84f1244365e05f689ace02355473008d1fc8866f8547f"
             },
             {
               "alg" : "SHA3-256",
-              "content" : 
"ff1bdad8b6fda462fd3a54110c7f01007d4bd99a99404a20abea045a2f21f6bd"
+              "content" : 
"daa143aa46e4bc6a5116227deb0236b99aaa3d15e213db19b83e358aa9aca434"
             },
             {
               "alg" : "SHA3-512",
-              "content" : 
"69067b921a6e07932e247dcddbf7f67b5f8e9aee4e9f603b6fa466f57da3b411e2639e932ef940a66666e0fde7ba16f2b84d7348ebacced9b573d5be274455ff"
+              "content" : 
"2656e4e335c95aaf2a531182d47f911218cb4f372cd676ea43437292e0a6a6f5c9a4581126e3ef2e1f2d2cb7a5ac928a8db7bc27fff8bcfd3a7c0b709d97d906"
             },
             {
               "alg" : "SHA-384",
-              "content" : 
"ea6d1749e734eb73788e2c427a3cc98af197fc141228d79fda7e3e440a0bb9d3724cc8f3e318368e0ec922b187cb7e21"
+              "content" : 
"f4d9f57cd6a5f17ae04201b6fa123572c1fa4552e3a61633bec3f598f1f3cf52eaad4d23560262af6a6c63e9d701801d"
             },
             {
               "alg" : "SHA3-384",
-              "content" : 
"8664a9d92721b1c7104cd4a6a9e4f785ffcd225bfabb6a911a3f4780e749acfc7afbc5ae3b873709e057e0e9dfae7b07"
+              "content" : 
"b3ba3c9d1206fa7cf3d1a90f12f145ce742ace71446cce5dc4ab3e98480933b55d8fc7c9d00cf19bc2d8faf88c3607a1"
             }
           ],
           "licenses" : [
@@ -146,35 +146,35 @@
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "d325f6c7629142693fd8b9012f4ad22c"
+          "content" : "93377dd0fcea7a2d943bde92bdb2056d"
         },
         {
           "alg" : "SHA-1",
-          "content" : "e96723969081ffd5efbaa87c4378b7545f4fabe2"
+          "content" : "25394ae9ad3888e7e3634099cce4d75b2f2e6862"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"209f8ba54603780c2f0180494961c33439381dc0e35d3dbf85d55bd4dba93c81"
+          "content" : 
"ddab2702eeda163f45f2171c4ede688e2f009bb3c69491f7a60b7d95d425eaa2"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"5e40d417a70385d1bf492e24bd0e82d3bf99402a404e5a71634c1a5e0ba4d19ec0a4ff21b87e31ce42a0960af51b091dcfd44b2b9e2ceffb07e7f91a3403bd96"
+          "content" : 
"4fe694b6825907a148eff248d8610fb11ce6458104c7d5b734d9143a01df86fea019209ed8197850bdb84f1244365e05f689ace02355473008d1fc8866f8547f"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"ff1bdad8b6fda462fd3a54110c7f01007d4bd99a99404a20abea045a2f21f6bd"
+          "content" : 
"daa143aa46e4bc6a5116227deb0236b99aaa3d15e213db19b83e358aa9aca434"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"69067b921a6e07932e247dcddbf7f67b5f8e9aee4e9f603b6fa466f57da3b411e2639e932ef940a66666e0fde7ba16f2b84d7348ebacced9b573d5be274455ff"
+          "content" : 
"2656e4e335c95aaf2a531182d47f911218cb4f372cd676ea43437292e0a6a6f5c9a4581126e3ef2e1f2d2cb7a5ac928a8db7bc27fff8bcfd3a7c0b709d97d906"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"ea6d1749e734eb73788e2c427a3cc98af197fc141228d79fda7e3e440a0bb9d3724cc8f3e318368e0ec922b187cb7e21"
+          "content" : 
"f4d9f57cd6a5f17ae04201b6fa123572c1fa4552e3a61633bec3f598f1f3cf52eaad4d23560262af6a6c63e9d701801d"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"8664a9d92721b1c7104cd4a6a9e4f785ffcd225bfabb6a911a3f4780e749acfc7afbc5ae3b873709e057e0e9dfae7b07"
+          "content" : 
"b3ba3c9d1206fa7cf3d1a90f12f145ce742ace71446cce5dc4ab3e98480933b55d8fc7c9d00cf19bc2d8faf88c3607a1"
         }
       ],
       "licenses" : [
@@ -818,44 +818,44 @@
     },
     {
       "type" : "library",
-      "bom-ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
+      "bom-ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
       "publisher" : "The Apache Software Foundation",
       "group" : "commons-codec",
       "name" : "commons-codec",
-      "version" : "1.22.0",
+      "version" : "1.22.1",
       "description" : "The Apache Commons Codec component contains encoders 
and decoders for formats such as Base16, Base32, Base64, digest, and 
Hexadecimal. In addition to these widely used encoders and decoders, the codec 
package also maintains a collection of phonetic encoding utilities.",
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "f14b9146cd553f4e8c5c3f5c9e2be611"
+          "content" : "7bfd10447817907ffd7f14fbc6493940"
         },
         {
           "alg" : "SHA-1",
-          "content" : "6b3eb4beb7058c2a638f5f17bcb388649fd339dd"
+          "content" : "da09bcdb330deef7cfee70f30c6889fda70d5ebf"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"d164fe79f262c32d9b18a0b5b2d317d1c27653d5e98fd2b998c24bf901c72ce4"
+          "content" : 
"78a5d732fbd715e2d10bd7150d2f8030bae57267f8aacc5c88f642cb6c2e5d3f"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"5b67a5abf63948323101920fec10140d4370b841cc3c522a2b5e9864782640222c3094442861015494ddbc30bb7ef275722a54455c7c8333084842a26d8755da"
+          "content" : 
"1e2023b6e7715339a309226c94635db77fd3d8d7f6fc1048e0138dc4b4ff27540e1e1ff2238a41b94029a9497b2935af6e8b05eeeed69b76600c2f4eed3e36ed"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"566a61c3b928e33c5332e4fbb53283411c9f3d88810e84692a72664e711c8c9e"
+          "content" : 
"70d7c377536c088c88d043b4f3297cb58ea9bd7d8374514f16060ca62977253e"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"d300b773cd81403333626ce99a80a79febcf7e3bc4465c1bbd3e65fc8ad5fe04c07e0a4ab8ca51a61d515c7a095d786c78e8a8b657f7696703a6cc751e9d2421"
+          "content" : 
"7885692a52215d8ea620afc25b22719c835d9079265592a9b790e4c13b1cd5cbb023eb9cf39a304e463cf280dd7931ca966528c9bb14b58c400018699c058ec7"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"1cbfa58c62c4c3fad79f3a808e5d7fca87f4a96d2762f11243011ecf3ea0596638d00163b7fee20bab018a924cafa09f"
+          "content" : 
"29f01c913caa51660ff4a8623255f819961ee63b20b125a1c3e5f061b4a75864c1a349420f6d314009b4cf12524aecfb"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"1c0b65c0a1ab43e76dab19e4e0a622840dfcd603924f27bbd09c2261955047f1dd33e5c09a372badaa020f13a0b0124a"
+          "content" : 
"de7a0317378663055c9a2f80d30bc543549924e994a27c683ee1ff405587395d00b13d277dd39ceb09fa64a9f110d09e"
         }
       ],
       "licenses" : [
@@ -866,7 +866,7 @@
           }
         }
       ],
-      "purl" : "pkg:maven/commons-codec/[email protected]?type=jar",
+      "purl" : "pkg:maven/commons-codec/[email protected]?type=jar",
       "externalReferences" : [
         {
           "type" : "vcs",
@@ -882,7 +882,7 @@
         },
         {
           "type" : "bom",
-          "url" : 
"https://repo1.maven.org/maven2/commons-codec/commons-codec/1.22.0/commons-codec-1.22.0-cyclonedx.json";
+          "url" : 
"https://repo1.maven.org/maven2/commons-codec/commons-codec/1.22.1/commons-codec-1.22.1-cyclonedx.json";
         },
         {
           "type" : "mailing-list",
@@ -1549,44 +1549,44 @@
     },
     {
       "type" : "library",
-      "bom-ref" : 
"pkg:maven/org.cyclonedx/[email protected]?type=jar",
+      "bom-ref" : 
"pkg:maven/org.cyclonedx/[email protected]?type=jar",
       "publisher" : "OWASP Foundation",
       "group" : "org.cyclonedx",
       "name" : "cyclonedx-core-java",
-      "version" : "13.0.0",
+      "version" : "13.1.0",
       "description" : "The CycloneDX core module provides a model 
representation of the BOM along with utilities to assist in creating, parsing, 
and validating BOMs.",
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "1fe4b7cc2f01f52aef5544d73be07533"
+          "content" : "2a1f9504d12d4dda17ee5c99b9403600"
         },
         {
           "alg" : "SHA-1",
-          "content" : "d29aec05c781badba0ad5a589c37a1ff8b7fb583"
+          "content" : "7e386c72d52b61db961ca3e0dadb55015e8bb296"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"8c2bc1cccb4e2c6c0bcc2b0bacc4da0a110aad2a05791b750caf281e7769ce82"
+          "content" : 
"bae52da4a65d5e085c935a1c31f31d511ab499f4bf6526b568c12fb724f26363"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"92cd61fe5a21044d60fdf87e5a14c1655065601370e7c739db5ac5f803bd5282061c86ab6f38146d690309f8058cf09381806ad09e899a85dcf417e1d3b366c5"
+          "content" : 
"30271282daab9f49f3fd9cfbf38bb6c108f4a3c3888256dcb7e830b2d6b7459c561e261ca4555a20da24b27d7780886fcd3243b6f260bf04f684ba862db43521"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"4e2b3a5800ef8cdf7b50d926d4c18261ad54074173b1bf02079ea83ab1d1b3a2"
+          "content" : 
"f731996247ea9149e4918473f894af24901ede63d6565d2be446c827994aedd3"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"b63d4b54f84ec0071bd7263fbc190017fa28f15db7bee318fea9588d6b4063a408a7177410cfaa0d0fa9dbb34a5e0fb1ef5d63195f66014c64495cf5f46590db"
+          "content" : 
"f287f67e2510ec886385665f2790ce4c675c2a7ea175991660167825fd6e9fa3c3d867e74865081be91f0690bba215e5d010888e43c468e462dddba7dea9d108"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"81d28eeb136fd1751a4ba4ebbe20025e528b1c329804c164e540fd9ddd7da09c5752428a18120fdbccfd9d6f67750292"
+          "content" : 
"b9a088c711e4f3d99f07f4c4fada8fe40cff9fcfc83bd447f3eecde38f002d1d47dac98002645e3c43169ad3a333b1e0"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"dce70366596f8075dc6530a3e038b3bb43427b6ff6928483901309ddefd3840927da18e9f65176201187e4c420cbed7e"
+          "content" : 
"5f45b1ecfda645f548e9e4a0fcc906f17178745835e640d127fae37cf981da7b26ab60c540d6ad99bab56a946b9b2f9e"
         }
       ],
       "licenses" : [
@@ -1597,7 +1597,7 @@
           }
         }
       ],
-      "purl" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
+      "purl" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
       "externalReferences" : [
         {
           "type" : "vcs",
@@ -1671,7 +1671,7 @@
       "dependsOn" : [ ]
     },
     {
-      "ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
+      "ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
       "dependsOn" : [ ]
     },
     {
@@ -1683,7 +1683,7 @@
       "dependsOn" : [
         "pkg:maven/org.apache.ant/[email protected]?type=jar",
         "pkg:maven/org.apache.ant/[email protected]?type=jar",
-        "pkg:maven/org.cyclonedx/[email protected]?type=jar"
+        "pkg:maven/org.cyclonedx/[email protected]?type=jar"
       ]
     },
     {
@@ -1699,7 +1699,7 @@
     {
       "ref" : 
"pkg:maven/org.apache.commons/[email protected]?type=jar",
       "dependsOn" : [
-        "pkg:maven/commons-codec/[email protected]?type=jar"
+        "pkg:maven/commons-codec/[email protected]?type=jar"
       ]
     },
     {
@@ -1728,12 +1728,12 @@
       "dependsOn" : [ ]
     },
     {
-      "ref" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
+      "ref" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
       "dependsOn" : [
         
"pkg:maven/com.fasterxml.jackson.dataformat/[email protected]?type=jar",
         "pkg:maven/com.github.package-url/[email protected]?type=jar",
         "pkg:maven/com.networknt/[email protected]?type=jar",
-        "pkg:maven/commons-codec/[email protected]?type=jar",
+        "pkg:maven/commons-codec/[email protected]?type=jar",
         "pkg:maven/commons-io/[email protected]?type=jar",
         "pkg:maven/org.apache.commons/[email protected]?type=jar",
         "pkg:maven/org.apache.commons/[email protected]?type=jar"
diff --git a/example/ant-cyclonedx-0.2alpha.ivy.cdx.json 
b/example/ant-cyclonedx-0.2alpha.ivy.cdx.json
index d4b57ff..6a0c152 100644
--- a/example/ant-cyclonedx-0.2alpha.ivy.cdx.json
+++ b/example/ant-cyclonedx-0.2alpha.ivy.cdx.json
@@ -1,10 +1,10 @@
 {
   "bomFormat" : "CycloneDX",
   "specVersion" : "1.7",
-  "serialNumber" : "urn:uuid:2ef84f46-64af-4fb9-b3da-70f4fcb7acd3",
+  "serialNumber" : "urn:uuid:068b13c8-01a0-1000-9297-150796a001fc",
   "version" : 1,
   "metadata" : {
-    "timestamp" : "2026-08-07T14:13:23Z",
+    "timestamp" : "2026-08-15T17:49:33Z",
     "lifecycles" : [
       {
         "phase" : "build"
@@ -34,35 +34,35 @@
           "hashes" : [
             {
               "alg" : "MD5",
-              "content" : "d325f6c7629142693fd8b9012f4ad22c"
+              "content" : "93377dd0fcea7a2d943bde92bdb2056d"
             },
             {
               "alg" : "SHA-1",
-              "content" : "e96723969081ffd5efbaa87c4378b7545f4fabe2"
+              "content" : "25394ae9ad3888e7e3634099cce4d75b2f2e6862"
             },
             {
               "alg" : "SHA-256",
-              "content" : 
"209f8ba54603780c2f0180494961c33439381dc0e35d3dbf85d55bd4dba93c81"
+              "content" : 
"ddab2702eeda163f45f2171c4ede688e2f009bb3c69491f7a60b7d95d425eaa2"
             },
             {
               "alg" : "SHA-512",
-              "content" : 
"5e40d417a70385d1bf492e24bd0e82d3bf99402a404e5a71634c1a5e0ba4d19ec0a4ff21b87e31ce42a0960af51b091dcfd44b2b9e2ceffb07e7f91a3403bd96"
+              "content" : 
"4fe694b6825907a148eff248d8610fb11ce6458104c7d5b734d9143a01df86fea019209ed8197850bdb84f1244365e05f689ace02355473008d1fc8866f8547f"
             },
             {
               "alg" : "SHA3-256",
-              "content" : 
"ff1bdad8b6fda462fd3a54110c7f01007d4bd99a99404a20abea045a2f21f6bd"
+              "content" : 
"daa143aa46e4bc6a5116227deb0236b99aaa3d15e213db19b83e358aa9aca434"
             },
             {
               "alg" : "SHA3-512",
-              "content" : 
"69067b921a6e07932e247dcddbf7f67b5f8e9aee4e9f603b6fa466f57da3b411e2639e932ef940a66666e0fde7ba16f2b84d7348ebacced9b573d5be274455ff"
+              "content" : 
"2656e4e335c95aaf2a531182d47f911218cb4f372cd676ea43437292e0a6a6f5c9a4581126e3ef2e1f2d2cb7a5ac928a8db7bc27fff8bcfd3a7c0b709d97d906"
             },
             {
               "alg" : "SHA-384",
-              "content" : 
"ea6d1749e734eb73788e2c427a3cc98af197fc141228d79fda7e3e440a0bb9d3724cc8f3e318368e0ec922b187cb7e21"
+              "content" : 
"f4d9f57cd6a5f17ae04201b6fa123572c1fa4552e3a61633bec3f598f1f3cf52eaad4d23560262af6a6c63e9d701801d"
             },
             {
               "alg" : "SHA3-384",
-              "content" : 
"8664a9d92721b1c7104cd4a6a9e4f785ffcd225bfabb6a911a3f4780e749acfc7afbc5ae3b873709e057e0e9dfae7b07"
+              "content" : 
"b3ba3c9d1206fa7cf3d1a90f12f145ce742ace71446cce5dc4ab3e98480933b55d8fc7c9d00cf19bc2d8faf88c3607a1"
             }
           ],
           "licenses" : [
@@ -146,35 +146,35 @@
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "d325f6c7629142693fd8b9012f4ad22c"
+          "content" : "93377dd0fcea7a2d943bde92bdb2056d"
         },
         {
           "alg" : "SHA-1",
-          "content" : "e96723969081ffd5efbaa87c4378b7545f4fabe2"
+          "content" : "25394ae9ad3888e7e3634099cce4d75b2f2e6862"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"209f8ba54603780c2f0180494961c33439381dc0e35d3dbf85d55bd4dba93c81"
+          "content" : 
"ddab2702eeda163f45f2171c4ede688e2f009bb3c69491f7a60b7d95d425eaa2"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"5e40d417a70385d1bf492e24bd0e82d3bf99402a404e5a71634c1a5e0ba4d19ec0a4ff21b87e31ce42a0960af51b091dcfd44b2b9e2ceffb07e7f91a3403bd96"
+          "content" : 
"4fe694b6825907a148eff248d8610fb11ce6458104c7d5b734d9143a01df86fea019209ed8197850bdb84f1244365e05f689ace02355473008d1fc8866f8547f"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"ff1bdad8b6fda462fd3a54110c7f01007d4bd99a99404a20abea045a2f21f6bd"
+          "content" : 
"daa143aa46e4bc6a5116227deb0236b99aaa3d15e213db19b83e358aa9aca434"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"69067b921a6e07932e247dcddbf7f67b5f8e9aee4e9f603b6fa466f57da3b411e2639e932ef940a66666e0fde7ba16f2b84d7348ebacced9b573d5be274455ff"
+          "content" : 
"2656e4e335c95aaf2a531182d47f911218cb4f372cd676ea43437292e0a6a6f5c9a4581126e3ef2e1f2d2cb7a5ac928a8db7bc27fff8bcfd3a7c0b709d97d906"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"ea6d1749e734eb73788e2c427a3cc98af197fc141228d79fda7e3e440a0bb9d3724cc8f3e318368e0ec922b187cb7e21"
+          "content" : 
"f4d9f57cd6a5f17ae04201b6fa123572c1fa4552e3a61633bec3f598f1f3cf52eaad4d23560262af6a6c63e9d701801d"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"8664a9d92721b1c7104cd4a6a9e4f785ffcd225bfabb6a911a3f4780e749acfc7afbc5ae3b873709e057e0e9dfae7b07"
+          "content" : 
"b3ba3c9d1206fa7cf3d1a90f12f145ce742ace71446cce5dc4ab3e98480933b55d8fc7c9d00cf19bc2d8faf88c3607a1"
         }
       ],
       "licenses" : [
@@ -766,43 +766,43 @@
     },
     {
       "type" : "library",
-      "bom-ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
+      "bom-ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
       "group" : "commons-codec",
       "name" : "commons-codec",
-      "version" : "1.22.0",
+      "version" : "1.22.1",
       "description" : "The Apache Commons Codec component contains encoders 
and decoders for formats such as Base16, Base32, Base64, digest, and 
Hexadecimal. In addition to these widely used encoders and decoders, the codec 
package also maintains a collection of phonetic encoding utilities.",
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "f14b9146cd553f4e8c5c3f5c9e2be611"
+          "content" : "7bfd10447817907ffd7f14fbc6493940"
         },
         {
           "alg" : "SHA-1",
-          "content" : "6b3eb4beb7058c2a638f5f17bcb388649fd339dd"
+          "content" : "da09bcdb330deef7cfee70f30c6889fda70d5ebf"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"d164fe79f262c32d9b18a0b5b2d317d1c27653d5e98fd2b998c24bf901c72ce4"
+          "content" : 
"78a5d732fbd715e2d10bd7150d2f8030bae57267f8aacc5c88f642cb6c2e5d3f"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"5b67a5abf63948323101920fec10140d4370b841cc3c522a2b5e9864782640222c3094442861015494ddbc30bb7ef275722a54455c7c8333084842a26d8755da"
+          "content" : 
"1e2023b6e7715339a309226c94635db77fd3d8d7f6fc1048e0138dc4b4ff27540e1e1ff2238a41b94029a9497b2935af6e8b05eeeed69b76600c2f4eed3e36ed"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"566a61c3b928e33c5332e4fbb53283411c9f3d88810e84692a72664e711c8c9e"
+          "content" : 
"70d7c377536c088c88d043b4f3297cb58ea9bd7d8374514f16060ca62977253e"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"d300b773cd81403333626ce99a80a79febcf7e3bc4465c1bbd3e65fc8ad5fe04c07e0a4ab8ca51a61d515c7a095d786c78e8a8b657f7696703a6cc751e9d2421"
+          "content" : 
"7885692a52215d8ea620afc25b22719c835d9079265592a9b790e4c13b1cd5cbb023eb9cf39a304e463cf280dd7931ca966528c9bb14b58c400018699c058ec7"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"1cbfa58c62c4c3fad79f3a808e5d7fca87f4a96d2762f11243011ecf3ea0596638d00163b7fee20bab018a924cafa09f"
+          "content" : 
"29f01c913caa51660ff4a8623255f819961ee63b20b125a1c3e5f061b4a75864c1a349420f6d314009b4cf12524aecfb"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"1c0b65c0a1ab43e76dab19e4e0a622840dfcd603924f27bbd09c2261955047f1dd33e5c09a372badaa020f13a0b0124a"
+          "content" : 
"de7a0317378663055c9a2f80d30bc543549924e994a27c683ee1ff405587395d00b13d277dd39ceb09fa64a9f110d09e"
         }
       ],
       "licenses" : [
@@ -813,7 +813,7 @@
           }
         }
       ],
-      "purl" : "pkg:maven/commons-codec/[email protected]?type=jar",
+      "purl" : "pkg:maven/commons-codec/[email protected]?type=jar",
       "externalReferences" : [
         {
           "type" : "website",
@@ -882,72 +882,56 @@
       "type" : "library",
       "bom-ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
       "isExternal" : true,
-      "supplier" : {
-        "name" : "Apache Ant Project Management Committee",
-        "url" : [
-          "https://ant.apache.org/";
-        ]
-      },
       "group" : "org.apache.ant",
       "name" : "ant-launcher",
       "version" : "1.10.17",
-      "licenses" : [
-        {
-          "license" : {
-            "id" : "Apache-2.0",
-            "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
-          }
-        }
-      ],
-      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
-      "externalReferences" : [
-        {
-          "type" : "vcs",
-          "url" : "https://gitbox.apache.org/repos/asf/ant.git";
-        },
-        {
-          "type" : "issue-tracker",
-          "url" : "https://bz.apache.org/bugzilla/buglist.cgi?product=Ant";
-        },
+      "hashes" : [
         {
-          "type" : "website",
-          "url" : "https://ant.apache.org/";
+          "alg" : "MD5",
+          "content" : "6f03c0937a15756fd7bc7bb98d6ee360"
         },
         {
-          "type" : "advisories",
-          "url" : 
"https://ant.apache.org/security.html#Apache%20Ant%20Security%20Vulnerabilities";
+          "alg" : "SHA-1",
+          "content" : "a65884e1ff214f724a6e9c089365c71935c488e4"
         },
         {
-          "type" : "mailing-list",
-          "url" : "https://ant.apache.org/mail.html";
+          "alg" : "SHA-256",
+          "content" : 
"f6e3de06dc0ea396638004f1a003f55fdbd20c3e7ccfb9b7a524f49fd0ae8568"
         },
         {
-          "type" : "documentation",
-          "url" : "https://ant.apache.org/manual/";
+          "alg" : "SHA-512",
+          "content" : 
"73fef113f238f6fcfe94e7d58824207ea6557626262f27d3bd20ab3bbba6af848ee5998ad915a7fa3999e0e368bb1f7ae1bf90888295989a15236a73c7d08709"
         },
         {
-          "type" : "source-distribution",
-          "url" : "https://ant.apache.org/srcdownload.cgi";
+          "alg" : "SHA3-256",
+          "content" : 
"80ef280b77fd566dde6c6438a974f993db7540dc7a99ea89e43557df769a7f17"
         },
         {
-          "type" : "distribution",
-          "url" : "https://ant.apache.org/bindownload.cgi";
+          "alg" : "SHA3-512",
+          "content" : 
"b9700c9f92513d503c806ed1ce2fed1d351a79f609ac8b30d4ec27580b0976d67cbecbe040647c7602f549f18ef8ac4fa37cc54d47a577e5046f0f86ff21de39"
         },
         {
-          "type" : "license",
-          "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
+          "alg" : "SHA-384",
+          "content" : 
"3cfaf78d72581170b94df32d7b069bab2e10fa8ae56d2973de3a750ec45aaeb194d89714dacc77af8f9892802a4a7ec6"
         },
         {
-          "type" : "release-notes",
-          "url" : "https://github.com/apache/ant/blob/master/WHATSNEW";
-        },
+          "alg" : "SHA3-384",
+          "content" : 
"447a649c728ffc652a3676904a3001e41cd10387dafe90df97fa121c8e824822a98a00b9a3de3cbd93b19355ad51d7a7"
+        }
+      ],
+      "licenses" : [
         {
-          "type" : "security-contact",
-          "url" : "https://www.apache.org/security/";
-        },
+          "license" : {
+            "name" : "The Apache Software License, Version 2.0",
+            "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
+          }
+        }
+      ],
+      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
+      "externalReferences" : [
         {
-          "type" : "rfc-9116",
-          "url" : "https://ant.apache.org/.well-known/security.txt";
+          "type" : "website",
+          "url" : "https://ant.apache.org/";
         }
       ]
     },
@@ -955,72 +939,56 @@
       "type" : "library",
       "bom-ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
       "isExternal" : true,
-      "supplier" : {
-        "name" : "Apache Ant Project Management Committee",
-        "url" : [
-          "https://ant.apache.org/";
-        ]
-      },
       "group" : "org.apache.ant",
       "name" : "ant",
       "version" : "1.10.17",
-      "licenses" : [
-        {
-          "license" : {
-            "id" : "Apache-2.0",
-            "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
-          }
-        }
-      ],
-      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
-      "externalReferences" : [
-        {
-          "type" : "vcs",
-          "url" : "https://gitbox.apache.org/repos/asf/ant.git";
-        },
-        {
-          "type" : "issue-tracker",
-          "url" : "https://bz.apache.org/bugzilla/buglist.cgi?product=Ant";
-        },
+      "hashes" : [
         {
-          "type" : "website",
-          "url" : "https://ant.apache.org/";
+          "alg" : "MD5",
+          "content" : "7deb57aad47476c63e707ea57533e43b"
         },
         {
-          "type" : "advisories",
-          "url" : 
"https://ant.apache.org/security.html#Apache%20Ant%20Security%20Vulnerabilities";
+          "alg" : "SHA-1",
+          "content" : "fa8a13422ac460563171d10a37c3f28340a953f6"
         },
         {
-          "type" : "mailing-list",
-          "url" : "https://ant.apache.org/mail.html";
+          "alg" : "SHA-256",
+          "content" : 
"8be692e02837f41a47a3d21cde6655792142fdf42fe23bcb16d7129cad9b2284"
         },
         {
-          "type" : "documentation",
-          "url" : "https://ant.apache.org/manual/";
+          "alg" : "SHA-512",
+          "content" : 
"f1cc1a82e1abcf613d4ccf080f83fcd51acd7d4a2f1c2841cca90dd1ebaa96fab2df6411abd2cf97e2ec74231b1540a5d15c12117ba777ab1538b61f9f2b5fa9"
         },
         {
-          "type" : "source-distribution",
-          "url" : "https://ant.apache.org/srcdownload.cgi";
+          "alg" : "SHA3-256",
+          "content" : 
"540a9cc40d8c9c4e004b04bd6af4a590e18d2077e93d441a9dcbdf90798b31b6"
         },
         {
-          "type" : "distribution",
-          "url" : "https://ant.apache.org/bindownload.cgi";
+          "alg" : "SHA3-512",
+          "content" : 
"7a65837340a624a8f9eb68a56c78b6891ddf95cd617ccbc227e2fe88b53f59c2cea7d856b4d803898f2bb2317dbc8f8124d3c35154e3cee555d97fe064a8739d"
         },
         {
-          "type" : "license",
-          "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
+          "alg" : "SHA-384",
+          "content" : 
"2af275805479b9cfcfdae25f19cce911922207bc2fb77c2c44caf8633c56cd7d772ab30134bac68aacf0ea6e444fa50c"
         },
         {
-          "type" : "release-notes",
-          "url" : "https://github.com/apache/ant/blob/master/WHATSNEW";
-        },
+          "alg" : "SHA3-384",
+          "content" : 
"71205d360f909df37fef5b427538c22977e01801108a1cb37387d1f72e784509796a915c2069a12762a78b990d0aa207"
+        }
+      ],
+      "licenses" : [
         {
-          "type" : "security-contact",
-          "url" : "https://www.apache.org/security/";
-        },
+          "license" : {
+            "name" : "The Apache Software License, Version 2.0",
+            "url" : "https://www.apache.org/licenses/LICENSE-2.0.txt";
+          }
+        }
+      ],
+      "purl" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
+      "externalReferences" : [
         {
-          "type" : "rfc-9116",
-          "url" : "https://ant.apache.org/.well-known/security.txt";
+          "type" : "website",
+          "url" : "https://ant.apache.org/";
         }
       ]
     },
@@ -1254,43 +1222,43 @@
     },
     {
       "type" : "library",
-      "bom-ref" : 
"pkg:maven/org.cyclonedx/[email protected]?type=jar",
+      "bom-ref" : 
"pkg:maven/org.cyclonedx/[email protected]?type=jar",
       "group" : "org.cyclonedx",
       "name" : "cyclonedx-core-java",
-      "version" : "13.0.0",
+      "version" : "13.1.0",
       "description" : "The CycloneDX core module provides a model 
representation of the BOM along with utilities to assist in creating, parsing, 
and validating BOMs.",
       "hashes" : [
         {
           "alg" : "MD5",
-          "content" : "1fe4b7cc2f01f52aef5544d73be07533"
+          "content" : "2a1f9504d12d4dda17ee5c99b9403600"
         },
         {
           "alg" : "SHA-1",
-          "content" : "d29aec05c781badba0ad5a589c37a1ff8b7fb583"
+          "content" : "7e386c72d52b61db961ca3e0dadb55015e8bb296"
         },
         {
           "alg" : "SHA-256",
-          "content" : 
"8c2bc1cccb4e2c6c0bcc2b0bacc4da0a110aad2a05791b750caf281e7769ce82"
+          "content" : 
"bae52da4a65d5e085c935a1c31f31d511ab499f4bf6526b568c12fb724f26363"
         },
         {
           "alg" : "SHA-512",
-          "content" : 
"92cd61fe5a21044d60fdf87e5a14c1655065601370e7c739db5ac5f803bd5282061c86ab6f38146d690309f8058cf09381806ad09e899a85dcf417e1d3b366c5"
+          "content" : 
"30271282daab9f49f3fd9cfbf38bb6c108f4a3c3888256dcb7e830b2d6b7459c561e261ca4555a20da24b27d7780886fcd3243b6f260bf04f684ba862db43521"
         },
         {
           "alg" : "SHA3-256",
-          "content" : 
"4e2b3a5800ef8cdf7b50d926d4c18261ad54074173b1bf02079ea83ab1d1b3a2"
+          "content" : 
"f731996247ea9149e4918473f894af24901ede63d6565d2be446c827994aedd3"
         },
         {
           "alg" : "SHA3-512",
-          "content" : 
"b63d4b54f84ec0071bd7263fbc190017fa28f15db7bee318fea9588d6b4063a408a7177410cfaa0d0fa9dbb34a5e0fb1ef5d63195f66014c64495cf5f46590db"
+          "content" : 
"f287f67e2510ec886385665f2790ce4c675c2a7ea175991660167825fd6e9fa3c3d867e74865081be91f0690bba215e5d010888e43c468e462dddba7dea9d108"
         },
         {
           "alg" : "SHA-384",
-          "content" : 
"81d28eeb136fd1751a4ba4ebbe20025e528b1c329804c164e540fd9ddd7da09c5752428a18120fdbccfd9d6f67750292"
+          "content" : 
"b9a088c711e4f3d99f07f4c4fada8fe40cff9fcfc83bd447f3eecde38f002d1d47dac98002645e3c43169ad3a333b1e0"
         },
         {
           "alg" : "SHA3-384",
-          "content" : 
"dce70366596f8075dc6530a3e038b3bb43427b6ff6928483901309ddefd3840927da18e9f65176201187e4c420cbed7e"
+          "content" : 
"5f45b1ecfda645f548e9e4a0fcc906f17178745835e640d127fae37cf981da7b26ab60c540d6ad99bab56a946b9b2f9e"
         }
       ],
       "licenses" : [
@@ -1301,7 +1269,7 @@
           }
         }
       ],
-      "purl" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
+      "purl" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
       "externalReferences" : [
         {
           "type" : "website",
@@ -1482,7 +1450,7 @@
       ]
     },
     {
-      "ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
+      "ref" : "pkg:maven/commons-codec/[email protected]?type=jar",
       "dependsOn" : [ ]
     },
     {
@@ -1492,11 +1460,11 @@
     {
       "ref" : "pkg:maven/org.apache.ant/[email protected]?type=jar",
       "dependsOn" : [
-        "pkg:maven/commons-codec/[email protected]?type=jar",
+        "pkg:maven/commons-codec/[email protected]?type=jar",
         "pkg:maven/org.apache.ant/[email protected]?type=jar",
         "pkg:maven/org.apache.ant/[email protected]?type=jar",
         "pkg:maven/org.apache.ivy/[email protected]?type=jar",
-        "pkg:maven/org.cyclonedx/[email protected]?type=jar"
+        "pkg:maven/org.cyclonedx/[email protected]?type=jar"
       ]
     },
     {
@@ -1526,12 +1494,12 @@
       "dependsOn" : [ ]
     },
     {
-      "ref" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
+      "ref" : "pkg:maven/org.cyclonedx/[email protected]?type=jar",
       "dependsOn" : [
         
"pkg:maven/com.fasterxml.jackson.dataformat/[email protected]?type=jar",
         "pkg:maven/com.github.package-url/[email protected]?type=jar",
         "pkg:maven/com.networknt/[email protected]?type=jar",
-        "pkg:maven/commons-codec/[email protected]?type=jar",
+        "pkg:maven/commons-codec/[email protected]?type=jar",
         "pkg:maven/commons-io/[email protected]?type=jar",
         "pkg:maven/org.apache.commons/[email protected]?type=jar",
         "pkg:maven/org.apache.commons/[email protected]?type=jar"
diff --git a/src/main/org/apache/ant/cyclonedx/Component.java 
b/src/main/org/apache/ant/cyclonedx/Component.java
index afa748c..07744d3 100644
--- a/src/main/org/apache/ant/cyclonedx/Component.java
+++ b/src/main/org/apache/ant/cyclonedx/Component.java
@@ -25,9 +25,11 @@ import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import java.util.Stack;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 
 import org.apache.tools.ant.BuildException;
@@ -123,6 +125,48 @@ public class Component extends DataType {
         Comparator.comparing(Property::getName)
         .thenComparing(Property::getValue, 
Comparator.nullsLast(Comparator.naturalOrder()));
 
+    /**
+     * Default constructor.
+     */
+    public Component() {
+    }
+
+    /**
+     * Copy constructor creating a shallow copy.
+     *
+     * @param other component to copy data from
+     * @since CycloneDX Antlib 0.2
+     */
+    protected Component(Component other) {
+        this.resource = other.resource;
+        this.type = other.type;
+        this.name = other.name;
+        this.group = other.group;
+        this.publisher = other.publisher;
+        this.version = other.version;
+        this.description = other.description;
+        this.copyright = other.copyright;
+        this.manufacturer = other.manufacturer;
+        this.supplier = other.supplier;
+        this.supplierIsManufacturer = other.supplierIsManufacturer;
+        this.licenses = new ArrayList<>(other.licenses);
+        this.purl = other.purl;
+        this.bomRef = other.bomRef;
+        this.externalReferences = new ArrayList<>(other.externalReferences);
+        this.scope = other.scope;
+        this.isExternal = other.isExternal;
+        this.nestedComponents = new ArrayList<>(other.nestedComponents);
+        this.dependencies = new ArrayList<>(other.dependencies);
+        this.unknownDependencies = other.unknownDependencies;
+        this.resolved = other.resolved;
+        this.authors = new ArrayList<>(other.authors);
+        this.tags = new HashSet<>(other.tags);
+        this.properties = new ArrayList<>(other.properties);
+        this.mimeType = other.mimeType;
+        this.sbomLink = other.sbomLink;
+        this.ivyModule = other.ivyModule;
+    }
+
     /**
      * Sets the resource the component is about.
      *
@@ -588,6 +632,20 @@ public class Component extends DataType {
         return externalReferences;
     }
 
+    /**
+     * Gets whether the isExternal flag is true.
+     *
+     * @return whether the isExternal flag is true
+     * @since CycloneDX Antlib 0.2
+     */
+    boolean getIsExternal() {
+        if (isReference()) {
+            return getRef().getIsExternal();
+        }
+        dieOnCircularReference();
+        return isExternal;
+    }
+
     /**
      * Gets whether any licenses have been explicitly configured for this 
component.
      *
@@ -1129,6 +1187,7 @@ public class Component extends DataType {
         private String resolveId;
         private Reference antIvyEngineRef;
         private String pattern;
+        private List<Component> templateComponents = new ArrayList<>();
 
         /**
          * Sets the configurations to include in the SBOM.
@@ -1224,5 +1283,31 @@ public class Component extends DataType {
         String getPattern() {
             return pattern;
         }
+
+        /**
+         * Adds a nested template component.
+         *
+         * @param c nested template component
+         */
+        public void addTemplateComponent(Component c) {
+            templateComponents.add(c);
+        }
+
+        Map<String, Component> getTemplateComponents() {
+            return templateComponents.stream()
+                .collect(Collectors.toMap(IvyModule::getTemplateComponentKey, 
Function.identity()));
+        }
+
+        static String getTemplateComponentKey(Component c) {
+            String group = c.getGroup();
+            if (group == null) {
+                group = "";
+            }
+            String name = c.getName();
+            if (name == null) {
+                name = "";
+            }
+            return group + ":" + name;
+        }
     }
 }
diff --git a/src/main/org/apache/ant/cyclonedx/IvyModuleComponentResolver.java 
b/src/main/org/apache/ant/cyclonedx/IvyModuleComponentResolver.java
index 65fa1e8..87d2d34 100644
--- a/src/main/org/apache/ant/cyclonedx/IvyModuleComponentResolver.java
+++ b/src/main/org/apache/ant/cyclonedx/IvyModuleComponentResolver.java
@@ -177,17 +177,20 @@ class IvyModuleComponentResolver {
                                   Set<ModuleRevisionId> optionalModules,
                                   Set<ModuleRevisionId> externalModules,
                                   Map<ModuleRevisionId, File> componentFiles) {
-        Component c = new Component();
+        ModuleRevisionId mrid = md.getModuleRevisionId();
+        Component template = 
ivyModule.getTemplateComponents().get(mrid.getOrganisation() + ":" + 
mrid.getName());
+        Component c = template == null ? new Component() : new 
Component(template);
         c.setProject(project);
         fillFromModuleDescriptor(c, md, dependencyTree);
 
-        ModuleRevisionId mrid = md.getModuleRevisionId();
         if (optionalModules.contains(mrid)) {
             c.setScope(ComponentScope.from(Scope.OPTIONAL));
         }
-        c.setIsExternal(externalModules.contains(mrid));
+        if (!c.getIsExternal()) {
+            c.setIsExternal(externalModules.contains(mrid));
+        }
         File f = componentFiles.get(mrid);
-        if (f != null) {
+        if (f != null && c.getVersion().equals(mrid.getRevision())) {
             c.add(new FileResource(f));
         }
         return c;
diff --git a/src/tests/antunit/component-ivymodule-test.xml 
b/src/tests/antunit/component-ivymodule-test.xml
index 3cfe765..653f2f5 100644
--- a/src/tests/antunit/component-ivymodule-test.xml
+++ b/src/tests/antunit/component-ivymodule-test.xml
@@ -252,7 +252,9 @@
         value="https://example.org/"/>
   </target>
 
-  <target name="testComponentDataFromDependencyIsReplacedByExplicitComponent">
+  <target
+      name="testComponentDataFromDependencyIsReplacedByExplicitComponent"
+      depends="commonReferences">
     <ivy:resolve file="resources/foo-bar.ivy.xml"
                  xmlns:ivy="antlib:org.apache.ivy.ant"/>
     <cdx:componentbom outputdirectory="${output}" format="xml"
@@ -266,7 +268,9 @@
         version="1.10.17"
         isExternal="true"
         description="Apache Ant Core"
-        id="ant"/>
+        id="ant">
+        <manufacturer refid="ant-team"/>
+      </additionalComponent>
     </cdx:componentbom>
     <copy todir="/tmp" file="${output}/bom.xml"/>
     <xmlproperty file="${output}/bom.xml"/>
@@ -309,6 +313,14 @@
         xmlns:au="antlib:org.apache.ant.antunit"
         name="bom.dependencies.dependency(ref)"
         
value="pkg:maven/foo/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.manufacturer.name"
+        value="Apache Ant Development Team"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.manufacturer.url"
+        value="https://ant.apache.org/"/>
     <!-- additionalComponent hasn't got any dependencies -->
     <au:assertPropertyEquals
         xmlns:au="antlib:org.apache.ant.antunit"
@@ -320,4 +332,82 @@
         resource="${output}/bom.xml"
         value='&lt;hash 
alg="SHA-1"&gt;fa8a13422ac460563171d10a37c3f28340a953f6&lt;/hash&gt;'/>
   </target>
+
+  <target name="testComponentDataFromDependencyIsAugmentedByTemplateComponent"
+          depends="commonReferences">
+    <ivy:resolve file="resources/foo-bar.ivy.xml"
+                 xmlns:ivy="antlib:org.apache.ivy.ant"/>
+    <cdx:componentbom outputdirectory="${output}" format="xml"
+                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <component>
+        <ivymodule>
+          <templateComponent
+              name="ant"
+              group="org.apache.ant"
+              isExternal="true"
+              description="Apache Ant Core"
+              id="ant">
+            <manufacturer refid="ant-team"/>
+          </templateComponent>
+        </ivymodule>
+      </component>
+    </cdx:componentbom>
+    <copy todir="/tmp" file="${output}/bom.xml"/>
+    <xmlproperty file="${output}/bom.xml"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.name"
+        value="ant-launcher,ant"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component(type)"
+        value="library,library"/>
+    <au:assertPropertyNotSet
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.scope"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component(isExternal)"
+        value="true"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.description"
+        value="Apache Ant Core"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.group"
+        value="org.apache.ant,org.apache.ant"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.version"
+        value="1.10.17,1.10.17"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.purl"
+        
value="pkg:maven/org.apache.ant/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component(bom-ref)"
+        
value="pkg:maven/org.apache.ant/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.dependencies.dependency(ref)"
+        
value="pkg:maven/foo/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.manufacturer.name"
+        value="Apache Ant Development Team"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.components.component.manufacturer.url"
+        value="https://ant.apache.org/"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.dependencies.dependency.dependency(ref)"
+        
value="pkg:maven/org.apache.ant/[email protected]?type=jar,pkg:maven/org.apache.ant/[email protected]?type=jar"/>
+    <au:assertResourceContains
+        xmlns:au="antlib:org.apache.ant.antunit"
+        resource="${output}/bom.xml"
+        value='&lt;hash 
alg="SHA-1"&gt;fa8a13422ac460563171d10a37c3f28340a953f6&lt;/hash&gt;'/>
+  </target>
 </project>

Reply via email to