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.time.OffsetDateTime;
020import java.util.Objects;
021
022import com.fasterxml.jackson.annotation.JsonFormat;
023import com.fasterxml.jackson.annotation.JsonInclude;
024import com.fasterxml.jackson.annotation.JsonProperty;
025
026/**
027 * Metadata about a build invocation: its identifier and start and finish timestamps.
028 *
029 * @see <a href="https://slsa.dev/spec/v1.2">SLSA v1.2 Specification</a>
030 * @since 1.10.0
031 */
032@JsonInclude(JsonInclude.Include.NON_NULL)
033public class BuildMetadata {
034
035    /** Timestamp when the build completed. */
036    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
037    @JsonProperty("finishedOn")
038    private OffsetDateTime finishedOn;
039    /** Identifier for this build invocation. */
040    @JsonProperty("invocationId")
041    private String invocationId;
042    /** Timestamp when the build started. */
043    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss'Z'")
044    @JsonProperty("startedOn")
045    private OffsetDateTime startedOn;
046
047    /** Creates a new BuildMetadata instance. */
048    public BuildMetadata() {
049    }
050
051    /**
052     * Creates a new BuildMetadata instance with all fields set.
053     *
054     * @param invocationId identifier for this build invocation.
055     * @param startedOn    timestamp when the build started.
056     * @param finishedOn   timestamp when the build completed.
057     */
058    public BuildMetadata(final String invocationId, final OffsetDateTime startedOn, final OffsetDateTime finishedOn) {
059        this.invocationId = invocationId;
060        this.startedOn = startedOn;
061        this.finishedOn = finishedOn;
062    }
063
064    @Override
065    public boolean equals(final Object o) {
066        if (!(o instanceof BuildMetadata)) {
067            return false;
068        }
069        final BuildMetadata that = (BuildMetadata) o;
070        return Objects.equals(invocationId, that.invocationId) && Objects.equals(startedOn, that.startedOn) && Objects.equals(finishedOn, that.finishedOn);
071    }
072
073    /**
074     * Gets the timestamp of when the build completed, serialized as RFC 3339 in UTC ({@code "Z"} suffix).
075     *
076     * @return The completion timestamp, or {@code null} if not set.
077     */
078    public OffsetDateTime getFinishedOn() {
079        return finishedOn;
080    }
081
082    /**
083     * Gets the identifier for this build invocation.
084     *
085     * @return The invocation identifier, or {@code null} if not set.
086     */
087    public String getInvocationId() {
088        return invocationId;
089    }
090
091    /**
092     * Gets the timestamp of when the build started, serialized as RFC 3339 in UTC ({@code "Z"} suffix).
093     *
094     * @return The start timestamp, or {@code null} if not set.
095     */
096    public OffsetDateTime getStartedOn() {
097        return startedOn;
098    }
099
100    @Override
101    public int hashCode() {
102        return Objects.hash(invocationId, startedOn, finishedOn);
103    }
104
105    /**
106     * Sets the timestamp of when the build completed.
107     *
108     * @param finishedOn The completion timestamp.
109     * @return this for chaining.
110     */
111    public BuildMetadata setFinishedOn(final OffsetDateTime finishedOn) {
112        this.finishedOn = finishedOn;
113        return this;
114    }
115
116    /**
117     * Sets the identifier for this build invocation.
118     *
119     * @param invocationId The invocation identifier.
120     * @return this for chaining.
121     */
122    public BuildMetadata setInvocationId(final String invocationId) {
123        this.invocationId = invocationId;
124        return this;
125    }
126
127    /**
128     * Sets the timestamp of when the build started.
129     *
130     * @param startedOn The start timestamp.
131     * @return this for chaining.
132     */
133    public BuildMetadata setStartedOn(final OffsetDateTime startedOn) {
134        this.startedOn = startedOn;
135        return this;
136    }
137
138    @Override
139    public String toString() {
140        return "BuildMetadata{invocationId='" + invocationId + "', startedOn=" + startedOn + ", finishedOn=" + finishedOn + '}';
141    }
142}