Package com.ecwid.mailchimp.internal.gson

Source Code of com.ecwid.mailchimp.internal.gson.MailChimpObjectTypeAdapter

/*
* Copyright 2012 Ecwid, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ecwid.mailchimp.internal.gson;

import com.ecwid.mailchimp.MailChimpObject;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
*
* @author Vasily Karyaev <v.karyaev@gmail.com>
*/
class MailChimpObjectTypeAdapter extends TypeAdapter<MailChimpObject> {

  static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
    @Override
    @SuppressWarnings("unchecked")
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
      if (MailChimpObject.class.isAssignableFrom(type.getRawType())) {
        return (TypeAdapter<T>) new MailChimpObjectTypeAdapter(gson, (TypeToken<MailChimpObject>) type);
      } else {
        return null;
      }
    }
  };

  private final Gson gson;
  private final Constructor<? extends MailChimpObject> constructor;

  @SuppressWarnings("unchecked")
  private MailChimpObjectTypeAdapter(Gson gson, TypeToken<MailChimpObject> type) {
    this.gson = gson;

    try {
      this.constructor = ((Class<? extends MailChimpObject>) 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<Object> result = new ArrayList<Object>();
    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;
  }
}
TOP

Related Classes of com.ecwid.mailchimp.internal.gson.MailChimpObjectTypeAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.