package com.fasterxml.jackson.databind.deser.std; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.introspect.AnnotatedMethod; import com.fasterxml.jackson.databind.util.ClassUtil; import com.fasterxml.jackson.databind.util.EnumResolver; import java.io.IOException; import java.lang.reflect.Method; public class EnumDeserializer extends StdScalarDeserializer<Enum<?>> { private static final long serialVersionUID = -5893263645879532318L; protected final EnumResolver<?> _resolver; @Override // com.fasterxml.jackson.databind.JsonDeserializer public boolean isCachable() { return true; } public EnumDeserializer(EnumResolver<?> enumResolver) { super(Enum.class); this._resolver = enumResolver; } public static JsonDeserializer<?> deserializerForCreator(DeserializationConfig deserializationConfig, Class<?> cls, AnnotatedMethod annotatedMethod) { Class cls2; Class<?> rawParameterType = annotatedMethod.getRawParameterType(0); if (rawParameterType == String.class) { cls2 = null; } else if (rawParameterType == Integer.TYPE || rawParameterType == Integer.class) { cls2 = Integer.class; } else if (rawParameterType == Long.TYPE || rawParameterType == Long.class) { cls2 = Long.class; } else { throw new IllegalArgumentException("Parameter #0 type for factory method (" + annotatedMethod + ") not suitable, must be java.lang.String or int/Integer/long/Long"); } if (deserializationConfig.canOverrideAccessModifiers()) { ClassUtil.checkAndFixAccess(annotatedMethod.getMember()); } return new FactoryBasedDeserializer(cls, annotatedMethod, cls2); } @Override // com.fasterxml.jackson.databind.JsonDeserializer public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { JsonToken currentToken = jsonParser.getCurrentToken(); if (currentToken == JsonToken.VALUE_STRING || currentToken == JsonToken.FIELD_NAME) { String text = jsonParser.getText(); Enum<?> findEnum = this._resolver.findEnum(text); return findEnum == null ? _deserializeAltString(jsonParser, deserializationContext, text) : findEnum; } else if (currentToken != JsonToken.VALUE_NUMBER_INT) { return _deserializeOther(jsonParser, deserializationContext); } else { if (!deserializationContext.isEnabled(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS)) { int intValue = jsonParser.getIntValue(); Enum<?> r0 = this._resolver.getEnum(intValue); if (r0 != null || deserializationContext.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { return r0; } Integer valueOf = Integer.valueOf(intValue); Class<?> enumClass = this._resolver.getEnumClass(); throw deserializationContext.weirdNumberException(valueOf, enumClass, "index value outside legal index range [0.." + this._resolver.lastValidIndex() + "]"); } throw deserializationContext.mappingException("Not allowed to deserialize Enum value out of JSON number (disable DeserializationConfig.DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS to allow)"); } } private final Enum<?> _deserializeAltString(JsonParser jsonParser, DeserializationContext deserializationContext, String str) throws IOException { String trim = str.trim(); if (trim.length() != 0) { char charAt = trim.charAt(0); if (charAt >= '0' && charAt <= '9') { try { Enum<?> r5 = this._resolver.getEnum(Integer.parseInt(trim)); if (r5 != null) { return r5; } } catch (NumberFormatException unused) { } } } else if (deserializationContext.isEnabled(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT)) { return null; } if (deserializationContext.isEnabled(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL)) { return null; } Class<?> enumClass = this._resolver.getEnumClass(); throw deserializationContext.weirdStringException(trim, enumClass, "value not one of declared Enum instance names: " + this._resolver.getEnums()); } private final Enum<?> _deserializeOther(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { if (jsonParser.getCurrentToken() != JsonToken.START_ARRAY || !deserializationContext.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) { throw deserializationContext.mappingException(this._resolver.getEnumClass()); } jsonParser.nextToken(); Enum<?> deserialize = deserialize(jsonParser, deserializationContext); if (jsonParser.nextToken() == JsonToken.END_ARRAY) { return deserialize; } JsonToken jsonToken = JsonToken.END_ARRAY; throw deserializationContext.wrongTokenException(jsonParser, jsonToken, "Attempted to unwrap single value array for single '" + this._resolver.getEnumClass().getName() + "' value but there was more than a single value in the array"); } protected static class FactoryBasedDeserializer extends StdScalarDeserializer<Object> { private static final long serialVersionUID = -7775129435872564122L; protected final Class<?> _enumClass; protected final Method _factory; protected final Class<?> _inputType; public FactoryBasedDeserializer(Class<?> cls, AnnotatedMethod annotatedMethod, Class<?> cls2) { super(Enum.class); this._enumClass = cls; this._factory = annotatedMethod.getAnnotated(); this._inputType = cls2; } @Override // com.fasterxml.jackson.databind.JsonDeserializer public Object deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { Object obj; Class<?> cls = this._inputType; if (cls == null) { obj = jsonParser.getText(); } else if (cls == Integer.class) { obj = Integer.valueOf(jsonParser.getValueAsInt()); } else if (cls == Long.class) { obj = Long.valueOf(jsonParser.getValueAsLong()); } else { throw deserializationContext.mappingException(this._enumClass); } try { return this._factory.invoke(this._enumClass, obj); } catch (Exception e) { Throwable rootCause = ClassUtil.getRootCause(e); if (rootCause instanceof IOException) { throw ((IOException) rootCause); } throw deserializationContext.instantiationException(this._enumClass, rootCause); } } } }