diff --git a/src/main/java/com/ecwid/mailchimp/internal/gson/MailChimpObjectTypeAdapter.java b/src/main/java/com/ecwid/mailchimp/internal/gson/MailChimpObjectTypeAdapter.java index ec80801..31ff874 100644 --- a/src/main/java/com/ecwid/mailchimp/internal/gson/MailChimpObjectTypeAdapter.java +++ b/src/main/java/com/ecwid/mailchimp/internal/gson/MailChimpObjectTypeAdapter.java @@ -37,102 +37,111 @@ */ class MailChimpObjectTypeAdapter extends TypeAdapter { - static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { - @Override - @SuppressWarnings("unchecked") - public TypeAdapter create(Gson gson, TypeToken type) { - if (MailChimpObject.class.isAssignableFrom(type.getRawType())) { - return (TypeAdapter) new MailChimpObjectTypeAdapter(gson, (TypeToken) type); - } else { - return null; - } - } - }; - - private final Gson gson; - private final Constructor constructor; - - @SuppressWarnings("unchecked") - private MailChimpObjectTypeAdapter(Gson gson, TypeToken type) { - this.gson = gson; - - try { - this.constructor = ((Class) type.getRawType()).getDeclaredConstructor(); - this.constructor.setAccessible(true); - } catch(NoSuchMethodException e) { - throw new IllegalArgumentException("No no-arg counstructor found in "+type.getRawType()); - } - } - - @Override - public void write(JsonWriter out, MailChimpObject value) throws IOException { - gson.getAdapter(Map.class).write(out, value); - } - - @Override - public MailChimpObject read(JsonReader in) throws IOException { - if (in.peek() == JsonToken.NULL) { - in.nextNull(); - return null; - } - - MailChimpObject result; - try { - result = constructor.newInstance(); - } catch(Exception e) { - throw new RuntimeException("Failed to invoke " + constructor + " with no args", e); - } - - in.beginObject(); - while (in.hasNext()) { - final String key; - if (in.peek() == JsonToken.NAME) { - key = in.nextName(); - } else { - key = in.nextString(); - } - - final Object value; - - Type valueType = result.getReflectiveMappingTypes().get(key); - if (valueType != null) { - value = gson.getAdapter(TypeToken.get(valueType)).read(in); - } else { - if (in.peek() == JsonToken.BEGIN_OBJECT) { - value = gson.getAdapter(MailChimpObject.class).read(in); - } else if(in.peek() == JsonToken.BEGIN_ARRAY) { - value = readList(in); - } else { - value = gson.getAdapter(Object.class).read(in); - } - } - - if (result.put(key, value) != null) { - throw new JsonSyntaxException("duplicate key: " + key); - } - } - in.endObject(); - - return result; - } - - private List readList(JsonReader in) throws IOException { - List result = new ArrayList(); - in.beginArray(); - while(in.peek() != JsonToken.END_ARRAY) { - final Object element; - - if (in.peek() == JsonToken.BEGIN_OBJECT) { - element = gson.getAdapter(MailChimpObject.class).read(in); - } else if(in.peek() == JsonToken.BEGIN_ARRAY) { - element = readList(in); - } else { - element = gson.getAdapter(Object.class).read(in); - } - - result.add(element); - } - in.endArray(); - return result; - } + static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() { + @Override + @SuppressWarnings("unchecked") + public TypeAdapter create(Gson gson, TypeToken type) { + if (MailChimpObject.class.isAssignableFrom(type.getRawType())) { + return (TypeAdapter) new MailChimpObjectTypeAdapter(gson, (TypeToken) type); + } else { + return null; + } + } + }; + + private final Gson gson; + private final Constructor constructor; + + @SuppressWarnings("unchecked") + private MailChimpObjectTypeAdapter(Gson gson, TypeToken type) { + this.gson = gson; + + try { + this.constructor = ((Class) type.getRawType()).getDeclaredConstructor(); + this.constructor.setAccessible(true); + } catch(NoSuchMethodException e) { + throw new IllegalArgumentException("No no-arg counstructor found in "+type.getRawType()); + } + } + + @Override + public void write(JsonWriter out, MailChimpObject value) throws IOException { + gson.getAdapter(Map.class).write(out, value); + } + + @Override + public MailChimpObject read(JsonReader in) throws IOException { + if (in.peek() == JsonToken.NULL) { + in.nextNull(); + return null; + } + + MailChimpObject result; + try { + result = constructor.newInstance(); + } catch(Exception e) { + throw new RuntimeException("Failed to invoke " + constructor + " with no args", e); + } + + if (in.peek() == JsonToken.BEGIN_ARRAY) { + in.beginArray(); + if (in.peek() != JsonToken.END_ARRAY) { + throw new IllegalStateException("Expected empty array as empty mailchimp object."); + } + in.endArray(); + return result; + } + + in.beginObject(); + while (in.hasNext()) { + final String key; + if (in.peek() == JsonToken.NAME) { + key = in.nextName(); + } else { + key = in.nextString(); + } + + final Object value; + + Type valueType = result.getReflectiveMappingTypes().get(key); + if (valueType != null) { + value = gson.getAdapter(TypeToken.get(valueType)).read(in); + } else { + if (in.peek() == JsonToken.BEGIN_OBJECT) { + value = gson.getAdapter(MailChimpObject.class).read(in); + } else if(in.peek() == JsonToken.BEGIN_ARRAY) { + value = readList(in); + } else { + value = gson.getAdapter(Object.class).read(in); + } + } + + if (result.put(key, value) != null) { + throw new JsonSyntaxException("duplicate key: " + key); + } + } + in.endObject(); + + return result; + } + + private List readList(JsonReader in) throws IOException { + List result = new ArrayList(); + in.beginArray(); + while(in.peek() != JsonToken.END_ARRAY) { + final Object element; + + if (in.peek() == JsonToken.BEGIN_OBJECT) { + element = gson.getAdapter(MailChimpObject.class).read(in); + } else if(in.peek() == JsonToken.BEGIN_ARRAY) { + element = readList(in); + } else { + element = gson.getAdapter(Object.class).read(in); + } + + result.add(element); + } + in.endArray(); + return result; + } }