private static void assignObjectIds(final Object jsonVal,
            final Map<ReferenceEqualityKey<Object>, JSONObject> objToJSONVal, final ClassFieldCache classFieldCache,
            final Map<ReferenceEqualityKey<JSONReference>, CharSequence> jsonReferenceToId,
            final AtomicInteger objId, final boolean onlySerializePublicFields) {
        if (jsonVal instanceof JSONObject) {
            for (final Entry<String, Object> item : ((JSONObject) jsonVal).items) {
                assignObjectIds(item.getValue(), objToJSONVal, classFieldCache, jsonReferenceToId, objId,
                        onlySerializePublicFields);
            }
        } else if (jsonVal instanceof JSONArray) {
            for (final Object item : ((JSONArray) jsonVal).items) {
                assignObjectIds(item, objToJSONVal, classFieldCache, jsonReferenceToId, objId,
                        onlySerializePublicFields);
            }
        } else if (jsonVal instanceof JSONReference) {
            // Get the referenced (non-JSON) object
            final Object refdObj = ((JSONReference) jsonVal).idObject;
            if (refdObj == null) {
                // Should not happen
                throw ClassGraphException.newClassGraphException("Internal inconsistency");
            }
            // Look up the JSON object corresponding to the referenced object
            final ReferenceEqualityKey<Object> refdObjKey = new ReferenceEqualityKey<>(refdObj);
            final JSONObject refdJsonVal = objToJSONVal.get(refdObjKey);
            if (refdJsonVal == null) {
                // Should not happen
                throw ClassGraphException.newClassGraphException("Internal inconsistency");
            }
            // See if the JSON object has an @Id field
            // (for serialization, typeResolutions can be null)
            final Field annotatedField = classFieldCache.get(refdObj.getClass()).idField;
            CharSequence idStr = null;
            if (annotatedField != null) {
                // Get id value from field annotated with @Id
                try {
                    final Object idObject = annotatedField.get(refdObj);
                    if (idObject != null) {
                        idStr = idObject.toString();
                        refdJsonVal.objectId = idStr;
                    }
                } catch (IllegalArgumentException | IllegalAccessException e) {
                    // Should not happen
                    throw new IllegalArgumentException("Could not access @Id-annotated field " + annotatedField, e);
                }
            }
            if (idStr == null) {
                // No @Id field, or field value is null -- check if ref'd JSON Object already has an id
                if (refdJsonVal.objectId == null) {
                    // Ref'd JSON object doesn't have an id yet -- generate unique integer id
                    idStr = JSONUtils.ID_PREFIX + objId.getAndIncrement() + JSONUtils.ID_SUFFIX;
                    refdJsonVal.objectId = idStr;
                } else {
                    idStr = refdJsonVal.objectId;
                }
            }
            // Link both the JSON representation ob the object to the id
            jsonReferenceToId.put(new ReferenceEqualityKey<>((JSONReference) jsonVal), idStr);
        }
        // if (jsonVal == null) then do nothing
    }
private static void assignObjectIds ( final Object jsonVal , final Map < ReferenceEqualityKey < Object > , JSONObject > objToJSONVal , final ClassFieldCache classFieldCache , final Map < ReferenceEqualityKey < JSONReference > , CharSequence > jsonReferenceToId , final AtomicInteger objId , final boolean onlySerializePublicFields ) { if ( jsonVal instanceof JSONObject ) { for ( final Entry < String , Object > item : ( ( JSONObject ) jsonVal ) . items ) { assignObjectIds ( item . getValue ( ) , objToJSONVal , classFieldCache , jsonReferenceToId , objId , onlySerializePublicFields ) ; } } else if ( jsonVal instanceof JSONArray ) { for ( final Object item : ( ( JSONArray ) jsonVal ) . items ) { assignObjectIds ( item , objToJSONVal , classFieldCache , jsonReferenceToId , objId , onlySerializePublicFields ) ; } } else if ( jsonVal instanceof JSONReference ) { final Object refdObj = ( ( JSONReference ) jsonVal ) . idObject ; if ( refdObj == null ) { throw ClassGraphException . newClassGraphException ( "Internal inconsistency" ) ; } final ReferenceEqualityKey < Object > refdObjKey = new ReferenceEqualityKey < > ( refdObj ) ; final JSONObject refdJsonVal = objToJSONVal . get ( refdObjKey ) ; if ( refdJsonVal == null ) { throw ClassGraphException . newClassGraphException ( "Internal inconsistency" ) ; } final Field annotatedField = classFieldCache . get ( refdObj . getClass ( ) ) . idField ; CharSequence idStr = null ; if ( annotatedField != null ) { try { final Object idObject = annotatedField . get ( refdObj ) ; if ( idObject != null ) { idStr = idObject . toString ( ) ; refdJsonVal . objectId = idStr ; } } catch ( IllegalArgumentException | IllegalAccessException e ) { throw new IllegalArgumentException ( "Could not access @Id-annotated field " + annotatedField , e ) ; } } if ( idStr == null ) { if ( refdJsonVal . objectId == null ) { idStr = JSONUtils . ID_PREFIX + objId . getAndIncrement ( ) + JSONUtils . ID_SUFFIX ; refdJsonVal . objectId = idStr ; } else { idStr = refdJsonVal . objectId ; } } jsonReferenceToId . put ( new ReferenceEqualityKey < > ( ( JSONReference ) jsonVal ) , idStr ) ; } }
Create a unique id for each referenced JSON object.

@param jsonVal
the json val
@param objToJSONVal
a map from obj to JSON val
@param classFieldCache
the class field cache
@param jsonReferenceToId
a map from json reference to id
@param objId
the object id
@param onlySerializePublicFields
whether to only serialize public fields