1 /** 2 * Portions of this software was developed by employees of the National Institute 3 * of Standards and Technology (NIST), an agency of the Federal Government and is 4 * being made available as a public service. Pursuant to title 17 United States 5 * Code Section 105, works of NIST employees are not subject to copyright 6 * protection in the United States. This software may be subject to foreign 7 * copyright. Permission in the United States and in foreign countries, to the 8 * extent that NIST may hold copyright, to use, copy, modify, create derivative 9 * works, and distribute this software and its documentation without fee is hereby 10 * granted on a non-exclusive basis, provided that this notice and disclaimer 11 * of warranty appears in all copies. 12 * 13 * THE SOFTWARE IS PROVIDED 'AS IS' WITHOUT ANY WARRANTY OF ANY KIND, EITHER 14 * EXPRESSED, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY 15 * THAT THE SOFTWARE WILL CONFORM TO SPECIFICATIONS, ANY IMPLIED WARRANTIES OF 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND FREEDOM FROM 17 * INFRINGEMENT, AND ANY WARRANTY THAT THE DOCUMENTATION WILL CONFORM TO THE 18 * SOFTWARE, OR ANY WARRANTY THAT THE SOFTWARE WILL BE ERROR FREE. IN NO EVENT 19 * SHALL NIST BE LIABLE FOR ANY DAMAGES, INCLUDING, BUT NOT LIMITED TO, DIRECT, 20 * INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF, RESULTING FROM, 21 * OR IN ANY WAY CONNECTED WITH THIS SOFTWARE, WHETHER OR NOT BASED UPON WARRANTY, 22 * CONTRACT, TORT, OR OTHERWISE, WHETHER OR NOT INJURY WAS SUSTAINED BY PERSONS OR 23 * PROPERTY OR OTHERWISE, AND WHETHER OR NOT LOSS WAS SUSTAINED FROM, OR AROSE OUT 24 * OF THE RESULTS OF, OR USE OF, THE SOFTWARE OR SERVICES PROVIDED HEREUNDER. 25 */ 26 27 package gov.nist.secauto.swid.builder.resource.file; 28 29 import static gov.nist.secauto.swid.builder.util.Util.requireNonEmpty; 30 31 import gov.nist.secauto.swid.builder.resource.HashAlgorithm; 32 import gov.nist.secauto.swid.builder.resource.HashUtils; 33 import gov.nist.secauto.swid.builder.resource.ResourceCollectionEntryGenerator; 34 35 import java.io.BufferedInputStream; 36 import java.io.File; 37 import java.io.FileInputStream; 38 import java.io.IOException; 39 import java.io.InputStream; 40 import java.security.NoSuchAlgorithmException; 41 import java.util.LinkedHashMap; 42 import java.util.Map; 43 import java.util.Objects; 44 45 public class FileBuilder extends AbstractFileSystemItemBuilder<FileBuilder> { 46 private Long size; 47 private String version; 48 private Map<HashAlgorithm, byte[]> hashAlgorithmToValueMap = new LinkedHashMap<>(); 49 50 protected FileBuilder() { 51 super(); 52 } 53 54 @Override 55 public void reset() { 56 super.reset(); 57 this.size = null; 58 this.version = null; 59 this.hashAlgorithmToValueMap = new LinkedHashMap<>(); 60 } 61 62 public static FileBuilder create() { 63 return new FileBuilder(); 64 } 65 66 @Override 67 public <T> void accept(T parentContext, ResourceCollectionEntryGenerator<T> creator) { 68 creator.generate(parentContext, this); 69 } 70 71 public Long getSize() { 72 return size; 73 } 74 75 public String getVersion() { 76 return version; 77 } 78 79 public Map<HashAlgorithm, byte[]> getHashAlgorithmToValueMap() { 80 return hashAlgorithmToValueMap; 81 } 82 83 /** 84 * Sets the to-be-built file's size to the provided value. 85 * 86 * @param size 87 * a non-zero integer indicating the file's size in bytes 88 * @return the same builder instance 89 */ 90 public FileBuilder size(long size) { 91 if (size < 0) { 92 throw new IllegalArgumentException("the size value must be a positive number"); 93 } 94 this.size = size; 95 return this; 96 } 97 98 /** 99 * Sets the to-be-built file's hash value, for the provided algorithm, to the provided value. An 100 * {@link InputStream} is used to retrieve the files contents to calculate the hash value. The 101 * caller is resposnible for closing the stream used by this method. 102 * 103 * @param algorithm 104 * the algorithm to establish a hash value for 105 * @param file 106 * the file to hash 107 * @return the same builder instance 108 * @throws NoSuchAlgorithmException 109 * if the hash algorithm is not supported 110 * @throws IOException 111 * if an error occurs while reading the stream 112 */ 113 public FileBuilder hash(HashAlgorithm algorithm, File file) throws NoSuchAlgorithmException, IOException { 114 InputStream is = new BufferedInputStream(new FileInputStream(file)); 115 return hash(algorithm, is); 116 } 117 118 /** 119 * Sets the file's hash value, for the provided algorithm, to the provided value. An 120 * {@link InputStream} is used to retrieve the files contents to calculate the hash value. The 121 * caller is responsible for closing the stream used by this method. 122 * 123 * @param algorithm 124 * the algorithm to establish a hash value for 125 * @param is 126 * an {@link InputStream} that can be used to read the file 127 * @return the same builder instance 128 * @throws NoSuchAlgorithmException 129 * if the hash algorithm is not supported 130 * @throws IOException 131 * if an error occurs while reading the stream 132 */ 133 public FileBuilder hash(HashAlgorithm algorithm, InputStream is) throws NoSuchAlgorithmException, IOException { 134 byte[] digest = HashUtils.hash(algorithm, is); 135 return hash(algorithm, digest); 136 } 137 138 /** 139 * Sets the file's hash value, for the provided algorithm, to the provided value. 140 * 141 * @param algorithm 142 * the algorithm to establish a hash value for 143 * @param hashBytes 144 * the digest value as a byte array. 145 * @return the same builder instance 146 */ 147 public FileBuilder hash(HashAlgorithm algorithm, byte[] hashBytes) { 148 Objects.requireNonNull(algorithm, "algorithm"); 149 Objects.requireNonNull(hashBytes, "hashBytes"); 150 hashAlgorithmToValueMap.put(algorithm, hashBytes); 151 return this; 152 } 153 154 /** 155 * Sets the file's hash value, for the provided algorithm, to the provided value. 156 * 157 * @param algorithm 158 * the algorithm to establish a hash value for 159 * @param hashHexBytes 160 * the digest value as a hex string. 161 * @return the same builder instance 162 */ 163 public FileBuilder hash(HashAlgorithm algorithm, String hashHexBytes) { 164 Objects.requireNonNull(algorithm, "algorithm"); 165 Objects.requireNonNull(hashHexBytes, "hashBytes"); 166 hashAlgorithmToValueMap.put(algorithm, HashUtils.toBytes(hashHexBytes)); 167 return this; 168 } 169 170 /** 171 * Sets the to-be-built file's version to the provided value. 172 * 173 * @param version 174 * the version value to use 175 * @return the same builder instance 176 */ 177 public FileBuilder version(String version) { 178 requireNonEmpty(version, "version"); 179 this.version = version; 180 return this; 181 } 182 183 }