Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.polyglotted.common.util.MapRetriever Maven / Gradle / Ivy
package io.polyglotted.common.util;
import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.TypeToken;
import io.polyglotted.common.model.MapResult;
import io.polyglotted.common.model.Pair;
import io.polyglotted.common.util.ListBuilder.ImmutableListBuilder;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static io.polyglotted.common.model.MapResult.immutableResult;
import static io.polyglotted.common.model.Pair.pair;
import static io.polyglotted.common.util.Assertions.checkBool;
import static io.polyglotted.common.util.Assertions.checkContains;
import static io.polyglotted.common.util.CollUtil.toArray;
import static io.polyglotted.common.util.EnumCache.fetchEnumValueFor;
import static io.polyglotted.common.util.ListBuilder.immutableList;
import static io.polyglotted.common.util.ListBuilder.immutableListBuilder;
import static io.polyglotted.common.util.MapBuilder.immutableMap;
import static io.polyglotted.common.util.NullUtil.nonNull;
import static io.polyglotted.common.util.ReflectionUtil.declaredField;
import static io.polyglotted.common.util.ReflectionUtil.fieldValue;
import static io.polyglotted.common.util.ReflectionUtil.isAssignable;
import static io.polyglotted.common.util.ReflectionUtil.safeClass;
import static io.polyglotted.common.util.ReflectionUtil.safeFieldValue;
import static io.polyglotted.common.util.StrUtil.safePrefix;
import static io.polyglotted.common.util.StrUtil.safeSuffix;
@SuppressWarnings({"unchecked", "unused", "WeakerAccess"})
public abstract class MapRetriever {
public static final Class> MAP_CLASS = (Class>) new TypeToken>() {}.getRawType();
public static final Class> STRMAP_CLASS = (Class>) new TypeToken>() {}.getRawType();
public static final Class>> MAP_LIST_CLASS = (Class>>)
new TypeToken>>() {}.getRawType();
public static final Class> STRING_LIST_CLASS = (Class>) new TypeToken>() {}.getRawType();
protected static Pattern LIST_PATTERN = Pattern.compile("\\[(\\d+)\\]");
public static Map deepSet(Map map, String property, Object newValue) {
if (!property.contains(".")) { map.put(property, newValue); return map; }
checkBool(!property.startsWith("."), "property cannot begin with a dot");
try {
String[] parts = property.split("\\.");
Map child = map;
for (int i = 0; i < parts.length - 1; i++) {
Map child2 = MAP_CLASS.cast(child.get(parts[i]));
if (child2 == null) {
child2 = new LinkedHashMap<>(); child.put(parts[i], child2);
}
child = child2;
}
child.put(parts[parts.length - 1], newValue); return map;
} catch (Exception ex) { throw new IllegalArgumentException("failed to deepSet " + property + " - " + ex.getMessage()); }
}
public static void deepReplace(Object map, String property, Object newValue) {
if (!property.contains(".")) { mapSetOrReflect(map, property, newValue); return; }
Pair lastChild = lastChild(map, property);
if (lastChild != null) { mapSetOrReflect(lastChild._a, lastChild._b, newValue); }
}
public static void mapSetOrReflect(Object object, String property, Object newValue) {
if (object instanceof Map) { ((Map) object).put(property, newValue); }
else { safeFieldValue(object, property, newValue); }
}
public static T deepRetrieve(Object map, String property) { return deepRetrieve(map, property, null); }
public static T deepRetrieve(Object map, String property, T defVal) {
if (!property.contains(".")) { return mapGetOrReflect(map, property); }
Pair lastChild = lastChild(map, property);
return lastChild == null ? defVal : mapGetOrReflect(lastChild._a, lastChild._b, defVal);
}
private static Pair lastChild(Object map, String property) {
checkBool(!property.startsWith("."), "property cannot begin with a dot");
String[] parts = property.split("\\.");
Object child = map;
for (int i = 0; i < parts.length - 1; i++) {
child = mapGetOrReflect(child, parts[i]);
if (child == null) return null;
}
return Pair.pair(child, parts[parts.length - 1]);
}
public static T mapGetOrReflect(Object object, String property) { return mapGetOrReflect(object, property, null); }
public static T mapGetOrReflect(Object object, String property, T defVal) {
if (object instanceof List) {
Matcher matcher = LIST_PATTERN.matcher(property);
checkBool(matcher.matches(), "property `" + property + "` not formatted as a [index]");
List list = (List) object;
int index = Integer.parseInt(matcher.group(1));
return index < list.size() ? (T) list.get(index) : defVal;
}
if (object instanceof Map) return (T) nonNull(((Map) object).get(property), defVal);
Field field = declaredField(object.getClass(), property);
return field == null ? defVal : nonNull(fieldValue(object, field), defVal);
}
public static List deepCollect(Map map, String property, Class super T> clazz) {
checkBool(!property.startsWith("."), "property cannot begin with a dot");
if (!property.contains(".")) {
Object val = map.get(property);
return val == null ? immutableList() : (val instanceof List ? (List) val : immutableList((T) val));
}
ImmutableListBuilder result = immutableListBuilder();
walkProps(map, safePrefix(property, "."), safeSuffix(property, "."), result, clazz);
return result.build();
}
private static void walkProps(Map map, String prop, String remains, ImmutableListBuilder result, Class super T> clazz) {
Object child = map.get(prop);
if (remains.isEmpty()) {
if (child instanceof Collection) {
for (Object gc : (Collection>) child) { if (isAssignable(clazz, safeClass(gc))) { result.add((T) gc); } }
}
else if (isAssignable(clazz, safeClass(child))) { result.add((T) child); }
return;
}
Pair remainsPair = remains.contains(".") ? pair(safePrefix(remains, "."), safeSuffix(remains, ".")) : pair(remains, "");
if (child instanceof Map) { walkProps(asMap(child), remainsPair._a, remainsPair._b, result, clazz); }
else if (child instanceof Collection) {
for (Object gc : (Collection>) child) { walkProps(asMap(gc), remainsPair._a, remainsPair._b, result, clazz); }
}
}
public static String optStr(Map map, String prop) { return stringVal(map, prop, false, null); }
public static String optStr(Map map, String prop, String defVal) { return stringVal(map, prop, false, defVal); }
public static String reqdStr(Map map, String prop) { return stringVal(map, prop, true, null); }
public static boolean boolVal(Map map, String prop, boolean defVal) { return asValue(map, prop, Boolean.class, defVal); }
public static int intVal(Map map, String prop, int defVal) { return asValue(map, prop, Integer.class, defVal); }
public static long longVal(Map map, String prop, long defVal) { return asValue(map, prop, Long.class, defVal); }
public static Long longStrVal(Map map, String prop) {
Object value = map.get(prop);
return value == null ? null : value instanceof Number ? ((Number) value).longValue() : Long.parseLong(String.valueOf(value));
}
public static long longStrVal(Map map, String prop, long defaultValue) {
Object value = map.get(prop);
return value == null ? defaultValue : value instanceof Number ? ((Number) value).longValue() : Long.parseLong(String.valueOf(value));
}
public static String stringVal(Map map, String prop, boolean required, String defVal) {
return nonNull((String) map.get(required ? reqdProp(map, prop) : prop), defVal);
}
public static String[] strArrayVal(Map map, String prop) { return toArray(listVal(map, prop), String.class); }
public static T[] arrayVal(Map map, String prop, Class extends T> clazz) { return toArray(listVal(map, prop), clazz); }
public static List> mapListVal(Map map, String prop) { return asValue(map, prop, List.class, immutableList()); }
public static List listVal(Map map, String prop) { return asValue(map, prop, List.class, immutableList()); }
public static MapResult resultVal(Map map, String prop) {
Object result = map.get(prop);
return (result instanceof MapResult) ? (MapResult) result :
(result instanceof Map ? immutableResult(MAP_CLASS.cast(result)) : immutableResult());
}
public static Map mapVal(Map map, String prop) { return asValue(map, prop, MAP_CLASS, immutableMap()); }
public static T asNullable(Map map, String prop, Class clazz) { return clazz.cast(map.get(prop)); }
public static > E enumValue(Map map, String prop, Class enumClass) {
Object obj = map.get(reqdProp(map, prop));
return obj instanceof String ? (E) fetchEnumValueFor(enumClass, (String) obj) : enumClass.cast(obj);
}
public static T optValue(Map map, String prop) { return (T) map.get(prop); }
public static T optValue(Map map, String prop, T defValue) { return (T) nonNull(map.get(prop), defValue); }
public static T reqdValue(Map map, String prop) { return (T) map.get(reqdProp(map, prop)); }
public static T asValue(Map map, String prop, Class clazz, T defVal) { return nonNull(clazz.cast(map.get(prop)), defVal); }
public static String reqdProp(Map map, String prop) { return checkContains(map, prop); }
public static Map asMap(Object object) { return object == null ? immutableMap() : MAP_CLASS.cast(object); }
public static T removeVal(Map map, String prop) { return (T) map.remove(reqdProp(map, prop)); }
public static T removeIfExists(Map map, String prop) { return removeIfExists(map, prop, null); }
public static T removeIfExists(Map map, String prop, T defVl) { return map.containsKey(prop) ? (T) map.remove(prop) : defVl; }
public static Set> safeEntries(Map map) { return map == null ? ImmutableSet.of() : map.entrySet(); }
}