package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Hashtable; import java.util.IdentityHashMap; import java.util.LinkedHashMap; import java.util.Map; import java.util.Properties; import java.util.SortedMap; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; import com.alibaba.fastjson.parser.ParseContext; import com.alibaba.fastjson.util.AntiCollisionHashMap; public class MapDeserializer implements ObjectDeserializer { public final static MapDeserializer instance = new MapDeserializer(); @SuppressWarnings("unchecked") public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.NULL) { lexer.nextToken(JSONToken.COMMA); return null; } Map<Object, Object> map = createMap(type); ParseContext context = parser.getContext(); try { parser.setContext(context, map, fieldName); if (lexer.token() == JSONToken.RBRACE) { lexer.nextToken(JSONToken.COMMA); return (T) map; } return (T) deserialze(parser, type, fieldName, map); } finally { parser.setContext(context); } } @SuppressWarnings({"rawtypes", "unchecked"}) protected Object deserialze(DefaultJSONParser parser, Type type, Object fieldName, Map map) { if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; Type keyType = parameterizedType.getActualTypeArguments()[0]; Type valueType = parameterizedType.getActualTypeArguments()[1]; if (String.class == keyType) { return DefaultObjectDeserializer.instance.parseMap(parser, (Map<String, Object>) map, valueType, fieldName); } else { return DefaultObjectDeserializer.instance.parseMap(parser, map, keyType, valueType, fieldName); } } else { return parser.parseObject(map, fieldName); } } @SuppressWarnings({"unchecked", "rawtypes"}) protected Map<Object, Object> createMap(Type type) { if (type == Properties.class) { return new Properties(); } if (type == Hashtable.class) { return new Hashtable(); } if (type == IdentityHashMap.class) { return new IdentityHashMap(); } if (type == SortedMap.class || type == TreeMap.class) { return new TreeMap(); } if (type == ConcurrentMap.class || type == ConcurrentHashMap.class) { return new ConcurrentHashMap(); } if (type == Map.class) { return new AntiCollisionHashMap(); } if (type == HashMap.class) { // return new HashMap(); } if (type == LinkedHashMap.class) { return new LinkedHashMap(); } if (type instanceof ParameterizedType) { ParameterizedType parameterizedType = (ParameterizedType) type; return createMap(parameterizedType.getRawType()); } if (type instanceof Class<?>) { Class<?> clazz = (Class<?>) type; if (clazz.isInterface()) { throw new JSONException("unsupport type " + type); } try { return (Map<Object, Object>) clazz.newInstance(); } catch (Exception e) { throw new JSONException("unsupport type " + type, e); } } throw new JSONException("unsupport type " + type); } public int getFastMatchToken() { return JSONToken.LBRACE; } }