gson: Why deepCopy is not public?

Is there a reason why the deepCopy methods are not public? I see that they were public for some time in an earlier revision then was made “default” access level but I couldn’t find the reason.

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 27 (1 by maintainers)

Most upvoted comments

Guys please make deepCopy public…

+1 to make the deepCopy public. This feature is naturally expected to be provided by the gson library. There are lot of cases where you just want to take some your JsonObject as a source (or template) for your further manipulations(adding/removing properties, etc) but keeping the original untouched. with deepCopy you don’t need to reinvent a wheel in every of your projects. you simply use it out of the box.

+1 for making deepCopy() public. My code below would alter the source, which I’d like to prevent:

private JsonElement removeAttribute(String attribute, JsonObject source) {
    source.remove(attribute);
    return source;
}

+1 My life would be easier if this were public. I need to perform a large number of String substitutions to a copy of my JsonObject (and it’s many children etc) while leaving the original as I found it.

Here’s my workaround solution:

public class GsonUtils {

    public static JsonObject deepCopy(JsonObject jsonObject) {
        JsonObject result = new JsonObject();

        for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
            if (entry.getValue().isJsonObject()) {
                result.add(entry.getKey(), deepCopy(entry.getValue().getAsJsonObject()));
            } else if (entry.getValue().isJsonArray()) {
                result.add(entry.getKey(), deepCopy(entry.getValue().getAsJsonArray()));
            } else if (entry.getValue().isJsonPrimitive()) {
                result.add(entry.getKey(), new JsonPrimitive(entry.getValue().getAsString()));
            }

        }

        return result;
    }

    private static JsonArray deepCopy(JsonArray jsonArray) {
        JsonArray result = new JsonArray();

        for (JsonElement jsonElement : jsonArray) {
            if (jsonElement.isJsonObject()) {
                result.add(deepCopy(jsonElement.getAsJsonObject()));
            } else if (jsonElement.isJsonArray()) {
                result.add(deepCopy(jsonElement.getAsJsonArray()));
            } else if (jsonElement.isJsonPrimitive()) {
                result.add(new JsonPrimitive(jsonElement.getAsString()));
            }
        }

        return result;
    }
}

+1 deepCopy() should be public, I would use it when merging two JsonObject’s into one when the JsonObjects are settings and default settings… like so…

public static JsonObject merge(String overrideJson, JsonObject defaultObj) {
    return mergeInto((JsonObject)new JsonParser().parse(overrideJson), defaultObj);
}
public static JsonObject merge(JsonObject overrideObj, JsonObject defaultObj) {
    return mergeOverride((JsonObject)deepClone(defaultObj), overrideObj);
}
public static JsonObject mergeOverride(JsonObject targetObj, JsonObject overrideObj) {
    for (Map.Entry<String, JsonElement> entry : overrideObj.entrySet())
            targetObj.add(entry.getKey(), deepClone(entry.getValue()));
    return targetObj;
}
public static JsonObject mergeInto(JsonObject targetObj, JsonObject defaultObj) {
    for (Map.Entry<String, JsonElement> entry : defaultObj.entrySet()) {
        if (targetObj.has(entry.getKey()) == false)
            targetObj.add(entry.getKey(), deepClone(entry.getValue()));
    }
    return targetObj;
}
public static JsonElement deepClone(JsonElement el){
    if (el.isJsonPrimitive() || el.isJsonNull())
        return el;
    if (el.isJsonArray()) {
        JsonArray array = new JsonArray();
        for(JsonElement arrayEl: el.getAsJsonArray())
            array.add(deepClone(arrayEl));
        return array;
    }
    if(el.isJsonObject()) {
        JsonObject obj = new JsonObject();
        for (Map.Entry<String, JsonElement> entry : el.getAsJsonObject().entrySet()) {
            obj.add(entry.getKey(), deepClone(entry.getValue()));
        }
        return obj;
    }
    throw new IllegalArgumentException("JsonElement type " + el.getClass().getName());
}

It’s public now, please close.