You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by do...@apache.org on 2008/06/12 02:54:53 UTC

svn commit: r666937 - in /incubator/shindig/trunk/java/social-api/src: main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java

Author: doll
Date: Wed Jun 11 17:54:52 2008
New Revision: 666937

URL: http://svn.apache.org/viewvc?rev=666937&view=rev
Log:
Improved the BeanJsonConverter so that it handles converting json to a Map. Includes test. 

Note: There is a todo in the code for fetching the generic types from the Map class (which is why I didn't write this code the first time). Right now the converter assumes the Map is just String to String which definitely won't work in all cases. The simple workaround is to just make a pojo class with a Map inside so that the code can fetch the generics. 


Modified:
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java?rev=666937&r1=666936&r2=666937&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/util/BeanJsonConverter.java Wed Jun 11 17:54:52 2008
@@ -17,26 +17,23 @@
  */
 package org.apache.shindig.social.opensocial.util;
 
-import org.apache.shindig.social.opensocial.model.MediaItem;
-
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.lang.reflect.Type;
 import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.Date;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Iterator;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
 /**
  * Converts pojos to json objects
  * TODO: Replace with standard library
@@ -162,53 +159,55 @@
   public <T> T convertToObject(String json, Class<T> className) {
     String errorMessage = "Could not convert " + json + " to " + className;
 
-    T pojo;
     try {
-      pojo = className.newInstance();
-    } catch (InstantiationException e) {
-      throw new RuntimeException(errorMessage);
+      T pojo = className.newInstance();
+      return convertToObjectPrivate(json, pojo);
+    } catch (JSONException e) {
+      throw new RuntimeException(errorMessage, e);
+    } catch (InvocationTargetException e) {
+      throw new RuntimeException(errorMessage, e);
     } catch (IllegalAccessException e) {
-      throw new RuntimeException(errorMessage);
+      throw new RuntimeException(errorMessage, e);
+    } catch (InstantiationException e) {
+      throw new RuntimeException(errorMessage, e);
     }
+  }
+
+  private <T> T convertToObjectPrivate(String json, T pojo)
+      throws JSONException, InvocationTargetException, IllegalAccessException,
+      InstantiationException {
 
     if (pojo instanceof String) {
-      return (T) json; // This is a weird cast...
+      pojo = (T) json; // This is a weird cast...
+
+    } else if (pojo instanceof Map) {
+      Type[] types = pojo.getClass().getTypeParameters();
+      // TODO: Figure out how to get the actual generic type for the
+      // second Map parameter. Right now we are hardcoding to String
+      Class<?> mapValueClass = String.class;
+
+      JSONObject jsonObject = new JSONObject(json);
+      Iterator iterator = jsonObject.keys();
+      while (iterator.hasNext()) {
+        String key = (String) iterator.next();
+        Object value = convertToObject(jsonObject.getString(key), mapValueClass);
+        ((Map<String, Object>) pojo).put(key, value);
+      }
 
     } else if (pojo instanceof List) {
       // TODO: process as a JSONArray
       throw new UnsupportedOperationException("We don't support lists as a " +
-          "base json type yet.");
+          "base json type yet. You can put it inside a pojo for now.");
 
     } else {
-      JSONObject jsonObject;
-      try {
-        jsonObject = new JSONObject(json);
-        return convertToObject(jsonObject, className);
-      } catch (JSONException e) {
-        throw new RuntimeException(errorMessage);
-      } catch (InvocationTargetException e) {
-        throw new RuntimeException(errorMessage);
-      } catch (IllegalAccessException e) {
-        throw new RuntimeException(errorMessage);
-      } catch (InstantiationException e) {
-        throw new RuntimeException(errorMessage);
-
-      }
-    }
-  }
-
-  public <T> T convertToObject(JSONObject jsonObject, Class<T> className)
-      throws JSONException, InvocationTargetException, IllegalAccessException,
-      InstantiationException {
-    T pojo = className.newInstance();
-
-    List<MethodPair> methods = getMatchingMethods(pojo, SETTER);
-    for (MethodPair setter : methods) {
-      if (jsonObject.has(setter.fieldName)) {
-        callSetterWithValue(pojo, setter.method, jsonObject, setter.fieldName);
+      JSONObject jsonObject = new JSONObject(json);
+      List<MethodPair> methods = getMatchingMethods(pojo, SETTER);
+      for (MethodPair setter : methods) {
+        if (jsonObject.has(setter.fieldName)) {
+          callSetterWithValue(pojo, setter.method, jsonObject, setter.fieldName);
+        }
       }
     }
-
     return pojo;
   }
 
@@ -225,7 +224,7 @@
       Class<?> listElementClass
           = (Class) genericListType.getActualTypeArguments()[0];
 
-      List list = Lists.newArrayList();
+      List<Object> list = Lists.newArrayList();
       JSONArray jsonArray = jsonObject.getJSONArray(fieldName);
       for (int i = 0; i < jsonArray.length(); i++) {
         list.add(convertToObject(jsonArray.getString(i), listElementClass));

Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java?rev=666937&r1=666936&r2=666937&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/BeanJsonConverterTest.java Wed Jun 11 17:54:52 2008
@@ -28,6 +28,7 @@
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
+import com.google.inject.TypeLiteral;
 import junit.framework.TestCase;
 import org.json.JSONArray;
 import org.json.JSONObject;
@@ -195,7 +196,7 @@
     assertEquals("video", actualItem.getType().toString());
   }
 
-  public void testJsonToMap() throws Exception {
+  public void testJsonToData() throws Exception {
     String jsonActivity = "{personId : 'john.doe', " +
         "appdata : {count : 0, favoriteColor : 'yellow'}}";
     DataCollection.Data result = beanJsonConverter.convertToObject(jsonActivity,
@@ -215,4 +216,22 @@
     }
   }
 
+  public void testJsonToMap() throws Exception {
+    String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";
+    Map<String, String> data = Maps.newHashMap();
+    data = beanJsonConverter.convertToObject(jsonActivity,
+        (Class<Map<String, String>>) data.getClass());
+
+    assertEquals(2, data.size());
+
+    for (String key : data.keySet()) {
+      String value = data.get(key);
+      if (key.equals("count")) {
+        assertEquals("0", value);
+      } else if (key.equals("favoriteColor")) {
+        assertEquals("yellow", value);
+      }
+    }
+  }
+
 }