shade.com.alibaba.fastjson2.util.GuavaSupport Maven / Gradle / Ivy
package com.alibaba.fastjson2.util;
import com.alibaba.fastjson2.JSONB;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.support.LambdaMiscCodec;
import com.alibaba.fastjson2.writer.ObjectWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
public class GuavaSupport {
static Class CLASS_IMMUTABLE_MAP;
static Class CLASS_IMMUTABLE_LIST;
static Class CLASS_IMMUTABLE_SET;
static Class CLASS_ARRAYLIST_MULTI_MAP;
static Supplier FUNC_IMMUTABLE_MAP_OF_0;
static BiFunction FUNC_IMMUTABLE_MAP_OF_1;
static Function FUNC_IMMUTABLE_MAP_COPY_OF;
static Supplier FUNC_IMMUTABLE_LIST_OF_0;
static Function FUNC_IMMUTABLE_LIST_OF_1;
static Function FUNC_IMMUTABLE_LIST_COPY_OF;
static Supplier FUNC_IMMUTABLE_SET_OF_0;
static Function FUNC_IMMUTABLE_SET_OF_1;
static Function FUNC_IMMUTABLE_SET_COPY_OF;
static Supplier FUNC_ARRAYLIST_MULTI_MAP_CREATE;
static Method METHOD_ARRAYLIST_MULTI_MAP_PUT_ALL;
static volatile boolean METHOD_ARRAYLIST_MULTI_MAP_ERROR;
static BiFunction FUNC_SINGLETON_IMMUTABLE_BIMAP;
public static Function immutableListConverter() {
return new ImmutableListConvertFunction();
}
public static Function immutableSetConverter() {
return new ImmutableSetConvertFunction();
}
public static Function immutableMapConverter() {
return new ImmutableSingletonMapConvertFunction();
}
public static Function singletonBiMapConverter() {
return new SingletonImmutableBiMapConvertFunction();
}
static class ImmutableSetConvertFunction
implements Function {
@Override
public Object apply(Object object) {
if (CLASS_IMMUTABLE_SET == null) {
CLASS_IMMUTABLE_SET = TypeUtils.loadClass("com.google.common.collect.ImmutableSet");
}
if (CLASS_IMMUTABLE_SET == null) {
throw new JSONException("class not found : com.google.common.collect.ImmutableSet");
}
List list = (List) object;
if (list.isEmpty()) {
if (FUNC_IMMUTABLE_SET_OF_0 == null) {
try {
Method method = CLASS_IMMUTABLE_SET.getMethod("of");
FUNC_IMMUTABLE_SET_OF_0 = LambdaMiscCodec.createSupplier(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableSet.of", e);
}
}
return FUNC_IMMUTABLE_SET_OF_0.get();
}
if (list.size() == 1) {
if (FUNC_IMMUTABLE_SET_OF_1 == null) {
try {
Method method = CLASS_IMMUTABLE_SET.getMethod("of", Object.class);
FUNC_IMMUTABLE_SET_OF_1 = LambdaMiscCodec.createFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableSet.of", e);
}
}
Object first = list.get(0);
return FUNC_IMMUTABLE_SET_OF_1.apply(first);
}
if (FUNC_IMMUTABLE_SET_COPY_OF == null) {
try {
Method method = CLASS_IMMUTABLE_SET.getMethod("copyOf", Collection.class);
FUNC_IMMUTABLE_SET_COPY_OF = LambdaMiscCodec.createFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableSet.copyOf", e);
}
}
return FUNC_IMMUTABLE_SET_COPY_OF.apply(list);
}
}
static class ImmutableListConvertFunction
implements Function {
@Override
public Object apply(Object object) {
if (CLASS_IMMUTABLE_LIST == null) {
CLASS_IMMUTABLE_LIST = TypeUtils.loadClass("com.google.common.collect.ImmutableList");
}
if (CLASS_IMMUTABLE_LIST == null) {
throw new JSONException("class not found : com.google.common.collect.ImmutableList");
}
List list = (List) object;
if (list.isEmpty()) {
if (FUNC_IMMUTABLE_LIST_OF_0 == null) {
try {
Method method = CLASS_IMMUTABLE_LIST.getMethod("of");
FUNC_IMMUTABLE_LIST_OF_0 = LambdaMiscCodec.createSupplier(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableList.of", e);
}
}
return FUNC_IMMUTABLE_LIST_OF_0.get();
}
if (list.size() == 1) {
if (FUNC_IMMUTABLE_LIST_OF_1 == null) {
try {
Method method = CLASS_IMMUTABLE_LIST.getMethod("of", Object.class);
FUNC_IMMUTABLE_LIST_OF_1 = LambdaMiscCodec.createFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableList.of", e);
}
}
Object first = list.get(0);
return FUNC_IMMUTABLE_LIST_OF_1.apply(first);
}
if (FUNC_IMMUTABLE_LIST_COPY_OF == null) {
try {
Method method = CLASS_IMMUTABLE_LIST.getMethod("copyOf", Collection.class);
FUNC_IMMUTABLE_LIST_COPY_OF = LambdaMiscCodec.createFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableList.copyOf", e);
}
}
return FUNC_IMMUTABLE_LIST_COPY_OF.apply(list);
}
}
public static ObjectWriter createAsMapWriter(Class objectClass) {
return new AsMapWriter(objectClass);
}
static class AsMapWriter
implements ObjectWriter {
final Class objectClass;
final String typeName;
final long typeNameHash;
final Function asMap;
protected byte[] typeNameJSONB;
public AsMapWriter(Class objectClass) {
this.objectClass = objectClass;
this.typeName = TypeUtils.getTypeName(objectClass);
this.typeNameHash = Fnv.hashCode64(typeName);
try {
Method method = objectClass.getMethod("asMap");
asMap = LambdaMiscCodec.createFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("create Guava AsMapWriter error", e);
}
}
@Override
public void write(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
Map map = (Map) asMap.apply(object);
jsonWriter.write(map);
}
@Override
public void writeJSONB(JSONWriter jsonWriter, Object object, Object fieldName, Type fieldType, long features) {
if (jsonWriter.isWriteTypeInfo(object, fieldType, features)) {
if (typeNameJSONB == null) {
typeNameJSONB = JSONB.toBytes(typeName);
}
jsonWriter.writeTypeName(typeNameJSONB, typeNameHash);
}
Map map = (Map) asMap.apply(object);
jsonWriter.write(map);
}
}
public static Function createConvertFunction(Class objectClass) {
String instanceTypeName = objectClass.getName();
if ("com.google.common.collect.ArrayListMultimap".equals(instanceTypeName)) {
if (CLASS_ARRAYLIST_MULTI_MAP == null) {
CLASS_ARRAYLIST_MULTI_MAP = objectClass;
}
if (!METHOD_ARRAYLIST_MULTI_MAP_ERROR && FUNC_ARRAYLIST_MULTI_MAP_CREATE == null) {
try {
Method method = CLASS_ARRAYLIST_MULTI_MAP.getMethod("create");
FUNC_ARRAYLIST_MULTI_MAP_CREATE = LambdaMiscCodec.createSupplier(method);
} catch (Throwable ignored) {
METHOD_ARRAYLIST_MULTI_MAP_ERROR = true;
}
}
if (!METHOD_ARRAYLIST_MULTI_MAP_ERROR && METHOD_ARRAYLIST_MULTI_MAP_PUT_ALL == null) {
try {
METHOD_ARRAYLIST_MULTI_MAP_PUT_ALL = CLASS_ARRAYLIST_MULTI_MAP.getMethod("putAll", Object.class, Iterable.class);
} catch (Throwable ignored) {
METHOD_ARRAYLIST_MULTI_MAP_ERROR = true;
}
}
if (FUNC_ARRAYLIST_MULTI_MAP_CREATE != null && METHOD_ARRAYLIST_MULTI_MAP_PUT_ALL != null) {
return new ArrayListMultimapConvertFunction(FUNC_ARRAYLIST_MULTI_MAP_CREATE, METHOD_ARRAYLIST_MULTI_MAP_PUT_ALL);
}
}
throw new JSONException("create map error : " + objectClass);
}
static class ArrayListMultimapConvertFunction
implements Function {
final Supplier method;
final Method putAllMethod;
public ArrayListMultimapConvertFunction(Supplier method, Method putAllMethod) {
this.method = method;
this.putAllMethod = putAllMethod;
}
@Override
public Object apply(Object o) {
Map map = (Map) o;
Object multiMap = method.get();
for (Map.Entry entry : (Iterable) map.entrySet()) {
Object key = entry.getKey();
Iterable item = (Iterable) entry.getValue();
try {
putAllMethod.invoke(multiMap, key, item);
} catch (Throwable e) {
throw new JSONException("putAll ArrayListMultimap error", e);
}
}
return multiMap;
}
}
static class SingletonImmutableBiMapConvertFunction
implements Function {
@Override
public Object apply(Object object) {
if (FUNC_SINGLETON_IMMUTABLE_BIMAP == null) {
try {
Constructor constructor = TypeUtils.loadClass("com.google.common.collect.SingletonImmutableBiMap")
.getDeclaredConstructor(Object.class, Object.class);
FUNC_SINGLETON_IMMUTABLE_BIMAP = LambdaMiscCodec.createBiFunction(constructor);
} catch (NoSuchMethodException | SecurityException e) {
throw new JSONException("method not found : com.google.common.collect.SingletonImmutableBiMap(Object, Object)", e);
}
}
Map map = (Map) object;
Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
return FUNC_SINGLETON_IMMUTABLE_BIMAP.apply(entry.getKey(), entry.getValue());
}
}
static class ImmutableSingletonMapConvertFunction
implements Function {
@Override
public Object apply(Object object) {
if (CLASS_IMMUTABLE_MAP == null) {
CLASS_IMMUTABLE_MAP = TypeUtils.loadClass("com.google.common.collect.ImmutableMap");
}
if (CLASS_IMMUTABLE_MAP == null) {
throw new JSONException("class not found : com.google.common.collect.ImmutableMap");
}
Map map = (Map) object;
if (map.size() == 0) {
if (FUNC_IMMUTABLE_MAP_OF_0 == null) {
try {
Method method = CLASS_IMMUTABLE_MAP.getMethod("of");
FUNC_IMMUTABLE_MAP_OF_0 = LambdaMiscCodec.createSupplier(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableMap.of", e);
}
}
return FUNC_IMMUTABLE_MAP_OF_0.get();
}
if (map.size() == 1) {
if (FUNC_IMMUTABLE_MAP_OF_1 == null) {
try {
Method method = CLASS_IMMUTABLE_MAP.getMethod("of", Object.class, Object.class);
method.setAccessible(true);
FUNC_IMMUTABLE_MAP_OF_1 = LambdaMiscCodec.createBiFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableBiMap.of", e);
}
}
Map.Entry entry = (Map.Entry) map.entrySet().iterator().next();
return FUNC_IMMUTABLE_MAP_OF_1.apply(entry.getKey(), entry.getValue());
}
if (FUNC_IMMUTABLE_MAP_COPY_OF == null) {
try {
Method method = CLASS_IMMUTABLE_MAP.getMethod("copyOf", Map.class);
FUNC_IMMUTABLE_MAP_COPY_OF = LambdaMiscCodec.createFunction(method);
} catch (NoSuchMethodException e) {
throw new JSONException("method not found : com.google.common.collect.ImmutableBiMap.copyOf", e);
}
}
return FUNC_IMMUTABLE_MAP_COPY_OF.apply(map);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy