001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      https://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.commons.release.plugin.slsa.v1_2;
018
019import java.util.Objects;
020
021import com.fasterxml.jackson.annotation.JsonInclude;
022import com.fasterxml.jackson.annotation.JsonProperty;
023
024/**
025 * Root predicate of an SLSA v1.2 provenance attestation, describing what was built and how.
026 *
027 * <p>
028 * This predicate combines a {@link BuildDefinition} (the inputs) with {@link RunDetails} (the execution context). It is intended to be
029 * used as the {@code predicate} field of an in-toto {@link Statement}.
030 * </p>
031 *
032 * @see <a href="https://slsa.dev/spec/v1.2">SLSA v1.2 Specification</a>
033 * @since 1.10.0
034 */
035@JsonInclude(JsonInclude.Include.NON_NULL)
036public class Provenance {
037
038    /** Predicate type URI used in the in-toto {@link Statement} wrapping this provenance. */
039    public static final String PREDICATE_TYPE = "https://slsa.dev/provenance/v1";
040
041    /** Inputs that defined the build. */
042    @JsonProperty("buildDefinition")
043    private BuildDefinition buildDefinition;
044
045    /** Details about the build invocation. */
046    @JsonProperty("runDetails")
047    private RunDetails runDetails;
048
049    /** Creates a new Provenance instance. */
050    public Provenance() {
051    }
052
053    /**
054     * Creates a new Provenance with the given build definition and run details.
055     *
056     * @param buildDefinition inputs that defined the build.
057     * @param runDetails      details about the build invocation.
058     */
059    public Provenance(final BuildDefinition buildDefinition, final RunDetails runDetails) {
060        this.buildDefinition = buildDefinition;
061        this.runDetails = runDetails;
062    }
063
064    @Override
065    public boolean equals(final Object o) {
066        if (this == o) {
067            return true;
068        }
069        if (o == null || getClass() != o.getClass()) {
070            return false;
071        }
072        final Provenance that = (Provenance) o;
073        return Objects.equals(buildDefinition, that.buildDefinition) && Objects.equals(runDetails, that.runDetails);
074    }
075
076    /**
077     * Gets the build definition describing all inputs that produced the build output.
078     *
079     * <p>
080     * Includes source code, dependencies, build tools, base images, and other materials.
081     * </p>
082     *
083     * @return The build definition, or {@code null} if not set.
084     */
085    public BuildDefinition getBuildDefinition() {
086        return buildDefinition;
087    }
088
089    /**
090     * Gets the details about the invocation of the build tool and the environment in which it was run.
091     *
092     * @return The run details, or {@code null} if not set.
093     */
094    public RunDetails getRunDetails() {
095        return runDetails;
096    }
097
098    @Override
099    public int hashCode() {
100        return Objects.hash(buildDefinition, runDetails);
101    }
102
103    /**
104     * Sets the build definition describing all inputs that produced the build output.
105     *
106     * @param buildDefinition The build definition.
107     * @return this for chaining.
108     */
109    public Provenance setBuildDefinition(final BuildDefinition buildDefinition) {
110        this.buildDefinition = buildDefinition;
111        return this;
112    }
113
114    /**
115     * Sets the details about the invocation of the build tool and the environment in which it was run.
116     *
117     * @param runDetails The run details.
118     * @return this for chaining.
119     */
120    public Provenance setRunDetails(final RunDetails runDetails) {
121        this.runDetails = runDetails;
122        return this;
123    }
124
125    @Override
126    public String toString() {
127        return "Provenance{buildDefinition=" + buildDefinition + ", runDetails=" + runDetails + '}';
128    }
129}