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());
+ }
}