package com.alibaba.fastjson.parser.deserializer; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.HashMap; import java.util.Map; import com.alibaba.fastjson.JSONException; import com.alibaba.fastjson.parser.DefaultJSONParser; import com.alibaba.fastjson.parser.JSONLexer; import com.alibaba.fastjson.parser.JSONToken; @SuppressWarnings("rawtypes") public class EnumDeserializer implements ObjectDeserializer { private final Class<?> enumClass; private final Map<Integer, Enum> ordinalMap = new HashMap<Integer, Enum>(); private final Map<String, Enum> nameMap = new HashMap<String, Enum>(); public EnumDeserializer(Class<?> enumClass) { this.enumClass = enumClass; try { Method valueMethod = enumClass.getMethod("values"); Object[] values = (Object[]) valueMethod.invoke(null); for (Object value : values) { Enum e = (Enum) value; ordinalMap.put(e.ordinal(), e); nameMap.put(e.name(), e); } } catch (Exception ex) { throw new JSONException("init enum values error, " + enumClass.getName()); } } @SuppressWarnings("unchecked") public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { try { Object value; final JSONLexer lexer = parser.getLexer(); if (lexer.token() == JSONToken.LITERAL_INT) { value = lexer.intValue(); lexer.nextToken(JSONToken.COMMA); T e = (T) ordinalMap.get(value); if (e == null) { throw new JSONException("parse enum " + enumClass.getName() + " error, value : " + value); } return e; } else if (lexer.token() == JSONToken.LITERAL_STRING) { String strVal = lexer.stringVal(); lexer.nextToken(JSONToken.COMMA); if (strVal.length() == 0) { return (T) null; } value = nameMap.get(strVal); return (T) Enum.valueOf((Class<Enum>) enumClass, strVal); } else if (lexer.token() == JSONToken.NULL) { value = null; lexer.nextToken(JSONToken.COMMA); return null; } else { value = parser.parse(); } throw new JSONException("parse enum " + enumClass.getName() + " error, value : " + value); } catch (JSONException e) { throw e; } catch (Throwable e) { throw new JSONException(e.getMessage(), e); } } public int getFastMatchToken() { return JSONToken.LITERAL_INT; } }