private static Object jsonBasicValueToObject(final Object jsonVal, final Type expectedType,
            final boolean convertStringToNumber) {
        if (jsonVal == null) {
            return null;
        } else if (jsonVal instanceof JSONArray || jsonVal instanceof JSONObject) {
            throw ClassGraphException.newClassGraphException("Expected a basic value type");
        }
        if (expectedType instanceof ParameterizedType) {
            // TODO: add support for Class<T> reference values, which may be parameterized
            throw new IllegalArgumentException("Got illegal ParameterizedType: " + expectedType);
        } else if (!(expectedType instanceof Class<?>)) {
            throw new IllegalArgumentException("Got illegal basic value type: " + expectedType);
        }

        final Class<?> rawType = (Class<?>) expectedType;
        if (rawType == String.class) {
            if (!(jsonVal instanceof CharSequence)) {
                throw new IllegalArgumentException("Expected string; got " + jsonVal.getClass().getName());
            }
            return jsonVal.toString();

        } else if (rawType == CharSequence.class) {
            if (!(jsonVal instanceof CharSequence)) {
                throw new IllegalArgumentException("Expected CharSequence; got " + jsonVal.getClass().getName());
            }
            return jsonVal;

        } else if (rawType == Integer.class || rawType == Integer.TYPE) {
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return Integer.parseInt(jsonVal.toString());
            }
            if (!(jsonVal instanceof Integer)) {
                throw new IllegalArgumentException("Expected integer; got " + jsonVal.getClass().getName());
            }
            return jsonVal;

        } else if (rawType == Long.class || rawType == Long.TYPE) {
            final boolean isLong = jsonVal instanceof Long;
            final boolean isInteger = jsonVal instanceof Integer;
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return isLong ? Long.parseLong(jsonVal.toString()) : Integer.parseInt(jsonVal.toString());
            }
            if (!(isLong || isInteger)) {
                throw new IllegalArgumentException("Expected long; got " + jsonVal.getClass().getName());
            }
            if (isLong) {
                return jsonVal;
            } else {
                return (long) (Integer) jsonVal;
            }

        } else if (rawType == Short.class || rawType == Short.TYPE) {
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return Short.parseShort(jsonVal.toString());
            }
            if (!(jsonVal instanceof Integer)) {
                throw new IllegalArgumentException("Expected short; got " + jsonVal.getClass().getName());
            }
            final int intValue = (Integer) jsonVal;
            if (intValue < Short.MIN_VALUE || intValue > Short.MAX_VALUE) {
                throw new IllegalArgumentException("Expected short; got out-of-range value " + intValue);
            }
            return (short) intValue;

        } else if (rawType == Float.class || rawType == Float.TYPE) {
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return Float.parseFloat(jsonVal.toString());
            }
            if (!(jsonVal instanceof Double)) {
                throw new IllegalArgumentException("Expected float; got " + jsonVal.getClass().getName());
            }
            final double doubleValue = (Double) jsonVal;
            if (doubleValue < Float.MIN_VALUE || doubleValue > Float.MAX_VALUE) {
                throw new IllegalArgumentException("Expected float; got out-of-range value " + doubleValue);
            }
            return (float) doubleValue;

        } else if (rawType == Double.class || rawType == Double.TYPE) {
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return Double.parseDouble(jsonVal.toString());
            }
            if (!(jsonVal instanceof Double)) {
                throw new IllegalArgumentException("Expected double; got " + jsonVal.getClass().getName());
            }
            return jsonVal;

        } else if (rawType == Byte.class || rawType == Byte.TYPE) {
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return Byte.parseByte(jsonVal.toString());
            }
            if (!(jsonVal instanceof Integer)) {
                throw new IllegalArgumentException("Expected byte; got " + jsonVal.getClass().getName());
            }
            final int intValue = (Integer) jsonVal;
            if (intValue < Byte.MIN_VALUE || intValue > Byte.MAX_VALUE) {
                throw new IllegalArgumentException("Expected byte; got out-of-range value " + intValue);
            }
            return (byte) intValue;

        } else if (rawType == Character.class || rawType == Character.TYPE) {
            if (!(jsonVal instanceof CharSequence)) {
                throw new IllegalArgumentException("Expected character; got " + jsonVal.getClass().getName());
            }
            final CharSequence charSequence = (CharSequence) jsonVal;
            if (charSequence.length() != 1) {
                throw new IllegalArgumentException("Expected single character; got string");
            }
            return charSequence.charAt(0);

        } else if (rawType == Boolean.class || rawType == Boolean.TYPE) {
            if (convertStringToNumber && jsonVal instanceof CharSequence) {
                return Boolean.parseBoolean(jsonVal.toString());
            }
            if (!(jsonVal instanceof Boolean)) {
                throw new IllegalArgumentException("Expected boolean; got " + jsonVal.getClass().getName());
            }
            return jsonVal;
        } else if (Enum.class.isAssignableFrom(rawType)) {
            if (!(jsonVal instanceof CharSequence)) {
                throw new IllegalArgumentException(
                        "Expected string for enum value; got " + jsonVal.getClass().getName());
            }
            @SuppressWarnings({ "rawtypes", "unchecked" })
            final Enum enumValue = Enum.valueOf((Class<Enum>) rawType, jsonVal.toString());
            return enumValue;

        } else if (JSONUtils.getRawType(expectedType).isAssignableFrom(jsonVal.getClass())) {
            return jsonVal;

        } else {
            throw new IllegalArgumentException("Got type " + jsonVal.getClass() + "; expected " + expectedType);
        }
    }
private static Object jsonBasicValueToObject ( final Object jsonVal , final Type expectedType , final boolean convertStringToNumber ) { if ( jsonVal == null ) { return null ; } else if ( jsonVal instanceof JSONArray || jsonVal instanceof JSONObject ) { throw ClassGraphException . newClassGraphException ( "Expected a basic value type" ) ; } if ( expectedType instanceof ParameterizedType ) { throw new IllegalArgumentException ( "Got illegal ParameterizedType: " + expectedType ) ; } else if ( ! ( expectedType instanceof Class < ? > ) ) { throw new IllegalArgumentException ( "Got illegal basic value type: " + expectedType ) ; } final Class < ? > rawType = ( Class < ? > ) expectedType ; if ( rawType == String . class ) { if ( ! ( jsonVal instanceof CharSequence ) ) { throw new IllegalArgumentException ( "Expected string; got " + jsonVal . getClass ( ) . getName ( ) ) ; } return jsonVal . toString ( ) ; } else if ( rawType == CharSequence . class ) { if ( ! ( jsonVal instanceof CharSequence ) ) { throw new IllegalArgumentException ( "Expected CharSequence; got " + jsonVal . getClass ( ) . getName ( ) ) ; } return jsonVal ; } else if ( rawType == Integer . class || rawType == Integer . TYPE ) { if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return Integer . parseInt ( jsonVal . toString ( ) ) ; } if ( ! ( jsonVal instanceof Integer ) ) { throw new IllegalArgumentException ( "Expected integer; got " + jsonVal . getClass ( ) . getName ( ) ) ; } return jsonVal ; } else if ( rawType == Long . class || rawType == Long . TYPE ) { final boolean isLong = jsonVal instanceof Long ; final boolean isInteger = jsonVal instanceof Integer ; if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return isLong ? Long . parseLong ( jsonVal . toString ( ) ) : Integer . parseInt ( jsonVal . toString ( ) ) ; } if ( ! ( isLong || isInteger ) ) { throw new IllegalArgumentException ( "Expected long; got " + jsonVal . getClass ( ) . getName ( ) ) ; } if ( isLong ) { return jsonVal ; } else { return ( long ) ( Integer ) jsonVal ; } } else if ( rawType == Short . class || rawType == Short . TYPE ) { if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return Short . parseShort ( jsonVal . toString ( ) ) ; } if ( ! ( jsonVal instanceof Integer ) ) { throw new IllegalArgumentException ( "Expected short; got " + jsonVal . getClass ( ) . getName ( ) ) ; } final int intValue = ( Integer ) jsonVal ; if ( intValue < Short . MIN_VALUE || intValue > Short . MAX_VALUE ) { throw new IllegalArgumentException ( "Expected short; got out-of-range value " + intValue ) ; } return ( short ) intValue ; } else if ( rawType == Float . class || rawType == Float . TYPE ) { if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return Float . parseFloat ( jsonVal . toString ( ) ) ; } if ( ! ( jsonVal instanceof Double ) ) { throw new IllegalArgumentException ( "Expected float; got " + jsonVal . getClass ( ) . getName ( ) ) ; } final double doubleValue = ( Double ) jsonVal ; if ( doubleValue < Float . MIN_VALUE || doubleValue > Float . MAX_VALUE ) { throw new IllegalArgumentException ( "Expected float; got out-of-range value " + doubleValue ) ; } return ( float ) doubleValue ; } else if ( rawType == Double . class || rawType == Double . TYPE ) { if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return Double . parseDouble ( jsonVal . toString ( ) ) ; } if ( ! ( jsonVal instanceof Double ) ) { throw new IllegalArgumentException ( "Expected double; got " + jsonVal . getClass ( ) . getName ( ) ) ; } return jsonVal ; } else if ( rawType == Byte . class || rawType == Byte . TYPE ) { if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return Byte . parseByte ( jsonVal . toString ( ) ) ; } if ( ! ( jsonVal instanceof Integer ) ) { throw new IllegalArgumentException ( "Expected byte; got " + jsonVal . getClass ( ) . getName ( ) ) ; } final int intValue = ( Integer ) jsonVal ; if ( intValue < Byte . MIN_VALUE || intValue > Byte . MAX_VALUE ) { throw new IllegalArgumentException ( "Expected byte; got out-of-range value " + intValue ) ; } return ( byte ) intValue ; } else if ( rawType == Character . class || rawType == Character . TYPE ) { if ( ! ( jsonVal instanceof CharSequence ) ) { throw new IllegalArgumentException ( "Expected character; got " + jsonVal . getClass ( ) . getName ( ) ) ; } final CharSequence charSequence = ( CharSequence ) jsonVal ; if ( charSequence . length ( ) != 1 ) { throw new IllegalArgumentException ( "Expected single character; got string" ) ; } return charSequence . charAt ( 0 ) ; } else if ( rawType == Boolean . class || rawType == Boolean . TYPE ) { if ( convertStringToNumber && jsonVal instanceof CharSequence ) { return Boolean . parseBoolean ( jsonVal . toString ( ) ) ; } if ( ! ( jsonVal instanceof Boolean ) ) { throw new IllegalArgumentException ( "Expected boolean; got " + jsonVal . getClass ( ) . getName ( ) ) ; } return jsonVal ; } else if ( Enum . class . isAssignableFrom ( rawType ) ) { if ( ! ( jsonVal instanceof CharSequence ) ) { throw new IllegalArgumentException ( "Expected string for enum value; got " + jsonVal . getClass ( ) . getName ( ) ) ; } @ SuppressWarnings ( { "rawtypes" , "unchecked" } ) final Enum enumValue = Enum . valueOf ( ( Class < Enum > ) rawType , jsonVal . toString ( ) ) ; return enumValue ; } else if ( JSONUtils . getRawType ( expectedType ) . isAssignableFrom ( jsonVal . getClass ( ) ) ) { return jsonVal ; } else { throw new IllegalArgumentException ( "Got type " + jsonVal . getClass ( ) + "; expected " + expectedType ) ; } }
Deserialize a JSON basic value (String, Integer, Long, or Double), conforming it to the expected type
(Character, Short, etc.).

@param jsonVal
the json val
@param expectedType
the expected type
@param convertStringToNumber
if true, convert strings to numbers
@return the object