/src/main/java/com/alibaba/fastjson/parser/deserializer/ArrayListTypeFieldDeserializer.java

https://github.com/alibaba/fastjson · Java · 211 lines · 180 code · 31 blank · 0 comment · 65 complexity · c3af8f2e92bd492cfbe159d6fe30bf54 MD5 · raw file

  1. package com.alibaba.fastjson.parser.deserializer;
  2. import java.lang.reflect.ParameterizedType;
  3. import java.lang.reflect.Type;
  4. import java.lang.reflect.TypeVariable;
  5. import java.lang.reflect.WildcardType;
  6. import java.util.ArrayList;
  7. import java.util.Collection;
  8. import java.util.Map;
  9. import com.alibaba.fastjson.JSON;
  10. import com.alibaba.fastjson.TypeReference;
  11. import com.alibaba.fastjson.parser.DefaultJSONParser;
  12. import com.alibaba.fastjson.parser.Feature;
  13. import com.alibaba.fastjson.parser.JSONLexer;
  14. import com.alibaba.fastjson.parser.JSONToken;
  15. import com.alibaba.fastjson.parser.ParseContext;
  16. import com.alibaba.fastjson.parser.ParserConfig;
  17. import com.alibaba.fastjson.util.FieldInfo;
  18. import com.alibaba.fastjson.util.ParameterizedTypeImpl;
  19. public class ArrayListTypeFieldDeserializer extends FieldDeserializer {
  20. private final Type itemType;
  21. private int itemFastMatchToken;
  22. private ObjectDeserializer deserializer;
  23. public ArrayListTypeFieldDeserializer(ParserConfig mapping, Class<?> clazz, FieldInfo fieldInfo){
  24. super(clazz, fieldInfo);
  25. Type fieldType = fieldInfo.fieldType;
  26. if (fieldType instanceof ParameterizedType) {
  27. Type argType = ((ParameterizedType) fieldInfo.fieldType).getActualTypeArguments()[0];
  28. if (argType instanceof WildcardType) {
  29. WildcardType wildcardType = (WildcardType) argType;
  30. Type[] upperBounds = wildcardType.getUpperBounds();
  31. if (upperBounds.length == 1) {
  32. argType = upperBounds[0];
  33. }
  34. }
  35. this.itemType = argType;
  36. } else {
  37. this.itemType = Object.class;
  38. }
  39. }
  40. public int getFastMatchToken() {
  41. return JSONToken.LBRACKET;
  42. }
  43. @SuppressWarnings("rawtypes")
  44. @Override
  45. public void parseField(DefaultJSONParser parser, Object object, Type objectType, Map<String, Object> fieldValues) {
  46. JSONLexer lexer = parser.lexer;
  47. final int token = lexer.token();
  48. if (token == JSONToken.NULL
  49. || (token == JSONToken.LITERAL_STRING && lexer.stringVal().length() == 0)) {
  50. if (object == null) {
  51. fieldValues.put(fieldInfo.name, null);
  52. } else {
  53. setValue(object, null);
  54. }
  55. return;
  56. }
  57. ArrayList list = new ArrayList();
  58. ParseContext context = parser.getContext();
  59. parser.setContext(context, object, fieldInfo.name);
  60. parseArray(parser, objectType, list);
  61. parser.setContext(context);
  62. if (object == null) {
  63. fieldValues.put(fieldInfo.name, list);
  64. } else {
  65. setValue(object, list);
  66. }
  67. }
  68. @SuppressWarnings({ "unchecked", "rawtypes" })
  69. public final void parseArray(DefaultJSONParser parser, Type objectType, Collection array) {
  70. Type itemType = this.itemType;
  71. ObjectDeserializer itemTypeDeser = this.deserializer;
  72. if (objectType instanceof ParameterizedType) {
  73. if (itemType instanceof TypeVariable) {
  74. TypeVariable typeVar = (TypeVariable) itemType;
  75. ParameterizedType paramType = (ParameterizedType) objectType;
  76. Class<?> objectClass = null;
  77. if (paramType.getRawType() instanceof Class) {
  78. objectClass = (Class<?>) paramType.getRawType();
  79. }
  80. int paramIndex = -1;
  81. if (objectClass != null) {
  82. for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) {
  83. TypeVariable item = objectClass.getTypeParameters()[i];
  84. if (item.getName().equals(typeVar.getName())) {
  85. paramIndex = i;
  86. break;
  87. }
  88. }
  89. }
  90. if (paramIndex != -1) {
  91. itemType = paramType.getActualTypeArguments()[paramIndex];
  92. if (!itemType.equals(this.itemType)) {
  93. itemTypeDeser = parser.getConfig().getDeserializer(itemType);
  94. }
  95. }
  96. } else if (itemType instanceof ParameterizedType) {
  97. ParameterizedType parameterizedItemType = (ParameterizedType) itemType;
  98. Type[] itemActualTypeArgs = parameterizedItemType.getActualTypeArguments();
  99. if (itemActualTypeArgs.length == 1 && itemActualTypeArgs[0] instanceof TypeVariable) {
  100. TypeVariable typeVar = (TypeVariable) itemActualTypeArgs[0];
  101. ParameterizedType paramType = (ParameterizedType) objectType;
  102. Class<?> objectClass = null;
  103. if (paramType.getRawType() instanceof Class) {
  104. objectClass = (Class<?>) paramType.getRawType();
  105. }
  106. int paramIndex = -1;
  107. if (objectClass != null) {
  108. for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) {
  109. TypeVariable item = objectClass.getTypeParameters()[i];
  110. if (item.getName().equals(typeVar.getName())) {
  111. paramIndex = i;
  112. break;
  113. }
  114. }
  115. }
  116. if (paramIndex != -1) {
  117. itemActualTypeArgs[0] = paramType.getActualTypeArguments()[paramIndex];
  118. itemType = TypeReference.intern(
  119. new ParameterizedTypeImpl(itemActualTypeArgs, parameterizedItemType.getOwnerType(), parameterizedItemType.getRawType())
  120. );
  121. }
  122. }
  123. }
  124. } else if (itemType instanceof TypeVariable && objectType instanceof Class) {
  125. Class objectClass = (Class) objectType;
  126. TypeVariable typeVar = (TypeVariable) itemType;
  127. objectClass.getTypeParameters();
  128. for (int i = 0, size = objectClass.getTypeParameters().length; i < size; ++i) {
  129. TypeVariable item = objectClass.getTypeParameters()[i];
  130. if (item.getName().equals(typeVar.getName())) {
  131. Type[] bounds = item.getBounds();
  132. if (bounds.length == 1) {
  133. itemType = bounds[0];
  134. }
  135. break;
  136. }
  137. }
  138. }
  139. final JSONLexer lexer = parser.lexer;
  140. final int token = lexer.token();
  141. if (token == JSONToken.LBRACKET) {
  142. if (itemTypeDeser == null) {
  143. itemTypeDeser = deserializer = parser.getConfig().getDeserializer(itemType);
  144. itemFastMatchToken = deserializer.getFastMatchToken();
  145. }
  146. lexer.nextToken(itemFastMatchToken);
  147. for (int i = 0; ; ++i) {
  148. if (lexer.isEnabled(Feature.AllowArbitraryCommas)) {
  149. while (lexer.token() == JSONToken.COMMA) {
  150. lexer.nextToken();
  151. continue;
  152. }
  153. }
  154. if (lexer.token() == JSONToken.RBRACKET) {
  155. break;
  156. }
  157. Object val = itemTypeDeser.deserialze(parser, itemType, i);
  158. array.add(val);
  159. parser.checkListResolve(array);
  160. if (lexer.token() == JSONToken.COMMA) {
  161. lexer.nextToken(itemFastMatchToken);
  162. continue;
  163. }
  164. }
  165. lexer.nextToken(JSONToken.COMMA);
  166. } else if (token == JSONToken.LITERAL_STRING && fieldInfo.unwrapped) {
  167. String str = lexer.stringVal();
  168. lexer.nextToken();
  169. DefaultJSONParser valueParser = new DefaultJSONParser(str);
  170. valueParser.parseArray(array);
  171. } else {
  172. if (itemTypeDeser == null) {
  173. itemTypeDeser = deserializer = parser.getConfig().getDeserializer(itemType);
  174. }
  175. Object val = itemTypeDeser.deserialze(parser, itemType, 0);
  176. array.add(val);
  177. parser.checkListResolve(array);
  178. }
  179. }
  180. }