package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParseContext; import com.alibaba.fastjson.parser.ParserConfig; import com.alibaba.fastjson.util.FieldInfo; public class ArrayListTypeFieldDeserializer extends FieldDeserializer { private final Type itemType; private int itemFastMatchToken; private ObjectDeserializer deserializer; public ArrayListTypeFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo) { super(clazz, fieldInfo); Type fieldType = getFieldType(); if (fieldType instanceof ParameterizedType) { this.itemType = ((ParameterizedType) getFieldType()).getActualTypeArguments()[0]; } else { this.itemType = Object.class; } } public int getFastMatchToken() { return JSONToken.LBRACKET; } @SuppressWarnings("rawtypes") @Override public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) { if (parser.getLexer().token() == JSONToken.NULL) { setValue(object, null); return; } ArrayList list = new ArrayList(); ParseContext context = parser.getContext(); parser.setContext(context, object, fieldInfo.getName()); parseArray(parser, objectType, list); parser.setContext(context); if (object == null) { fieldValues.put(fieldInfo.getName(), list); } else { setValue(object, list); } } @SuppressWarnings({"unchecked", "rawtypes"}) public final void parseArray(DefaultJSONParser parser, Type objectType, Collection array) { Type itemType = this.itemType;; if (itemType instanceof TypeVariable && objectType instanceof ParameterizedType) { TypeVariable typeVar = (TypeVariable) itemType; ParameterizedType paramType = (ParameterizedType) objectType; Class<?> objectClass = null; if (paramType.getRawType() instanceof Class) { objectClass = (Class<?>) paramType.getRawType(); } int paramIndex = -1; if (objectClass != null) { for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) { TypeVariable item = objectClass.getTypeParameters()[i]; if (item.getName().equals(typeVar.getName())) { paramIndex = i; break; } } } if (paramIndex != -1) { itemType = paramType.getActualTypeArguments()[paramIndex]; } } final JSONLexer lexer = parser.getLexer(); if (lexer.token() != JSONToken.LBRACKET) { throw new JSONException("exepct '[', but " + JSONToken.name(lexer.token())); } if (deserializer == null) { deserializer = parser.getConfig().getDeserializer(itemType); itemFastMatchToken = deserializer.getFastMatchToken(); } lexer.nextToken(itemFastMatchToken); for (int i = 0;; ++i) { if (lexer.isEnabled(Feature.AllowArbitraryCommas)) { while (lexer.token() == JSONToken.COMMA) { lexer.nextToken(); continue; } } if (lexer.token() == JSONToken.RBRACKET) { break; } Object val = deserializer.deserialze(parser, itemType, i); array.add(val); parser.checkListResolve(array); if (lexer.token() == JSONToken.COMMA) { lexer.nextToken(itemFastMatchToken); continue; } } lexer.nextToken(JSONToken.COMMA); } }