001 /* 002 * SonarQube, open source software quality management tool. 003 * Copyright (C) 2008-2014 SonarSource 004 * mailto:contact AT sonarsource DOT com 005 * 006 * SonarQube is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 3 of the License, or (at your option) any later version. 010 * 011 * SonarQube is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public License 017 * along with this program; if not, write to the Free Software Foundation, 018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 019 */ 020 package org.sonar.home.cache; 021 022 import org.apache.commons.io.IOUtils; 023 024 import java.io.File; 025 import java.io.FileInputStream; 026 import java.io.IOException; 027 import java.io.InputStream; 028 import java.math.BigInteger; 029 import java.security.MessageDigest; 030 031 /** 032 * Hashes used to store files in the cache directory. 033 * 034 * @since 3.5 035 */ 036 public class FileHashes { 037 038 private static final int STREAM_BUFFER_LENGTH = 1024; 039 040 public String of(File file) { 041 try { 042 return of(new FileInputStream(file)); 043 } catch (IOException e) { 044 throw new IllegalStateException("Fail to compute hash of: " + file.getAbsolutePath(), e); 045 } 046 } 047 048 /** 049 * Computes the hash of given stream. The stream is closed by this method. 050 */ 051 public String of(InputStream input) { 052 try { 053 MessageDigest digest = MessageDigest.getInstance("MD5"); 054 byte[] hash = digest(input, digest); 055 return toHex(hash); 056 057 } catch (Exception e) { 058 throw new IllegalStateException("Fail to compute hash", e); 059 060 } finally { 061 IOUtils.closeQuietly(input); 062 } 063 } 064 065 private byte[] digest(InputStream input, MessageDigest digest) throws IOException { 066 final byte[] buffer = new byte[STREAM_BUFFER_LENGTH]; 067 int read = input.read(buffer, 0, STREAM_BUFFER_LENGTH); 068 while (read > -1) { 069 digest.update(buffer, 0, read); 070 read = input.read(buffer, 0, STREAM_BUFFER_LENGTH); 071 } 072 return digest.digest(); 073 } 074 075 static String toHex(byte[] bytes) { 076 BigInteger bi = new BigInteger(1, bytes); 077 return String.format("%0" + (bytes.length << 1) + "x", bi); 078 } 079 }