diff --git a/Dorkbox-Util/src/dorkbox/util/FileUtil.java b/Dorkbox-Util/src/dorkbox/util/FileUtil.java index 8f4095b..005234a 100644 --- a/Dorkbox-Util/src/dorkbox/util/FileUtil.java +++ b/Dorkbox-Util/src/dorkbox/util/FileUtil.java @@ -15,10 +15,16 @@ */ package dorkbox.util; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.*; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.RandomAccessFile; +import java.io.Reader; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.LinkedList; @@ -26,6 +32,9 @@ import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + /** * File related utilities. *

@@ -37,6 +46,7 @@ import java.util.zip.ZipInputStream; * Peter Donald, Jeff Turner, Matthew Hawthorne, Martin Cooper, * Jeremias Maerki, Stephen Colebourne */ +@SuppressWarnings({"WeakerAccess", "Duplicates", "unused"}) public class FileUtil { private static final Logger logger = LoggerFactory.getLogger(FileUtil.class); @@ -114,9 +124,9 @@ class FileUtil { try { fin = new FileInputStream(source); fout = new FileOutputStream(dest); - Sys.copyStream(fin, fout); + IO.copyStream(fin, fout); - Sys.close(fin); + IO.close(fin); if (!source.delete()) { logger.warn("Failed to delete {} after brute force copy to {}.", source, dest); } @@ -127,8 +137,8 @@ class FileUtil { return false; } finally { - Sys.close(fin); - Sys.close(fout); + IO.close(fin); + IO.close(fout); } } @@ -141,10 +151,12 @@ class FileUtil { List lines = new ArrayList(); try { BufferedReader bin = new BufferedReader(in); - for (String line; (line = bin.readLine()) != null; lines.add(line)) { + String line; + while ((line = bin.readLine()) != null) { + lines.add(line); } } finally { - Sys.close(in); + IO.close(in); } return lines; } @@ -212,6 +224,7 @@ class FileUtil { // if out doesn't exist, then create it. File parentOut = out.getParentFile(); if (!parentOut.canWrite()) { + //noinspection ResultOfMethodCallIgnored parentOut.mkdirs(); } @@ -246,6 +259,7 @@ class FileUtil { } } + //noinspection ResultOfMethodCallIgnored out.setLastModified(in.lastModified()); return out; @@ -299,6 +313,7 @@ class FileUtil { } } + //noinspection ResultOfMethodCallIgnored one.setLastModified(System.currentTimeMillis()); return one; @@ -333,6 +348,7 @@ class FileUtil { } if (out.canRead()) { + //noinspection ResultOfMethodCallIgnored out.delete(); } @@ -373,6 +389,7 @@ class FileUtil { if (src.isDirectory()) { // if directory not exists, create it if (!dest.exists()) { + //noinspection ResultOfMethodCallIgnored dest.mkdir(); Logger logger2 = logger; if (logger2.isTraceEnabled()) { @@ -383,13 +400,15 @@ class FileUtil { // list all the directory contents String files[] = src.list(); - for (String file : files) { - // construct the src and dest file structure - File srcFile = new File(src, file); - File destFile = new File(dest, file); + if (files != null) { + for (String file : files) { + // construct the src and dest file structure + File srcFile = new File(src, file); + File destFile = new File(dest, file); - // recursive copy - copyDirectory(srcFile, destFile, namesToIgnore); + // recursive copy + copyDirectory(srcFile, destFile, namesToIgnore); + } } } else { @@ -424,6 +443,7 @@ class FileUtil { if (src.isDirectory()) { // if directory not exists, create it if (!dest.exists()) { + //noinspection ResultOfMethodCallIgnored dest.mkdir(); Logger logger2 = logger; if (logger2.isTraceEnabled()) { @@ -434,13 +454,15 @@ class FileUtil { // list all the directory contents String files[] = src.list(); - for (String file : files) { - // construct the src and dest file structure - File srcFile = new File(src, file); - File destFile = new File(dest, file); + if (files != null) { + for (String file : files) { + // construct the src and dest file structure + File srcFile = new File(src, file); + File destFile = new File(dest, file); - // recursive copy - moveDirectory(srcFile, destFile, fileNamesToIgnore); + // recursive copy + moveDirectory(srcFile, destFile, fileNamesToIgnore); + } } } else { @@ -465,11 +487,12 @@ class FileUtil { } /** - * Deletes a file or directory and all files and sub-directories under it. + * Deletes a file, directory + all files and sub-directories under it. The directory is ALSO deleted if it because empty as a result + * of this operation * * @param namesToIgnore if prefaced with a '/', it will treat the name to ignore as a directory instead of file * - * @return true iff the file/dir was deleted (or didn't exist) + * @return true IFF the file/dir was deleted or didn't exist at first */ public static boolean delete(File file, String... namesToIgnore) { @@ -477,6 +500,7 @@ class FileUtil { return true; } + boolean thingsDeleted = false; boolean ignored = false; Logger logger2 = logger; if (file.isDirectory()) { @@ -544,7 +568,7 @@ class FileUtil { if (logger2.isTraceEnabled()) { logger2.trace("Deleting file: {}", file2); } - file2.delete(); + thingsDeleted |= file2.delete(); } } } @@ -563,7 +587,8 @@ class FileUtil { logger2.trace("Deleting file: {}", file); } - return file.delete(); + thingsDeleted |= file.delete(); + return thingsDeleted; } @@ -645,6 +670,7 @@ class FileUtil { try { in.mark(ZIP_HEADER.length); for (int i = 0; i < ZIP_HEADER.length; i++) { + //noinspection NumericCastThatLosesPrecision if (ZIP_HEADER[i] != (byte) in.read()) { isZip = false; break; @@ -833,13 +859,13 @@ class FileUtil { FileOutputStream output = new FileOutputStream(file); try { - Sys.copyStream(inputStream, output); + IO.copyStream(inputStream, output); } finally { - Sys.close(output); + IO.close(output); } } } finally { - Sys.close(inputStream); + IO.close(inputStream); } } @@ -1096,7 +1122,6 @@ class FileUtil { * Extracts a file from a zip into a TEMP file, if possible. The TEMP file is deleted upon JVM exit. * * @return the location of the extracted file, or NULL if the file cannot be extracted or doesn't exist. - * @throws IOException */ public static String extractFromZip(String zipFile, String fileToExtract) throws IOException { @@ -1127,7 +1152,7 @@ class FileUtil { FileOutputStream output = new FileOutputStream(tempFile); try { - Sys.copyStream(inputStrem, output); + IO.copyStream(inputStrem, output); } finally { output.close(); } @@ -1675,13 +1700,13 @@ class FileUtil { if (ch1 == ':') { ch0 = Character.toUpperCase(ch0); if (ch0 >= 'A' && ch0 <= 'Z') { + //noinspection PointlessBooleanExpression if (len == 2 || isSeparator(filename.charAt(2)) == false) { return 2; } return 3; } return -1; - } else if (isSeparator(ch0) && isSeparator(ch1)) { int posUnix = filename.indexOf(UNIX_SEPARATOR, 2); @@ -1724,16 +1749,20 @@ class FileUtil { /** * Gets the extension of a file (text after the last '.') * - * @return null if there is no extension + * @return "" if there is no extension or fileName is null */ public static String getExtension(String fileName) { + if (fileName == null) { + return ""; + } + int dot = fileName.lastIndexOf('.'); if (dot > -1) { return fileName.substring(dot + 1); } else { - return null; + return ""; } } diff --git a/Dorkbox-Util/src/dorkbox/util/IO.java b/Dorkbox-Util/src/dorkbox/util/IO.java new file mode 100644 index 0000000..be4c367 --- /dev/null +++ b/Dorkbox-Util/src/dorkbox/util/IO.java @@ -0,0 +1,164 @@ +/* + * Copyright 2010 dorkbox, llc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package dorkbox.util; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.Reader; +import java.io.Writer; + +@SuppressWarnings("unused") +public +class IO { + /** + * Convenient close for a stream. + */ + @SuppressWarnings("Duplicates") + public static + void close(InputStream inputStream) { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException ioe) { + System.err.println("Error closing the input stream:" + inputStream); + ioe.printStackTrace(); + } + } + } + + /** + * Convenient close for a stream. + */ + @SuppressWarnings("Duplicates") + public static + void closeQuietly(InputStream inputStream) { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException ignored) { + } + } + } + + /** + * Convenient close for a stream. + */ + @SuppressWarnings("Duplicates") + public static + void close(OutputStream outputStream) { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException ioe) { + System.err.println("Error closing the output stream:" + outputStream); + ioe.printStackTrace(); + } + } + } + + /** + * Convenient close for a stream. + */ + @SuppressWarnings("Duplicates") + public static + void closeQuietly(OutputStream outputStream) { + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException ignored) { + } + } + } + + /** + * Convenient close for a Reader. + */ + @SuppressWarnings("Duplicates") + public static + void close(Reader inputReader) { + if (inputReader != null) { + try { + inputReader.close(); + } catch (IOException ioe) { + System.err.println("Error closing input reader: " + inputReader); + ioe.printStackTrace(); + } + } + } + + /** + * Convenient close for a Reader. + */ + @SuppressWarnings("Duplicates") + public static + void closeQuietly(Reader inputReader) { + if (inputReader != null) { + try { + inputReader.close(); + } catch (IOException ignored) { + } + } + } + + /** + * Convenient close for a Writer. + */ + @SuppressWarnings("Duplicates") + public static + void close(Writer outputWriter) { + if (outputWriter != null) { + try { + outputWriter.close(); + } catch (IOException ioe) { + System.err.println("Error closing output writer: " + outputWriter); + ioe.printStackTrace(); + } + } + } + + /** + * Convenient close for a Writer. + */ + @SuppressWarnings("Duplicates") + public static + void closeQuietly(Writer outputWriter) { + if (outputWriter != null) { + try { + outputWriter.close(); + } catch (IOException ignored) { + } + } + } + + /** + * Copy the contents of the input stream to the output stream. + *

+ * DOES NOT CLOSE THE STEAMS! + */ + public static + T copyStream(InputStream inputStream, T outputStream) throws IOException { + byte[] buffer = new byte[4096]; + int read; + while ((read = inputStream.read(buffer)) > 0) { + outputStream.write(buffer, 0, read); + } + outputStream.flush(); + + return outputStream; + } + +} diff --git a/Dorkbox-Util/src/dorkbox/util/Sys.java b/Dorkbox-Util/src/dorkbox/util/Sys.java index 3f3a828..0b9d052 100644 --- a/Dorkbox-Util/src/dorkbox/util/Sys.java +++ b/Dorkbox-Util/src/dorkbox/util/Sys.java @@ -15,15 +15,10 @@ */ package dorkbox.util; -import org.bouncycastle.crypto.digests.SHA256Digest; - import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; -import java.io.Reader; -import java.io.Writer; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Arrays; @@ -32,6 +27,9 @@ import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.TimeUnit; +import org.bouncycastle.crypto.digests.SHA256Digest; + +@SuppressWarnings({"unused", "WeakerAccess"}) public final class Sys { public static final int KILOBYTE = 1024; @@ -251,144 +249,6 @@ class Sys { return String.format("%.4g " + text, value); } - - /** - * Convenient close for a stream. - */ - @SuppressWarnings("Duplicates") - public static - void close(InputStream inputStream) { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException ioe) { - System.err.println("Error closing the input stream:" + inputStream); - ioe.printStackTrace(); - } - } - } - - /** - * Convenient close for a stream. - */ - @SuppressWarnings("Duplicates") - public static - void closeQuietly(InputStream inputStream) { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException ignored) { - } - } - } - - /** - * Convenient close for a stream. - */ - @SuppressWarnings("Duplicates") - public static - void close(OutputStream outputStream) { - if (outputStream != null) { - try { - outputStream.close(); - } catch (IOException ioe) { - System.err.println("Error closing the output stream:" + outputStream); - ioe.printStackTrace(); - } - } - } - - /** - * Convenient close for a stream. - */ - @SuppressWarnings("Duplicates") - public static - void closeQuietly(OutputStream outputStream) { - if (outputStream != null) { - try { - outputStream.close(); - } catch (IOException ignored) { - } - } - } - - /** - * Convenient close for a Reader. - */ - @SuppressWarnings("Duplicates") - public static - void close(Reader inputReader) { - if (inputReader != null) { - try { - inputReader.close(); - } catch (IOException ioe) { - System.err.println("Error closing input reader: " + inputReader); - ioe.printStackTrace(); - } - } - } - - /** - * Convenient close for a Reader. - */ - @SuppressWarnings("Duplicates") - public static - void closeQuietly(Reader inputReader) { - if (inputReader != null) { - try { - inputReader.close(); - } catch (IOException ignored) { - } - } - } - - /** - * Convenient close for a Writer. - */ - @SuppressWarnings("Duplicates") - public static - void close(Writer outputWriter) { - if (outputWriter != null) { - try { - outputWriter.close(); - } catch (IOException ioe) { - System.err.println("Error closing output writer: " + outputWriter); - ioe.printStackTrace(); - } - } - } - - /** - * Convenient close for a Writer. - */ - @SuppressWarnings("Duplicates") - public static - void closeQuietly(Writer outputWriter) { - if (outputWriter != null) { - try { - outputWriter.close(); - } catch (IOException ignored) { - } - } - } - - /** - * Copy the contents of the input stream to the output stream. - *

- * DOES NOT CLOSE THE STEAMS! - */ - public static - T copyStream(InputStream inputStream, T outputStream) throws IOException { - byte[] buffer = new byte[4096]; - int read; - while ((read = inputStream.read(buffer)) > 0) { - outputStream.write(buffer, 0, read); - } - outputStream.flush(); - - return outputStream; - } - /** * Convert the contents of the input stream to a byte array. */ @@ -498,6 +358,7 @@ class Sys { // NOTE: this saves the char array in UTF-16 format of bytes. byte[] bytes = new byte[text.length * 2]; for (int i = 0; i < text.length; i++) { + //noinspection CharUsedInArithmeticContext bytes[2 * i] = (byte) (text[i] >> 8); bytes[2 * i + 1] = (byte) text[i]; } @@ -518,6 +379,7 @@ class Sys { return new byte[length]; } + //noinspection NumericCastThatLosesPrecision bytes[i] = (byte) intValue; } @@ -635,8 +497,9 @@ class Sys { /** * A 4-digit hex result. */ + @SuppressWarnings("CharUsedInArithmeticContext") public static - void hex4(char c, StringBuilder sb) { + void hex4(final char c, final StringBuilder sb) { sb.append(HEX_CHARS[(c & 0xF000) >> 12]); sb.append(HEX_CHARS[(c & 0x0F00) >> 8]); sb.append(HEX_CHARS[(c & 0x00F0) >> 4]); diff --git a/Dorkbox-Util/src/dorkbox/util/crypto/CryptoPGP.java b/Dorkbox-Util/src/dorkbox/util/crypto/CryptoPGP.java index c2f198f..d55b9cd 100644 --- a/Dorkbox-Util/src/dorkbox/util/crypto/CryptoPGP.java +++ b/Dorkbox-Util/src/dorkbox/util/crypto/CryptoPGP.java @@ -15,20 +15,6 @@ */ package dorkbox.util.crypto; -import dorkbox.util.OS; -import dorkbox.util.Sys; -import org.bouncycastle.bcpg.ArmoredOutputStream; -import org.bouncycastle.bcpg.BCPGOutputStream; -import org.bouncycastle.bcpg.CompressionAlgorithmTags; -import org.bouncycastle.openpgp.*; -import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; -import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; -import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; -import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; -import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; -import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; -import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; - import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; @@ -47,6 +33,39 @@ import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.bouncycastle.bcpg.ArmoredOutputStream; +import org.bouncycastle.bcpg.BCPGOutputStream; +import org.bouncycastle.bcpg.CompressionAlgorithmTags; +import org.bouncycastle.openpgp.PGPCompressedData; +import org.bouncycastle.openpgp.PGPCompressedDataGenerator; +import org.bouncycastle.openpgp.PGPEncryptedData; +import org.bouncycastle.openpgp.PGPEncryptedDataGenerator; +import org.bouncycastle.openpgp.PGPException; +import org.bouncycastle.openpgp.PGPLiteralData; +import org.bouncycastle.openpgp.PGPLiteralDataGenerator; +import org.bouncycastle.openpgp.PGPObjectFactory; +import org.bouncycastle.openpgp.PGPPublicKey; +import org.bouncycastle.openpgp.PGPPublicKeyRing; +import org.bouncycastle.openpgp.PGPPublicKeyRingCollection; +import org.bouncycastle.openpgp.PGPSecretKey; +import org.bouncycastle.openpgp.PGPSecretKeyRing; +import org.bouncycastle.openpgp.PGPSecretKeyRingCollection; +import org.bouncycastle.openpgp.PGPSignature; +import org.bouncycastle.openpgp.PGPSignatureGenerator; +import org.bouncycastle.openpgp.PGPSignatureList; +import org.bouncycastle.openpgp.PGPSignatureSubpacketGenerator; +import org.bouncycastle.openpgp.PGPUtil; +import org.bouncycastle.openpgp.operator.PBESecretKeyDecryptor; +import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator; +import org.bouncycastle.openpgp.operator.bc.BcPBESecretKeyDecryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPContentSignerBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDataEncryptorBuilder; +import org.bouncycastle.openpgp.operator.bc.BcPGPDigestCalculatorProvider; +import org.bouncycastle.openpgp.operator.bc.BcPublicKeyKeyEncryptionMethodGenerator; + +import dorkbox.util.IO; +import dorkbox.util.OS; + /** * PGP crypto related methods */ @@ -158,7 +177,7 @@ class CryptoPGP { } catch (IOException e) { throw new PGPException("Unable to save signature to file " + file.getAbsolutePath() + ".asc", e); } finally { - Sys.close(fileOutputStream1); + IO.close(fileOutputStream1); } } @@ -260,9 +279,9 @@ class CryptoPGP { } catch (Exception e) { e.printStackTrace(); } finally { - Sys.close(bcOutputStream); - Sys.close(outputStream); - Sys.close(literalDataOutput); + IO.close(bcOutputStream); + IO.close(outputStream); + IO.close(literalDataOutput); } return byteArrayOutputStream.toByteArray(); @@ -366,9 +385,9 @@ class CryptoPGP { } catch (Exception e) { e.printStackTrace(); } finally { - Sys.close(bcOutputStream); - Sys.close(outputStream); - Sys.close(literalDataOutput); + IO.close(bcOutputStream); + IO.close(outputStream); + IO.close(literalDataOutput); } return byteArrayOutputStream.toByteArray(); @@ -394,7 +413,7 @@ class CryptoPGP { } catch (IOException e) { throw new PGPException("No private key found in stream!", e); } finally { - Sys.close(inputStream); + IO.close(inputStream); } // look for the key ring that is used to authenticate our reporting facilities @@ -605,7 +624,7 @@ class CryptoPGP { throw e; } finally { compressedDataGenerator.close(); - Sys.close(compressedOutput); + IO.close(compressedOutput); } SecureRandom random = new SecureRandom(); @@ -638,8 +657,8 @@ class CryptoPGP { } catch (PGPException e) { throw e; } finally { - Sys.close(encryptedOutput); - Sys.close(armoredOut); + IO.close(encryptedOutput); + IO.close(armoredOut); } String encrypted = new String(byteArrayOutputStream.toByteArray()); @@ -804,12 +823,12 @@ class CryptoPGP { FileOutputStream fileOutputStream = new FileOutputStream(new File("/home/user/dorkbox/hello2.txt")); fileOutputStream.write(textBytes); fileOutputStream.flush(); - Sys.close(fileOutputStream); + IO.close(fileOutputStream); FileOutputStream fileOutputStream1 = new FileOutputStream(new File("/home/user/dorkbox/hello2.txt.asc")); fileOutputStream1.write(bytes); fileOutputStream1.flush(); - Sys.close(fileOutputStream1); + IO.close(fileOutputStream1); } }