/src/main/java/com/alibaba/fastjson/parser/ParserConfig.java
Java | 534 lines | 429 code | 81 blank | 24 comment | 101 complexity | 653817d27e09123e5cad461b81acf688 MD5 | raw file
- /*
- * Copyright 1999-2101 Alibaba Group.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.alibaba.fastjson.parser;
- import java.io.Closeable;
- import java.io.File;
- import java.io.Serializable;
- import java.lang.reflect.Field;
- import java.lang.reflect.Modifier;
- import java.lang.reflect.ParameterizedType;
- import java.lang.reflect.Type;
- import java.lang.reflect.TypeVariable;
- import java.lang.reflect.WildcardType;
- import java.math.BigDecimal;
- import java.math.BigInteger;
- import java.net.Inet4Address;
- import java.net.Inet6Address;
- import java.net.InetAddress;
- import java.net.InetSocketAddress;
- import java.net.URI;
- import java.net.URL;
- import java.nio.charset.Charset;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Calendar;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.LinkedHashMap;
- import java.util.List;
- import java.util.Locale;
- import java.util.Map;
- import java.util.Set;
- import java.util.TimeZone;
- import java.util.TreeMap;
- import java.util.UUID;
- import java.util.concurrent.ConcurrentHashMap;
- import java.util.concurrent.ConcurrentMap;
- import java.util.concurrent.atomic.AtomicIntegerArray;
- import java.util.concurrent.atomic.AtomicLongArray;
- import java.util.regex.Pattern;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONException;
- import com.alibaba.fastjson.JSONObject;
- import com.alibaba.fastjson.asm.ASMException;
- import com.alibaba.fastjson.parser.deserializer.ASMDeserializerFactory;
- import com.alibaba.fastjson.parser.deserializer.ASMJavaBeanDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ArrayDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ArrayListStringDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ArrayListStringFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ArrayListTypeDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ArrayListTypeFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.AtomicIntegerArrayDeserializer;
- import com.alibaba.fastjson.parser.deserializer.AtomicLongArrayDeserializer;
- import com.alibaba.fastjson.parser.deserializer.AutowiredObjectDeserializer;
- import com.alibaba.fastjson.parser.deserializer.BigDecimalDeserializer;
- import com.alibaba.fastjson.parser.deserializer.BigIntegerDeserializer;
- import com.alibaba.fastjson.parser.deserializer.BooleanDeserializer;
- import com.alibaba.fastjson.parser.deserializer.BooleanFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.CalendarDeserializer;
- import com.alibaba.fastjson.parser.deserializer.CharArrayDeserializer;
- import com.alibaba.fastjson.parser.deserializer.CharacterDeserializer;
- import com.alibaba.fastjson.parser.deserializer.CharsetDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ClassDerializer;
- import com.alibaba.fastjson.parser.deserializer.CollectionDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ColorDeserializer;
- import com.alibaba.fastjson.parser.deserializer.DateDeserializer;
- import com.alibaba.fastjson.parser.deserializer.DateFormatDeserializer;
- import com.alibaba.fastjson.parser.deserializer.DefaultFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.DefaultObjectDeserializer;
- import com.alibaba.fastjson.parser.deserializer.EnumDeserializer;
- import com.alibaba.fastjson.parser.deserializer.FieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.FileDeserializer;
- import com.alibaba.fastjson.parser.deserializer.FloatDeserializer;
- import com.alibaba.fastjson.parser.deserializer.FontDeserializer;
- import com.alibaba.fastjson.parser.deserializer.InetAddressDeserializer;
- import com.alibaba.fastjson.parser.deserializer.InetSocketAddressDeserializer;
- import com.alibaba.fastjson.parser.deserializer.IntegerDeserializer;
- import com.alibaba.fastjson.parser.deserializer.IntegerFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.JSONArrayDeserializer;
- import com.alibaba.fastjson.parser.deserializer.JSONObjectDeserializer;
- import com.alibaba.fastjson.parser.deserializer.JavaBeanDeserializer;
- import com.alibaba.fastjson.parser.deserializer.JavaObjectDeserializer;
- import com.alibaba.fastjson.parser.deserializer.LocaleDeserializer;
- import com.alibaba.fastjson.parser.deserializer.LongDeserializer;
- import com.alibaba.fastjson.parser.deserializer.LongFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.MapDeserializer;
- import com.alibaba.fastjson.parser.deserializer.NumberDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
- import com.alibaba.fastjson.parser.deserializer.PatternDeserializer;
- import com.alibaba.fastjson.parser.deserializer.PointDeserializer;
- import com.alibaba.fastjson.parser.deserializer.RectangleDeserializer;
- import com.alibaba.fastjson.parser.deserializer.SqlDateDeserializer;
- import com.alibaba.fastjson.parser.deserializer.StackTraceElementDeserializer;
- import com.alibaba.fastjson.parser.deserializer.StringDeserializer;
- import com.alibaba.fastjson.parser.deserializer.StringFieldDeserializer;
- import com.alibaba.fastjson.parser.deserializer.ThrowableDeserializer;
- import com.alibaba.fastjson.parser.deserializer.TimeDeserializer;
- import com.alibaba.fastjson.parser.deserializer.TimeZoneDeserializer;
- import com.alibaba.fastjson.parser.deserializer.TimestampDeserializer;
- import com.alibaba.fastjson.parser.deserializer.URIDeserializer;
- import com.alibaba.fastjson.parser.deserializer.URLDeserializer;
- import com.alibaba.fastjson.parser.deserializer.UUIDDeserializer;
- import com.alibaba.fastjson.util.ASMUtils;
- import com.alibaba.fastjson.util.DeserializeBeanInfo;
- import com.alibaba.fastjson.util.FieldInfo;
- import com.alibaba.fastjson.util.IdentityHashMap;
- import com.alibaba.fastjson.util.ServiceLoader;
- /**
- * @author wenshao<szujobs@hotmail.com>
- */
- public class ParserConfig {
- public static ParserConfig getGlobalInstance() {
- return global;
- }
- private final Set<Class<?>> primitiveClasses = new HashSet<Class<?>>();
- private static ParserConfig global = new ParserConfig();
- private final IdentityHashMap<Type, ObjectDeserializer> derializers = new IdentityHashMap<Type, ObjectDeserializer>();
- private DefaultObjectDeserializer defaultSerializer = new DefaultObjectDeserializer();
- private boolean asmEnable = !ASMUtils.isAndroid();
- protected final SymbolTable symbolTable = new SymbolTable();
- public DefaultObjectDeserializer getDefaultSerializer() {
- return defaultSerializer;
- }
- public ParserConfig(){
- primitiveClasses.add(boolean.class);
- primitiveClasses.add(Boolean.class);
- primitiveClasses.add(char.class);
- primitiveClasses.add(Character.class);
- primitiveClasses.add(byte.class);
- primitiveClasses.add(Byte.class);
- primitiveClasses.add(short.class);
- primitiveClasses.add(Short.class);
- primitiveClasses.add(int.class);
- primitiveClasses.add(Integer.class);
- primitiveClasses.add(long.class);
- primitiveClasses.add(Long.class);
- primitiveClasses.add(float.class);
- primitiveClasses.add(Float.class);
- primitiveClasses.add(double.class);
- primitiveClasses.add(Double.class);
- primitiveClasses.add(BigInteger.class);
- primitiveClasses.add(BigDecimal.class);
- primitiveClasses.add(String.class);
- primitiveClasses.add(java.util.Date.class);
- primitiveClasses.add(java.sql.Date.class);
- primitiveClasses.add(java.sql.Time.class);
- primitiveClasses.add(java.sql.Timestamp.class);
- derializers.put(SimpleDateFormat.class, DateFormatDeserializer.instance);
- derializers.put(java.sql.Timestamp.class, TimestampDeserializer.instance);
- derializers.put(java.sql.Date.class, SqlDateDeserializer.instance);
- derializers.put(java.sql.Time.class, TimeDeserializer.instance);
- derializers.put(java.util.Date.class, DateDeserializer.instance);
- derializers.put(Calendar.class, CalendarDeserializer.instance);
- derializers.put(JSONObject.class, JSONObjectDeserializer.instance);
- derializers.put(JSONArray.class, JSONArrayDeserializer.instance);
- derializers.put(Map.class, MapDeserializer.instance);
- derializers.put(HashMap.class, MapDeserializer.instance);
- derializers.put(LinkedHashMap.class, MapDeserializer.instance);
- derializers.put(TreeMap.class, MapDeserializer.instance);
- derializers.put(ConcurrentMap.class, MapDeserializer.instance);
- derializers.put(ConcurrentHashMap.class, MapDeserializer.instance);
- derializers.put(Collection.class, CollectionDeserializer.instance);
- derializers.put(List.class, CollectionDeserializer.instance);
- derializers.put(ArrayList.class, CollectionDeserializer.instance);
- derializers.put(Object.class, JavaObjectDeserializer.instance);
- derializers.put(String.class, StringDeserializer.instance);
- derializers.put(char.class, CharacterDeserializer.instance);
- derializers.put(Character.class, CharacterDeserializer.instance);
- derializers.put(byte.class, NumberDeserializer.instance);
- derializers.put(Byte.class, NumberDeserializer.instance);
- derializers.put(short.class, NumberDeserializer.instance);
- derializers.put(Short.class, NumberDeserializer.instance);
- derializers.put(int.class, IntegerDeserializer.instance);
- derializers.put(Integer.class, IntegerDeserializer.instance);
- derializers.put(long.class, LongDeserializer.instance);
- derializers.put(Long.class, LongDeserializer.instance);
- derializers.put(BigInteger.class, BigIntegerDeserializer.instance);
- derializers.put(BigDecimal.class, BigDecimalDeserializer.instance);
- derializers.put(float.class, FloatDeserializer.instance);
- derializers.put(Float.class, FloatDeserializer.instance);
- derializers.put(double.class, NumberDeserializer.instance);
- derializers.put(Double.class, NumberDeserializer.instance);
- derializers.put(boolean.class, BooleanDeserializer.instance);
- derializers.put(Boolean.class, BooleanDeserializer.instance);
- derializers.put(Class.class, ClassDerializer.instance);
- derializers.put(char[].class, CharArrayDeserializer.instance);
- derializers.put(UUID.class, UUIDDeserializer.instance);
- derializers.put(TimeZone.class, TimeZoneDeserializer.instance);
- derializers.put(Locale.class, LocaleDeserializer.instance);
- derializers.put(InetAddress.class, InetAddressDeserializer.instance);
- derializers.put(Inet4Address.class, InetAddressDeserializer.instance);
- derializers.put(Inet6Address.class, InetAddressDeserializer.instance);
- derializers.put(InetSocketAddress.class, InetSocketAddressDeserializer.instance);
- derializers.put(File.class, FileDeserializer.instance);
- derializers.put(URI.class, URIDeserializer.instance);
- derializers.put(URL.class, URLDeserializer.instance);
- derializers.put(Pattern.class, PatternDeserializer.instance);
- derializers.put(Charset.class, CharsetDeserializer.instance);
- derializers.put(Number.class, NumberDeserializer.instance);
- derializers.put(AtomicIntegerArray.class, AtomicIntegerArrayDeserializer.instance);
- derializers.put(AtomicLongArray.class, AtomicLongArrayDeserializer.instance);
- derializers.put(StackTraceElement.class, StackTraceElementDeserializer.instance);
- derializers.put(Serializable.class, defaultSerializer);
- derializers.put(Cloneable.class, defaultSerializer);
- derializers.put(Comparable.class, defaultSerializer);
- derializers.put(Closeable.class, defaultSerializer);
- try {
- derializers.put(Class.forName("java.awt.Point"), PointDeserializer.instance);
- derializers.put(Class.forName("java.awt.Font"), FontDeserializer.instance);
- derializers.put(Class.forName("java.awt.Rectangle"), RectangleDeserializer.instance);
- derializers.put(Class.forName("java.awt.Color"), ColorDeserializer.instance);
- } catch (Throwable e) {
- // skip
- }
- }
- public boolean isAsmEnable() {
- return asmEnable;
- }
- public void setAsmEnable(boolean asmEnable) {
- this.asmEnable = asmEnable;
- }
- public SymbolTable getSymbolTable() {
- return symbolTable;
- }
- public IdentityHashMap<Type, ObjectDeserializer> getDerializers() {
- return derializers;
- }
- public ObjectDeserializer getDeserializer(Type type) {
- ObjectDeserializer derializer = this.derializers.get(type);
- if (derializer != null) {
- return derializer;
- }
- if (type instanceof Class<?>) {
- return getDeserializer((Class<?>) type, type);
- }
- if (type instanceof ParameterizedType) {
- Type rawType = ((ParameterizedType) type).getRawType();
- if (rawType instanceof Class<?>) {
- return getDeserializer((Class<?>) rawType, type);
- } else {
- return getDeserializer(rawType);
- }
- }
- return this.defaultSerializer;
- }
- public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
- ObjectDeserializer derializer = derializers.get(type);
- if (derializer != null) {
- return derializer;
- }
- if (type == null) {
- type = clazz;
- }
- derializer = derializers.get(type);
- if (derializer != null) {
- return derializer;
- }
- if (type instanceof WildcardType || type instanceof TypeVariable || type instanceof ParameterizedType) {
- derializer = derializers.get(clazz);
- }
- if (derializer != null) {
- return derializer;
- }
- 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
- }
- derializer = derializers.get(type);
- if (derializer != null) {
- return derializer;
- }
- if (clazz.isEnum()) {
- derializer = new EnumDeserializer(clazz);
- } else if (clazz.isArray()) {
- return ArrayDeserializer.instance;
- } else if (clazz == Set.class || clazz == HashSet.class || clazz == Collection.class || clazz == List.class
- || clazz == ArrayList.class) {
- if (type instanceof ParameterizedType) {
- Type itemType = ((ParameterizedType) type).getActualTypeArguments()[0];
- if (itemType == String.class) {
- derializer = ArrayListStringDeserializer.instance;
- } else {
- derializer = new ArrayListTypeDeserializer(clazz, itemType);
- }
- } else {
- derializer = CollectionDeserializer.instance;
- }
- } else if (Collection.class.isAssignableFrom(clazz)) {
- derializer = CollectionDeserializer.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;
- }
- public ObjectDeserializer createJavaBeanDeserializer(Class<?> clazz, Type type) {
- if (clazz == Class.class) {
- return this.defaultSerializer;
- }
- boolean asmEnable = this.asmEnable;
- if (asmEnable && !Modifier.isPublic(clazz.getModifiers())) {
- asmEnable = false;
- }
- if (clazz.getTypeParameters().length != 0) {
- asmEnable = false;
- }
- if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) {
- asmEnable = false;
- }
- if (asmEnable) {
- DeserializeBeanInfo beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);
- if (beanInfo.getFieldList().size() > 200) {
- asmEnable = false;
- }
-
- for (FieldInfo fieldInfo : beanInfo.getFieldList()) {
- if (fieldInfo.isGetOnly()) {
- asmEnable = false;
- break;
- }
- Class<?> fieldClass = fieldInfo.getFieldClass();
- if (!Modifier.isPublic(fieldClass.getModifiers())) {
- asmEnable = false;
- break;
- }
- if (fieldClass.isMemberClass() && !Modifier.isStatic(fieldClass.getModifiers())) {
- asmEnable = false;
- }
- }
- }
- if (asmEnable) {
- if (clazz.isMemberClass() && !Modifier.isStatic(clazz.getModifiers())) {
- asmEnable = false;
- }
- }
- if (!asmEnable) {
- return new JavaBeanDeserializer(this, clazz, type);
- }
- try {
- return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz, type);
- // } catch (VerifyError e) {
- // e.printStackTrace();
- // return new JavaBeanDeserializer(this, clazz, type);
- } catch (NoSuchMethodException error) {
- return new JavaBeanDeserializer(this, clazz, type);
- } catch (ASMException asmError) {
- return new JavaBeanDeserializer(this, clazz, type);
- } catch (Exception e) {
- throw new JSONException("create asm deserializer error, " + clazz.getName(), e);
- }
- }
- public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
- boolean asmEnable = this.asmEnable;
- if (!Modifier.isPublic(clazz.getModifiers())) {
- asmEnable = false;
- }
- if (fieldInfo.getFieldClass() == Class.class) {
- asmEnable = false;
- }
- if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) {
- asmEnable = false;
- }
- if (!asmEnable) {
- return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo);
- }
- try {
- return ASMDeserializerFactory.getInstance().createFieldDeserializer(mapping, clazz, fieldInfo);
- } catch (Throwable e) {
- // skip
- }
- return createFieldDeserializerWithoutASM(mapping, clazz, fieldInfo);
- }
- public FieldDeserializer createFieldDeserializerWithoutASM(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
- Class<?> fieldClass = fieldInfo.getFieldClass();
- if (fieldClass == boolean.class || fieldClass == Boolean.class) {
- return new BooleanFieldDeserializer(mapping, clazz, fieldInfo);
- }
- if (fieldClass == int.class || fieldClass == Integer.class) {
- return new IntegerFieldDeserializer(mapping, clazz, fieldInfo);
- }
- if (fieldClass == long.class || fieldClass == Long.class) {
- return new LongFieldDeserializer(mapping, clazz, fieldInfo);
- }
- if (fieldClass == String.class) {
- return new StringFieldDeserializer(mapping, clazz, fieldInfo);
- }
- if (fieldClass == List.class || fieldClass == ArrayList.class) {
- Type fieldType = fieldInfo.getFieldType();
- if (fieldType instanceof ParameterizedType) {
- Type itemType = ((ParameterizedType) fieldType).getActualTypeArguments()[0];
- if (itemType == String.class) {
- return new ArrayListStringFieldDeserializer(mapping, clazz, fieldInfo);
- }
- }
- return new ArrayListTypeFieldDeserializer(mapping, clazz, fieldInfo);
- }
- return new DefaultFieldDeserializer(mapping, clazz, fieldInfo);
- }
- public void putDeserializer(Type type, ObjectDeserializer deserializer) {
- derializers.put(type, deserializer);
- }
- public ObjectDeserializer getDeserializer(FieldInfo fieldInfo) {
- return getDeserializer(fieldInfo.getFieldClass(), fieldInfo.getFieldType());
- }
- public boolean isPrimitive(Class<?> clazz) {
- return primitiveClasses.contains(clazz);
- }
- public static Field getField(Class<?> clazz, String fieldName) {
- for (Field item : clazz.getDeclaredFields()) {
- if (fieldName.equals(item.getName())) {
- return item;
- }
- }
- if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
- return getField(clazz.getSuperclass(), fieldName);
- }
- return null;
- }
- public Map<String, FieldDeserializer> getFieldDeserializers(Class<?> clazz) {
- ObjectDeserializer deserizer = getDeserializer(clazz);
- if (deserizer instanceof JavaBeanDeserializer) {
- return ((JavaBeanDeserializer) deserizer).getFieldDeserializerMap();
- } else if (deserizer instanceof ASMJavaBeanDeserializer) {
- return ((ASMJavaBeanDeserializer) deserizer).getInnterSerializer().getFieldDeserializerMap();
- } else {
- return Collections.emptyMap();
- }
- }
- }