001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.eclipse.aether.spi.connector.checksum; 020 021import java.io.BufferedInputStream; 022import java.io.ByteArrayInputStream; 023import java.io.File; 024import java.io.IOException; 025import java.io.InputStream; 026import java.nio.ByteBuffer; 027import java.nio.file.Files; 028import java.nio.file.Path; 029import java.util.LinkedHashMap; 030import java.util.List; 031import java.util.Map; 032 033/** 034 * Helper for checksum operations. 035 * 036 * @since 1.8.0 037 */ 038public final class ChecksumAlgorithmHelper { 039 private ChecksumAlgorithmHelper() { 040 // nop 041 } 042 043 /** 044 * Calculates checksums for specified data. 045 * 046 * @param data The content for which to calculate checksums, must not be {@code null}. 047 * @param factories The checksum algorithm factories to use, must not be {@code null}. 048 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 049 * calculate it, never {@code null}. 050 * @throws IOException In case of any problem. 051 */ 052 public static Map<String, String> calculate(byte[] data, List<ChecksumAlgorithmFactory> factories) 053 throws IOException { 054 try (InputStream inputStream = new ByteArrayInputStream(data)) { 055 return calculate(inputStream, factories); 056 } 057 } 058 059 /** 060 * Calculates checksums for specified file. 061 * 062 * @param file The file for which to calculate checksums, must not be {@code null}. 063 * @param factories The checksum algorithm factories to use, must not be {@code null}. 064 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 065 * calculate it, never {@code null}. 066 * @throws IOException In case of any problem. 067 */ 068 public static Map<String, String> calculate(File file, List<ChecksumAlgorithmFactory> factories) 069 throws IOException { 070 return calculate(file.toPath(), factories); 071 } 072 073 /** 074 * Calculates checksums for specified file. 075 * 076 * @param path The file for which to calculate checksums, must not be {@code null}. 077 * @param factories The checksum algorithm factories to use, must not be {@code null}. 078 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 079 * calculate it, never {@code null}. 080 * @throws IOException In case of any problem. 081 * @since 2.0.0 082 */ 083 public static Map<String, String> calculate(Path path, List<ChecksumAlgorithmFactory> factories) 084 throws IOException { 085 try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(path))) { 086 return calculate(inputStream, factories); 087 } 088 } 089 090 private static Map<String, String> calculate(InputStream inputStream, List<ChecksumAlgorithmFactory> factories) 091 throws IOException { 092 LinkedHashMap<String, ChecksumAlgorithm> algorithms = new LinkedHashMap<>(); 093 factories.forEach(f -> algorithms.put(f.getName(), f.getAlgorithm())); 094 final byte[] buffer = new byte[1024 * 32]; 095 for (; ; ) { 096 int read = inputStream.read(buffer); 097 if (read < 0) { 098 break; 099 } 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}