From d59d2aaef414cfbe4e063af406fef6b9ad5cb6dc Mon Sep 17 00:00:00 2001 From: Vicky Thakor Date: Fri, 26 Mar 2021 03:22:18 +0000 Subject: [PATCH] fix: JSONObject, Console added --- README.md | 8 +- build.gradle | 4 +- .../java/com/javaquery/util/io/Console.java | 45 ++ .../com/javaquery/util/json/JSONObject.java | 409 ++++++++++++++++++ .../com/javaquery/util/string/Strings.java | 5 +- .../com/javaquery/util/time/DatePattern.java | 3 +- .../javaquery/util/time/DateTimeFormat.java | 15 + .../java/com/javaquery/util/time/Dates.java | 54 +-- .../com/javaquery/util/io/TestConsole.java | 20 + .../com/javaquery/util/json/TestJSONEnum.java | 9 + .../javaquery/util/json/TestJSONObject.java | 115 +++++ .../com/javaquery/util/time/TestDates.java | 308 +++++++------ 12 files changed, 818 insertions(+), 177 deletions(-) create mode 100644 src/main/java/com/javaquery/util/io/Console.java create mode 100644 src/main/java/com/javaquery/util/json/JSONObject.java create mode 100644 src/main/java/com/javaquery/util/time/DateTimeFormat.java create mode 100644 src/test/java/com/javaquery/util/io/TestConsole.java create mode 100644 src/test/java/com/javaquery/util/json/TestJSONEnum.java create mode 100644 src/test/java/com/javaquery/util/json/TestJSONObject.java diff --git a/README.md b/README.md index ad4c632..af09c73 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ Goal is to remove repeated boler plate utility code from your project. This libr - Collections: Provides wide range of operation you perform on collection (List, Set and Map) interfaces like nullOrEmpty(Collection), nonNullNonEmpty(Collection), batches(List source, int batchSize), etc... - Files: Provides wide range of operation you perform on java.io.File like createNewFile(T file), writeToFile(T file, String data), appendToFile(T file, String data, boolean appendNewLine), etc... +- Console: Provides replacement of System.out.println() using .log() and System.err.println() using error(). +- JFile: Extends java.io.File and provide some extra function on file like getExtension, read, write. +- JSONObject: Uses org.json.JSONObject and provides facility optValue at any path in JSONObject, like items.item[0].batters.batter[2].available - Strings: Provides wide range of operation you perform on java.lang.String like nullOrEmpty(String str), joinStrings(String separator, String... strings), removeNotSupportedASCIICharacters(String str), etc... - DatePattern: Provides wide range of Date patterns commonly used worldwide like yyyyMMddHHmmss, yyyy-MM-dd HH:mm:ss'Z', yyyy-MM-dd'T'HH:mm:ss.SSSSSSS-HH:MM, etc... - DateRange: Class can be used to store start-date and end-date. @@ -15,17 +18,18 @@ Goal is to remove repeated boler plate utility code from your project. This libr - Assert: Provides wide range of operation for Assertions like nonNull(Object object, Supplier exceptionSupplier), isTrue(boolean expression, Supplier exceptionSupplier), nonNullNonEmpty(Collection collection, Supplier exceptionSupplier), etc... - Objects: Provides wide range of operation on java.lang.Object like isNull(Object obj), nonNull(Object obj). - Regex: Provides wide range of operation using regular expression like isNumber(String value), isAlphaNumeric(String value), isValidEmail(String value). +- UniqueIdGenerator: Generate unique time based random alphanumeric string like Firebase keys. # Maven ``` com.javaquery util - 1.0.1 + 1.0.4 ``` # Gradle ``` -implementation 'com.javaquery:util:1.0.1' +implementation 'com.javaquery:util:1.0.4' ``` diff --git a/build.gradle b/build.gradle index 0dc2c67..b9f64a2 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'com.javaquery' -version '1.0.3' +version '1.0.4' repositories { mavenCentral() @@ -13,6 +13,8 @@ repositories { dependencies { implementation('org.slf4j:slf4j-api:+') + implementation('org.json:json:+') + testImplementation('org.junit.jupiter:junit-jupiter:5.7.0') } diff --git a/src/main/java/com/javaquery/util/io/Console.java b/src/main/java/com/javaquery/util/io/Console.java new file mode 100644 index 0000000..f337df5 --- /dev/null +++ b/src/main/java/com/javaquery/util/io/Console.java @@ -0,0 +1,45 @@ +package com.javaquery.util.io; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + * @author vicky.thakor + * @since 1.4 + */ +public final class Console { + + private static final Logger LOGGER = LoggerFactory.getLogger(Console.class); + + /** + * Print object to output stream. Internally it uses System.out.println(obj); + * @param object object to print on console + */ + public static void log(Object object){ + System.out.println(object); + } + + /** + * Print object to output stream. Internally it uses System.err.println(obj); + * @param object object to print on console + */ + public static void error(Object object){ + System.err.println(object); + } + + /** + * Read String from console. + * @return String input provided in console + */ + public static String read(){ + try(BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))){ + return reader.readLine(); + }catch (Exception e){ + LOGGER.error(e.getMessage(), e); + } + return null; + } +} diff --git a/src/main/java/com/javaquery/util/json/JSONObject.java b/src/main/java/com/javaquery/util/json/JSONObject.java new file mode 100644 index 0000000..fafedcb --- /dev/null +++ b/src/main/java/com/javaquery/util/json/JSONObject.java @@ -0,0 +1,409 @@ +package com.javaquery.util.json; + +import com.javaquery.util.Objects; +import com.javaquery.util.string.Strings; +import org.json.JSONArray; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.HashMap; +import java.util.Map; + +/** + * @author vicky.thakor + * @since 1.0.4 + */ +public final class JSONObject { + + private org.json.JSONObject ROOT; + private Map CACHED_OBJECT; + + /** + * @param json json string to prepare {@link JSONObject} + */ + public JSONObject(String json) { + this(new org.json.JSONObject(json)); + } + + /** + * @param jsonObject {@link org.json.JSONObject} to prepare {@link JSONObject} + */ + public JSONObject(org.json.JSONObject jsonObject){ + ROOT = jsonObject; + CACHED_OBJECT = new HashMap<>(); + } + + /** + * Get an optional boolean associated with a key. It returns false if there + * is no such key, or if the value is not Boolean.TRUE or the String "true". + * + * @param key A key string. + * @return The truth. + */ + public boolean optBoolean(String key) { + return optBoolean(key, false); + } + + /** + * Get an optional boolean associated with a key. It returns the + * defaultValue if there is no such key, or if it is not a Boolean or the + * String "true" or "false" (case insensitive). + * + * @param key A key string. + * @param defaultValue The default. + * @return The truth. + */ + public boolean optBoolean(String key, boolean defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optBoolean(keyPath.key, defaultValue); + } + + /** + * Get an optional BigDecimal associated with a key, or the defaultValue if + * there is no such key or if its value is not a number. If the value is a + * string, an attempt will be made to evaluate it as a number. If the value + * is float or double, then the {@link BigDecimal#BigDecimal(double)} + * constructor will be used. See notes on the constructor for conversion + * issues that may arise. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public BigDecimal optBigDecimal(String key, BigDecimal defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optBigDecimal(keyPath.key, defaultValue); + } + + /** + * Get an optional BigInteger associated with a key, or the defaultValue if + * there is no such key or if its value is not a number. If the value is a + * string, an attempt will be made to evaluate it as a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public BigInteger optBigInteger(String key, BigInteger defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optBigInteger(keyPath.key, defaultValue); + } + + /** + * Get an optional double associated with a key, or NaN if there is no such + * key or if its value is not a number. If the value is a string, an attempt + * will be made to evaluate it as a number. + * + * @param key A string which is the key. + * @return An object which is the value. + */ + public double optDouble(String key) { + return optDouble(key, Double.NaN); + } + + /** + * Get an optional double associated with a key, or the defaultValue if + * there is no such key or if its value is not a number. If the value is a + * string, an attempt will be made to evaluate it as a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public double optDouble(String key, double defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optDouble(keyPath.key, defaultValue); + } + + /** + * Get the enum value associated with a key. + * + * @param Enum Type + * @param clazz The type of enum to retrieve. + * @param key A key string. + * @return The enum value associated with the key or null if not found + */ + public > E optEnum(Class clazz, String key) { + return this.optEnum(clazz, key, null); + } + + /** + * Get the enum value associated with a key. + * + * @param Enum Type + * @param clazz The type of enum to retrieve. + * @param key A key string. + * @param defaultValue The default in case the value is not found + * @return The enum value associated with the key or defaultValue + * if the value is not found or cannot be assigned to clazz + */ + public > E optEnum(Class clazz, String key, E defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optEnum(clazz, keyPath.key, defaultValue); + } + + /** + * Get the optional double value associated with an index. NaN is returned + * if there is no value for the index, or if the value is not a number and + * cannot be converted to a number. + * + * @param key A key string. + * @return The value. + */ + public float optFloat(String key) { + return optFloat(key, Float.NaN); + } + + /** + * Get the optional double value associated with an index. The defaultValue + * is returned if there is no value for the index, or if the value is not a + * number and cannot be converted to a number. + * + * @param key A key string. + * @param defaultValue The default value. + * @return The value. + */ + public float optFloat(String key, float defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optFloat(keyPath.key, defaultValue); + } + + /** + * Get an optional int value associated with a key, or zero if there is no + * such key or if the value is not a number. If the value is a string, an + * attempt will be made to evaluate it as a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public int optInt(String key) { + return optInt(key, 0); + } + + /** + * Get an optional int value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public int optInt(String key, int defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optInt(keyPath.key, defaultValue); + } + + /** + * Get an optional long value associated with a key, or zero if there is no + * such key or if the value is not a number. If the value is a string, an + * attempt will be made to evaluate it as a number. + * + * @param key A key string. + * @return An object which is the value. + */ + public long optLong(String key) { + return optLong(key, 0); + } + + /** + * Get an optional long value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public long optLong(String key, long defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optLong(keyPath.key, defaultValue); + } + + /** + * Get an optional {@link Number} value associated with a key, or null + * if there is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number ({@link BigDecimal}). This method + * would be used in cases where type coercion of the number value is unwanted. + * + * @param key A key string. + * @return An object which is the value. + */ + public Number optNumber(String key) { + return optNumber(key, null); + } + + /** + * Get an optional {@link Number} value associated with a key, or the default if there + * is no such key or if the value is not a number. If the value is a string, + * an attempt will be made to evaluate it as a number. This method + * would be used in cases where type coercion of the number value is unwanted. + * + * @param key A key string. + * @param defaultValue The default. + * @return An object which is the value. + */ + public Number optNumber(String key, Number defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optNumber(keyPath.key, defaultValue); + } + + /** + * Get an optional string associated with a key. It returns an empty string + * if there is no such key. If the value is not a string and is not null, + * then it is converted to a string. + * + * @param key A key string. + * @return A string which is the value. + */ + public String optString(String key) { + return optString(key, ""); + } + + /** + * Get an optional string associated with a key. It returns the defaultValue + * if there is no such key. + * + * @param key A key string. + * @param defaultValue The default. + * @return A string which is the value. + */ + public String optString(String key, String defaultValue) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optString(keyPath.key, defaultValue); + } + + /** + * Get an optional JSONObject associated with a key. It returns null if + * there is no such key, or if its value is not a JSONObject. + * + * @param key A key string. + * @return A JSONObject which is the value. + */ + public org.json.JSONObject optJSONObject(String key) { + KeyPath keyPath = new KeyPath(key); + org.json.JSONObject jsonObject = findByKey(keyPath); + org.json.JSONObject result = jsonObject.optJSONObject(keyPath.key); + if (Objects.isNull(result) && keyPath.key.contains("[") && keyPath.key.endsWith("]")) { + result = arrayJSONObject(jsonObject, keyPath.key); + } + return result; + } + + /** + * Get an optional JSONArray associated with a key. It returns null if there + * is no such key, or if its value is not a JSONArray. + * + * @param key A key string. + * @return A JSONArray which is the value. + */ + public JSONArray optJSONArray(String key) { + KeyPath keyPath = new KeyPath(key); + return findByKey(keyPath).optJSONArray(keyPath.key); + } + + /** + * Find {@link org.json.JSONObject} at provided path + * @param keyPath object containg key and path of object + * @return A {@link org.json.JSONObject} which hold the value + */ + private org.json.JSONObject findByKey(KeyPath keyPath) { + if (Strings.nonNullNonEmpty(keyPath.path)) { + if (CACHED_OBJECT.containsKey(keyPath.path)) { + return CACHED_OBJECT.get(keyPath.path); + } else { + org.json.JSONObject result = (org.json.JSONObject) recursion(ROOT, keyPath.path); + CACHED_OBJECT.put(keyPath.path, result); + return result; + } + } else { + return ROOT; + } + } + + /** + * Do a recursive call to fine Object at provided path + * + * @param jsonObject input {@link org.json.JSONObject} + * @param path a path to find object + * @return Object at provided path + */ + private Object recursion(org.json.JSONObject jsonObject, String path) { + if (path.contains(".")) { + int dotIndex = path.indexOf("."); + String subKey = path.substring(0, dotIndex); + String remainingKey = path.substring(dotIndex + 1); + + if (subKey.contains("[") && subKey.endsWith("]")) { + org.json.JSONObject jsonArrayValueObject = arrayJSONObject(jsonObject, subKey); + if (Objects.nonNull(jsonArrayValueObject)) { + return recursion(jsonArrayValueObject, remainingKey); + } + } + + Object object = jsonObject.opt(subKey); + if (object instanceof org.json.JSONObject) { + return recursion(jsonObject.optJSONObject(subKey), remainingKey); + } + } else { + if (path.contains("[") && path.endsWith("]")) { + return arrayJSONObject(jsonObject, path); + } + + return jsonObject.optJSONObject(path); + } + return jsonObject; + } + + /** + * Get {@link org.json.JSONObject} from {@link JSONArray} from provided index + * @param jsonObject input {@link org.json.JSONObject}. + * @param keyWithIndex String value of index i.e "[1]" + * @return org.json.JSONObject from {@link JSONArray} + */ + private org.json.JSONObject arrayJSONObject(org.json.JSONObject jsonObject, String keyWithIndex) { + if (keyWithIndex.contains("[") && keyWithIndex.endsWith("]")) { + int startBracket = keyWithIndex.indexOf("["); + int endBracket = keyWithIndex.indexOf("]"); + String arrayName = keyWithIndex.substring(0, startBracket); + int arrayIndex = Integer.parseInt(keyWithIndex.substring(startBracket + 1, endBracket)); + + JSONArray jsonArray = jsonObject.optJSONArray(arrayName); + if(Objects.nonNull(jsonArray)){ + return jsonArray.optJSONObject(arrayIndex); + } + } + return null; + } + + /** + * Nullify object for garbage collection + */ + public void flush() { + ROOT = null; + CACHED_OBJECT = null; + } + + /** + * To hold key and path to find object. + */ + private static class KeyPath { + private final String key; + private String path; + + public KeyPath(String key) { + int dotIndex = key.lastIndexOf("."); + if (dotIndex > 0) { + this.key = key.substring(dotIndex + 1); + this.path = key.substring(0, dotIndex); + } else { + this.key = key; + } + } + } + + @Override + public String toString() { + return ROOT.toString(); + } +} diff --git a/src/main/java/com/javaquery/util/string/Strings.java b/src/main/java/com/javaquery/util/string/Strings.java index be6335c..5c1a00e 100644 --- a/src/main/java/com/javaquery/util/string/Strings.java +++ b/src/main/java/com/javaquery/util/string/Strings.java @@ -12,8 +12,9 @@ */ public final class Strings { - private final static String UNSUPPORTED_ASCII_PATTERN = "[^\\x20-\\x7e]"; - private final static String UNSUPPORTED_UNICODE_PATTERN = "[\\uD83C-\\uDBFF\\uDC00-\\uDFFF]+"; + public static final String EMPTY_STRING = ""; + private static final String UNSUPPORTED_ASCII_PATTERN = "[^\\x20-\\x7e]"; + private static final String UNSUPPORTED_UNICODE_PATTERN = "[\\uD83C-\\uDBFF\\uDC00-\\uDFFF]+"; private Strings() { } diff --git a/src/main/java/com/javaquery/util/time/DatePattern.java b/src/main/java/com/javaquery/util/time/DatePattern.java index c179b13..037a919 100644 --- a/src/main/java/com/javaquery/util/time/DatePattern.java +++ b/src/main/java/com/javaquery/util/time/DatePattern.java @@ -4,7 +4,7 @@ * @author vicky.thakor * @since 1.0 */ -public enum DatePattern { +public enum DatePattern implements DateTimeFormat{ Y_M_D("yyyyMMdd"), Y_M_D_HMS("yyyyMMddHHmmss"), @@ -41,6 +41,7 @@ public enum DatePattern { this.value = value; } + @Override public String getValue() { return value; } diff --git a/src/main/java/com/javaquery/util/time/DateTimeFormat.java b/src/main/java/com/javaquery/util/time/DateTimeFormat.java new file mode 100644 index 0000000..8777539 --- /dev/null +++ b/src/main/java/com/javaquery/util/time/DateTimeFormat.java @@ -0,0 +1,15 @@ +package com.javaquery.util.time; + +/** + * @author vicky.thakor + * @since 1.0.4 + * @see DatePattern + */ +public interface DateTimeFormat { + + /** + * @see DatePattern + * @return date time pattern to parse or format + */ + String getValue(); +} diff --git a/src/main/java/com/javaquery/util/time/Dates.java b/src/main/java/com/javaquery/util/time/Dates.java index 566c1ac..59b7f14 100644 --- a/src/main/java/com/javaquery/util/time/Dates.java +++ b/src/main/java/com/javaquery/util/time/Dates.java @@ -94,14 +94,14 @@ public static Date reduce(Date date, int type, int amount) { } /** - * Returns {@code SimpleDateFormat} with given {@code DatePattern} and {@code Timezone} + * Returns {@code SimpleDateFormat} with given {@code DateTimeFormat} and {@code Timezone} * - * @param datePattern a {@code DatePattern} to set for {@code SimpleDateFormat} + * @param dateTimeFormat a {@code DateTimeFormat} to set for {@code SimpleDateFormat} * @param timeZone a {@code Timezone} to set for {@code SimpleDateFormat} - * @return Returns {@code SimpleDateFormat} with given {@code DatePattern} and {@code Timezone} + * @return Returns {@code SimpleDateFormat} with given {@code DateTimeFormat} and {@code Timezone} */ - private static SimpleDateFormat getSimpleDateFormat(DatePattern datePattern, TimeZone timeZone) { - SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern.getValue()); + private static SimpleDateFormat getSimpleDateFormat(DateTimeFormat dateTimeFormat, TimeZone timeZone) { + SimpleDateFormat simpleDateFormat = new SimpleDateFormat(dateTimeFormat.getValue()); simpleDateFormat.setTimeZone(timeZone); return simpleDateFormat; } @@ -111,13 +111,13 @@ private static SimpleDateFormat getSimpleDateFormat(DatePattern datePattern, Tim * it returns {@code null}. * * @param date a String date to parse - * @param datePattern pattern to parse the date + * @param dateTimeFormat pattern to parse the date * @param timeZone timezone to parse the date * @return Returns Date object of given String date using provided timezone, in case of ParseException * it returns {@code null}. */ - public static Date parse(String date, DatePattern datePattern, TimeZone timeZone) { - SimpleDateFormat simpleDateFormat = getSimpleDateFormat(datePattern, timeZone); + public static Date parse(String date, DateTimeFormat dateTimeFormat, TimeZone timeZone) { + SimpleDateFormat simpleDateFormat = getSimpleDateFormat(dateTimeFormat, timeZone); try { return simpleDateFormat.parse(date); } catch (ParseException e) {/* Silent exception */} @@ -129,55 +129,55 @@ public static Date parse(String date, DatePattern datePattern, TimeZone timeZone * it returns {@code null}. * * @param date a String date to parse - * @param datePattern pattern to parse the date + * @param dateTimeFormat pattern to parse the date * @return Returns Date object of given String date using system timezone, in case of ParseException * it returns {@code null}. */ - public static Date parse(String date, DatePattern datePattern) { - return parse(date, datePattern, SYSTEM_TIMEZONE); + public static Date parse(String date, DateTimeFormat dateTimeFormat) { + return parse(date, dateTimeFormat, SYSTEM_TIMEZONE); } /** - * Returns {@code Date} object in String, formatted by given {@code DatePattern} and {@code TimeZone} + * Returns {@code Date} object in String, formatted by given {@code DateTimeFormat} and {@code TimeZone} * * @param date a {@code Date} object to format - * @param datePattern pattern to format {@code Date} + * @param dateTimeFormat pattern to format {@code Date} * @param timeZone {@code TimeZone} to use while formatting {@code Date} - * @return Returns {@code Date} object in String, formatted by given {@code DatePattern} and {@code TimeZone} + * @return Returns {@code Date} object in String, formatted by given {@code DateTimeFormat} and {@code TimeZone} */ - public static String format(Date date, DatePattern datePattern, TimeZone timeZone) { - SimpleDateFormat simpleDateFormat = getSimpleDateFormat(datePattern, timeZone); + public static String format(Date date, DateTimeFormat dateTimeFormat, TimeZone timeZone) { + SimpleDateFormat simpleDateFormat = getSimpleDateFormat(dateTimeFormat, timeZone); return simpleDateFormat.format(date); } /** - * Returns {@code Date} object in String, formatted by given {@code DatePattern} and using + * Returns {@code Date} object in String, formatted by given {@code DateTimeFormat} and using * system {@code TimeZone} * * @param date a {@code Date} object to format - * @param datePattern pattern to format {@code Date} - * @return Returns {@code Date} object in String, formatted by given {@code DatePattern} and using + * @param dateTimeFormat pattern to format {@code Date} + * @return Returns {@code Date} object in String, formatted by given {@code DateTimeFormat} and using * system {@code TimeZone} */ - public static String format(Date date, DatePattern datePattern) { - return format(date, datePattern, SYSTEM_TIMEZONE); + public static String format(Date date, DateTimeFormat dateTimeFormat) { + return format(date, dateTimeFormat, SYSTEM_TIMEZONE); } /** * Returns String {@code Date} by performing two operation on {@code Date} object, - * {@link Dates#addInDate(Date, int, int)} and {@link Dates#format(Date, DatePattern)} + * {@link Dates#addInDate(Date, int, int)} and {@link Dates#format(Date, DateTimeFormat)} * * @param date a {@code Date} object to format * @param type the calendar field. For example, {@code Calendar.DAY_OF_MONTH} * @param amount the amount of date or time to be added to the field. - * @param datePattern pattern to format {@code Date} + * @param dateTimeFormat pattern to format {@code Date} * @return Returns String {@code Date} by performing two operation on {@code Date} object, - * {@link Dates#addInDate(Date, int, int)} and {@link Dates#format(Date, DatePattern)} + * {@link Dates#addInDate(Date, int, int)} and {@link Dates#format(Date, DateTimeFormat)} * @see Dates#addInDate(Date, int, int) - * @see Dates#format(Date, DatePattern) + * @see Dates#format(Date, DateTimeFormat) */ - public static String addInDateAndFormat(Date date, int type, int amount, DatePattern datePattern) { - return format(addInDate(date, type, amount), datePattern); + public static String addInDateAndFormat(Date date, int type, int amount, DateTimeFormat dateTimeFormat) { + return format(addInDate(date, type, amount), dateTimeFormat); } /** diff --git a/src/test/java/com/javaquery/util/io/TestConsole.java b/src/test/java/com/javaquery/util/io/TestConsole.java new file mode 100644 index 0000000..c171633 --- /dev/null +++ b/src/test/java/com/javaquery/util/io/TestConsole.java @@ -0,0 +1,20 @@ +package com.javaquery.util.io; + +import org.junit.jupiter.api.Test; + +/** + * @author vicky.thakor + * @since 1.0.4 + */ +public class TestConsole { + + @Test + public void test_log(){ + Console.log("Hello World!"); + } + + @Test + public void test_error(){ + Console.error("Hello World!"); + } +} diff --git a/src/test/java/com/javaquery/util/json/TestJSONEnum.java b/src/test/java/com/javaquery/util/json/TestJSONEnum.java new file mode 100644 index 0000000..df589ad --- /dev/null +++ b/src/test/java/com/javaquery/util/json/TestJSONEnum.java @@ -0,0 +1,9 @@ +package com.javaquery.util.json; + +/** + * @author vicky.thakor + * @since 1.0.4 + */ +public enum TestJSONEnum { + Regular, Chocolate +} diff --git a/src/test/java/com/javaquery/util/json/TestJSONObject.java b/src/test/java/com/javaquery/util/json/TestJSONObject.java new file mode 100644 index 0000000..59654f4 --- /dev/null +++ b/src/test/java/com/javaquery/util/json/TestJSONObject.java @@ -0,0 +1,115 @@ +package com.javaquery.util.json; + +import com.javaquery.util.io.Console; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; + +import java.math.BigDecimal; +import java.math.BigInteger; + +/** + * @author vicky.thakor + * @since 1.4 + */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +public class TestJSONObject { + private static final String STRING_JSON_OBJECT = "{\"author\":\"vicky\",\"items\":{\"item\":[{\"ppu\":0.55,\"batters\":{\"batter\":[{\"available\":true,\"id\":\"1001\",\"type\":\"Regular\"},{\"available\":false,\"id\":\"1002\",\"type\":\"Chocolate\"},{\"id\":\"1003\",\"type\":\"Blueberry\"},{\"id\":\"1004\",\"type\":\"Devil's Food\"}]},\"name\":\"Cake\",\"id\":\"0001\",\"type\":\"donut\",\"topping\":[{\"id\":\"5001\",\"type\":\"None\"},{\"id\":\"5002\",\"type\":\"Glazed\"},{\"id\":\"5005\",\"type\":\"Sugar\",\"kg\":652398},{\"id\":\"5007\",\"type\":\"Powdered Sugar\",\"kg\":875},{\"id\":\"5006\",\"type\":\"Chocolate with Sprinkles\"},{\"id\":\"5003\",\"type\":\"Chocolate\"},{\"id\":\"5004\",\"type\":\"Maple\"}]}]}}"; + private static final JSONObject JSONOBJECT = new JSONObject(STRING_JSON_OBJECT); + + @Test + public void test_optBoolean() { + Assertions.assertTrue(JSONOBJECT.optBoolean("items.item[0].batters.batter[0].available")); + Assertions.assertTrue(JSONOBJECT.optBoolean("items.item[0].batters.batter[2].available", true)); + } + + @Test + public void test_optBigDecimal() { + Assertions.assertEquals(new BigDecimal(652398), JSONOBJECT.optBigDecimal("items.item[0].topping[2].kg", new BigDecimal(0))); + Assertions.assertEquals(new BigDecimal(-1), JSONOBJECT.optBigDecimal("items.item[0].topping[2].gm", new BigDecimal(-1))); + } + + @Test + public void test_optBigInteger() { + Assertions.assertEquals(BigInteger.valueOf(652398L), JSONOBJECT.optBigInteger("items.item[0].topping[2].kg", BigInteger.valueOf(0L))); + Assertions.assertEquals(BigInteger.valueOf(-1), JSONOBJECT.optBigInteger("items.item[0].topping[2].gm", BigInteger.valueOf(-1L))); + } + + @Test + public void test_optDouble() { + Assertions.assertEquals(875d, JSONOBJECT.optDouble("items.item[0].topping[3].kg")); + Assertions.assertEquals(-1d, JSONOBJECT.optDouble("items.item[0].topping[2].gm", -1)); + } + + @Test + public void test_optEnum() { + Assertions.assertEquals(TestJSONEnum.Regular, JSONOBJECT.optEnum(TestJSONEnum.class, "items.item[0].batters.batter[0].type")); + Assertions.assertEquals(TestJSONEnum.Chocolate, JSONOBJECT.optEnum(TestJSONEnum.class, "items.item[0].batters.batter[2].type", TestJSONEnum.Chocolate)); + } + + @Test + public void test_optFloat() { + Assertions.assertEquals(875f, JSONOBJECT.optFloat("items.item[0].topping[3].kg")); + Assertions.assertEquals(-1f, JSONOBJECT.optFloat("items.item[0].topping[2].gm", -1)); + } + + @Test + public void test_optInt() { + Assertions.assertEquals(875, JSONOBJECT.optInt("items.item[0].topping[3].kg")); + Assertions.assertEquals(-1, JSONOBJECT.optInt("items.item[0].topping[2].gm", -1)); + } + + @Test + public void test_optLong() { + Assertions.assertEquals(875L, JSONOBJECT.optLong("items.item[0].topping[3].kg")); + Assertions.assertEquals(-1L, JSONOBJECT.optLong("items.item[0].topping[2].gm", -1)); + } + + @Test + public void test_optNumber() { + Assertions.assertEquals(875, JSONOBJECT.optNumber("items.item[0].topping[3].kg")); + Assertions.assertEquals(-1, JSONOBJECT.optNumber("items.item[0].topping[2].gm", -1)); + } + + @Test + public void test_optString() { + Assertions.assertEquals("donut", JSONOBJECT.optString("items.item[0].type")); + Assertions.assertEquals("test", JSONOBJECT.optString("items.item[0].topping[1].value", "test")); + Assertions.assertEquals("vicky", JSONOBJECT.optString("author")); + } + + @Test + public void test_optJSONObject() { + org.json.JSONObject jsonObject = JSONOBJECT.optJSONObject("items.item[0].batters.batter[0]"); + Assertions.assertEquals("Regular", jsonObject.optString("type")); + } + + @Test + public void test_optJSONObject_1() { + org.json.JSONObject jsonObject = JSONOBJECT.optJSONObject("items.dummy[0].batters.batter[0]"); + Assertions.assertNull(jsonObject); + } + + @Test + public void test_optJSONObject_2() { + org.json.JSONObject jsonObject = JSONOBJECT.optJSONObject("items.item.batters.batter[0]"); + Assertions.assertNull(jsonObject); + } + + @Test + public void test_optJSONArray() { + org.json.JSONArray jsonArray = JSONOBJECT.optJSONArray("items.item[0].batters.batter"); + Assertions.assertEquals(4, jsonArray.length()); + } + + @Test + public void test_toString(){ + Assertions.assertEquals(STRING_JSON_OBJECT, JSONOBJECT.toString()); + } + + @AfterAll + public void test_flush(){ + JSONOBJECT.flush(); + } +} diff --git a/src/test/java/com/javaquery/util/time/TestDates.java b/src/test/java/com/javaquery/util/time/TestDates.java index 7056250..3cd87e0 100644 --- a/src/test/java/com/javaquery/util/time/TestDates.java +++ b/src/test/java/com/javaquery/util/time/TestDates.java @@ -13,148 +13,168 @@ */ public class TestDates { - private static final Calendar CALENDAR = Calendar.getInstance(); - - @Test public void test_currentTimeMillis() { - long expected = System.currentTimeMillis(); - long result = Dates.currentTimeMillis(); - long difference = result - expected; - Assertions.assertTrue(difference >= 0 && difference < 5); - } - - @Test public void test_addInDate() { - Date date = Dates.parse("2021-01-19", DatePattern.Y_M_D_1); - Date expected = Dates.parse("2021-01-20", DatePattern.Y_M_D_1); - - Date result = Dates.addInDate(date, Calendar.DATE, 1); - Assertions.assertEquals(expected, result); - } - - @Test public void test_addInDate_1() { - Date date = Dates.parse("2021-01-19", DatePattern.Y_M_D_1); - Date expected = Dates.parse("2020-12-19", DatePattern.Y_M_D_1); - - Date result = Dates.addInDate(date, Calendar.MONTH, -1); - Assertions.assertEquals(expected, result); - } - - @Test public void test_increment() { - Date date = Dates.parse("2021-01-20 10:10:00", DatePattern.Y_M_D__HMS); - Date expected = Dates.parse("2021-01-20 10:20:00", DatePattern.Y_M_D__HMS); - - Date result = Dates.increment(date, Calendar.MINUTE, 10); - Assertions.assertEquals(expected, result); - } - - @Test public void test_increment_1() { - Date date = Dates.parse("2021-01-20 10:10:00", DatePattern.Y_M_D__HMS); - Date expected = Dates.parse("2021-01-20 10:10:10", DatePattern.Y_M_D__HMS); - - Date result = Dates.increment(date, Calendar.SECOND, -10); - Assertions.assertEquals(expected, result); - } - - @Test public void test_reduce() { - Date date = Dates.parse("2021-01-20 10:00:00", DatePattern.Y_M_D__HMS); - Date expected = Dates.parse("2021-01-20 09:50:00", DatePattern.Y_M_D__HMS); - - Date result = Dates.reduce(date, Calendar.MINUTE, -10); - Assertions.assertEquals(expected, result); - } - - @Test public void test_reduce_1() { - Date date = Dates.parse("2021-01-20 10:00:10", DatePattern.Y_M_D__HMS); - Date expected = Dates.parse("2021-01-20 10:00:00", DatePattern.Y_M_D__HMS); - - Date result = Dates.reduce(date, Calendar.SECOND, 10); - Assertions.assertEquals(expected, result); - } - - @Test public void test_addInCurrentDate() { - Date date = Dates.addInCurrentDate(Calendar.YEAR, 1); - CALENDAR.setTime(date); - - int currentYear = Calendar.getInstance().get(Calendar.YEAR); - - Assertions.assertEquals(currentYear + 1, CALENDAR.get(Calendar.YEAR)); - } - - @Test public void test_addInCurrentDate_1() { - Date date = Dates.addInCurrentDate(Calendar.YEAR, -5); - CALENDAR.setTime(date); - - int currentYear = Calendar.getInstance().get(Calendar.YEAR); - - Assertions.assertEquals(currentYear - 5, CALENDAR.get(Calendar.YEAR)); - } - - @Test public void test_parse() { - Date date = Dates.parse("2021-01-20T10:10:00+05:30", DatePattern.Y_M_D_T_HMSX, TimeZone.getTimeZone("UTC")); - CALENDAR.setTime(date); //Output: Wed Jan 20 04:40:00 UTC 2021 - - Assertions.assertEquals(2021, CALENDAR.get(Calendar.YEAR)); - Assertions.assertEquals(1, CALENDAR.get(Calendar.MONTH) + 1); - Assertions.assertEquals(20, CALENDAR.get(Calendar.DATE)); - Assertions.assertEquals(4, CALENDAR.get(Calendar.HOUR)); - Assertions.assertEquals(40, CALENDAR.get(Calendar.MINUTE)); - Assertions.assertEquals(0, CALENDAR.get(Calendar.SECOND)); - } - - @Test public void test_parse_1() { - Date date = Dates.parse("2021-01-19", DatePattern.Y_M_D_1); - CALENDAR.setTime(date); - - Assertions.assertEquals(2021, CALENDAR.get(Calendar.YEAR)); - Assertions.assertEquals(1, CALENDAR.get(Calendar.MONTH) + 1); - Assertions.assertEquals(19, CALENDAR.get(Calendar.DATE)); - } - - @Test public void test_parse_2() { - Date date = Dates.parse("2021-19", DatePattern.Y_M_D_1); - Assertions.assertNull(date); - } - - @Test public void test_format() { - Date date = Dates.parse("2021-01-20T04:40:00+00:00", DatePattern.Y_M_D_T_HMSX, TimeZone.getTimeZone("UTC")); - String result = Dates.format(date, DatePattern.Y_M_D_T_HMSX, TimeZone.getTimeZone("IST")); - Assertions.assertEquals("2021-01-20T10:10:00+05:30", result); - } - - @Test public void test_format_1() { - Date date = Dates.parse("2021-01-20T10:10:00", DatePattern.Y_M_D_T_HMS); - String result = Dates.format(date, DatePattern.Y_M_D_HMS); - Assertions.assertEquals("20210120101000", result); - } - - @Test public void test_addInDateAndFormat() { - Date date = Dates.parse("2021-01-20T10:10:00", DatePattern.Y_M_D_T_HMS); - String result = Dates.addInDateAndFormat(date, Calendar.MONTH, -1, DatePattern.Y_M_D_HMS); - Assertions.assertEquals("20201220101000", result); - } - - @Test public void test_dateToEpochSeconds() { - Date date = Dates.parse("2021-01-20T10:10:00", DatePattern.Y_M_D_T_HMS); - long result = Dates.epochSeconds(date); - Assertions.assertEquals(1611137400, result); - } - - @Test public void test_getDate() { - Date result = Dates.getDate(2020, 1, 20, 10, 10, 10); - Assertions.assertEquals("Mon Jan 20 10:10:10 UTC 2020", result.toString()); - } - - @Test public void test_getDate_1() { - Date result = Dates.getDate(2020, 1, 20); - Assertions.assertEquals("Mon Jan 20 00:00:00 UTC 2020", result.toString()); - } - - @Test public void test_Month(){ - Assertions.assertEquals(1, Dates.Month.JANUARY.getValue()); - } - - @Test public void test_Month_currentMonth(){ - int expected = Calendar.getInstance().get(Calendar.MONTH) + 1; - - Assertions.assertEquals(expected, Dates.Month.currentMonth().getValue()); - } + private static final Calendar CALENDAR = Calendar.getInstance(); + + @Test + public void test_currentTimeMillis() { + long expected = System.currentTimeMillis(); + long result = Dates.currentTimeMillis(); + long difference = result - expected; + Assertions.assertTrue(difference >= 0 && difference < 5); + } + + @Test + public void test_addInDate() { + Date date = Dates.parse("2021-01-19", DatePattern.Y_M_D_1); + Date expected = Dates.parse("2021-01-20", DatePattern.Y_M_D_1); + + Date result = Dates.addInDate(date, Calendar.DATE, 1); + Assertions.assertEquals(expected, result); + } + + @Test + public void test_addInDate_1() { + Date date = Dates.parse("2021-01-19", DatePattern.Y_M_D_1); + Date expected = Dates.parse("2020-12-19", DatePattern.Y_M_D_1); + + Date result = Dates.addInDate(date, Calendar.MONTH, -1); + Assertions.assertEquals(expected, result); + } + + @Test + public void test_increment() { + Date date = Dates.parse("2021-01-20 10:10:00", DatePattern.Y_M_D__HMS); + Date expected = Dates.parse("2021-01-20 10:20:00", DatePattern.Y_M_D__HMS); + + Date result = Dates.increment(date, Calendar.MINUTE, 10); + Assertions.assertEquals(expected, result); + } + + @Test + public void test_increment_1() { + Date date = Dates.parse("2021-01-20 10:10:00", DatePattern.Y_M_D__HMS); + Date expected = Dates.parse("2021-01-20 10:10:10", DatePattern.Y_M_D__HMS); + + Date result = Dates.increment(date, Calendar.SECOND, -10); + Assertions.assertEquals(expected, result); + } + + @Test + public void test_reduce() { + Date date = Dates.parse("2021-01-20 10:00:00", DatePattern.Y_M_D__HMS); + Date expected = Dates.parse("2021-01-20 09:50:00", DatePattern.Y_M_D__HMS); + + Date result = Dates.reduce(date, Calendar.MINUTE, -10); + Assertions.assertEquals(expected, result); + } + + @Test + public void test_reduce_1() { + Date date = Dates.parse("2021-01-20 10:00:10", DatePattern.Y_M_D__HMS); + Date expected = Dates.parse("2021-01-20 10:00:00", DatePattern.Y_M_D__HMS); + + Date result = Dates.reduce(date, Calendar.SECOND, 10); + Assertions.assertEquals(expected, result); + } + + @Test + public void test_addInCurrentDate() { + Date date = Dates.addInCurrentDate(Calendar.YEAR, 1); + CALENDAR.setTime(date); + + int currentYear = Calendar.getInstance().get(Calendar.YEAR); + + Assertions.assertEquals(currentYear + 1, CALENDAR.get(Calendar.YEAR)); + } + + @Test + public void test_addInCurrentDate_1() { + Date date = Dates.addInCurrentDate(Calendar.YEAR, -5); + CALENDAR.setTime(date); + + int currentYear = Calendar.getInstance().get(Calendar.YEAR); + + Assertions.assertEquals(currentYear - 5, CALENDAR.get(Calendar.YEAR)); + } + + @Test + public void test_parse() { + Date date = Dates.parse("2021-01-20T10:10:00+05:30", DatePattern.Y_M_D_T_HMSX, TimeZone.getTimeZone("UTC")); + CALENDAR.setTime(date); //Output: Wed Jan 20 04:40:00 UTC 2021 + + Assertions.assertEquals(2021, CALENDAR.get(Calendar.YEAR)); + Assertions.assertEquals(1, CALENDAR.get(Calendar.MONTH) + 1); + Assertions.assertEquals(20, CALENDAR.get(Calendar.DATE)); + Assertions.assertEquals(4, CALENDAR.get(Calendar.HOUR)); + Assertions.assertEquals(40, CALENDAR.get(Calendar.MINUTE)); + Assertions.assertEquals(0, CALENDAR.get(Calendar.SECOND)); + } + + @Test + public void test_parse_1() { + Date date = Dates.parse("2021-01-19", DatePattern.Y_M_D_1); + CALENDAR.setTime(date); + + Assertions.assertEquals(2021, CALENDAR.get(Calendar.YEAR)); + Assertions.assertEquals(1, CALENDAR.get(Calendar.MONTH) + 1); + Assertions.assertEquals(19, CALENDAR.get(Calendar.DATE)); + } + + @Test + public void test_parse_2() { + Date date = Dates.parse("2021-19", DatePattern.Y_M_D_1); + Assertions.assertNull(date); + } + + @Test + public void test_format() { + Date date = Dates.parse("2021-01-20T04:40:00+00:00", DatePattern.Y_M_D_T_HMSX, TimeZone.getTimeZone("UTC")); + String result = Dates.format(date, DatePattern.Y_M_D_T_HMSX, TimeZone.getTimeZone("IST")); + Assertions.assertEquals("2021-01-20T10:10:00+05:30", result); + } + + @Test + public void test_format_1() { + Date date = Dates.parse("2021-01-20T10:10:00", DatePattern.Y_M_D_T_HMS); + String result = Dates.format(date, DatePattern.Y_M_D_HMS); + Assertions.assertEquals("20210120101000", result); + } + + @Test + public void test_addInDateAndFormat() { + Date date = Dates.parse("2021-01-20T10:10:00", DatePattern.Y_M_D_T_HMS); + String result = Dates.addInDateAndFormat(date, Calendar.MONTH, -1, DatePattern.Y_M_D_HMS); + Assertions.assertEquals("20201220101000", result); + } + + @Test + public void test_dateToEpochSeconds() { + Date date = Dates.parse("2021-01-20T10:10:00", DatePattern.Y_M_D_T_HMS); + long result = Dates.epochSeconds(date); + Assertions.assertEquals(1611137400, result); + } + + @Test + public void test_getDate() { + Date result = Dates.getDate(2020, 1, 20, 10, 10, 10); + Assertions.assertEquals("Mon Jan 20 10:10:10 UTC 2020", result.toString()); + } + + @Test + public void test_getDate_1() { + Date result = Dates.getDate(2020, 1, 20); + Assertions.assertEquals("Mon Jan 20 00:00:00 UTC 2020", result.toString()); + } + + @Test + public void test_Month() { + Assertions.assertEquals(1, Dates.Month.JANUARY.getValue()); + } + + @Test + public void test_Month_currentMonth() { + int expected = Calendar.getInstance().get(Calendar.MONTH) + 1; + + Assertions.assertEquals(expected, Dates.Month.currentMonth().getValue()); + } }