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">