Component.java
/*
* Copyright © 2025 Christian Grobmeier, Piotr P. Karwasz
*
* Licensed 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://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.
*/
package io.github.sbom.enforcer;
import com.github.packageurl.PackageURL;
import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import org.eclipse.aether.artifact.Artifact;
import org.jspecify.annotations.Nullable;
/**
* Metadata associated to a Maven artifact.
*/
public interface Component {
/**
* The resolved artifact described by this component.
*/
Artifact getArtifact();
/**
* The package URL of the described component as specified in the bill of materials.
*/
@Nullable
PackageURL getPurl();
/**
* All the SBOM artifacts published for the given component.
*/
Collection<Artifact> getBillsOfMaterials();
/**
* References to other documents related to the artifact as specified in the bill of materials.
*/
Collection<ExternalReference> getExternalReferences();
/**
* Hash values of the component as specified in the bill of materials
* <p>
* These can differ from the hashes of the file given by {@link #getArtifact()}.
* </p>
* @return A map from hash algorithm names to hash values.
*/
Map<ChecksumAlgorithm, String> getChecksums();
/**
* A reference to an external resource.
*/
interface ExternalReference {
/**
* The type of external reference.
* <p>
* The values can be any constants used by CycloneDX or SPDX.
* </p>
*
* @see <a href="https://cyclonedx.org/docs/1.6/json/#components_items_externalReferences_items_type">CycloneDX external reference types</a>
* @see <a href="https://spdx.github.io/spdx-spec/v2.3/external-repository-identifiers/">SPDX 2.x external repository identifiers</a>
* @see <a href="https://spdx.github.io/spdx-spec/v3.0.1/model/Core/Vocabularies/ExternalRefType/">SPDX 3.x external reference types</a>
*/
String getReferenceType();
/**
* The location of the external resource.
*/
String getLocation();
/**
* The MIME type of the external resource or {@code null} if unknown.
*/
@Nullable
String getContentType();
}
/**
* Enumeration of supported checksum algorithms.
*/
enum ChecksumAlgorithm {
ADLER32(null, "ADLER32", null),
MD2(null, "MD2", "MD2"),
MD4(null, "MD4", null),
MD5("MD5", "MD5", "MD5"),
MD6(null, "MD6", null),
SHA1("SHA-1", "SHA1", "SHA-1"),
SHA224(null, "SHA224", "SHA-224"),
SHA_256("SHA-256", "SHA256", "SHA-256"),
SHA_384("SHA-384", "SHA384", "SHA-384"),
SHA_512("SHA-512", "SHA512", "SHA-512"),
SHA3_256("SHA3-256", "SHA3-256", "SHA3-256"),
SHA3_384("SHA3-384", "SHA3-384", "SHA3-384"),
SHA3_512("SHA3-512", "SHA3-512", "SHA3-512"),
BLAKE2b_256("BLAKE2b-256", "BLAKE2b-256", "BLAKE2B-256"),
BLAKE2b_384("BLAKE2b-384", "BLAKE2b-384", "BLAKE2B-384"),
BLAKE2b_512("BLAKE2b-512", "BLAKE2b-512", "BLAKE2B-512"),
BLAKE3("BLAKE3", "BLAKE3", "BLAKE3-256");
private final @Nullable String cyclonedx;
private final @Nullable String spdx;
private final @Nullable String jce;
ChecksumAlgorithm(@Nullable String cyclonedx, @Nullable String spdx, @Nullable String jce) {
this.cyclonedx = cyclonedx;
this.spdx = spdx;
this.jce = jce;
}
/**
* Checks if the algorithm is supported by CycloneDX.
* @return {@code true} if the algorithm is supported by the CycloneDX standard.
*/
public boolean isCycloneDx() {
return cyclonedx != null;
}
/**
* Returns the identifier used in CycloneDX documents.
*/
public String toCycloneDx() {
return Objects.requireNonNull(cyclonedx);
}
/**
* Parses a CycloneDX checksum identifier.
*/
public static ChecksumAlgorithm fromCycloneDx(String spec) {
Objects.requireNonNull(spec);
for (ChecksumAlgorithm algorithm : values()) {
if (spec.equals(algorithm.cyclonedx)) {
return algorithm;
}
}
throw new IllegalArgumentException("No enum constant with spec " + spec);
}
/**
* The name used by Java Cryptography Extensions.
*/
public String toJce() {
return jce != null ? jce : name();
}
}
/**
* List of properties of {@link Artifact} objects returned by {@link Component} methods.
*/
final class Properties {
/**
* The URL of the Maven repository where the component is or will be available.
* <p>
* This property is always present if the component is not on Maven Central.
* </p>
*/
public static final String REPOSITORY_URL = "repository_url";
/**
* The URL of the Maven Central repository used in the Super POM.
* @see <a href="https://maven.apache.org/ref/current/maven-model-builder/super-pom.html">Super POM</a>
*/
public static final String MAVEN_CENTRAL_URL = "https://repo.maven.apache.org/maven2";
/**
* Alternative location of Maven Central.
*/
public static final String MAVEN_CENTRAL_ALT_URL = "https://repo1.maven.org/maven2";
private Properties() {}
}
}