+ String filename = project.shortenFilename(file).replace('\\', '/');
+ String hash = hashFile(project.getLocalPath(), filename);
+ fileList.add(new ScannedFile(filename, hash));
+ }
+ }
+
+ /**
+ * 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. */