src/main/java/com/cedarsoftware/util/io/Resolver.java
protected Object createJavaObjectInstance(Class clazz, JsonObject jsonObj)
    {
        final boolean useMapsLocal = useMaps;
        String type = jsonObj.type;

        // We can't set values to an Object, so well try to use the contained type instead
		if ("java.lang.Object".equals(type))
        {
			Object value = jsonObj.get("value");
        	if (jsonObj.keySet().size() == 1 && value != null)
            {
        		type = value.getClass().getName();
        	}
        }

        Object mate;

        // @type always takes precedence over inferred Java (clazz) type.
        if (type != null)
        {    // @type is explicitly set, use that as it always takes precedence
            Class c;
            try
            {
                c = MetaUtils.classForName(type, reader.getClassLoader(), failOnUnknownType);
            }
            catch (Exception e)
            {
                if (useMapsLocal)
                {
                    jsonObj.type = null;
                    jsonObj.target = null;
                    return jsonObj;
                }
                else
                {
                    String name = clazz == null ? "null" : clazz.getName();
                    throw new JsonIoException("Unable to create class: " + name, e);
                }
            }
            if (c.isArray())
            {    // Handle []
                Object[] items = jsonObj.getArray();
                int size = (items == null) ? 0 : items.length;
                if (c == char[].class)
                {
                    jsonObj.moveCharsToMate();
                    mate = jsonObj.target;
                }
                else
                {
                    mate = Array.newInstance(c.getComponentType(), size);
                }
            }
            else
            {    // Handle regular field.object reference
                if (MetaUtils.isPrimitive(c))
                {
                    mate = MetaUtils.convert(c, jsonObj.get("value"));
                }
                else if (c == Class.class)
                {
                    mate = MetaUtils.classForName((String) jsonObj.get("value"), reader.getClassLoader());
                }
                else if (c.isEnum())
                {
                    mate = getEnum(c, jsonObj);
                }
                else if (Enum.class.isAssignableFrom(c)) // anonymous subclass of an enum
                {
                    mate = getEnum(c.getSuperclass(), jsonObj);
                }
                else if (EnumSet.class.isAssignableFrom(c))
                {
                    mate = getEnumSet(c, jsonObj);
                }
                else if ((mate = coerceCertainTypes(c.getName())) != null)
                {   // if coerceCertainTypes() returns non-null, it did the work
                }
                else
                {
                    mate = newInstance(c, jsonObj);
                }
            }
        }
        else
        {    // @type, not specified, figure out appropriate type
            Object[] items = jsonObj.getArray();

            // if @items is specified, it must be an [] type.
            // if clazz.isArray(), then it must be an [] type.
            if (clazz.isArray() || (items != null && clazz == Object.class && !jsonObj.containsKey("@keys")))
            {
                int size = (items == null) ? 0 : items.length;
                mate = Array.newInstance(clazz.isArray() ? clazz.getComponentType() : Object.class, size);
            }
            else if (clazz.isEnum())
            {
                mate = getEnum(clazz, jsonObj);
            }
            else if (Enum.class.isAssignableFrom(clazz)) // anonymous subclass of an enum
            {
                mate = getEnum(clazz.getSuperclass(), jsonObj);
            }
            else if (EnumSet.class.isAssignableFrom(clazz)) // anonymous subclass of an enum
            {
                mate = getEnumSet(clazz, jsonObj);
            }
            else if ((mate = coerceCertainTypes(clazz.getName())) != null)
            {   // if coerceCertainTypes() returns non-null, it did the work
            }
            else if (clazz == Object.class && !useMapsLocal)
            {
                if (unknownClass == null)
                {
                    mate = new JsonObject();
                    ((JsonObject)mate).type = Map.class.getName();
                }
                else if (unknownClass instanceof String)
                {
                    mate = newInstance(MetaUtils.classForName(((String)unknownClass).trim(), reader.getClassLoader()), jsonObj);
                }
                else
                {
                    throw new JsonIoException("Unable to determine object type at column: " + jsonObj.col + ", line: " + jsonObj.line + ", content: " + jsonObj);
                }
            }
            else
            {
                mate = newInstance(clazz, jsonObj);
            }
        }
        jsonObj.target = mate;
        return jsonObj.target;
    }
protected Object createJavaObjectInstance(Class clazz, JsonObject jsonObj)
    {
        final boolean useMapsLocal = useMaps;
        String type = jsonObj.type;

        // We can't set values to an Object, so well try to use the contained type instead
		if ("java.lang.Object".equals(type))
        {
			Object value = jsonObj.get("value");
        	if (jsonObj.keySet().size() == 1 && value != null)
            {
        		type = value.getClass().getName();
        	}
        }

        Object mate;

        // @type always takes precedence over inferred Java (clazz) type.
        if (type != null)
        {    // @type is explicitly set, use that as it always takes precedence
            Class c;
            try
            {
                c = MetaUtils.classForName(type, reader.getClassLoader(), failOnUnknownType);
            }
            catch (Exception e)
            {
                if (useMapsLocal)
                {
                    jsonObj.type = null;
                    jsonObj.target = null;
                    return jsonObj;
                }
                else
                {
                    String name = clazz == null ? "null" : clazz.getName();
                    throw new JsonIoException("Unable to create class: " + name, e);
                }
            }
            if (c.isArray())
            {    // Handle []
                Object[] items = jsonObj.getArray();
                int size = (items == null) ? 0 : items.length;
                if (c == char[].class)
                {
                    jsonObj.moveCharsToMate();
                    mate = jsonObj.target;
                }
                else
                {
                    mate = Array.newInstance(c.getComponentType(), size);
                }
            }
            else
            {    // Handle regular field.object reference
                if (MetaUtils.isPrimitive(c))
                {
                    mate = MetaUtils.convert(c, jsonObj.get("value"));
                }
                else if (c == Class.class)
                {
                    mate = MetaUtils.classForName((String) jsonObj.get("value"), reader.getClassLoader());
                }
                else if (c.isEnum())
                {
                    mate = getEnum(c, jsonObj);
                }
                else if (Enum.class.isAssignableFrom(c)) // anonymous subclass of an enum
                {
                    mate = getEnum(c.getSuperclass(), jsonObj);
                }
                else if (EnumSet.class.isAssignableFrom(c))
                {
                    mate = getEnumSet(c, jsonObj);
                }
                else if ((mate = coerceCertainTypes(c.getName())) != null)
                {   // if coerceCertainTypes() returns non-null, it did the work
                }
                else
                {
                    mate = newInstance(c, jsonObj);
                }
            }
        }
        else
        {    // @type, not specified, figure out appropriate type
            Object[] items = jsonObj.getArray();

            // if @items is specified, it must be an [] type.
            // if clazz.isArray(), then it must be an [] type.
            if (clazz.isArray() || (items != null && clazz == Object.class && !jsonObj.containsKey("@keys")))
            {
                int size = (items == null) ? 0 : items.length;
                mate = Array.newInstance(clazz.isArray() ? clazz.getComponentType() : Object.class, size);
            }
            else if (clazz.isEnum())
            {
                mate = getEnum(clazz, jsonObj);
            }
            else if (Enum.class.isAssignableFrom(clazz)) // anonymous subclass of an enum
            {
                mate = getEnum(clazz.getSuperclass(), jsonObj);
            }
            else if (EnumSet.class.isAssignableFrom(clazz)) // anonymous subclass of an enum
            {
                mate = getEnumSet(clazz, jsonObj);
            }
            else if ((mate = coerceCertainTypes(clazz.getName())) != null)
            {   // if coerceCertainTypes() returns non-null, it did the work
            }
            else if (clazz == Object.class && !useMapsLocal)
            {
                if (unknownClass == null)
                {
                    mate = new JsonObject();
                    ((JsonObject)mate).type = Map.class.getName();
                }
                else if (unknownClass instanceof String)
                {
                    mate = newInstance(MetaUtils.classForName(((String)unknownClass).trim(), reader.getClassLoader()), jsonObj);
                }
                else
                {
                    throw new JsonIoException("Unable to determine object type at column: " + jsonObj.col + ", line: " + jsonObj.line + ", content: " + jsonObj);
                }
            }
            else
            {
                mate = newInstance(clazz, jsonObj);
            }
        }
        jsonObj.target = mate;
        return jsonObj.target;
    }
protected Object createJavaObjectInstance ( Class clazz , JsonObject jsonObj ) { final boolean useMapsLocal = useMaps ; String type = jsonObj . type ; // We can't set values to an Object, so well try to use the contained type instead if ( "java.lang.Object" . equals ( type ) ) { Object value = jsonObj . get ( "value" ) ; if ( jsonObj . keySet ( ) . size ( ) == 1 && value != null ) { type = value . getClass ( ) . getName ( ) ; } } Object mate ; // @type always takes precedence over inferred Java (clazz) type. if ( type != null ) { // @type is explicitly set, use that as it always takes precedence Class c ; try { c = MetaUtils . classForName ( type , reader . getClassLoader ( ) , failOnUnknownType ) ; } catch ( Exception e ) { if ( useMapsLocal ) { jsonObj . type = null ; jsonObj . target = null ; return jsonObj ; } else { String name = clazz == null ? "null" : clazz . getName ( ) ; throw new JsonIoException ( "Unable to create class: " + name , e ) ; } } if ( c . isArray ( ) ) { // Handle [] Object [ ] items = jsonObj . getArray ( ) ; int size = ( items == null ) ? 0 : items . length ; if ( c == char [ ] . class ) { jsonObj . moveCharsToMate ( ) ; mate = jsonObj . target ; } else { mate = Array . newInstance ( c . getComponentType ( ) , size ) ; } } else { // Handle regular field.object reference if ( MetaUtils . isPrimitive ( c ) ) { mate = MetaUtils . convert ( c , jsonObj . get ( "value" ) ) ; } else if ( c == Class . class ) { mate = MetaUtils . classForName ( ( String ) jsonObj . get ( "value" ) , reader . getClassLoader ( ) ) ; } else if ( c . isEnum ( ) ) { mate = getEnum ( c , jsonObj ) ; } else if ( Enum . class . isAssignableFrom ( c ) ) // anonymous subclass of an enum { mate = getEnum ( c . getSuperclass ( ) , jsonObj ) ; } else if ( EnumSet . class . isAssignableFrom ( c ) ) { mate = getEnumSet ( c , jsonObj ) ; } else if ( ( mate = coerceCertainTypes ( c . getName ( ) ) ) != null ) { // if coerceCertainTypes() returns non-null, it did the work } else { mate = newInstance ( c , jsonObj ) ; } } } else { // @type, not specified, figure out appropriate type Object [ ] items = jsonObj . getArray ( ) ; // if @items is specified, it must be an [] type. // if clazz.isArray(), then it must be an [] type. if ( clazz . isArray ( ) || ( items != null && clazz == Object . class && ! jsonObj . containsKey ( "@keys" ) ) ) { int size = ( items == null ) ? 0 : items . length ; mate = Array . newInstance ( clazz . isArray ( ) ? clazz . getComponentType ( ) : Object . class , size ) ; } else if ( clazz . isEnum ( ) ) { mate = getEnum ( clazz , jsonObj ) ; } else if ( Enum . class . isAssignableFrom ( clazz ) ) // anonymous subclass of an enum { mate = getEnum ( clazz . getSuperclass ( ) , jsonObj ) ; } else if ( EnumSet . class . isAssignableFrom ( clazz ) ) // anonymous subclass of an enum { mate = getEnumSet ( clazz , jsonObj ) ; } else if ( ( mate = coerceCertainTypes ( clazz . getName ( ) ) ) != null ) { // if coerceCertainTypes() returns non-null, it did the work } else if ( clazz == Object . class && ! useMapsLocal ) { if ( unknownClass == null ) { mate = new JsonObject ( ) ; ( ( JsonObject ) mate ) . type = Map . class . getName ( ) ; } else if ( unknownClass instanceof String ) { mate = newInstance ( MetaUtils . classForName ( ( ( String ) unknownClass ) . trim ( ) , reader . getClassLoader ( ) ) , jsonObj ) ; } else { throw new JsonIoException ( "Unable to determine object type at column: " + jsonObj . col + ", line: " + jsonObj . line + ", content: " + jsonObj ) ; } } else { mate = newInstance ( clazz , jsonObj ) ; } } jsonObj . target = mate ; return jsonObj . target ; }
This method creates a Java Object instance based on the passed in parameters.
If the JsonObject contains a key '@type' then that is used, as the type was explicitly
set in the JSON stream.  If the key '@type' does not exist, then the passed in Class
is used to create the instance, handling creating an Array or regular Object
instance.
<br>
The '@type' is not often specified in the JSON input stream, as in many
cases it can be inferred from a field reference or array component type.

@param clazz   Instance will be create of this class.
@param jsonObj Map-of-Map representation of object to create.
@return a new Java object of the appropriate type (clazz) using the jsonObj to provide
enough hints to get the right class instantiated.  It is not populated when returned.
This method creates a Java Object instance based on the passed in parameters . If the JsonObject contains a key @type then that is used as the type was explicitly set in the JSON stream . If the key @type does not exist then the passed in Class is used to create the instance handling creating an Array or regular Object instance . <br > The @type is not often specified in the JSON input stream as in many cases it can be inferred from a field reference or array component type .