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 1d150fb  allow component type and scope to be set using spec-names
1d150fb is described below

commit 1d150fb008010d52bc2c60f3b71c71886e41a7d1
Author: Stefan Bodewig <[email protected]>
AuthorDate: Thu May 14 17:47:41 2026 +0200

    allow component type and scope to be set using spec-names
---
 src/main/org/apache/ant/cyclonedx/Component.java   | 14 ++++----
 .../org/apache/ant/cyclonedx/ComponentBomTask.java |  2 +-
 .../org/apache/ant/cyclonedx/ComponentScope.java   | 36 ++++++++++++++++++++
 .../org/apache/ant/cyclonedx/ComponentType.java    | 36 ++++++++++++++++++++
 src/main/org/apache/ant/cyclonedx/EnumUtils.java   | 38 ++++++++++++++++++++++
 .../org/apache/ant/cyclonedx/OutputFormat.java     |  7 ++--
 src/main/org/apache/ant/cyclonedx/SpecVersion.java |  6 +---
 src/tests/antunit/componentbom-test.xml            | 21 +++++++++---
 8 files changed, 141 insertions(+), 19 deletions(-)

diff --git a/src/main/org/apache/ant/cyclonedx/Component.java 
b/src/main/org/apache/ant/cyclonedx/Component.java
index b2b4bac..e44b0c8 100644
--- a/src/main/org/apache/ant/cyclonedx/Component.java
+++ b/src/main/org/apache/ant/cyclonedx/Component.java
@@ -68,9 +68,9 @@ public class Component extends DataType {
         this.resource = resource;
     }
 
-    public void setType(org.cyclonedx.model.Component.Type type) {
+    public void setType(ComponentType type) {
         checkAttributesAllowed();
-        this.type = type;
+        this.type = type.getType();
     }
 
     public void setName(String name) {
@@ -210,9 +210,9 @@ public class Component extends DataType {
         externalReferences.addAll(set.getExternalReferences());
     }
 
-    public void setScope(org.cyclonedx.model.Component.Scope scope) {
+    public void setScope(ComponentScope scope) {
         checkAttributesAllowed();
-        this.scope = scope;
+        this.scope = scope.getScope();
     }
 
     public void setIsExternal(boolean isExternal) {
@@ -468,7 +468,7 @@ public class Component extends DataType {
     }
 
     private void fillFrom(org.cyclonedx.model.Component real) {
-        setType(real.getType());
+        setType(ComponentType.from(real.getType()));
         setName(real.getName());
         setGroup(real.getGroup());
         setVersion(real.getVersion());
@@ -478,7 +478,9 @@ public class Component extends DataType {
         setMimeType(real.getMimeType());
         setPurl(real.getPurl());
         setBomRef(real.getBomRef());
-        setScope(real.getScope());
+        if (real.getScope() != null) {
+            setScope(ComponentScope.from(real.getScope()));
+        }
         OrganizationalEntity manufacturer = real.getManufacturer();
         if (manufacturer != null) {
             this.manufacturer = Organization.from(manufacturer);
diff --git a/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java 
b/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java
index a8d6cf9..c0bc776 100644
--- a/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java
+++ b/src/main/org/apache/ant/cyclonedx/ComponentBomTask.java
@@ -179,7 +179,7 @@ public class ComponentBomTask extends Task {
                 c.setProject(getProject());
                 c.add(r);
                 c.setName(r.getName());
-                c.setType(org.cyclonedx.model.Component.Type.FILE);
+                
c.setType(ComponentType.from(org.cyclonedx.model.Component.Type.FILE));
                 
cs.add(c.toAdditionalCycloneDxComponent(specVersion.getVersion()));
             }
             bom.setComponents(cs);
diff --git a/src/main/org/apache/ant/cyclonedx/ComponentScope.java 
b/src/main/org/apache/ant/cyclonedx/ComponentScope.java
new file mode 100644
index 0000000..bd657f7
--- /dev/null
+++ b/src/main/org/apache/ant/cyclonedx/ComponentScope.java
@@ -0,0 +1,36 @@
+package org.apache.ant.cyclonedx;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+import org.cyclonedx.model.Component.Scope;
+
+/**
+ * CycloneDX component type.
+ *
+ * <p>Accepts the enum constants like {@code LIBRARY} as well as the
+ * lowercase version {@code library}. The values are directly provided
+ * by CycloneDX Core's enum.</p>
+ */
+public class ComponentScope extends EnumeratedAttribute {
+
+    @Override
+    public String[] getValues() {
+        return EnumUtils.valuesPlus(Scope.class, Scope::getScopeName);
+    }
+
+    /**
+     * Translates this instance to a {@link Scope}.
+     *
+     * @throws BuildException if the value can not be translated.
+     */
+    public Scope getScope() {
+        return EnumUtils.valueOf(Scope.class, getValue(), Scope::getScopeName);
+    }
+
+    static ComponentScope from(Scope scope) {
+        ComponentScope s = new ComponentScope();
+        s.setValue(scope.name());
+        return s;
+    }
+}
diff --git a/src/main/org/apache/ant/cyclonedx/ComponentType.java 
b/src/main/org/apache/ant/cyclonedx/ComponentType.java
new file mode 100644
index 0000000..02b1241
--- /dev/null
+++ b/src/main/org/apache/ant/cyclonedx/ComponentType.java
@@ -0,0 +1,36 @@
+package org.apache.ant.cyclonedx;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.types.EnumeratedAttribute;
+
+import org.cyclonedx.model.Component.Type;
+
+/**
+ * CycloneDX component type.
+ *
+ * <p>Accepts the enum constants like {@code LIBRARY} as well as the
+ * lowercase version {@code library}. The values are directly provided
+ * by CycloneDX Core's enum.</p>
+ */
+public class ComponentType extends EnumeratedAttribute {
+
+    @Override
+    public String[] getValues() {
+        return EnumUtils.valuesPlus(Type.class, Type::getTypeName);
+    }
+
+    /**
+     * Translates this instance to a {@link Type}.
+     *
+     * @throws BuildException if the value can not be translated.
+     */
+    public Type getType() {
+        return EnumUtils.valueOf(Type.class, getValue(), Type::getTypeName);
+    }
+
+    static ComponentType from(Type type) {
+        ComponentType t = new ComponentType();
+        t.setValue(type.name());
+        return t;
+    }
+}
diff --git a/src/main/org/apache/ant/cyclonedx/EnumUtils.java 
b/src/main/org/apache/ant/cyclonedx/EnumUtils.java
new file mode 100644
index 0000000..ea0a482
--- /dev/null
+++ b/src/main/org/apache/ant/cyclonedx/EnumUtils.java
@@ -0,0 +1,38 @@
+package org.apache.ant.cyclonedx;
+
+import java.util.Arrays;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import org.apache.tools.ant.BuildException;
+
+class EnumUtils {
+    static <E extends Enum<E>> String[] valuesPlus(
+        Class<E> clazz,
+        Function<E, String> alternativeProvider) {
+        return Arrays.stream(clazz.getEnumConstants())
+            .flatMap(e -> Stream.of(e.name(), alternativeProvider.apply(e)))
+            .toArray(String[]::new);
+    }
+
+    static <E extends Enum<E>> E valueOf(
+        Class<E> clazz,
+        String value,
+        Function<E, String> alternativeProvider) throws BuildException {
+        if (value == null) {
+            throw new NullPointerException("value must not be null");
+        }
+        E en = Arrays.stream(clazz.getEnumConstants())
+            .filter(e -> value.equals(alternativeProvider.apply(e)))
+            .findFirst()
+            .orElse(null);
+        if (en != null) {
+            return en;
+        }
+        try {
+            return Enum.valueOf(clazz, value);
+        } catch (IllegalArgumentException ex) {
+            throw new BuildException(value + " is not a supported " + 
clazz.getName());
+        }
+    }
+}
diff --git a/src/main/org/apache/ant/cyclonedx/OutputFormat.java 
b/src/main/org/apache/ant/cyclonedx/OutputFormat.java
index 5a77793..f24248f 100644
--- a/src/main/org/apache/ant/cyclonedx/OutputFormat.java
+++ b/src/main/org/apache/ant/cyclonedx/OutputFormat.java
@@ -24,6 +24,8 @@ import org.cyclonedx.Format;
  */
 public class OutputFormat extends EnumeratedAttribute {
 
+    private static final String ALL = "ALL";
+
     public static final OutputFormat JSON;
 
     static {
@@ -34,9 +36,8 @@ public class OutputFormat extends EnumeratedAttribute {
     @Override
     public String[] getValues() {
         return Stream
-            .concat(Arrays.stream(Format.values())
-                    .flatMap(f -> Stream.of(f.name(), f.getExtension())),
-                    Stream.of("all", "ALL"))
+            .concat(Arrays.stream(EnumUtils.valuesPlus(Format.class, 
Format::getExtension)),
+                    Stream.of(ALL, ALL.toLowerCase(Locale.ENGLISH)))
             .toArray(String[]::new);
     }
 
diff --git a/src/main/org/apache/ant/cyclonedx/SpecVersion.java 
b/src/main/org/apache/ant/cyclonedx/SpecVersion.java
index a06d861..4e124ba 100644
--- a/src/main/org/apache/ant/cyclonedx/SpecVersion.java
+++ b/src/main/org/apache/ant/cyclonedx/SpecVersion.java
@@ -1,8 +1,6 @@
 package org.apache.ant.cyclonedx;
 
-import java.util.Arrays;
 import java.util.Objects;
-import java.util.stream.Stream;
 
 import org.apache.tools.ant.BuildException;
 import org.apache.tools.ant.types.EnumeratedAttribute;
@@ -27,9 +25,7 @@ public class SpecVersion extends EnumeratedAttribute {
 
     @Override
     public String[] getValues() {
-        return Arrays.stream(Version.values())
-            .flatMap(v -> Stream.of(v.name(), v.getVersionString()))
-            .toArray(String[]::new);
+        return EnumUtils.valuesPlus(Version.class, Version::getVersionString);
     }
 
     /**
diff --git a/src/tests/antunit/componentbom-test.xml 
b/src/tests/antunit/componentbom-test.xml
index 1bee6a0..431c578 100644
--- a/src/tests/antunit/componentbom-test.xml
+++ b/src/tests/antunit/componentbom-test.xml
@@ -174,7 +174,7 @@
       <url url="https://example.org/"/>
     </cdx:organization>
 
-    <cdx:componentbom outputdirectory="${output}" format="xml"
+    <cdx:componentbom outputdirectory="${output}" format="XML"
                       xmlns:cdx="antlib:org.apache.ant.cyclonedx">
       <manufacturer refid="example"/>
       <supplier name="Example 2">
@@ -319,6 +319,18 @@
         value="application"/>
   </target>
 
+  <target name="testComponentTypeCanBeSetInLowerCase">
+    <cdx:componentbom outputdirectory="${output}" format="xml"
+                      xmlns:cdx="antlib:org.apache.ant.cyclonedx">
+      <component name="testname" type="application"/>
+    </cdx:componentbom>
+    <xmlproperty file="${output}/bom.xml"/>
+    <au:assertPropertyEquals
+        xmlns:au="antlib:org.apache.ant.antunit"
+        name="bom.metadata.component(type)"
+        value="application"/>
+  </target>
+
   <target name="testCalculatesPurlAndBomRef">
     <cdx:componentbom outputdirectory="${output}" format="xml"
                       xmlns:cdx="antlib:org.apache.ant.cyclonedx">
@@ -496,20 +508,21 @@
                       xmlns:cdx="antlib:org.apache.ant.cyclonedx">
       <component name="testname"/>
       <additionalComponent name="dependency" scope="OPTIONAL"/>
+      <additionalComponent name="dependency2" scope="optional"/>
     </cdx:componentbom>
     <xmlproperty file="${output}/bom.xml"/>
     <au:assertPropertyEquals
         xmlns:au="antlib:org.apache.ant.antunit"
         name="bom.components.component.name"
-        value="dependency"/>
+        value="dependency,dependency2"/>
     <au:assertPropertyEquals
         xmlns:au="antlib:org.apache.ant.antunit"
         name="bom.components.component(type)"
-        value="library"/>
+        value="library,library"/>
     <au:assertPropertyEquals
         xmlns:au="antlib:org.apache.ant.antunit"
         name="bom.components.component.scope"
-        value="optional"/>
+        value="optional,optional"/>
   </target>
 
   <target name="testDependencies">

Reply via email to