Skip to content

Instantly share code, notes, and snippets.

@pagetronic
Created January 3, 2023 20:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pagetronic/ed9a532562bb7db4854c9291330984bb to your computer and use it in GitHub Desktop.
Save pagetronic/ed9a532562bb7db4854c9291330984bb to your computer and use it in GitHub Desktop.
/*
* Copyright 2019 Laurent PAGE, Apache Licence 2.0
*/
package com.agroneo.grow.system.utils;
import android.text.Html;
import android.text.Spanned;
import androidx.annotation.NonNull;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
/**
* A cool toolkit for Json manipulation
*/
@SuppressWarnings("unchecked")
public class Json implements Map<String, Object>, Serializable {
/**
* The Datas.
*/
//The real store
private final LinkedHashMap<String, Object> datas;
/**
* Init empty
*/
public Json() {
datas = new LinkedHashMap<>();
}
/**
* Init this a Json string, parse and make
*
* @param json_string the json string
*/
public Json(String json_string) {
datas = new LinkedHashMap<>();
try {
if (json_string == null || json_string.equals("")) {
return;
}
Gson gson = new Gson();
datas.putAll(gson.fromJson(json_string, Map.class));
} catch (Exception ignore) {
}
}
/**
* Init and put Map object entries
*
* @param map for initialisation
*/
public Json(Map<String, Object> map) {
datas = new LinkedHashMap<>();
datas.putAll(map);
}
/**
* Init and put anything have entries
*
* @param obj for initialisation
*/
public Json(Object obj) {
datas = new LinkedHashMap<>();
if (obj == null) {
return;
}
putAll((Map<String, Object>) obj);
}
/**
* Init with one entry
*
* @param key to put where
* @param value to put at key
*/
public Json(String key, Object value) {
datas = new LinkedHashMap<>();
datas.put(key, value);
}
/**
* Get t.
*
* @param <T> the type parameter
* @param key the key
* @param clazz the clazz
* @return the t
*/
private <T> T get(String key, Class<T> clazz) {
try {
if (get(key) == null) {
return null;
}
if (clazz.equals(Integer.class)) {
return clazz.cast(((Number) datas.get(key)).intValue());
}
return clazz.cast(datas.get(key));
} catch (Exception e) {
return null;
}
}
/**
* Get the ID as _id or id
*
* @return the id as String
*/
public String getId() {
if (containsKey("_id")) {
return getString("_id");
} else {
return getString("id");
}
}
/**
* Get anything from key
*
* @param key where find value
* @return value at key
*/
public Object get(String key) {
return datas.get(key);
}
/**
* Get anything from key with a failure value
*
* @param key where find the value
* @param def returned if there is no entry at key
* @return value at key
*/
public Object get(String key, Object def) {
if (get(key) == null) {
return def;
}
return get(key);
}
/**
* Get a string with a length limitation
*
* @param key where find the value
* @return null or a string
*/
public String getString(String key) {
if (key == null) {
return null;
}
return get(key, String.class);
}
/**
* Get a string spanned
*
* @param key where find the value
* @return the spanned
*/
public Spanned getSpanned(String key) {
return Html.fromHtml(getString(key, ""), Html.FROM_HTML_MODE_LEGACY);
}
/**
* Get a string spanned
*
* @param key where find the value
* @param max length
* @return the spanned
*/
public Spanned getSpanned(String key, int max) {
return Html.fromHtml(Fx.truncate(getString(key, ""), max), Html.FROM_HTML_MODE_LEGACY);
}
/**
* Get a string with a length limitation with a failure value
*
* @param key where find the value
* @param def returned if there is no entry at key
* @return null or a truncated string
*/
public String getString(String key, String def) {
if (containsKey(key) && get(key) != null) {
return getString(key);
}
return def;
}
/**
* Get a string with a limitation to possibles values
*
* @param key where find the value
* @param possibles values
* @return null or a value in possibles parameter
*/
public String getChoice(String key, String... possibles) {
for (String possible : possibles) {
if (possible.equals(get(key))) {
return getString(key);
}
}
return null;
}
/**
* Get a boolean with a failure value
*
* @param key where find the value
* @param def returned if there is no entry at key
* @return true or false
*/
public boolean getBoolean(String key, boolean def) {
try {
if (containsKey(key) && get(key) != null) {
return get(key, Boolean.class);
}
return def;
} catch (Exception e) {
if (getString(key, "").equals("true")) {
return true;
}
if (getString(key, "").equals("false")) {
return false;
}
return def;
}
}
/**
* Get a Date object at key
*
* @param key where find the value
* @return null or a Date object
*/
public Date getDate(String key) {
if (!containsKey(key)) {
return null;
}
Date date = get(key, Date.class);
if (date != null) {
return date;
}
return parseDate(key);
}
/**
* Get a Date object at key with a failure value
*
* @param key where find the value
* @param def returned if there is no entry at key
* @return null or a Date object
*/
public Date getDate(String key, Date def) {
if (get(key) == null) {
return def;
}
return get(key, Date.class);
}
/**
* Parse a string value as a Date object
* Needed to parse when Json is created from a string
*
* @param key where find the value
* @return null or a Date object
*/
public Date parseDate(String key) {
if (getString(key) == null) {
return null;
}
try {
SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS", Locale.FRANCE);
//fm.setTimeSurface(TimeSurface.getTimeSurface("UTC"));
return fm.parse(getString(key));
} catch (Exception e) {
return null;
}
}
/**
* Get a Integer at key
*
* @param key where find the value
* @return int value
*/
public int getInteger(String key) {
if (get(key).getClass().equals(Long.class)) {
return get(key, Long.class).intValue();
}
try {
return get(key, Integer.class);
} catch (Exception e) {
return Integer.parseInt(getString(key));
}
}
/**
* Get a Integer at key with a failure value
*
* @param key where find the value
* @param def returned if there is no entry at key
* @return int value
*/
public int getInteger(String key, int def) {
try {
if (datas.get(key) == null) {
return def;
}
return (int) get(key);
} catch (Exception e) {
try {
return Integer.parseInt(getString(key));
} catch (Exception ex) {
return def;
}
}
}
/**
* Get a Double at key
*
* @param key where find the value
* @return double value
*/
public double getDouble(String key) {
try {
return get(key, Double.class);
} catch (Exception e) {
return Double.parseDouble(getString(key));
}
}
/**
* Get a Double at key with a failure value
*
* @param key where find the value
* @param def returned if there is no entry at key
* @return double value
*/
public double getDouble(String key, double def) {
if (datas.get(key) == null) {
return def;
}
try {
return getDouble(key);
} catch (Exception e) {
try {
return getInteger(key);
} catch (Exception ex) {
return def;
}
}
}
/**
* Get a List of string
*
* @param key where find the values
* @return List of string values
*/
public List<String> getList(String key) {
return getList(key, String.class);
}
/**
* Get a List of object in a specific class
*
* @param <T> the type parameter
* @param key where find the values
* @param clazz Class of the objects in the result
* @return List of objects values
*/
public <T> List<T> getList(String key, Class<T> clazz) {
return (List<T>) datas.get(key);
}
/**
* Get a Json
*
* @param key where find the json
* @return Json value
*/
public Json getJson(String key) {
if (get(key) == null) {
return null;
}
try {
if (get(key).getClass().equals(Json.class)) {
return get(key, Json.class);
} else {
return new Json(get(key));
}
} catch (Exception e) {
return null;
}
}
/**
* Get a List of Jsons
*
* @param key where find the jsons
* @return List of Jsons values
*/
public List<Json> getListJson(String key) {
if (key == null || get(key) == null) {
return null;
}
Iterator<?> list = get(key, List.class).iterator();
List<Json> outlist = new ArrayList<>();
while (list.hasNext()) {
Object obj = list.next();
if (Json.class.isAssignableFrom(obj.getClass())) {
outlist.add((Json) obj);
} else if (Map.class.isAssignableFrom(obj.getClass())) {
outlist.add(new Json(obj));
} else {
return null;
}
}
return outlist;
}
/**
* Get a List of Integer
*
* @param key where find the ints
* @return List of Integers values
*/
public List<Integer> getListInteger(String key) {
List<Integer> list = new ArrayList<>();
for (Object item : getList(key)) {
if (Double.class.isAssignableFrom(item.getClass())) {
list.add(((Double) item).intValue());
} else {
list.add((int) item);
}
}
return list;
}
/**
* Count entries in this object
*
* @return number of entries
*/
@Override
public int size() {
return datas.size();
}
/**
* Is this object empty ?
*
* @return true if empty
*/
@Override
public boolean isEmpty() {
return datas.isEmpty();
}
/**
* Is this object contains entry at this key ?
*
* @param key where to find entry
* @return true if contains
*/
@Override
public boolean containsKey(Object key) {
return datas.containsKey(key);
}
/**
* Is this object contains this value ?
*
* @param value to find in this object
* @return true if contains
*/
@Override
public boolean containsValue(Object value) {
return datas.containsValue(value);
}
/**
* Get entry at a specific key
*
* @param key where find the value
* @return the entry value
*/
@Override
public Object get(Object key) {
return datas.get(key);
}
/**
* Put a value in this Json object at the end
*
* @param key where to put an entry
* @param value to put in entry
* @return this object
*/
@NonNull
public Json put(String key, Object value) {
datas.remove(key);
datas.put(key, value);
return this;
}
/**
* Put a value in this Json object at first
*
* @param key where to put an entry
* @param value to put in entry
* @return this object
*/
public Json prepend(String key, Object value) {
datas.remove(key);
Json clone = new Json(this);
datas.clear();
datas.put(key, value);
datas.putAll(clone);
return this;
}
/**
* Put a value in this Json object at the same place if exists, or at the end
*
* @param key where to put an entry
* @param value to put in entry
* @return this object
*/
public Json set(String key, Object value) {
datas.put(key, value);
return this;
}
/**
* Put all entry of a Map object
*
* @param map where entries have to be putted
*/
@Override
public void putAll(Map<? extends String, ?> map) {
datas.putAll(map);
}
/**
* Put all entry of a Json object
*
* @param map where entries have to be putted
* @return the json
*/
public Json putAll(Json map) {
datas.putAll(map);
return this;
}
/**
* Json contain entry at this key ?
*
* @param key where to find entry
* @return true if Json contain entry
*/
public boolean containsKey(String key) {
return datas.containsKey(key);
}
/**
* Remove entry
*
* @param key where to find the entry
* @return this Json object
*/
public Json remove(String key) {
datas.remove(key);
return this;
}
/**
* Remove value
*
* @param object to remove
* @return value of this entry
*/
@Override
public Object remove(Object object) {
return datas.remove(object);
}
/**
* Create or add value to a List in this object
*
* @param key where to find or create a List
* @param value to add to the List
* @return this Json object
*/
public Json add(String key, Object value) {
List<Object> values = getList(key, Object.class);
if (values == null) {
values = new ArrayList<>();
}
values.add(value);
return put(key, values);
}
/**
* Create or add value to a List in this object at a specific position
*
* @param key where to find or create a List
* @param value to add to the List
* @param position where to add value
* @return this Json object
*/
public Json add(String key, Object value, int position) {
List<Object> values = getList(key, Object.class);
if (values == null) {
values = new ArrayList<>();
}
values.add(position, value);
return put(key, values);
}
/**
* Get all entries in this object
*
* @return entries set
*/
@Override
public Set<Entry<String, Object>> entrySet() {
return datas.entrySet();
}
/**
* Get all keys in this object
*
* @return keys set
*/
@Override
public Set<String> keySet() {
return datas.keySet();
}
/**
* Get all keys in this object
*
* @return List of keys
*/
public List<String> keyList() {
List<String> keys = new ArrayList<>();
Collections.addAll(keys, datas.keySet().toArray(new String[0]));
return keys;
}
/**
* Get all values in this object
*
* @return values collection
*/
@Override
public Collection<Object> values() {
return datas.values();
}
/**
* Clear/Empty this Json object
*/
@Override
public void clear() {
datas.clear();
}
/**
* Stringify this object as JavaScript standard
*
* @return a string usable in JavaScript
*/
@Override
public String toString() {
return toString(true);
}
/**
* Stringify this object as JavaScript standard in low weight/compressed
*
* @param compressed the compressed
* @return a compressed string usable in JavaScript
*/
public String toString(boolean compressed) {
if (compressed) {
return new Gson().toJson(this);
}
return new GsonBuilder().setPrettyPrinting().create().toJson(this);
}
/**
* Simple clone function
*
* @return a clone of this object
*/
@Override
public Json clone() {
try {
return (Json) super.clone();
} catch (CloneNotSupportedException e) {
return new Json(this);
}
}
/**
* Get a List representation of this Object
*
* @return a List of the entries
*/
public List<Json> toList() {
List<Json> arr = new ArrayList<>();
for (Entry<String, Object> entry : datas.entrySet()) {
arr.add(new Json("key", entry.getKey()).put("value", entry.getValue()));
}
return arr;
}
/**
* Get the key of a value
*
* @param value the value
* @return the first key where the value can be found
*/
public String findKey(Object value) {
if (value == null) {
return null;
}
for (Entry<String, Object> set : entrySet()) {
if (set.getValue().equals(value)) {
return set.getKey();
}
}
return null;
}
/**
* Sort entries by key
*
* @return Json where entries are alphabetical ordered
*/
public Json sort() {
List<String> keys = Arrays.asList(keySet().toArray(new String[0]));
Collections.sort(keys);
Collections.reverse(keys);
for (String key : keys) {
prepend(key, get(key));
}
return this;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment