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.Map; 020import java.util.Objects; 021 022import com.fasterxml.jackson.annotation.JsonInclude; 023import com.fasterxml.jackson.annotation.JsonProperty; 024 025/** 026 * Description of an artifact or resource referenced in the build, identified by URI and cryptographic digest. 027 * 028 * <p> 029 * Used to represent inputs to, outputs from, or byproducts of the build process. 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 ResourceDescriptor { 037 038 /** Additional key-value metadata about the resource. */ 039 @JsonProperty("annotations") 040 private Map<String, Object> annotations; 041 /** Raw contents of the resource, base64-encoded in JSON. */ 042 @JsonProperty("content") 043 private byte[] content; 044 /** Map of digest algorithm names to hex-encoded values. */ 045 @JsonProperty("digest") 046 private Map<String, String> digest; 047 /** Download URI for the resource, if different from {@link #uri}. */ 048 @JsonProperty("downloadLocation") 049 private String downloadLocation; 050 /** Media type of the resource. */ 051 @JsonProperty("mediaType") 052 private String mediaType; 053 /** Human-readable name of the resource. */ 054 @JsonProperty("name") 055 private String name; 056 /** URI identifying the resource. */ 057 @JsonProperty("uri") 058 private String uri; 059 060 /** Creates a new ResourceDescriptor instance. */ 061 public ResourceDescriptor() { 062 } 063 064 /** 065 * Creates a new ResourceDescriptor with the given URI and digest. 066 * 067 * @param uri URI identifying the resource. 068 * @param digest map of digest algorithm names to their hex-encoded values. 069 */ 070 public ResourceDescriptor(final String uri, final Map<String, String> digest) { 071 this.uri = uri; 072 this.digest = digest; 073 } 074 075 @Override 076 public boolean equals(final Object o) { 077 if (this == o) { 078 return true; 079 } 080 if (o == null || getClass() != o.getClass()) { 081 return false; 082 } 083 final ResourceDescriptor that = (ResourceDescriptor) o; 084 return Objects.equals(uri, that.uri) && Objects.equals(digest, that.digest); 085 } 086 087 /** 088 * Gets additional key-value metadata about the resource, such as filename, size, or builder-specific attributes. 089 * 090 * @return The annotations map, or {@code null} if not set. 091 */ 092 public Map<String, Object> getAnnotations() { 093 return annotations; 094 } 095 096 /** 097 * Gets the raw contents of the resource, base64-encoded when serialized to JSON. 098 * 099 * @return The resource content, or {@code null} if not set. 100 */ 101 public byte[] getContent() { 102 return content; 103 } 104 105 /** 106 * Gets the map of cryptographic digest algorithms to their corresponding hex-encoded values for this resource. 107 * 108 * <p> 109 * Common keys include {@code "sha256"} and {@code "sha512"}. 110 * </p> 111 * 112 * @return The digest map, or {@code null} if not set. 113 */ 114 public Map<String, String> getDigest() { 115 return digest; 116 } 117 118 /** 119 * Gets the download URI for the resource, if different from {@link #getUri()}. 120 * 121 * @return The download location URI, or {@code null} if not set. 122 */ 123 public String getDownloadLocation() { 124 return downloadLocation; 125 } 126 127 /** 128 * Gets the media type of the resource (for example, {@code "application/octet-stream"}). 129 * 130 * @return The media type, or {@code null} if not set. 131 */ 132 public String getMediaType() { 133 return mediaType; 134 } 135 136 /** 137 * Gets the name of the resource. 138 * 139 * @return The resource name, or {@code null} if not set. 140 */ 141 public String getName() { 142 return name; 143 } 144 145 /** 146 * Gets the URI identifying the resource. 147 * 148 * @return The resource URI, or {@code null} if not set. 149 */ 150 public String getUri() { 151 return uri; 152 } 153 154 @Override 155 public int hashCode() { 156 return Objects.hash(uri, digest); 157 } 158 159 /** 160 * Sets additional key-value metadata about the resource. 161 * 162 * @param annotations The annotations map. 163 * @return this for chaining. 164 */ 165 public ResourceDescriptor setAnnotations(final Map<String, Object> annotations) { 166 this.annotations = annotations; 167 return this; 168 } 169 170 /** 171 * Sets the raw contents of the resource. 172 * 173 * @param content The resource content. 174 * @return this for chaining. 175 */ 176 public ResourceDescriptor setContent(final byte[] content) { 177 this.content = content; 178 return this; 179 } 180 181 /** 182 * Sets the map of cryptographic digest algorithms to their hex-encoded values. 183 * 184 * @param digest The digest map. 185 * @return this for chaining. 186 */ 187 public ResourceDescriptor setDigest(final Map<String, String> digest) { 188 this.digest = digest; 189 return this; 190 } 191 192 /** 193 * Sets the download URI for the resource. 194 * 195 * @param downloadLocation The download location URI. 196 * @return this for chaining. 197 */ 198 public ResourceDescriptor setDownloadLocation(final String downloadLocation) { 199 this.downloadLocation = downloadLocation; 200 return this; 201 } 202 203 /** 204 * Sets the media type of the resource. 205 * 206 * @param mediaType The media type. 207 * @return this for chaining. 208 */ 209 public ResourceDescriptor setMediaType(final String mediaType) { 210 this.mediaType = mediaType; 211 return this; 212 } 213 214 /** 215 * Sets the name of the resource. 216 * 217 * @param name The resource name. 218 * @return this for chaining. 219 */ 220 public ResourceDescriptor setName(final String name) { 221 this.name = name; 222 return this; 223 } 224 225 /** 226 * Sets the URI identifying the resource. 227 * 228 * @param uri The resource URI. 229 * @return this for chaining. 230 */ 231 public ResourceDescriptor setUri(final String uri) { 232 this.uri = uri; 233 return this; 234 } 235 236 @Override 237 public String toString() { 238 return "ResourceDescriptor{uri='" + uri + "', digest=" + digest + '}'; 239 } 240}