content: 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;
      }
  }
  