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.util.LinkedHashMap; 029import java.util.List; 030import java.util.Map; 031 032/** 033 * Helper for checksum operations. 034 * 035 * @since 1.8.0 036 */ 037public final class ChecksumAlgorithmHelper { 038 private ChecksumAlgorithmHelper() { 039 // nop 040 } 041 042 /** 043 * Calculates checksums for specified data. 044 * 045 * @param data The content for which to calculate checksums, must not be {@code null}. 046 * @param factories The checksum algorithm factories to use, must not be {@code null}. 047 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 048 * calculate it, never {@code null}. 049 * @throws IOException In case of any problem. 050 */ 051 public static Map<String, String> calculate(byte[] data, List<ChecksumAlgorithmFactory> factories) 052 throws IOException { 053 try (InputStream inputStream = new ByteArrayInputStream(data)) { 054 return calculate(inputStream, factories); 055 } 056 } 057 058 /** 059 * Calculates checksums for specified file. 060 * 061 * @param file The file for which to calculate checksums, must not be {@code null}. 062 * @param factories The checksum algorithm factories to use, must not be {@code null}. 063 * @return The calculated checksums, indexed by algorithm name, or the exception that occurred while trying to 064 * calculate it, never {@code null}. 065 * @throws IOException In case of any problem. 066 */ 067 public static Map<String, String> calculate(File file, List<ChecksumAlgorithmFactory> factories) 068 throws IOException { 069 try (InputStream inputStream = new BufferedInputStream(Files.newInputStream(file.toPath()))) { 070 return calculate(inputStream, factories); 071 } 072 } 073 074 private static Map<String, String> calculate(InputStream inputStream, List<ChecksumAlgorithmFactory> factories) 075 throws IOException { 076 LinkedHashMap<String, ChecksumAlgorithm> algorithms = new LinkedHashMap<>(); 077 factories.forEach(f -> algorithms.put(f.getName(), f.getAlgorithm())); 078 final byte[] buffer = new byte[1024 * 32]; 079 for (; ; ) { 080 int read = inputStream.read(buffer); 081 if (read < 0) { 082 break; 083 } 084 for (ChecksumAlgorithm checksumAlgorithm : algorithms.values()) { 085 checksumAlgorithm.update(ByteBuffer.wrap(buffer, 0, read)); 086 } 087 } 088 LinkedHashMap<String, String> result = new LinkedHashMap<>(); 089 algorithms.forEach((k, v) -> result.put(k, v.checksum())); 090 return result; 091 } 092}