package com.alibaba.fastjson.deserializer.issues569.parser;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.annotation.JSONType;
import com.alibaba.fastjson.parser.ParserConfig;
import com.alibaba.fastjson.parser.deserializer.*;
import com.alibaba.fastjson.serializer.AwtCodec;
import com.alibaba.fastjson.serializer.CollectionCodec;
import com.alibaba.fastjson.serializer.MiscCodec;
import com.alibaba.fastjson.serializer.ObjectArrayCodec;
import com.alibaba.fastjson.util.FieldInfo;
import com.alibaba.fastjson.util.JavaBeanInfo;
import com.alibaba.fastjson.util.ServiceLoader;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.util.*;
/**
* Author : BlackShadowWalker
* Date : 2016-10-10
*/
public class ParserConfigBug569 extends ParserConfig {
private static boolean awtError = false;
private static boolean jdk8Error = false;
private String[] denyList = new String[] { "java.lang.Thread" };
public FieldDeserializer createFieldDeserializer(ParserConfig mapping, //
JavaBeanInfo beanInfo, //
FieldInfo fieldInfo) {
Class<?> clazz = beanInfo.clazz;
Class<?> fieldClass = fieldInfo.fieldClass;
Class<?> deserializeUsing = null;
JSONField annotation = fieldInfo.getAnnotation();
if (annotation != null) {
deserializeUsing = annotation.deserializeUsing();
if (deserializeUsing == Void.class) {
deserializeUsing = null;
}
}
if (deserializeUsing == null && (fieldClass == List.class || fieldClass == ArrayList.class)) {
return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
}
return new DefaultFieldDeserializerBug569(mapping, clazz, fieldInfo);
}
public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
com.alibaba.fastjson.util.IdentityHashMap<Type, ObjectDeserializer> derializers = super.getDeserializers();
ObjectDeserializer derializer = derializers.get(type);
if (derializer != null) {
return derializer;
}
if (type == null) {
type = clazz;
}
derializer = derializers.get(type);
if (derializer != null) {
return derializer;
}
{
JSONType annotation = clazz.getAnnotation(JSONType.class);
if (annotation != null) {
Class<?> mappingTo = annotation.mappingTo();
if (mappingTo != Void.class) {
return getDeserializer(mappingTo, mappingTo);
}
}
}
if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
derializer = derializers.get(clazz);
}
if (derializer != null) {
return derializer;
}
String className = clazz.getName();
className = className.replace('$', '.');
for (int i = 0; i < denyList.length; ++i) {
String deny = denyList[i];
if (className.startsWith(deny)) {
throw new JSONException("parser deny : " + className);
}
}
if (className.startsWith("java.awt.") //
&& AwtCodec.support(clazz)) {
if (!awtError) {
try {
derializers.put(Class.forName("java.awt.Point"), AwtCodec.instance);
derializers.put(Class.forName("java.awt.Font"), AwtCodec.instance);
derializers.put(Class.forName("java.awt.Rectangle"), AwtCodec.instance);
derializers.put(Class.forName("java.awt.Color"), AwtCodec.instance);
} catch (Throwable e) {
// skip
awtError = true;
}
derializer = AwtCodec.instance;
}
}
if (!jdk8Error) {
try {
if (className.startsWith("java.time.")) {
derializers.put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.ZoneId"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.Period"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance);
derializers.put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance);
derializer = derializers.get(clazz);
} else if (className.startsWith("java.util.Optional")) {
derializers.put(Class.forName("java.util.Optional"), OptionalCodec.instance);
derializers.put(Class.forName("java.util.OptionalDouble"), OptionalCodec.instance);
derializers.put(Class.forName("java.util.OptionalInt"), OptionalCodec.instance);
derializers.put(Class.forName("java.util.OptionalLong"), OptionalCodec.instance);
derializer = derializers.get(clazz);
}
} catch (Throwable e) {
// skip
jdk8Error = true;
}
}
if (className.equals("java.nio.file.Path")) {
derializers.put(clazz, MiscCodec.instance);
}
final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
try {
for (AutowiredObjectDeserializer autowired : ServiceLoader.load(AutowiredObjectDeserializer.class,
classLoader)) {
for (Type forType : autowired.getAutowiredFor()) {
derializers.put(forType, autowired);
}
}
} catch (Exception ex) {
// skip
}
if (derializer == null) {
derializer = derializers.get(type);
}
if (derializer != null) {
return derializer;
}
if (clazz.isEnum()) {
derializer = new EnumDeserializer(clazz);
} else if (clazz.isArray()) {
derializer = ObjectArrayCodec.instance;
} else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class
|| clazz == ArrayList.class) {
derializer = CollectionCodec.instance;
} else if (Collection.class.isAssignableFrom(clazz)) {
derializer = CollectionCodec.instance;
} else if (Map.class.isAssignableFrom(clazz)) {
derializer = MapDeserializer.instance;
} else if (Throwable.class.isAssignableFrom(clazz)) {
derializer = new ThrowableDeserializer(this, clazz);
} else {
derializer = createJavaBeanDeserializer(clazz, type);
}
putDeserializer(type, derializer);
return derializer;
}
}