Document and clarify Argeo Util.
authorMathieu Baudier <mbaudier@argeo.org>
Wed, 28 Oct 2020 08:22:31 +0000 (09:22 +0100)
committerMathieu Baudier <mbaudier@argeo.org>
Wed, 28 Oct 2020 08:22:31 +0000 (09:22 +0100)
org.argeo.util/src/org/argeo/util/CsvParser.java
org.argeo.util/src/org/argeo/util/CsvParserWithLinesAsMap.java
org.argeo.util/src/org/argeo/util/CsvWriter.java
org.argeo.util/src/org/argeo/util/DigestUtils.java
org.argeo.util/src/org/argeo/util/DirH.java
org.argeo.util/src/org/argeo/util/LangUtils.java
org.argeo.util/src/org/argeo/util/PasswordEncryption.java
org.argeo.util/src/org/argeo/util/StreamUtils.java
org.argeo.util/src/org/argeo/util/Throughput.java
org.argeo.util/src/org/argeo/util/UtilsException.java [deleted file]

index 1f52e986e880f112ef0f463ff7a9ef6c1753cf7a..2774170595f3b8b46c9cb6ec8e140c1e7f35baf4 100644 (file)
@@ -4,6 +4,9 @@ import java.io.BufferedReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -22,42 +25,61 @@ public abstract class CsvParser {
 
        /**
         * Actually process a parsed line. If
-        * {@link #setStrictLineAsLongAsHeader(Boolean)} is true (default) the
-        * header and the tokens are guaranteed to have the same size.
+        * {@link #setStrictLineAsLongAsHeader(Boolean)} is true (default) the header
+        * and the tokens are guaranteed to have the same size.
         * 
-        * @param lineNumber
-        *            the current line number, starts at 1 (the header, if header
-        *            processing is enabled, the first line otherwise)
-        * @param header
-        *            the read-only header or null if {@link #setNoHeader(Boolean)}
-        *            is true (default is false)
-        * @param tokens
-        *            the parsed tokens
+        * @param lineNumber the current line number, starts at 1 (the header, if header
+        *                   processing is enabled, the first line otherwise)
+        * @param header     the read-only header or null if
+        *                   {@link #setNoHeader(Boolean)} is true (default is false)
+        * @param tokens     the parsed tokens
         */
-       protected abstract void processLine(Integer lineNumber,
-                       List<String> header, List<String> tokens);
+       protected abstract void processLine(Integer lineNumber, List<String> header, List<String> tokens);
 
        /**
         * Parses the CSV file (stream is closed at the end)
         */
        public synchronized void parse(InputStream in) {
-               parse(in, null);
+               parse(in, (Charset) null);
        }
 
        /**
         * Parses the CSV file (stream is closed at the end)
         */
        public synchronized void parse(InputStream in, String encoding) {
-               BufferedReader reader = null;
+               Reader reader;
+               if (encoding == null)
+                       reader = new InputStreamReader(in);
+               else
+                       try {
+                               reader = new InputStreamReader(in, encoding);
+                       } catch (UnsupportedEncodingException e) {
+                               throw new IllegalArgumentException(e);
+                       }
+               parse(reader);
+       }
+
+       /**
+        * Parses the CSV file (stream is closed at the end)
+        */
+       public synchronized void parse(InputStream in, Charset charset) {
+               Reader reader;
+               if (charset == null)
+                       reader = new InputStreamReader(in);
+               else
+                       reader = new InputStreamReader(in, charset);
+               parse(reader);
+       }
+
+       /**
+        * Parses the CSV file (stream is closed at the end)
+        */
+       public synchronized void parse(Reader r) {
                Integer lineCount = 0;
-               try {
-                       if (encoding == null)
-                               reader = new BufferedReader(new InputStreamReader(in));
-                       else
-                               reader = new BufferedReader(new InputStreamReader(in, encoding));
+               try (BufferedReader bufferedReader = new BufferedReader(r)) {
                        List<String> header = null;
                        if (!noHeader) {
-                               String headerStr = reader.readLine();
+                               String headerStr = bufferedReader.readLine();
                                if (headerStr == null)// empty file
                                        return;
                                lineCount++;
@@ -65,7 +87,7 @@ public abstract class CsvParser {
                                StringBuffer currStr = new StringBuffer("");
                                Boolean wasInquote = false;
                                while (parseLine(headerStr, header, currStr, wasInquote)) {
-                                       headerStr = reader.readLine();
+                                       headerStr = bufferedReader.readLine();
                                        if (headerStr == null)
                                                break;
                                        wasInquote = true;
@@ -74,7 +96,7 @@ public abstract class CsvParser {
                        }
 
                        String line = null;
-                       lines: while ((line = reader.readLine()) != null) {
+                       lines: while ((line = bufferedReader.readLine()) != null) {
                                line = preProcessLine(line);
                                if (line == null) {
                                        // skip line
@@ -85,7 +107,7 @@ public abstract class CsvParser {
                                StringBuffer currStr = new StringBuffer("");
                                Boolean wasInquote = false;
                                sublines: while (parseLine(line, tokens, currStr, wasInquote)) {
-                                       line = reader.readLine();
+                                       line = bufferedReader.readLine();
                                        if (line == null)
                                                break sublines;
                                        wasInquote = true;
@@ -96,29 +118,22 @@ public abstract class CsvParser {
                                        if (tokenSize == 1 && line.trim().equals(""))
                                                continue lines;// empty line
                                        if (headerSize != tokenSize) {
-                                               throw new UtilsException("Token size " + tokenSize
-                                                               + " is different from header size "
-                                                               + headerSize + " at line " + lineCount
-                                                               + ", line: " + line + ", header: " + header
+                                               throw new IllegalStateException("Token size " + tokenSize + " is different from header size "
+                                                               + headerSize + " at line " + lineCount + ", line: " + line + ", header: " + header
                                                                + ", tokens: " + tokens);
                                        }
                                }
                                processLine(lineCount, header, tokens);
                        }
-               } catch (UtilsException e) {
-                       throw e;
                } catch (IOException e) {
-                       throw new UtilsException("Cannot parse CSV file (line: "
-                                       + lineCount + ")", e);
-               } finally {
-                       StreamUtils.closeQuietly(reader);
+                       throw new RuntimeException("Cannot parse CSV file (line: " + lineCount + ")", e);
                }
        }
 
        /**
-        * Called before each (logical) line is processed, giving a change to modify
-        * it (typically for cleaning dirty files). To be overridden, return the
-        * line unchanged by default. Skip the line if 'null' is returned.
+        * Called before each (logical) line is processed, giving a change to modify it
+        * (typically for cleaning dirty files). To be overridden, return the line
+        * unchanged by default. Skip the line if 'null' is returned.
         */
        protected String preProcessLine(String line) {
                return line;
@@ -129,8 +144,7 @@ public abstract class CsvParser {
         * 
         * @return whether to continue parsing this line
         */
-       protected Boolean parseLine(String str, List<String> tokens,
-                       StringBuffer currStr, Boolean wasInquote) {
+       protected Boolean parseLine(String str, List<String> tokens, StringBuffer currStr, Boolean wasInquote) {
                // List<String> tokens = new ArrayList<String>();
 
                // System.out.println("#LINE: " + str);
@@ -209,8 +223,7 @@ public abstract class CsvParser {
                return strictLineAsLongAsHeader;
        }
 
-       public synchronized void setStrictLineAsLongAsHeader(
-                       Boolean strictLineAsLongAsHeader) {
+       public synchronized void setStrictLineAsLongAsHeader(Boolean strictLineAsLongAsHeader) {
                this.strictLineAsLongAsHeader = strictLineAsLongAsHeader;
        }
 
index 68fe8ad00d114f8829d9a09e7c940e7d16b69607..8eb6e94636a44146c2e5c37a5b8aa526d9efd9fe 100644 (file)
@@ -13,19 +13,15 @@ public abstract class CsvParserWithLinesAsMap extends CsvParser {
        /**
         * Actually processes a line.
         * 
-        * @param lineNumber
-        *            the current line number, starts at 1 (the header, if header
-        *            processing is enabled, the first lien otherwise)
-        * @param line
-        *            the parsed tokens as a map whose keys are the header fields
+        * @param lineNumber the current line number, starts at 1 (the header, if header
+        *                   processing is enabled, the first lien otherwise)
+        * @param line       the parsed tokens as a map whose keys are the header fields
         */
-       protected abstract void processLine(Integer lineNumber,
-                       Map<String, String> line);
+       protected abstract void processLine(Integer lineNumber, Map<String, String> line);
 
-       protected final void processLine(Integer lineNumber, List<String> header,
-                       List<String> tokens) {
+       protected final void processLine(Integer lineNumber, List<String> header, List<String> tokens) {
                if (header == null)
-                       throw new UtilsException("Only CSV with header is supported");
+                       throw new IllegalArgumentException("Only CSV with header is supported");
                Map<String, String> line = new HashMap<String, String>();
                for (int i = 0; i < header.size(); i++) {
                        String key = header.get(i);
index ba5b3c710ebd928ee5645041cdc3aa53550e5a72..97b5191035d83e41d1402b0eff0ff0595b74f03c 100644 (file)
@@ -18,8 +18,7 @@ public class CsvWriter {
        /**
         * Creates a CSV writer.
         * 
-        * @param out
-        *            the stream to write to. Caller is responsible for closing it.
+        * @param out the stream to write to. Caller is responsible for closing it.
         */
        public CsvWriter(OutputStream out) {
                this.out = new OutputStreamWriter(out);
@@ -28,21 +27,19 @@ public class CsvWriter {
        /**
         * Creates a CSV writer.
         * 
-        * @param out
-        *            the stream to write to. Caller is responsible for closing it.
+        * @param out the stream to write to. Caller is responsible for closing it.
         */
        public CsvWriter(OutputStream out, String encoding) {
                try {
                        this.out = new OutputStreamWriter(out, encoding);
                } catch (UnsupportedEncodingException e) {
-                       throw new UtilsException("Cannot initialize CSV writer", e);
+                       throw new IllegalArgumentException(e);
                }
        }
 
        /**
-        * Write a CSV line. Also used to write a header if needed (this is
-        * transparent for the CSV writer): simply call it first, before writing the
-        * lines.
+        * Write a CSV line. Also used to write a header if needed (this is transparent
+        * for the CSV writer): simply call it first, before writing the lines.
         */
        public void writeLine(List<?> tokens) {
                try {
@@ -55,14 +52,13 @@ public class CsvWriter {
                        out.write('\n');
                        out.flush();
                } catch (IOException e) {
-                       throw new UtilsException("Could not write " + tokens, e);
+                       throw new RuntimeException("Could not write " + tokens, e);
                }
        }
 
        /**
-        * Write a CSV line. Also used to write a header if needed (this is
-        * transparent for the CSV writer): simply call it first, before writing the
-        * lines.
+        * Write a CSV line. Also used to write a header if needed (this is transparent
+        * for the CSV writer): simply call it first, before writing the lines.
         */
        public void writeLine(Object[] tokens) {
                try {
@@ -79,7 +75,7 @@ public class CsvWriter {
                        out.write('\n');
                        out.flush();
                } catch (IOException e) {
-                       throw new UtilsException("Could not write " + tokens, e);
+                       throw new RuntimeException("Could not write " + tokens, e);
                }
        }
 
index 022af10385de6c2415d8dcaa007181691918230b..ce018007c6c637dce08d0c563e80d27a16c575cc 100644 (file)
@@ -20,7 +20,7 @@ public class DigestUtils {
        public final static String SHA512 = "SHA-512";
 
        private static Boolean debug = false;
-       // TODO: make it writable
+       // TODO: make it configurable
        private final static Integer byteBufferCapacity = 100 * 1024;// 100 KB
 
        public static byte[] sha1(byte[] bytes) {
@@ -29,8 +29,8 @@ public class DigestUtils {
                        digest.update(bytes);
                        byte[] checksum = digest.digest();
                        return checksum;
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot SHA1 digest", e);
+               } catch (NoSuchAlgorithmException e) {
+                       throw new IllegalArgumentException(e);
                }
        }
 
@@ -41,8 +41,8 @@ public class DigestUtils {
                        byte[] checksum = digest.digest();
                        String res = encodeHexString(checksum);
                        return res;
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot digest with algorithm " + algorithm, e);
+               } catch (NoSuchAlgorithmException e) {
+                       throw new IllegalArgumentException("Cannot digest with algorithm " + algorithm, e);
                }
        }
 
@@ -62,8 +62,10 @@ public class DigestUtils {
                        byte[] checksum = digest.digest();
                        String res = encodeHexString(checksum);
                        return res;
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot digest with algorithm " + algorithm, e);
+               } catch (NoSuchAlgorithmException e) {
+                       throw new IllegalArgumentException("Cannot digest with algorithm " + algorithm, e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
                } finally {
                        StreamUtils.closeQuietly(in);
                }
@@ -81,7 +83,7 @@ public class DigestUtils {
                        ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, sz);
                        return digest(algorithm, bb);
                } catch (IOException e) {
-                       throw new UtilsException("Cannot digest " + file + " with algorithm " + algorithm, e);
+                       throw new IllegalArgumentException("Cannot digest " + file + " with algorithm " + algorithm, e);
                } finally {
                        StreamUtils.closeQuietly(fis);
                        if (fc.isOpen())
@@ -105,7 +107,7 @@ public class DigestUtils {
                                System.out.println((end - begin) + " ms / " + ((end - begin) / 1000) + " s");
                        return res;
                } catch (NoSuchAlgorithmException e) {
-                       throw new UtilsException("Cannot digest with algorithm " + algorithm, e);
+                       throw new IllegalArgumentException("Cannot digest with algorithm " + algorithm, e);
                }
        }
 
@@ -146,8 +148,10 @@ public class DigestUtils {
                        if (debug)
                                System.out.println((end - begin) + " ms / " + ((end - begin) / 1000) + " s");
                        return md.digest();
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot digest " + file + "  with algorithm " + algorithm, e);
+               } catch (NoSuchAlgorithmException e) {
+                       throw new IllegalArgumentException("Cannot digest " + file + "  with algorithm " + algorithm, e);
+               } catch (IOException e) {
+                       throw new RuntimeException("Cannot digest " + file + "  with algorithm " + algorithm, e);
                }
        }
 
index 4035b96bc15b6c4409f10819f72e2c8450cdc5df..b6d962f068fa6c4ca711498b44c4922b65732369 100644 (file)
@@ -1,5 +1,6 @@
 package org.argeo.util;
 
+import java.io.IOException;
 import java.io.PrintStream;
 import java.nio.charset.Charset;
 import java.nio.file.DirectoryStream;
@@ -12,7 +13,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-/** Hashes the hashes of the files in a directory.*/
+/** Hashes the hashes of the files in a directory. */
 public class DirH {
 
        private final static Charset charset = Charset.forName("UTF-16");
@@ -30,12 +31,11 @@ public class DirH {
        private final byte[] dirName;
 
        /**
-        * @param dirName
-        *            can be null or empty
+        * @param dirName can be null or empty
         */
        private DirH(byte[][] hashes, byte[][] fileNames, byte[] dirName) {
                if (hashes.length != fileNames.length)
-                       throw new UtilsException(hashes.length + " hashes and " + fileNames.length + " file names");
+                       throw new IllegalArgumentException(hashes.length + " hashes and " + fileNames.length + " file names");
                this.hashes = hashes;
                this.fileNames = fileNames;
                this.dirName = dirName == null ? new byte[0] : dirName;
@@ -49,7 +49,7 @@ public class DirH {
                hashSize = hashes[0].length;
                for (int i = 0; i < hashes.length; i++) {
                        if (hashes[i].length != hashSize)
-                               throw new UtilsException(
+                               throw new IllegalArgumentException(
                                                "Hash size for " + new String(fileNames[i], charset) + " is " + hashes[i].length);
                }
 
@@ -63,7 +63,7 @@ public class DirH {
                        }
                        digest = md.digest();
                } catch (NoSuchAlgorithmException e) {
-                       throw new UtilsException("Cannot digest", e);
+                       throw new IllegalArgumentException("Cannot digest", e);
                }
        }
 
@@ -100,8 +100,8 @@ public class DirH {
                        }
                        byte[][] hashes = hs.toArray(new byte[hs.size()][]);
                        return new DirH(hashes, fileNames, dir.toString().getBytes(charset));
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot digest " + dir, e);
+               } catch (IOException e) {
+                       throw new RuntimeException("Cannot digest " + dir, e);
                }
        }
 
index 1a7a8815e262dd94e5d53becd48370665a36662a..7824d12de41945c37a6ea9eeb1962db4f390428d 100644 (file)
@@ -20,6 +20,7 @@ import java.util.Properties;
 import javax.naming.InvalidNameException;
 import javax.naming.ldap.LdapName;
 
+/** Utilities around Java basic features. */
 public class LangUtils {
        /*
         * NON-API OSGi
index a026bed22a36e5356a8033b85e1732e21174e092..c95c7879ef3f1225b438f11e5c8f8c718c58c908 100644 (file)
@@ -5,6 +5,8 @@ import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.security.GeneralSecurityException;
 import java.security.InvalidKeyException;
 import java.security.Key;
@@ -26,7 +28,8 @@ public class PasswordEncryption {
        public final static String DEFAULT_SECRETE_KEY_FACTORY = "PBKDF2WithHmacSHA1";
        public final static String DEFAULT_SECRETE_KEY_ENCRYPTION = "AES";
        public final static String DEFAULT_CIPHER_NAME = "AES/CBC/PKCS5Padding";
-       public final static String DEFAULT_CHARSET = "UTF-8";
+//     public final static String DEFAULT_CHARSET = "UTF-8";
+       public final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8;
 
        private Integer iterationCount = DEFAULT_ITERATION_COUNT;
        private Integer secreteKeyLength = DEFAULT_SECRETE_KEY_LENGTH;
@@ -68,11 +71,11 @@ public class PasswordEncryption {
                                        + " secrete key length instead of " + previousSecreteKeyLength);
                        try {
                                initKeyAndCiphers(password, passwordSalt, initializationVector);
-                       } catch (Exception e1) {
-                               throw new UtilsException("Cannot get secret key (with restricted length)", e1);
+                       } catch (GeneralSecurityException e1) {
+                               throw new IllegalStateException("Cannot get secret key (with restricted length)", e1);
                        }
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot get secret key", e);
+               } catch (GeneralSecurityException e) {
+                       throw new IllegalStateException("Cannot get secret key", e);
                }
        }
 
@@ -110,8 +113,6 @@ public class PasswordEncryption {
                        StreamUtils.closeQuietly(out);
                } catch (IOException e) {
                        throw e;
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot encrypt", e);
                } finally {
                        StreamUtils.closeQuietly(decryptedIn);
                }
@@ -123,8 +124,6 @@ public class PasswordEncryption {
                        StreamUtils.copy(decryptedIn, decryptedOut);
                } catch (IOException e) {
                        throw e;
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot decrypt", e);
                } finally {
                        StreamUtils.closeQuietly(encryptedIn);
                }
@@ -138,8 +137,8 @@ public class PasswordEncryption {
                        in = new ByteArrayInputStream(str.getBytes(DEFAULT_CHARSET));
                        encrypt(in, out);
                        return out.toByteArray();
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot encrypt", e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
                } finally {
                        StreamUtils.closeQuietly(out);
                }
@@ -152,8 +151,8 @@ public class PasswordEncryption {
                        out = new ByteArrayOutputStream();
                        decrypt(in, out);
                        return new String(out.toByteArray(), DEFAULT_CHARSET);
-               } catch (Exception e) {
-                       throw new UtilsException("Cannot decrypt", e);
+               } catch (IOException e) {
+                       throw new RuntimeException(e);
                } finally {
                        StreamUtils.closeQuietly(out);
                }
index 7e66c0a3935bc564b85a33df7978629e4ae6a32a..6d7d940ceaf74ea3b9dd60682688cb918ef6c9ff 100644 (file)
@@ -6,7 +6,7 @@ import java.io.OutputStream;
 import java.io.Reader;
 import java.io.Writer;
 
-/** Utilities to be used when APache COmmons IO is not available. */
+/** Utilities to be used when Apache Commons IO is not available. */
 class StreamUtils {
        private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;
 
index b8741a3eff28c864c250920f9f306d7ba1bbb7d4..266ddbc5885c0f0f75cdcdd9774a59acb96244e4 100644 (file)
@@ -4,9 +4,9 @@ import java.text.NumberFormat;
 import java.text.ParseException;
 import java.util.Locale;
 
+/** A throughput, that is, a value per unit of time. */
 public class Throughput {
-       private final static NumberFormat usNumberFormat = NumberFormat
-                       .getInstance(Locale.US);
+       private final static NumberFormat usNumberFormat = NumberFormat.getInstance(Locale.US);
 
        public enum Unit {
                s, m, h, d
@@ -30,7 +30,7 @@ public class Throughput {
                else if (unit.equals(Unit.d))
                        value = ((double) count * 24d * 60d * 60d * 1000d) / periodMs;
                else
-                       throw new UtilsException("Unsupported unit " + unit);
+                       throw new IllegalArgumentException("Unsupported unit " + unit);
                this.unit = unit;
        }
 
@@ -41,15 +41,14 @@ public class Throughput {
        public Throughput(String def) {
                int index = def.indexOf('/');
                if (def.length() < 3 || index <= 0 || index != def.length() - 2)
-                       throw new UtilsException(def + " no a proper throughput definition"
-                                       + " (should be <value>/<unit>, e.g. 3.54/s or 1500/h");
+                       throw new IllegalArgumentException(
+                                       def + " no a proper throughput definition" + " (should be <value>/<unit>, e.g. 3.54/s or 1500/h");
                String valueStr = def.substring(0, index);
                String unitStr = def.substring(index + 1);
                try {
                        this.value = usNumberFormat.parse(valueStr).doubleValue();
                } catch (ParseException e) {
-                       throw new UtilsException("Cannot parse " + valueStr
-                                       + " as a number.", e);
+                       throw new IllegalArgumentException("Cannot parse " + valueStr + " as a number.", e);
                }
                this.unit = Unit.valueOf(unitStr);
        }
@@ -64,7 +63,7 @@ public class Throughput {
                else if (unit.equals(Unit.d))
                        return Math.round((24d * 60d * 60d * 1000d) / value);
                else
-                       throw new UtilsException("Unsupported unit " + unit);
+                       throw new IllegalArgumentException("Unsupported unit " + unit);
        }
 
        @Override
diff --git a/org.argeo.util/src/org/argeo/util/UtilsException.java b/org.argeo.util/src/org/argeo/util/UtilsException.java
deleted file mode 100644 (file)
index 28b03d9..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.argeo.util;
-
-/** Utils specific exception. */
-class UtilsException extends RuntimeException {
-       private static final long serialVersionUID = 1L;
-
-       /** Creates an exception with a message. */
-       public UtilsException(String message) {
-               super(message);
-       }
-
-       /** Creates an exception with a message and a root cause. */
-       public UtilsException(String message, Throwable e) {
-               super(message, e);
-       }
-
-}