1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 package org.eclipse.aether.spi.connector.checksum; 20 21 import java.io.BufferedInputStream; 22 import java.io.ByteArrayInputStream; 23 import java.io.File; 24 import java.io.IOException; 25 import java.io.InputStream; 26 import java.nio.ByteBuffer; 27 import java.nio.file.Files; 28 import java.nio.file.Path; 29 import java.util.LinkedHashMap; 30 import java.util.List; 31 import java.util.Map; 32 33 /** 34 * Helper for checksum operations. 35 * 36 * @since 1.8.0 37 */ 38 public final class ChecksumAlgorithmHelper { 39 private ChecksumAlgorithmHelper() { 40 // nop 41 } 42 43 /** 44 * Calculates checksums for specified data. 45 * 46 * @param data The content for which to calculate checksums, must not be {@code null}. 47 * @param factories The checksum algorithm factories to use, must not be {@code null}. 48 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 49 * calculate it, never {@code null}. 50 * @throws IOException In case of any problem. 51 */ 52 public static Map<String, String> calculate(byte[] data, List<ChecksumAlgorithmFactory> factories) 53 throws IOException { 54 try (InputStream inputStream = new ByteArrayInputStream(data)) { 55 return calculate(inputStream, factories); 56 } 57 } 58 59 /** 60 * Calculates checksums for specified file. 61 * 62 * @param file The file for which to calculate checksums, must not be {@code null}. 63 * @param factories The checksum algorithm factories to use, must not be {@code null}. 64 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 65 * calculate it, never {@code null}. 66 * @throws IOException In case of any problem. 67 */ 68 public static Map<String, String> calculate(File file, List<ChecksumAlgorithmFactory> factories) 69 throws IOException { 70 return calculate(file.toPath(), factories); 71 } 72 73 /** 74 * Calculates checksums for specified file. 75 * 76 * @param path The file for which to calculate checksums, must not be {@code null}. 77 * @param factories The checksum algorithm factories to use, must not be {@code null}. 78 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 79 * calculate it, never {@code null}. 80 * @throws IOException In case of any problem. 81 * @since 2.0.0 82 */ 83 public static Map<String, String> calculate(Path path, List<ChecksumAlgorithmFactory> factories) 84 throws IOException { 85 try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(path))) { 86 return calculate(inputStream, factories); 87 } 88 } 89 90 private static Map<String, String> calculate(InputStream inputStream, List<ChecksumAlgorithmFactory> factories) 91 throws IOException { 92 LinkedHashMap<String, ChecksumAlgorithm> algorithms = new LinkedHashMap<>(); 93 factories.forEach(f -> algorithms.put(f.getName(), f.getAlgorithm())); 94 final byte[] buffer = new byte[1024 * 32]; 95 for (; ; ) { 96 int read = inputStream.read(buffer); 97 if (read < 0) { 98 break; 99 } 100 for (ChecksumAlgorithm checksumAlgorithm : algorithms.values()) { 101 checksumAlgorithm.update(ByteBuffer.wrap(buffer, 0, read)); 102 } 103 } 104 LinkedHashMap<String, String> result = new LinkedHashMap<>(); 105 algorithms.forEach((k, v) -> result.put(k, v.checksum())); 106 return result; 107 } 108 }