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.List;
020import java.util.Objects;
021
022import com.fasterxml.jackson.annotation.JsonProperty;
023
024/**
025 * In-toto v1 attestation envelope that binds a set of subject artifacts to an SLSA provenance predicate.
026 *
027 * @see <a href="https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md">in-toto Statement v1</a>
028 * @since 1.10.0
029 */
030public class Statement {
031
032    /** The in-toto statement schema URI. */
033    public static final String TYPE = "https://in-toto.io/Statement/v1";
034    /** The provenance predicate. */
035    @JsonProperty("predicate")
036    private Provenance predicate;
037    /** URI identifying the type of the predicate. */
038    @JsonProperty("predicateType")
039    private String predicateType;
040    /** Software artifacts that the attestation applies to. */
041    @JsonProperty("subject")
042    private List<ResourceDescriptor> subject;
043
044    /** Creates a new Statement instance. */
045    public Statement() {
046    }
047
048    @Override
049    public boolean equals(final Object o) {
050        if (!(o instanceof Statement)) {
051            return false;
052        }
053        final Statement statement = (Statement) o;
054        return Objects.equals(subject, statement.subject) && Objects.equals(predicateType, statement.predicateType) && Objects.equals(predicate,
055                statement.predicate);
056    }
057
058    /**
059     * Gets the JSON object type.
060     *
061     * @return Always {@value #TYPE}.
062     */
063    @JsonProperty("_type")
064    public String getType() {
065        return TYPE;
066    }
067
068    /**
069     * Gets the provenance predicate.
070     *
071     * <p>
072     * An unset predicate is treated the same as an empty predicate. The predicate may be omitted if {@code predicateType} fully describes the
073     * predicate.
074     * </p>
075     *
076     * @return The provenance predicate, or {@code null} if not set.
077     */
078    public Provenance getPredicate() {
079        return predicate;
080    }
081
082    /**
083     * Gets the URI identifying the type of the predicate.
084     *
085     * @return The predicate type URI, or {@code null} if no predicate has been set.
086     */
087    public String getPredicateType() {
088        return predicateType;
089    }
090
091    /**
092     * Gets the set of software artifacts that the attestation applies to.
093     *
094     * <p>
095     * Each element represents a single artifact. Artifacts are matched purely by digest, regardless of content type.
096     * </p>
097     *
098     * @return The list of subject artifacts, or {@code null} if not set.
099     */
100    public List<ResourceDescriptor> getSubject() {
101        return subject;
102    }
103
104    @Override
105    public int hashCode() {
106        return Objects.hash(subject, predicateType, predicate);
107    }
108
109    /**
110     * Sets the provenance predicate and automatically assigns {@code predicateType} to the SLSA provenance v1 URI.
111     *
112     * @param predicate The provenance predicate.
113     * @return this for chaining.
114     */
115    public Statement setPredicate(final Provenance predicate) {
116        this.predicate = predicate;
117        this.predicateType = Provenance.PREDICATE_TYPE;
118        return this;
119    }
120
121    /**
122     * Sets the set of software artifacts that the attestation applies to.
123     *
124     * @param subject The list of subject artifacts.
125     * @return this for chaining.
126     */
127    public Statement setSubject(final List<ResourceDescriptor> subject) {
128        this.subject = subject;
129        return this;
130    }
131
132    @Override
133    public String toString() {
134        return "Statement{type='" + TYPE + "', subject=" + subject + ", predicateType='" + predicateType + "', predicate=" + predicate + '}';
135    }
136}