ParserConfig.java
package com.alibaba.fastjson.parser;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.alibaba.fastjson2.JSONException;
import com.alibaba.fastjson2.JSONFactory;
import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.reader.ObjectReaderProvider;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Map;
import java.util.Properties;
public class ParserConfig {
public static final String DENY_PROPERTY = "fastjson.parser.deny";
public static final String AUTOTYPE_ACCEPT = "fastjson.parser.autoTypeAccept";
public static ParserConfig global = new ParserConfig(JSONFactory.getDefaultObjectReaderProvider(), false);
public static ParserConfig getGlobalInstance() {
return global;
}
final ObjectReaderProvider provider;
public final boolean fieldBase;
private boolean asmEnable;
private boolean autoTypeSupport;
ParserConfig(ObjectReaderProvider provider, boolean fieldBase) {
this.provider = provider;
this.fieldBase = fieldBase;
}
public ParserConfig() {
this(new ObjectReaderProvider(), false);
}
public ParserConfig(ClassLoader parentClassLoader) {
this(new ObjectReaderProvider(), false);
}
public ParserConfig(boolean fieldBase) {
this(new ObjectReaderProvider(), fieldBase);
}
public boolean isAsmEnable() {
return asmEnable;
}
public void setAsmEnable(boolean asmEnable) {
this.asmEnable = asmEnable;
}
public ObjectReaderProvider getProvider() {
return provider;
}
public void putDeserializer(Type type, ObjectDeserializer deserializer) {
getProvider().register(type, deserializer);
}
public Class<?> checkAutoType(Class type) {
return JSONFactory.getDefaultObjectReaderProvider().checkAutoType(type.getName(), null, 0);
}
public boolean isSafeMode() {
return ObjectReaderProvider.SAFE_MODE;
}
public void setSafeMode(boolean safeMode) {
if (safeMode != ObjectReaderProvider.SAFE_MODE) {
throw new JSONException("not support operation");
}
}
public boolean isAutoTypeSupport() {
return autoTypeSupport;
}
public void setAutoTypeSupport(boolean autoTypeSupport) {
this.autoTypeSupport = autoTypeSupport;
}
public void addAccept(String name) {
getProvider().addAutoTypeAccept(name);
}
public void addDeny(String name) {
getProvider().addAutoTypeDeny(name);
}
public void addDenyInternal(String name) {
getProvider().addAutoTypeDeny(name);
}
@Deprecated
public void setDefaultClassLoader(ClassLoader defaultClassLoader) {
// skip
}
public void addAutoTypeCheckHandler(AutoTypeCheckHandler h) {
if (getProvider().getAutoTypeBeforeHandler() != null) {
throw new JSONException("not support operation");
}
getProvider().setAutoTypeBeforeHandler(h);
}
/**
* @since 1.2.68
*/
public interface AutoTypeCheckHandler
extends JSONReader.AutoTypeBeforeHandler {
Class<?> handler(String typeName, Class<?> expectClass, int features);
default Class<?> apply(long typeNameHash, Class<?> expectClass, long features) {
return null;
}
default Class<?> apply(String typeName, Class<?> expectClass, long features) {
return handler(typeName, expectClass, (int) features);
}
}
public void configFromPropety(Properties properties) {
{
String property = properties.getProperty(DENY_PROPERTY);
String[] items = splitItemsFormProperty(property);
addItemsToDeny(items);
}
{
String property = properties.getProperty(AUTOTYPE_ACCEPT);
String[] items = splitItemsFormProperty(property);
addItemsToAccept(items);
}
}
private void addItemsToDeny(final String[] items) {
if (items == null) {
return;
}
for (int i = 0; i < items.length; ++i) {
String item = items[i];
this.addDeny(item);
}
}
private void addItemsToAccept(final String[] items) {
if (items == null) {
return;
}
for (int i = 0; i < items.length; ++i) {
String item = items[i];
this.addAccept(item);
}
}
private static String[] splitItemsFormProperty(final String property) {
if (property != null && property.length() > 0) {
return property.split(",");
}
return null;
}
public ObjectDeserializer get(Type type) {
ObjectReader objectReader = getProvider().getObjectReader(type);
if (objectReader instanceof ObjectDeserializer) {
return (ObjectDeserializer) objectReader;
}
return new ObjectDeserializerWrapper(objectReader);
}
public ObjectDeserializer getDeserializer(Type type) {
ObjectReader objectReader = getProvider().getObjectReader(type);
if (objectReader instanceof ObjectDeserializer) {
return (ObjectDeserializer) objectReader;
}
return new ObjectDeserializerWrapper(objectReader);
}
public ObjectDeserializer getDeserializer(Class<?> clazz, Type type) {
if (type == null) {
type = clazz;
}
ObjectReader objectReader = getProvider().getObjectReader(type);
if (objectReader instanceof ObjectDeserializer) {
return (ObjectDeserializer) objectReader;
}
return new ObjectDeserializerWrapper(objectReader);
}
/**
* fieldName,field ������������fieldName���������������������������findField���������
*
* @param clazz the specified goal class
* @param fieldCacheMap :map<fieldName ,Field>
*/
public static void parserAllFieldToCache(Class<?> clazz, Map<String, Field> fieldCacheMap) {
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
if (!fieldCacheMap.containsKey(fieldName)) {
fieldCacheMap.put(fieldName, field);
}
}
if (clazz.getSuperclass() != null && clazz.getSuperclass() != Object.class) {
parserAllFieldToCache(clazz.getSuperclass(), fieldCacheMap);
}
}
public static Field getFieldFromCache(String fieldName, Map<String, Field> fieldCacheMap) {
Field field = fieldCacheMap.get(fieldName);
if (field == null) {
field = fieldCacheMap.get("_" + fieldName);
}
if (field == null) {
field = fieldCacheMap.get("m_" + fieldName);
}
if (field == null) {
char c0 = fieldName.charAt(0);
if (c0 >= 'a' && c0 <= 'z') {
char[] chars = fieldName.toCharArray();
chars[0] -= 32; // lower
String fieldNameX = new String(chars);
field = fieldCacheMap.get(fieldNameX);
}
if (fieldName.length() > 2) {
char c1 = fieldName.charAt(1);
if (c0 >= 'a' && c0 <= 'z'
&& c1 >= 'A' && c1 <= 'Z') {
for (Map.Entry<String, Field> entry : fieldCacheMap.entrySet()) {
if (fieldName.equalsIgnoreCase(entry.getKey())) {
field = entry.getValue();
break;
}
}
}
}
}
return field;
}
}