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


The following commit(s) were added to refs/heads/main by this push:
     new 6e09f7a  make components and organizations reusable
6e09f7a is described below

commit 6e09f7a7cb7de2d8c3a6e97b14d6211d34ba09e2
Author: Stefan Bodewig <[email protected]>
AuthorDate: Sat May 2 08:26:29 2026 +0200

    make components and organizations reusable
---
 src/main/org/apache/ant/cyclonedx/Component.java   | 61 ++++++++++++++++++----
 .../org/apache/ant/cyclonedx/Organization.java     | 17 +++++-
 src/main/org/apache/ant/cyclonedx/ToolData.java    |  3 +-
 src/main/org/apache/ant/cyclonedx/antlib.xml       |  4 ++
 src/tests/antunit/componentbom-test.xml            | 31 ++++++-----
 5 files changed, 93 insertions(+), 23 deletions(-)

diff --git a/src/main/org/apache/ant/cyclonedx/Component.java 
b/src/main/org/apache/ant/cyclonedx/Component.java
index 2f18159..3811c9d 100644
--- a/src/main/org/apache/ant/cyclonedx/Component.java
+++ b/src/main/org/apache/ant/cyclonedx/Component.java
@@ -7,6 +7,7 @@ import java.util.List;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.types.DataType;
 import org.apache.tools.ant.types.Resource;
 import org.apache.tools.ant.types.resources.FileProvider;
 
@@ -15,7 +16,7 @@ import org.cyclonedx.model.LicenseChoice;
 import org.cyclonedx.model.OrganizationalEntity;
 import org.cyclonedx.util.BomUtils;
 
-public class Component {
+public class Component extends DataType {
     private Resource resource;
     private org.cyclonedx.model.Component.Type type = 
org.cyclonedx.model.Component.Type.LIBRARY;
     private String name;
@@ -35,6 +36,7 @@ public class Component {
     private boolean unknownDependencies = false;
 
     public void add(Resource resource) {
+        checkChildrenAllowed();
         if (this.resource != null) {
             throw new BuildException("component can only be defined for a 
single asset");
         }
@@ -42,54 +44,65 @@ public class Component {
     }
 
     public void setType(org.cyclonedx.model.Component.Type type) {
+        checkAttributesAllowed();
         this.type = type;
     }
 
     public void setName(String name) {
+        checkAttributesAllowed();
         this.name = name;
     }
 
     public void setGroup(String group) {
+        checkAttributesAllowed();
         this.group = group;
     }
 
     public void setVersion(String version) {
+        checkAttributesAllowed();
         this.version = version;
     }
 
     public void setDescription(String description) {
+        checkAttributesAllowed();
         this.description = description;
     }
 
-    public Organization createManufacturer() {
-        if (manufacturer != null) {
+    public void addManufacturer(Organization manufacturer) {
+        checkChildrenAllowed();
+        if (this.manufacturer != null) {
             throw new BuildException("component can only have one 
manufacturer");
         }
-        manufacturer = new Organization();
-        return manufacturer;
+        this.manufacturer = manufacturer;
     }
 
-    public Organization createSupplier() {
-        if (supplier != null) {
+    public void addSupplier(Organization supplier) {
+        checkChildrenAllowed();
+        if (this.supplier != null) {
             throw new BuildException("component can only have one supplier");
         }
-        supplier = new Organization();
-        return supplier;
+        this.supplier = supplier;
     }
 
     public void setManufacturerIsSupplier(boolean manufacturerIsSupplier) {
+        checkAttributesAllowed();
         this.manufacturerIsSupplier = manufacturerIsSupplier;
     }
 
     public void addConfiguredLicense(License l) {
+        checkChildrenAllowed();
         licenses.add(l.toCycloneDxLicense());
     }
 
     public void setPurl(String purl) {
+        checkAttributesAllowed();
         this.purl = purl;
     }
 
     public String getPurl() {
+        if (isReference()) {
+            return getRef().getPurl();
+        }
         if (purl != null) {
             return purl;
         }
@@ -100,10 +113,14 @@ public class Component {
     }
 
     public void setBomRef(String bomRef) {
+        checkAttributesAllowed();
         this.bomRef = bomRef;
     }
 
     public String getBomRef() {
+        if (isReference()) {
+            return getRef().getBomRef();
+        }
         if (bomRef == null) {
             return getPurl();
         }
@@ -111,35 +128,49 @@ public class Component {
     }
 
     public void addConfiguredExternalReference(ExternalReference ref) {
+        checkChildrenAllowed();
         externalReferences.add(ref.toCycloneDxExternalReference());
     }
 
     public void setScope(org.cyclonedx.model.Component.Scope scope) {
+        checkAttributesAllowed();
         this.scope = scope;
     }
 
     public void setIsExternal(boolean isExternal) {
+        checkAttributesAllowed();
         this.isExternal = isExternal;
     }
 
     public void addDependency(Dependency d) {
+        checkChildrenAllowed();
         dependencies.add(d);
     }
 
     public Iterable<Dependency> getDependencies() {
+        if (isReference()) {
+            return getRef().getDependencies();
+        }
         return dependencies;
     }
 
     public void setUnknownDependencies(boolean unknownDependencies) {
+        checkAttributesAllowed();
         this.unknownDependencies = unknownDependencies;
     }
 
     public boolean areDependenciesUnknown() {
+        if (isReference()) {
+            return getRef().areDependenciesUnknown();
+        }
         return unknownDependencies;
     }
 
     public org.cyclonedx.model.Component toMainCycloneDxComponent(Version 
bomVersion)
         throws IOException {
+        if (isReference()) {
+            return getRef().toMainCycloneDxComponent(bomVersion);
+        }
         if (isExternal) {
             throw new BuildException("isExternal can not be true for the main 
bom component");
         }
@@ -148,6 +179,9 @@ public class Component {
 
     public org.cyclonedx.model.Component 
toAdditionalCycloneDxComponent(Version bomVersion)
         throws IOException {
+        if (isReference()) {
+            return getRef().toAdditionalCycloneDxComponent(bomVersion);
+        }
         org.cyclonedx.model.Component component = 
toCycloneDxComponent(bomVersion);
         if (scope != null) {
             component.setScope(scope);
@@ -327,4 +361,13 @@ public class Component {
             throw new BuildException("componentRef '" + componentRef + "' 
doesn't refer to a component");
         }
     }
+
+    /**
+     * Perform the check for circular references and return the
+     * referenced Resource.
+     * @return <code>Component</code>.
+     */
+    protected Component getRef() {
+        return getCheckedRef(Component.class);
+    }
 }
diff --git a/src/main/org/apache/ant/cyclonedx/Organization.java 
b/src/main/org/apache/ant/cyclonedx/Organization.java
index 66aa552..5f7b123 100644
--- a/src/main/org/apache/ant/cyclonedx/Organization.java
+++ b/src/main/org/apache/ant/cyclonedx/Organization.java
@@ -3,23 +3,29 @@ package org.apache.ant.cyclonedx;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.tools.ant.types.DataType;
 import org.apache.tools.ant.types.resources.URLResource;
 
 import org.cyclonedx.model.OrganizationalEntity;
 
-public class Organization {
+public class Organization extends DataType {
     private String name;
     private List<String> urls = new ArrayList<>();
 
     public void setName(String name) {
+        checkAttributesAllowed();
         this.name = name;
     }
 
     public void addConfiguredUrl(URLResource url) {
+        checkAttributesAllowed();
         urls.add(url.getURL().toExternalForm());
     }
 
     public OrganizationalEntity toOrganizationalEntity() {
+        if (isReference()) {
+            return getRef().toOrganizationalEntity();
+        }
         OrganizationalEntity oe = new OrganizationalEntity();
         if (name != null) {
             oe.setName(name);
@@ -29,4 +35,13 @@ public class Organization {
         }
         return oe;
     }
+
+    /**
+     * Perform the check for circular references and return the
+     * referenced Resource.
+     * @return <code>Organization</code>.
+     */
+    protected Organization getRef() {
+        return getCheckedRef(Organization.class);
+    }
 }
diff --git a/src/main/org/apache/ant/cyclonedx/ToolData.java 
b/src/main/org/apache/ant/cyclonedx/ToolData.java
index 8698f93..d302216 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");
 
-        Organization manufacturer = antlibComponent.createManufacturer();
+        Organization manufacturer = new Organization();
         manufacturer.setName("Apache Ant Development Team");
         manufacturer.addConfiguredUrl(new 
URLResource("https://ant.apache.org/";));
+        antlibComponent.addManufacturer(manufacturer);
         antlibComponent.setManufacturerIsSupplier(true);
 
         Component.License license = new Component.License();
diff --git a/src/main/org/apache/ant/cyclonedx/antlib.xml 
b/src/main/org/apache/ant/cyclonedx/antlib.xml
index b2d7e68..3bf326d 100644
--- a/src/main/org/apache/ant/cyclonedx/antlib.xml
+++ b/src/main/org/apache/ant/cyclonedx/antlib.xml
@@ -20,4 +20,8 @@ under the License.
 <antlib xmlns:au="ant:current">
   <taskdef name="componentbom"
     classname="org.apache.ant.cyclonedx.ComponentBomTask"/>
+  <typedef name="component"
+    classname="org.apache.ant.cyclonedx.Component"/>
+  <typedef name="organization"
+    classname="org.apache.ant.cyclonedx.Organization"/>
 </antlib>
diff --git a/src/tests/antunit/componentbom-test.xml 
b/src/tests/antunit/componentbom-test.xml
index d445527..33a58f2 100644
--- a/src/tests/antunit/componentbom-test.xml
+++ b/src/tests/antunit/componentbom-test.xml
@@ -55,11 +55,13 @@
   </target>
 
   <target name="testToolMetadataInXmlFormat">
+    <cdx:component name="testname" id="test"
+                   xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <file file="${antlib.location}"/>
+    </cdx:component>
     <cdx:componentbom outputdirectory="${output}" format="xml"
                       xmlns:cdx="antlib:org.apache.ant.cyclonedx">
-      <component name="testname">
-        <file file="${antlib.location}"/>
-      </component>
+      <component refid="test"/>
     </cdx:componentbom>
     <xmlproperty file="${output}/bom.xml"/>
     <au:assertPropertyEquals
@@ -117,11 +119,14 @@
   </target>
 
   <target name="testSupplierAndManufacturerInMeta">
+    <cdx:organization name="Example" id="example"
+                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <url url="https://example.org/"/>
+    </cdx:organization>
+
     <cdx:componentbom outputdirectory="${output}" format="xml"
                       xmlns:cdx="antlib:org.apache.ant.cyclonedx">
-      <manufacturer name="Example">
-        <url url="https://example.org/"/>
-      </manufacturer>
+      <manufacturer refid="example"/>
       <supplier name="Example 2">
         <url url="https://example.com/"/>
       </supplier>
@@ -365,6 +370,12 @@
   </target>
 
   <target name="testAntlibsOwnBom">
+    <cdx:organization
+        name="Apache Ant Development Team"
+        id="ant-team"
+        xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <url url="https://ant.apache.org/"/>
+    </cdx:organization>
     <cdx:componentbom
         bomName="ant-cyclonedx-${artifact.version}-cyclonedx"
         outputdirectory="${output}"
@@ -378,9 +389,7 @@
           description="Apache CycloneDX Antlib"
           manufacturerIsSupplier="true">
         <file file="${antlib.location}"/>
-        <manufacturer name="Apache Ant Development Team">
-          <url url="https://ant.apache.org/"/>
-        </manufacturer>
+        <manufacturer refid="ant-team"/>
         <license licenseId="Apache-2.0"/>
         <externalReference
             type="VCS"
@@ -395,9 +404,7 @@
           isExternal="true"
           unknownDependencies="true"
           id="ant">
-        <manufacturer name="Apache Ant Development Team">
-          <url url="https://ant.apache.org/"/>
-        </manufacturer>
+        <manufacturer refid="ant-team"/>
         <license licenseId="Apache-2.0"/>
         <externalReference
             type="VCS"

Reply via email to