package fr.prcaen.externalresources.converter;
import android.support.annotation.Nullable;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import fr.prcaen.externalresources.model.Resource;
import fr.prcaen.externalresources.model.Resources;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Map;
public final class JsonConverter implements Converter {
private static final Gson GSON =
new GsonBuilder().registerTypeAdapter(Resource.class, new ResourceJsonDeserializer())
.create();
@Override @Nullable public Resources fromReader(Reader reader) throws IOException {
JsonObject jsonObject = GSON.fromJson(reader, JsonObject.class);
if (null == jsonObject) {
return null;
}
Resources resources = new Resources();
for (Map.Entry<String, JsonElement> entry : jsonObject.entrySet()) {
Resource resource = GSON.fromJson(entry.getValue(), Resource.class);
if (null != resource) {
resources.add(entry.getKey(), resource);
}
}
return resources;
}
@SuppressWarnings("unused") public Resources fromString(String string) throws IOException {
return fromReader(new StringReader(string));
}
protected static class ResourceJsonDeserializer implements JsonDeserializer<Resource> {
@Override
public Resource deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return get(json, 0);
}
@Nullable private Resource get(JsonElement json, int depth) throws JsonParseException {
if (json.isJsonPrimitive()) {
return get(json.getAsJsonPrimitive());
} else if (json.isJsonArray() && depth == 0) {
ArrayList<Resource> resources = new ArrayList<>();
for (JsonElement element : json.getAsJsonArray()) {
resources.add(get(element, 1));
}
Resource[] resourcesArray = new Resource[resources.size()];
resourcesArray = resources.toArray(resourcesArray);
return new Resource(resources.toArray(resourcesArray));
} else {
return null;
}
}
private Resource get(JsonPrimitive primitive) {
if (primitive.isBoolean()) {
return new Resource(primitive.getAsBoolean());
} else if (primitive.isNumber()) {
return new Resource(primitive.getAsNumber());
} else {
return new Resource(primitive.getAsString());
}
}
}
}