This is an automated email from the ASF dual-hosted git repository. asf-gitbox-commits pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/ant-antlibs-cyclonedx.git
commit caad2b677afb55b3600188106224295e52525028 Author: Stefan Bodewig <[email protected]> AuthorDate: Thu Jun 4 14:55:51 2026 +0200 introduce propertyset --- changes.xml | 8 ++ docs/component.html | 9 +- docs/index.html | 1 + docs/propertyset.html | 87 +++++++++++++++ src/main/org/apache/ant/cyclonedx/Component.java | 16 ++- src/main/org/apache/ant/cyclonedx/PropertySet.java | 59 ++++++++++ src/main/org/apache/ant/cyclonedx/antlib.xml | 2 + src/tests/antunit/properties-test.xml | 123 +++++++++++++++++++++ 8 files changed, 303 insertions(+), 2 deletions(-) diff --git a/changes.xml b/changes.xml index 4baa608..9c19b08 100644 --- a/changes.xml +++ b/changes.xml @@ -38,6 +38,14 @@ </properties> <release version="0.2" date="unreleased"> + <action type="fix" breaks-bwc="true"> + The name attribute of properties is required by the spec and + this is now enforced. + </action> + <action type="add"> + A new type "propertyset" can be used to group properties and + reuse common sets of properties for multiple components. + </action> </release> <release version="0.1" date="2026-06-03" description="initial release"> diff --git a/docs/component.html b/docs/component.html index 1116d02..5dd1c65 100644 --- a/docs/component.html +++ b/docs/component.html @@ -263,7 +263,7 @@ <h5>Attributes</h5> <tr> <td>name</td> <td>The name of the property.</td> - <td>No</td> + <td>Yes</td> </tr> <tr> <td>value</td> @@ -272,6 +272,13 @@ <h5>Attributes</h5> </tr> </table> + <h4>propertySet</h4> + + <p><em>since CycloneDX Antlib 0.2</em></p> + + <p>A nested <a href="propertyset.html">propertyset</a> specifies + properties for the component.</p> + <h4>license</h4> <p>A nested <a href="license.html">license</a> specifies the diff --git a/docs/index.html b/docs/index.html index 375d83b..978342f 100644 --- a/docs/index.html +++ b/docs/index.html @@ -72,6 +72,7 @@ <h2>Tasks and Types provided by this Ant Library</h2> <li><a href="externalreferenceset.html">externalreferenceset</a></li> <li><a href="license.html">license</a></li> <li><a href="organization.html">organization</a></li> + <li><a href="propertyset.html">propertyset</a></li> </ul> <h2>Requirements and Dependencies of this Ant Library</h2> diff --git a/docs/propertyset.html b/docs/propertyset.html new file mode 100644 index 0000000..3e8a0a5 --- /dev/null +++ b/docs/propertyset.html @@ -0,0 +1,87 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<html> + <head> + <meta http-equiv="Content-Language" content="en-us"></meta> + <link rel="stylesheet" type="text/css" href="style.css"> + <title>Apache CycloneDX Ant Library - propertyset</title> + </head> + + <body> + <h2 id="propertyset">propertyset</h2> + + <p><em>since CycloneDX Antlib 0.2</em></p> + + <p>propertysets are collections of properties that can be + associated to a component or an SBOM. They can be used as + top-level elements and be given an id so they can be later + referred to via the <code>refid</code> attribute - + see <a href="https://ant.apache.org/manual/using.html#references">the + Ant manual</a>.</p> + + <p>Apart from Ant's <code>id/refid</code> this element doesn't + support any attributes.</p> + + <h3>Nested elements</h3> + + <h4 id="property">property</h4> + + <p>Represents a single property to be added to the BOM.</p> + + <table class="attr"> + <tr> + <th scope="col">Attribute</th> + <th scope="col">Description</th> + <th scope="col">Required</th> + </tr> + <tr> + <td>name</td> + <td>The name of the property.</td> + <td>Yes</td> + </tr> + <tr> + <td>value</td> + <td>The value of the property.</td> + <td>No</td> + </tr> + </table> + + <h3>Examples</h3> + + <p>Below is a set of properties like those required by the BSI TR + for EU CRA compatible SBOM components.</p> + + <pre> + <cdx:propertyset + id="antlib-props" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <property + name="bsi:component:filename" + value="antlibs-cyclonedx.jar"/> + <property + name="bsi:component:executable" + value="non-executable"/> + <property + name="bsi:component:archive" + value="archive"/> + <property + name="bsi:component:structured" + value="structured"/> + </cdx:propertyset> + </pre> + + </body> diff --git a/src/main/org/apache/ant/cyclonedx/Component.java b/src/main/org/apache/ant/cyclonedx/Component.java index 6baae2e..0387135 100644 --- a/src/main/org/apache/ant/cyclonedx/Component.java +++ b/src/main/org/apache/ant/cyclonedx/Component.java @@ -248,11 +248,25 @@ public class Component extends DataType { * * @param property component property */ - public void addProperty(Property property) { + public void addConfiguredProperty(Property property) { checkChildrenAllowed(); + if (property.getName() == null) { + throw new BuildException("properties must have a name"); + } properties.add(property); } + /** + * Adds a set of properties to the component. + * + * @param set set of properties of component + * @since CycloneDX Antlib 0.2 + */ + public void addConfiguredPropertySet(PropertySet set) { + checkChildrenAllowed(); + properties.addAll(set.getProperties()); + } + /** * If set to {@code true} the supplier will also be used to * provide the manufacturer information. diff --git a/src/main/org/apache/ant/cyclonedx/PropertySet.java b/src/main/org/apache/ant/cyclonedx/PropertySet.java new file mode 100644 index 0000000..310afe1 --- /dev/null +++ b/src/main/org/apache/ant/cyclonedx/PropertySet.java @@ -0,0 +1,59 @@ +package org.apache.ant.cyclonedx; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.DataType; + +import org.cyclonedx.model.Property; + +/** + * A container for a collection of {@link Property}s. + * + * <p>This class is a type exposed by this Ant Library. When using the + * inherited {@code refid} attribute it can reference an instance + * defined previously - in which case no child elements are + * allowed.</p> + * + * @since CycloneDX Antlib 0.2 + */ +public class PropertySet extends DataType { + private List<Property> properties = new ArrayList<>(); + + /** + * Adds a property to the set. + * + * @param property set property + */ + public void addConfiguredProperty(Property property) { + checkChildrenAllowed(); + if (property.getName() == null) { + throw new BuildException("properties must have a name"); + } + properties.add(property); + } + + /** + * Return the external references contained in this set. + * + * @return external references contained in this set + */ + public Collection<Property> getProperties() { + if (isReference()) { + return getRef().getProperties(); + } + dieOnCircularReference(); + return properties; + } + + /** + * Perform the check for circular references and return the + * referenced PropertySet. + * @return <code>PropertySet</code>. + */ + protected PropertySet getRef() { + return getCheckedRef(PropertySet.class); + } +} diff --git a/src/main/org/apache/ant/cyclonedx/antlib.xml b/src/main/org/apache/ant/cyclonedx/antlib.xml index 33c442c..2e545bc 100644 --- a/src/main/org/apache/ant/cyclonedx/antlib.xml +++ b/src/main/org/apache/ant/cyclonedx/antlib.xml @@ -28,4 +28,6 @@ under the License. classname="org.apache.ant.cyclonedx.License"/> <typedef name="externalreferenceset" classname="org.apache.ant.cyclonedx.ExternalReferenceSet"/> + <typedef name="propertyset" + classname="org.apache.ant.cyclonedx.PropertySet"/> </antlib> diff --git a/src/tests/antunit/properties-test.xml b/src/tests/antunit/properties-test.xml new file mode 100644 index 0000000..92083b8 --- /dev/null +++ b/src/tests/antunit/properties-test.xml @@ -0,0 +1,123 @@ +<?xml version="1.0"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<project name="properties-test" default="antunit"> + + <import file="shared.xml" /> + + <target name="testPropertyRequiresName"> + <au:expectfailure + expectedMessage="properties must have a name" + xmlns:au="antlib:org.apache.ant.antunit"> + <cdx:componentbom + outputdirectory="${output}" format="xml" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <component name="testname"> + <property value="foo"/> + </component> + </cdx:componentbom> + </au:expectfailure> + <au:expectfailure + expectedMessage="properties must have a name" + xmlns:au="antlib:org.apache.ant.antunit"> + <cdx:propertyset + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <property value="foo"/> + </cdx:propertyset> + </au:expectfailure> + </target> + + <target name="testPropertyWorksAsDirectChildOfComponent"> + <cdx:componentbom + outputdirectory="${output}" format="xml" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <component name="testname"> + <property name="website" value="https://ant.apache.org/"/> + </component> + </cdx:componentbom> + <xmlproperty file="${output}/bom.xml"/> + <au:assertPropertyEquals + xmlns:au="antlib:org.apache.ant.antunit" + name="bom.metadata.component.properties.property(name)" + value="website"/> + <au:assertPropertyEquals + xmlns:au="antlib:org.apache.ant.antunit" + name="bom.metadata.component.properties.property" + value="https://ant.apache.org/"/> + </target> + + <target name="testPropertyWorksNestedIntoAsSet"> + <cdx:componentbom + outputdirectory="${output}" format="xml" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <component name="testname"> + <propertyset> + <property name="website" value="https://ant.apache.org/"/> + </propertyset> + </component> + </cdx:componentbom> + <xmlproperty file="${output}/bom.xml"/> + <au:assertPropertyEquals + xmlns:au="antlib:org.apache.ant.antunit" + name="bom.metadata.component.properties.property(name)" + value="website"/> + <au:assertPropertyEquals + xmlns:au="antlib:org.apache.ant.antunit" + name="bom.metadata.component.properties.property" + value="https://ant.apache.org/"/> + </target> + + <target name="testPropertyWorksViaReferenceToASet"> + <cdx:propertyset id="test-set" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <property name="website" value="https://ant.apache.org/"/> + </cdx:propertyset> + <cdx:componentbom + outputdirectory="${output}" format="xml" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <component name="testname"> + <propertyset refid="test-set"/> + </component> + </cdx:componentbom> + <xmlproperty file="${output}/bom.xml"/> + <au:assertPropertyEquals + xmlns:au="antlib:org.apache.ant.antunit" + name="bom.metadata.component.properties.property(name)" + value="website"/> + <au:assertPropertyEquals + xmlns:au="antlib:org.apache.ant.antunit" + name="bom.metadata.component.properties.property" + value="https://ant.apache.org/"/> + </target> + + <target + name="testPropertySetWithRefIdDoesntAllowNestedChildren"> + <cdx:propertyset id="test-set" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <property name="website" value="https://ant.apache.org/"/> + </cdx:propertyset> + <au:expectfailure + expectedMessage='You must not specify nested elements when using refid' + xmlns:au="antlib:org.apache.ant.antunit"> + <cdx:propertyset id="test-set" + refid="test-set" + xmlns:cdx="antlib:org.apache.ant.cyclonedx"> + <property name="website" value="https://ant.apache.org/"/> + </cdx:propertyset> + </au:expectfailure> + </target> +</project>
