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