+ /**
+ * Hashes the given file.
+ *
+ * @param path
+ * The path of the project
+ * @param filename
+ * The name of the file, relative to the project path
+ * @return The hash of the file
+ */
+ @SuppressWarnings("synthetic-access")
+ private static String hashFile(String path, String filename) {
+ InputStream fileInputStream = null;
+ DigestOutputStream digestOutputStream = null;
+ File file = new File(path, filename);
+ try {
+ fileInputStream = new FileInputStream(file);
+ digestOutputStream = new DigestOutputStream(new NullOutputStream(), MessageDigest.getInstance("SHA-256"));
+ StreamCopier.copy(fileInputStream, digestOutputStream, file.length());
+ return toHex(digestOutputStream.getMessageDigest().digest());
+ } catch (NoSuchAlgorithmException nsae1) {
+ logger.log(Level.WARNING, "Could not get SHA-256 digest!", nsae1);
+ } catch (IOException ioe1) {
+ logger.log(Level.WARNING, "Could not read file!", ioe1);
+ } finally {
+ Closer.close(digestOutputStream);
+ Closer.close(fileInputStream);
+ }
+ return toHex(new byte[32]);
+ }
+
+ /**
+ * Converts the given byte array into a hexadecimal string.
+ *
+ * @param array
+ * The array to convert
+ * @return The hexadecimal string
+ */
+ private static String toHex(byte[] array) {
+ StringBuilder hexString = new StringBuilder(array.length * 2);
+ for (byte b : array) {
+ hexString.append("0123456789abcdef".charAt((b >>> 4) & 0x0f)).append("0123456789abcdef".charAt(b & 0xf));
+ }
+ return hexString.toString();
+ }
+
+ /**
+ * {@link OutputStream} that discards all written bytes.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ private static class NullOutputStream extends OutputStream {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(int b) {
+ /* do nothing. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b) {
+ /* do nothing. */
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void write(byte[] b, int off, int len) {
+ /* do nothing. */
+ }
+
+ }
+
+ /**
+ * Container for a scanned file, consisting of the name of the file and its
+ * hash.
+ *
+ * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
+ */
+ public static class ScannedFile implements Comparable<ScannedFile> {
+
+ /** The name of the file. */
+ private final String filename;
+
+ /** The hash of the file. */
+ private final String hash;
+
+ /**
+ * Creates a new scanned file.
+ *
+ * @param filename
+ * The name of the file
+ * @param hash
+ * The hash of the file
+ */
+ public ScannedFile(String filename, String hash) {
+ this.filename = filename;
+ this.hash = hash;
+ }
+
+ //
+ // ACCESSORS
+ //
+
+ /**
+ * Returns the name of the file.
+ *
+ * @return The name of the file
+ */
+ public String getFilename() {
+ return filename;
+ }
+
+ /**
+ * Returns the hash of the file.
+ *
+ * @return The hash of the file
+ */
+ public String getHash() {
+ return hash;
+ }
+
+ //
+ // OBJECT METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int hashCode() {
+ return filename.hashCode();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return filename.equals(obj);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String toString() {
+ return filename;
+ }
+
+ //
+ // COMPARABLE METHODS
+ //
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public int compareTo(ScannedFile scannedFile) {
+ return filename.compareTo(scannedFile.filename);
+ }
+
+ }
+
+}