Package com.google.gwt.query.vm

Source Code of com.google.gwt.query.vm.JsonFactoryJre$JsonBuilderHandler

package com.google.gwt.query.vm;

import java.lang.reflect.Array;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Proxy;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.gwt.query.client.IsProperties;
import com.google.gwt.query.client.Function;
import com.google.gwt.query.client.Properties;
import com.google.gwt.query.client.builders.JsonBuilder;
import com.google.gwt.query.client.builders.JsonFactory;
import com.google.gwt.query.client.builders.Name;
import com.google.gwt.query.rebind.JsonBuilderGenerator;

public class JsonFactoryJre implements JsonFactory  {

  static JsonFactoryJre jsonFactory = new JsonFactoryJre();

  public static class JsonBuilderHandler implements InvocationHandler {
    private JSONObject jsonObject;

    public JsonBuilderHandler() {
      jsonObject = new JSONObject();
    }

    public JsonBuilderHandler(JSONObject j) {
       jsonObject = j;
    }

    public JsonBuilderHandler(String payload) throws Throwable {
      jsonObject = new JSONObject(payload);
    }

    @SuppressWarnings("unchecked")
    private <T> Object jsonArrayToList(JSONArray j, Class<T> ctype, boolean isArray) {
      List<T> l = new ArrayList<T>();
      for (int i = 0; j != null && i < j.length() ; i++) {
        l.add((T)getValue(j, i, null, null, ctype, null));
      }
      return l.isEmpty() ? null : isArray ? l.toArray((T[])Array.newInstance(ctype, l.size())) : l;
    }

    private Object getValue(JSONArray arr, int idx, JSONObject obj, String attr, Class<?> clz, Method method) {
      Object ret = null;
      try {
        if (clz.isArray() || clz.equals(List.class)) {
          Class<?> ctype = Object.class;
          if (clz.isArray()) {
            ctype = clz.getComponentType();
          } else {
            Type returnType = method.getGenericReturnType();
            if (returnType instanceof ParameterizedType) {
              ctype = (Class<?>)((ParameterizedType) returnType).getActualTypeArguments()[0];
            }
          }
          ret = jsonArrayToList(obj.getJSONArray(attr), ctype, clz.isArray());
        } else if (clz.equals(Date.class)) {
          ret = new Date(obj != null ? obj.getLong(attr): arr.getLong(idx));
        } else if (clz.equals(Boolean.class) || clz.isPrimitive() && clz == Boolean.TYPE) {
          try {
            ret = obj != null ? obj.getBoolean(attr): arr.getBoolean(idx);
          } catch (Exception e) {
            return Boolean.FALSE;
          }
        } else if (clz.equals(Byte.class) || clz.equals(Short.class) || clz.equals(Integer.class)
            || clz.isPrimitive() && (clz == Byte.TYPE || clz == Short.TYPE || clz == Integer.TYPE)) {
          try {
            ret = obj != null ? obj.getInt(attr): arr.getInt(idx);
          } catch (Exception e) {
            return 0;
          }
        } else if (clz.equals(Double.class) || clz.equals(Float.class)
            || clz.isPrimitive() && (clz == Double.TYPE || clz == Float.TYPE)) {
          try {
            ret = obj != null ? obj.getDouble(attr): arr.getDouble(idx);
          } catch (Exception e) {
            return .0;
          }
        } else if (clz.equals(Long.class)
            || clz.isPrimitive() && clz == Long.TYPE) {
          try {
            ret = obj != null ? obj.getLong(attr): arr.getLong(idx);
          } catch (Exception e) {
            return 0l;
          }
        } else {
          ret = obj != null ? obj.get(attr): arr.get(idx);
          if (ret == JSONObject.NULL ) {
            // org.json returns an Null object instead of null when parsing.
            ret = null;
          } else if (clz.equals(String.class)) {
            ret = String.valueOf(ret);
          } else if (ret instanceof JSONObject) {
            if (clz == Object.class) {
              ret = jsonFactory.createBinder((JSONObject)ret);
            } else if (IsProperties.class.isAssignableFrom(clz) && !clz.isAssignableFrom(ret.getClass())) {
              ret = jsonFactory.create(clz, (JSONObject)ret);
            }
          } else if (ret instanceof Number) {
            // Javascript always returns a double
            ret = Double.valueOf(((Number) ret).doubleValue());
          }
        }
      } catch (JSONException e) {
      }
      return ret;
    }

    private <T> JSONArray listToJsonArray(Object...l) throws Throwable {
      JSONArray ret = new JSONArray();
      for (Object o: l) {
        setValue(ret, null, null, o, null);
      }
      return ret;
    }

    private Object setValue(JSONArray arr, JSONObject obj, String attr, Object o, Method method) {
      try {
        if (o == null) {
          return o;
        }
        if (o instanceof String) {
          return obj != null ? obj.put(attr, o) : arr.put(o);
        } else if (o instanceof Boolean) {
          return obj != null ? obj.put(attr, o) : arr.put(o);
        } else if (o instanceof Number) {
          return obj != null ? obj.put(attr, o) : arr.put(o);
        } else if (o instanceof Date) {
          return obj != null ? obj.put(attr, ((Date) o).getTime()) : arr.put(((Date) o).getTime());
        } else if (o instanceof IsProperties) {
          return obj != null ? obj.put(attr, ((IsProperties) o).getDataImpl()) : arr.put(((IsProperties) o).getDataImpl());
        } else if (o.getClass().isArray() || o instanceof List) {
          Object[] arg;
          if (o.getClass().isArray()) {
            arg = (Object[])o;
          } else {
            arg = ((List<?>)o).toArray();
          }
          JSONArray a = listToJsonArray(arg);
          return obj != null ? obj.put(attr, a) : arr.put(a);
        } else {
          if (!(o instanceof Function) && !(o instanceof JSONObject)) {
            System.out.println("Unkown setter object " + attr + " " + o.getClass().getName() + " " + o);
          }
          return obj != null ? obj.put(attr, o) : arr.put(o);
        }
      } catch (Throwable e) {
        e.printStackTrace();
      }
      return null;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      String mname = method.getName();
      Class<?>[] classes = method.getParameterTypes();
      int largs = classes.length;

      Name name = method.getAnnotation(Name.class);
      String attr = name != null ? name.value() : deCapitalize(mname.replaceFirst("^[gs]et", ""));

      if ("getFieldNames".equals(mname)) {
        return JSONObject.getNames(jsonObject);
      } else if ("as".equals(mname)) {
        Class<? extends JsonBuilder> clz = (Class<? extends JsonBuilder>)args[0];
        return jsonFactory.create(clz, jsonObject);
      } else if ("getJsonName".equals(mname)) {
        return JsonBuilderGenerator.classNameToJsonName(getDataBindingClassName(proxy.getClass()));
      } else if (mname.matches("getProperties|getDataImpl")) {
        return jsonObject;
      } else if (largs > 0 && ("parse".equals(mname) || "load".equals(mname))) {
        String json = String.valueOf(args[0]);
        if (largs > 1 && Boolean.TRUE.equals(args[0])) {
          json = Properties.wrapPropertiesString(json);
        }
        jsonObject = new JSONObject(json);
      } else if (mname.matches("toString")) {
        return jsonObject.toString();
      } else if (mname.matches("toJsonWithName")) {
        String jsonName = JsonBuilderGenerator.classNameToJsonName(getDataBindingClassName(proxy.getClass()));
        return "{\"" + jsonName + "\":"+ jsonObject.toString() + "}";
      } else if (mname.matches("toJson")) {
        return jsonObject.toString() ;
      } else if ("toQueryString".equals(mname)) {
        return param(jsonObject);
      } else if (largs == 1 && mname.equals("get")) {
        Class<?> ret = method.getReturnType();
        attr = String.valueOf(args[0]);
        return getValue(null, 0, jsonObject, attr, ret, method);
      } else if (largs == 0 || mname.startsWith("get")) {
        Class<?> ret = method.getReturnType();
        return getValue(null, 0, jsonObject, attr, ret, method);
      } else if (largs == 2 && mname.equals("set")) {
        setValue(null, jsonObject, String.valueOf(args[0]), args[1], method);
        return proxy;
      } else if (largs == 1 || mname.startsWith("set")) {
        setValue(null, jsonObject, attr, args[0], method);
        return proxy;
      }
      return null;
    }
   
    private String deCapitalize(String s) {
      return s != null && s.length() > 0 ? s.substring(0, 1).toLowerCase() + s.substring(1) : s;
    }

    private String getDataBindingClassName(Class<?> type) {
      for (Class<?> c : type.getInterfaces()) {
        if (c.equals(JsonBuilder.class)) {
          return type.getName();
        } else {
          return getDataBindingClassName(c);
        }
      }
      return null;
    }
   
    private String param(JSONObject o) {
      String ret = "";
      for (String k : JSONObject.getNames(o)) {
        ret += ret.isEmpty() ? "" : "&";
        JSONObject p = null;
        JSONArray a = null;
        String s = null;
        try {
          a = o.getJSONArray(k);
        } catch (Exception e) {
        }
        if (a != null) {
          for (int i = 0, l = a.length(); i < l ; i++) {
            ret += i > 0 ? "&" : "";
            try {
              p = a.getJSONObject(i);
            } catch (Exception e) {
              try {
                s = String.valueOf(a.get(i));
              } catch (Exception d) {
              }
            }
            if (p != null) {
              ret += k + "[]=" + p.toString();
            } else if (s != null){
              ret += k + "[]=" + s;
            }
          }
        } else {
          try {
            p = o.getJSONObject(k);
          } catch (Exception e) {
            try {
              s = String.valueOf(o.get(k));
            } catch (Exception d) {
            }
          }
          if (p != null) {
            ret += k + "=" + p.toString();
          } else if (s != null) {
            if (!"null".equalsIgnoreCase(s)) {
              ret += k + "=" + s;
            }
          }
        }
      }
      return ret;
    }
  }

  @SuppressWarnings("unchecked")
  public <T> T create(Class<T> clz, JSONObject jso) {
    InvocationHandler handler = new JsonBuilderHandler(jso);
    return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] {clz}, handler);
  }

  @SuppressWarnings("unchecked")
  public <T extends JsonBuilder> T create(Class<T> clz) {
    InvocationHandler handler = new JsonBuilderHandler();
    return (T) Proxy.newProxyInstance(clz.getClassLoader(), new Class[] {clz}, handler);
  }
 
  public IsProperties createBinder() {
    InvocationHandler handler = new JsonBuilderHandler();
    return (IsProperties)Proxy.newProxyInstance(IsProperties.class.getClassLoader(), new Class[] {IsProperties.class}, handler);
  }
 
  public IsProperties createBinder(JSONObject jso) {
    InvocationHandler handler = new JsonBuilderHandler(jso);
    return (IsProperties)Proxy.newProxyInstance(IsProperties.class.getClassLoader(), new Class[] {IsProperties.class}, handler);
  }

  @Override
  public IsProperties create(String s) {
    IsProperties ret = createBinder();
    ret.parse(s);
    return ret;
  }

  @Override
  public IsProperties create() {
    return createBinder();
  }
}
TOP

Related Classes of com.google.gwt.query.vm.JsonFactoryJre$JsonBuilderHandler

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.