/src/main/java/com/alibaba/fastjson/parser/deserializer/JavaBeanDeserializer.java
Java | 343 lines | 281 code | 62 blank | 0 comment | 96 complexity | ce277d7868d885f24b7c657d232d6a52 MD5 | raw file
- package com.alibaba.fastjson.parser.deserializer;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.Proxy;
- import java.lang.reflect.Type;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.IdentityHashMap;
- import java.util.List;
- import java.util.Map;
- import com.alibaba.fastjson.JSONException;
- import com.alibaba.fastjson.JSONObject;
- import com.alibaba.fastjson.parser.DefaultJSONParser;
- import com.alibaba.fastjson.parser.DefaultJSONParser.ResolveTask;
- import com.alibaba.fastjson.parser.Feature;
- import com.alibaba.fastjson.parser.JSONScanner;
- import com.alibaba.fastjson.parser.JSONToken;
- import com.alibaba.fastjson.parser.ParseContext;
- import com.alibaba.fastjson.parser.ParserConfig;
- import com.alibaba.fastjson.util.DeserializeBeanInfo;
- import com.alibaba.fastjson.util.FieldInfo;
- import com.alibaba.fastjson.util.TypeUtils;
- public class JavaBeanDeserializer implements ObjectDeserializer {
- private final Map<String, FieldDeserializer> feildDeserializerMap = new IdentityHashMap<String, FieldDeserializer>();
- private final List<FieldDeserializer> fieldDeserializers = new ArrayList<FieldDeserializer>();
- private final Class<?> clazz;
- private final Type type;
- private DeserializeBeanInfo beanInfo;
- public JavaBeanDeserializer(DeserializeBeanInfo beanInfo){
- this.beanInfo = beanInfo;
- this.clazz = beanInfo.getClazz();
- this.type = beanInfo.getType();
- }
- public JavaBeanDeserializer(ParserConfig config, Class<?> clazz){
- this(config, clazz, clazz);
- }
- public JavaBeanDeserializer(ParserConfig config, Class<?> clazz, Type type){
- this.clazz = clazz;
- this.type = type;
- beanInfo = DeserializeBeanInfo.computeSetters(clazz, type);
- for (FieldInfo fieldInfo : beanInfo.getFieldList()) {
- addFieldDeserializer(config, clazz, fieldInfo);
- }
- }
- public Map<String, FieldDeserializer> getFieldDeserializerMap() {
- return feildDeserializerMap;
- }
- public Class<?> getClazz() {
- return clazz;
- }
- public Type getType() {
- return type;
- }
- private void addFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
- FieldDeserializer fieldDeserializer = createFieldDeserializer(mapping, clazz, fieldInfo);
- feildDeserializerMap.put(fieldInfo.getName().intern(), fieldDeserializer);
- fieldDeserializers.add(fieldDeserializer);
- }
- public FieldDeserializer createFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) {
- return mapping.createFieldDeserializer(mapping, clazz, fieldInfo);
- }
- public Object createInstance(DefaultJSONParser parser, Type type) {
- if (type instanceof Class) {
- if (clazz.isInterface()) {
- Class<?> clazz = (Class<?>) type;
- ClassLoader loader = Thread.currentThread().getContextClassLoader();
- final JSONObject obj = new JSONObject();
- Object proxy = Proxy.newProxyInstance(loader, new Class<?>[] { clazz }, obj);
- return proxy;
- }
- }
- if (beanInfo.getDefaultConstructor() == null) {
- return null;
- }
- Object object;
- try {
- Constructor<?> constructor = beanInfo.getDefaultConstructor();
- if (constructor.getParameterTypes().length == 0) {
- object = constructor.newInstance();
- } else {
- object = constructor.newInstance(parser.getContext().getObject());
- }
- } catch (Exception e) {
- throw new JSONException("create instance error, class " + clazz.getName(), e);
- }
- if (parser.isEnabled(Feature.InitStringFieldAsEmpty)) {
- for (FieldInfo fieldInfo : beanInfo.getFieldList()) {
- if (fieldInfo.getFieldClass() == String.class) {
- try {
- fieldInfo.set(object, "");
- } catch (Exception e) {
- throw new JSONException("create instance error, class " + clazz.getName(), e);
- }
- }
- }
- }
- return object;
- }
- @SuppressWarnings("unchecked")
- public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
- JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx
- if (lexer.token() == JSONToken.NULL) {
- lexer.nextToken(JSONToken.COMMA);
- return null;
- }
- ParseContext context = parser.getContext();
- ParseContext childContext = null;
- Object object = null;
- try {
- Map<String, Object> fieldValues = null;
- if (lexer.token() == JSONToken.RBRACE) {
- lexer.nextToken(JSONToken.COMMA);
- return (T) createInstance(parser, type);
- }
- if (lexer.token() != JSONToken.LBRACE && lexer.token() != JSONToken.COMMA) {
- throw new JSONException("syntax error, expect {, actual " + lexer.tokenName());
- }
- if (parser.getResolveStatus() == DefaultJSONParser.TypeNameRedirect) {
- parser.setResolveStatus(DefaultJSONParser.NONE);
- }
- for (;;) {
- String key = lexer.scanSymbol(parser.getSymbolTable());
- if (key == null) {
- if (lexer.token() == JSONToken.RBRACE) {
- lexer.nextToken(JSONToken.COMMA);
- break;
- }
- if (lexer.token() == JSONToken.COMMA) {
- if (parser.isEnabled(Feature.AllowArbitraryCommas)) {
- continue;
- }
- }
- }
- if ("$ref" == key) {
- lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
- if (lexer.token() == JSONToken.LITERAL_STRING) {
- String ref = lexer.stringVal();
- if ("@".equals(ref)) {
- object = context.getObject();
- } else if ("..".equals(ref)) {
- ParseContext parentContext = context.getParentContext();
- if (parentContext.getObject() != null) {
- object = parentContext.getObject();
- } else {
- parser.addResolveTask(new ResolveTask(parentContext, ref));
- parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
- }
- } else if ("$".equals(ref)) {
- ParseContext rootContext = context;
- while (rootContext.getParentContext() != null) {
- rootContext = rootContext.getParentContext();
- }
- if (rootContext.getObject() != null) {
- object = rootContext.getObject();
- } else {
- parser.addResolveTask(new ResolveTask(rootContext, ref));
- parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
- }
- } else {
- parser.addResolveTask(new ResolveTask(context, ref));
- parser.setResolveStatus(DefaultJSONParser.NeedToResolve);
- }
- } else {
- throw new JSONException("illegal ref, " + JSONToken.name(lexer.token()));
- }
- lexer.nextToken(JSONToken.RBRACE);
- if (lexer.token() != JSONToken.RBRACE) {
- throw new JSONException("illegal ref");
- }
- lexer.nextToken(JSONToken.COMMA);
- childContext = parser.setContext(context, object, fieldName);
- return (T) object;
- }
- if ("@type" == key) {
- lexer.nextTokenWithColon(JSONToken.LITERAL_STRING);
- if (lexer.token() == JSONToken.LITERAL_STRING) {
- String typeName = lexer.stringVal();
- lexer.nextToken(JSONToken.COMMA);
- if (type instanceof Class && typeName.equals(((Class<?>) type).getName())) {
- if (lexer.token() == JSONToken.RBRACE) {
- lexer.nextToken();
- break;
- }
- continue;
- }
- Class<?> userType = TypeUtils.loadClass(typeName);
- ObjectDeserializer deserizer = parser.getConfig().getDeserializer(userType);
- return (T) deserizer.deserialze(parser, userType, fieldName);
- } else {
- throw new JSONException("syntax error");
- }
- }
- if (object == null && fieldValues == null) {
- object = createInstance(parser, type);
- if (object == null) {
- fieldValues = new HashMap<String, Object>(this.fieldDeserializers.size());
- }
- childContext = parser.setContext(context, object, fieldName);
- }
- boolean match = parseField(parser, key, object, type, fieldValues);
- if (!match) {
- if (lexer.token() == JSONToken.RBRACE) {
- lexer.nextToken();
- break;
- }
- continue;
- }
- if (lexer.token() == JSONToken.COMMA) {
- continue;
- }
- if (lexer.token() == JSONToken.RBRACE) {
- lexer.nextToken(JSONToken.COMMA);
- break;
- }
- if (lexer.token() == JSONToken.IDENTIFIER || lexer.token() == JSONToken.ERROR) {
- throw new JSONException("syntax error, unexpect token " + JSONToken.name(lexer.token()));
- }
- }
- if (object == null) {
- if (fieldValues == null) {
- object = createInstance(parser, type);
- return (T) object;
- }
- List<FieldInfo> fieldInfoList = beanInfo.getFieldList();
- int size = fieldInfoList.size();
- Object[] params = new Object[size];
- for (int i = 0; i < size; ++i) {
- FieldInfo fieldInfo = fieldInfoList.get(i);
- params[i] = fieldValues.get(fieldInfo.getName());
- }
- if (beanInfo.getCreatorConstructor() != null) {
- try {
- object = beanInfo.getCreatorConstructor().newInstance(params);
- } catch (Exception e) {
- throw new JSONException("create instance error, "
- + beanInfo.getCreatorConstructor().toGenericString(), e);
- }
- } else if (beanInfo.getFactoryMethod() != null) {
- try {
- object = beanInfo.getFactoryMethod().invoke(null, params);
- } catch (Exception e) {
- throw new JSONException("create factory method error, "
- + beanInfo.getFactoryMethod().toString(), e);
- }
- }
- }
- return (T) object;
- } finally {
- if (childContext != null) {
- childContext.setObject(object);
- }
- parser.setContext(context);
- }
- }
- public boolean parseField(DefaultJSONParser parser, String key, Object object, Type objectType,
- Map<String, Object> fieldValues) {
- JSONScanner lexer = (JSONScanner) parser.getLexer(); // xxx
- FieldDeserializer fieldDeserializer = feildDeserializerMap.get(key);
- if (fieldDeserializer == null) {
- for (Map.Entry<String, FieldDeserializer> entry : feildDeserializerMap.entrySet()) {
- if (entry.getKey().equalsIgnoreCase(key)) {
- fieldDeserializer = entry.getValue();
- break;
- }
- }
- }
- if (fieldDeserializer == null) {
- if (!parser.isEnabled(Feature.IgnoreNotMatch)) {
- throw new JSONException("setter not found, class " + clazz.getName() + ", property " + key);
- }
- lexer.nextTokenWithColon();
- parser.parse(); // skip
- return false;
- }
- lexer.nextTokenWithColon(fieldDeserializer.getFastMatchToken());
- fieldDeserializer.parseField(parser, object, objectType, fieldValues);
- return true;
- }
- public int getFastMatchToken() {
- return JSONToken.LBRACE;
- }
- }