You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by et...@apache.org on 2009/02/13 00:12:33 UTC

svn commit: r743921 - in /incubator/shindig/trunk/java: common/src/main/java/org/apache/shindig/protocol/ common/src/main/java/org/apache/shindig/protocol/conversion/ common/src/test/java/org/apache/shindig/protocol/ common/src/test/java/org/apache/shi...

Author: etnu
Date: Thu Feb 12 23:12:32 2009
New Revision: 743921

URL: http://svn.apache.org/viewvc?rev=743921&view=rev
Log:
Patch 1 of x for SHINDIG-912.

This patch moves serialization responsibility entirely into JsonSerializer, leaving BeanJsonConverter responsible only for converting JSON to objects.


Modified:
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java
    incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
    incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java
    incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/RestfulCollectionTest.java
    incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/TestHandler.java
    incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanJsonConverterTest.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java

Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/ApiServlet.java Thu Feb 12 23:12:32 2009
@@ -26,13 +26,14 @@
 import com.google.inject.Inject;
 import com.google.inject.name.Named;
 
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 import java.util.Collections;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 /**
  * Common base class for API servlets.
  */

Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/JsonRpcServlet.java Thu Feb 12 23:12:32 2009
@@ -17,22 +17,26 @@
  */
 package org.apache.shindig.protocol;
 
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang.StringUtils;
 import org.apache.shindig.auth.SecurityToken;
+import org.apache.shindig.common.JsonSerializer;
 import org.apache.shindig.common.util.JsonConversionUtil;
 
 import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.Future;
 
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -42,9 +46,8 @@
 public class JsonRpcServlet extends ApiServlet {
 
   @Override
-  protected void doGet(HttpServletRequest servletRequest,
-      HttpServletResponse servletResponse)
-      throws ServletException, IOException {
+  protected void doGet(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
+      throws IOException {
     SecurityToken token = getSecurityToken(servletRequest);
     if (token == null) {
       sendSecurityError(servletResponse);
@@ -61,9 +64,8 @@
   }
 
   @Override
-  protected void doPost(HttpServletRequest servletRequest,
-      HttpServletResponse servletResponse)
-      throws ServletException, IOException {
+  protected void doPost(HttpServletRequest servletRequest, HttpServletResponse servletResponse)
+      throws IOException {
     SecurityToken token = getSecurityToken(servletRequest);
     if (token == null) {
       sendSecurityError(servletResponse);
@@ -105,16 +107,17 @@
 
     // Resolve each Future into a response.
     // TODO: should use shared deadline across each request
-    JSONArray result = new JSONArray();
+    List<Object> result = new ArrayList<Object>(batch.length());
     for (int i = 0; i < batch.length(); i++) {
       JSONObject batchObj = batch.getJSONObject(i);
       String key = null;
       if (batchObj.has("id")) {
         key = batchObj.getString("id");
       }
-      result.put(getJSONResponse(key, getResponseItem(responses.get(i))));
+      result.add(getJSONResponse(key, getResponseItem(responses.get(i))));
     }
-    servletResponse.getWriter().write(result.toString());
+
+    JsonSerializer.append(servletResponse.getWriter(), result);
   }
 
   protected void dispatch(JSONObject request, HttpServletRequest servletRequest,
@@ -125,13 +128,14 @@
     }
 
     // getRpcHandler never returns null
-    Future future = getHandler(request, servletRequest).execute(token, jsonConverter);
+    Future<?> future = getHandler(request, servletRequest).execute(token, jsonConverter);
 
     // Resolve each Future into a response.
     // TODO: should use shared deadline across each request
     ResponseItem response = getResponseItem(future);
-    JSONObject result = getJSONResponse(key, response);
-    servletResponse.getWriter().write(result.toString());
+    Object result = getJSONResponse(key, response);
+
+    JsonSerializer.append(servletResponse.getWriter(), result);
   }
 
   /**
@@ -142,8 +146,8 @@
     return dispatcher.getRpcHandler(rpc);
   }
 
-  private JSONObject getJSONResponse(String key, ResponseItem responseItem) throws JSONException {
-    JSONObject result = new JSONObject();
+  private Object getJSONResponse(String key, ResponseItem responseItem) {
+    Map<String, Object> result = Maps.newHashMap();
     if (key != null) {
       result.put("id", key);
     }
@@ -151,18 +155,18 @@
       result.put("error", getErrorJson(responseItem));
     } else {
       Object response = responseItem.getResponse();
-      Object converted = jsonConverter.convertToJson(response);
 
-      if (response instanceof RestfulCollection) {
-        // FIXME this is a little hacky because of the field names in the RestfulCollection
-        ((JSONObject)converted).put("list", ((JSONObject)converted).remove("entry"));
-        result.put("data", converted);
-      } else if (response instanceof DataCollection) {
-        if (((JSONObject)converted).has("entry")) {
-          result.put("data", ((JSONObject)converted).get("entry"));
-        }
+      if (response instanceof DataCollection) {
+        result.put("data", ((DataCollection) response).getEntry());
+      } else if (response instanceof RestfulCollection) {
+        Map<String, Object> map = Maps.newHashMap();
+        RestfulCollection<?> collection = (RestfulCollection<?>) response;
+        map.put("startIndex", collection.getStartIndex());
+        map.put("totalResults", collection.getTotalResults());
+        map.put("list", collection.getEntry());
+        result.put("data", map);
       } else {
-        result.put("data", converted);
+        result.put("data", response);
       }
     }
     return result;
@@ -171,8 +175,8 @@
   // TODO(doll): Refactor the responseItem so that the fields on it line up with this format.
   // Then we can use the general converter to output the response to the client and we won't
   // be harcoded to json.
-  private JSONObject getErrorJson(ResponseItem responseItem) throws JSONException {
-    JSONObject error = new JSONObject();
+  private Object getErrorJson(ResponseItem responseItem) {
+    Map<String, Object> error = new HashMap<String, Object>(2, 1);
     error.put("code", responseItem.getError().getHttpErrorCode());
 
     String message = responseItem.getError().toString();
@@ -186,14 +190,7 @@
   @Override
   protected void sendError(HttpServletResponse servletResponse, ResponseItem responseItem)
       throws IOException {
-    try {
-      JSONObject error = getErrorJson(responseItem);
-      servletResponse.getWriter().write(error.toString());
-    } catch (JSONException je) {
-      // This really shouldn't ever happen
-      servletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
-          "Error generating error response " + je.getMessage());
-    }
+    JsonSerializer.append(servletResponse.getWriter(), getErrorJson(responseItem));
   }
 
   private void sendBadRequest(Throwable t, HttpServletResponse response) throws IOException {

Modified: incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java (original)
+++ incubator/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java Thu Feb 12 23:12:32 2009
@@ -17,10 +17,11 @@
  */
 package org.apache.shindig.protocol.conversion;
 
+import org.apache.shindig.common.JsonProperty;
+import org.apache.shindig.common.JsonSerializer;
 import org.apache.shindig.protocol.model.Enum;
 import org.apache.shindig.protocol.model.EnumImpl;
 
-import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.inject.Inject;
@@ -35,13 +36,11 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.util.Collection;
 import java.util.Date;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Converts pojos to json objects.
@@ -49,16 +48,10 @@
  */
 public class BeanJsonConverter implements BeanConverter {
 
-  private static final Object[] EMPTY_OBJECT = {};
-  private static final Set<String> EXCLUDED_FIELDS = ImmutableSet.of("class", "declaringclass");
-  private static final String GETTER_PREFIX  = "get";
-  private static final String SETTER_PREFIX = "set";
-
-  // Only compute the filtered getters/setters once per-class
-  private static final ConcurrentHashMap<Class,List<MethodPair>> GETTER_METHODS = Maps.newConcurrentHashMap();
-  private static final ConcurrentHashMap<Class,List<MethodPair>> SETTER_METHODS = Maps.newConcurrentHashMap();
+  // Only compute the filtered setters once per-class
+  private static final Map<Class<?>, Map<String, Method>> setters = Maps.newConcurrentHashMap();
 
-  private Injector injector;
+  private final Injector injector;
 
   @Inject
   public BeanJsonConverter(Injector injector) {
@@ -76,141 +69,41 @@
    * @return An object whos toString method will return json
    */
   public String convertToString(final Object pojo) {
-    return convertToJson(pojo).toString();
+    return JsonSerializer.serialize(pojo);
   }
 
-  /**
-   * Convert the passed in object to a json object.
-   *
-   * @param pojo The object to convert
-   * @return An object whos toString method will return json
-   */
-  public Object convertToJson(final Object pojo) {
-    try {
-      return translateObjectToJson(pojo);
-    } catch (JSONException e) {
-      throw new RuntimeException("Could not translate " + pojo + " to json", e);
-    }
-  }
-
-  private Object translateObjectToJson(final Object val) throws JSONException {
-    if (val instanceof Object[]) {
-      JSONArray array = new JSONArray();
-      for (Object asd : (Object[]) val) {
-        array.put(translateObjectToJson(asd));
-      }
-      return array;
-
-    } else if (val instanceof List) {
-      JSONArray list = new JSONArray();
-      for (Object item : (List<?>) val) {
-        list.put(translateObjectToJson(item));
-      }
-      return list;
-
-    } else if (val instanceof Map) {
-      JSONObject map = new JSONObject();
-      Map<?, ?> originalMap = (Map<?, ?>) val;
-
-      for (Entry<?, ?> item : originalMap.entrySet()) {
-        map.put(item.getKey().toString(), translateObjectToJson(item.getValue()));
-      }
-      return map;
-
-    } else if (val != null && val.getClass().isEnum()) {
-      return val.toString();
-    } else if (val instanceof String
-        || val instanceof CharSequence
-        || val instanceof Boolean
-        || val instanceof Integer
-        || val instanceof Date
-        || val instanceof Long
-        || val instanceof Float
-        || val instanceof JSONObject
-        || val instanceof JSONArray
-        || val == null) {
-      return val;
-    }
-
-    return convertMethodsToJson(val);
-  }
+  private static Map<String, Method> getSetters(Object pojo) {
+    Class<?> clazz = pojo.getClass();
 
-  /**
-   * Convert the object to {@link JSONObject} reading Pojo properties
-   *
-   * @param pojo The object to convert
-   * @return A JSONObject representing this pojo
-   */
-  private JSONObject convertMethodsToJson(final Object pojo) {
-    List<MethodPair> availableGetters;
-
-    availableGetters = GETTER_METHODS.get(pojo.getClass());
-    if (availableGetters == null) {
-      availableGetters = getMatchingMethods(pojo, GETTER_PREFIX, false);
-      GETTER_METHODS.putIfAbsent(pojo.getClass(), availableGetters);
+    Map<String, Method> methods = setters.get(clazz);
+    if (methods != null) {
+      return methods;
     }
+    // Ensure consistent method ordering by using a linked hash map.
+    methods = Maps.newHashMap();
 
-    JSONObject toReturn = new JSONObject();
-    for (MethodPair getter : availableGetters) {
-      try {
-        Object val = getter.method.invoke(pojo, EMPTY_OBJECT);
-        if (val != null) {
-          toReturn.put(getter.fieldName, translateObjectToJson(val));
-        }
-      } catch (JSONException e) {
-        throw new RuntimeException(errorMessage(pojo, getter), e);
-      } catch (IllegalAccessException e) {
-        throw new RuntimeException(errorMessage(pojo, getter), e);
-      } catch (InvocationTargetException e) {
-        throw new RuntimeException(errorMessage(pojo, getter), e);
-      } catch (IllegalArgumentException e) {
-        throw new RuntimeException(errorMessage(pojo, getter), e);
+    for (Method method : clazz.getMethods()) {
+      String name = getPropertyName(method);
+      if (name != null) {
+        methods.put(name, method);
       }
     }
-    return toReturn;
-  }
 
-  private static String errorMessage(Object pojo, MethodPair getter) {
-    return "Could not encode the " + getter.method + " method on "
-        + pojo.getClass().getName();
-  }
-
-  private static final class MethodPair {
-    public Method method;
-    public String fieldName;
-
-    protected MethodPair(final Method method, final String fieldName) {
-      this.method = method;
-      this.fieldName = fieldName;
-    }
+    setters.put(clazz, methods);
+    return methods;
   }
 
-
-  private List<MethodPair> getMatchingMethods(Object pojo, String prefix, boolean allowHaveArgs) {
-
-    List<MethodPair> availableGetters = Lists.newArrayList();
-    Method[] methods = pojo.getClass().getMethods();
-    for (Method method : methods) {
+  private static String getPropertyName(Method method) {
+    JsonProperty property = method.getAnnotation(JsonProperty.class);
+    if (property == null) {
       String name = method.getName();
-      if (!method.getName().startsWith(prefix)) {
-        continue;
-      }
-      int prefixlen = prefix.length();
-
-      String fieldName = name.substring(prefixlen, prefixlen+1).toLowerCase() +
-          name.substring(prefixlen + 1);
-
-      if (EXCLUDED_FIELDS.contains(fieldName.toLowerCase())) {
-        continue;
+      if (name.startsWith("set")) {
+        return name.substring(3, 4).toLowerCase() + name.substring(4);
       }
-      if (!allowHaveArgs) {
-        if (method.getParameterTypes().length != 0) {
-          continue;
-        }
-      }
-      availableGetters.add(new MethodPair(method, fieldName));
+      return null;
+    } else {
+      return property.value();
     }
-    return availableGetters;
   }
 
   public <T> T convertToObject(String json, Class<T> className) {
@@ -251,23 +144,16 @@
         ((Map<String, Object>) pojo).put(key, value);
       }
 
-    } else if (pojo instanceof List) {
+    } else if (pojo instanceof Collection) {
       JSONArray array = new JSONArray(json);
       for (int i = 0; i < array.length(); i++) {
-        ((List<Object>) pojo).add(array.get(i));
+        ((Collection<Object>) pojo).add(array.get(i));
       }
     } else {
       JSONObject jsonObject = new JSONObject(json);
-      List<MethodPair> methods;
-      methods = SETTER_METHODS.get(pojo.getClass());
-      if (methods == null) {
-        methods = getMatchingMethods(pojo, SETTER_PREFIX, true);
-        SETTER_METHODS.putIfAbsent(pojo.getClass(), methods);
-      }
-
-      for (MethodPair setter : methods) {
-        if (jsonObject.has(setter.fieldName)) {
-          callSetterWithValue(pojo, setter.method, jsonObject, setter.fieldName);
+      for (Map.Entry<String, Method> setter : getSetters(pojo).entrySet()) {
+        if (jsonObject.has(setter.getKey())) {
+          callSetterWithValue(pojo, setter.getValue(), jsonObject, setter.getKey());
         }
       }
     }
@@ -365,8 +251,9 @@
     } else if (expectedType.equals(Boolean.class) || expectedType.equals(Boolean.TYPE)) {
       value = jsonObject.getBoolean(fieldName);
     } else if (expectedType.equals(Float.class) || expectedType.equals(Float.TYPE)) {
-      String stringFloat = jsonObject.getString(fieldName);
-      value = new Float(stringFloat);
+      value = ((Double) jsonObject.getDouble(fieldName)).floatValue();
+    } else if (expectedType.equals(Double.class) || expectedType.equals(Double.TYPE)) {
+      value = jsonObject.getDouble(fieldName);
     } else {
       // Assume its an injected type
       value = convertToObject(jsonObject.getJSONObject(fieldName).toString(), expectedType);

Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/JsonRpcServletTest.java Thu Feb 12 23:12:32 2009
@@ -17,24 +17,24 @@
  */
 package org.apache.shindig.protocol;
 
+import org.apache.shindig.common.JsonAssert;
 import org.apache.shindig.common.testing.FakeGadgetToken;
 import org.apache.shindig.protocol.conversion.BeanConverter;
 import org.apache.shindig.protocol.conversion.BeanJsonConverter;
 
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Sets;
-
-import junit.framework.TestCase;
 
 import org.easymock.IMocksControl;
 import org.easymock.classextension.EasyMock;
-import org.json.JSONArray;
-import org.json.JSONObject;
+
+import junit.framework.TestCase;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
+import java.util.Collections;
 
 import javax.servlet.ServletInputStream;
 import javax.servlet.http.HttpServletRequest;
@@ -56,8 +56,11 @@
   private BeanConverter xmlConverter;
   protected BeanConverter atomConverter;
 
-  private IMocksControl mockControl = EasyMock.createNiceControl();
+  private final IMocksControl mockControl = EasyMock.createNiceControl();
 
+  private final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+  private final PrintWriter writer = new PrintWriter(stream);
+  private final TestHandler handler = new TestHandler();
 
   @Override protected void setUp() throws Exception {
     servlet = new JsonRpcServlet();
@@ -68,49 +71,50 @@
     atomConverter = mockControl.createMock(BeanConverter.class);
 
     HandlerRegistry registry = new DefaultHandlerRegistry(null,
-        Sets.<Object>newHashSet(new TestHandler()), jsonConverter,
+        Collections.<Object>singleton(handler), jsonConverter,
         new HandlerExecutionListener.NoOpHandlerExecutionListener());
 
     servlet.setHandlerRegistry(registry);
     servlet.setBeanConverters(jsonConverter, xmlConverter, atomConverter);
+    handler.setMock(new TestHandler() {
+      @Override
+      public Object get(RequestItem req) {
+        return ImmutableMap.of("foo", "bar");
+      }
+    });
+  }
+
+  private String getOutput() throws IOException {
+    writer.close();
+    return stream.toString("UTF-8");
   }
 
   public void testMethodRecognition() throws Exception {
     setupRequest("{method:test.get,id:id,params:{userId:5,groupId:@self}}");
 
-    EasyMock.expect(jsonConverter.convertToJson(TestHandler.GET_RESPONSE))
-        .andReturn(new JSONObject(ImmutableMap.of("foo", "bar")));
-
-    JSONObject result = new JSONObject();
-    result.put("id", "id");
-    result.put("data", ImmutableMap.of("foo", "bar"));
-    PrintWriter writerMock = mockControl.createMock(PrintWriter.class);
-    EasyMock.expect(res.getWriter()).andReturn(writerMock);
-    writerMock.write(EasyMock.eq(result.toString()));
+    EasyMock.expect(res.getWriter()).andReturn(writer);
     EasyMock.expectLastCall();
 
     mockControl.replay();
     servlet.service(req, res);
     mockControl.verify();
-    mockControl.reset();
+
+    JsonAssert.assertJsonEquals("{id: 'id', data: {foo:'bar'}}", getOutput());
   }
 
   public void testInvalidService() throws Exception {
-    String json = "{method:junk.get,id:id,params:{userId:5,groupId:@self}}";
-    setupRequest(json);
+    setupRequest("{method:junk.get,id:id,params:{userId:5,groupId:@self}}");
 
-    JSONObject err = new JSONObject(
-        "{id:id,error:{message:'notImplemented: The method junk.get is not implemented',code:501}}");
-
-    PrintWriter writerMock = mockControl.createMock(PrintWriter.class);
-    EasyMock.expect(res.getWriter()).andReturn(writerMock);
-    writerMock.write(EasyMock.eq(err.toString()));
+    EasyMock.expect(res.getWriter()).andReturn(writer);
     EasyMock.expectLastCall();
 
     mockControl.replay();
     servlet.service(req, res);
     mockControl.verify();
-    mockControl.reset();
+
+    JsonAssert.assertJsonEquals(
+        "{id:id,error:{message:'notImplemented: The method junk.get is not implemented',code:501}}",
+        getOutput());
   }
 
 
@@ -121,38 +125,27 @@
   public void testFailedRequest() throws Exception {
     setupRequest("{id:id,method:test.futureException}");
 
-    JSONObject err = new JSONObject(
-        "{id:id,error:{message:'badRequest: FAILURE_MESSAGE',code:400}}");
-
-    PrintWriter writerMock = mockControl.createMock(PrintWriter.class);
-    EasyMock.expect(res.getWriter()).andReturn(writerMock);
-    writerMock.write(EasyMock.eq(err.toString()));
+    EasyMock.expect(res.getWriter()).andReturn(writer);
     EasyMock.expectLastCall();
 
     mockControl.replay();
     servlet.service(req, res);
-    mockControl.verify();
-    mockControl.reset();
+
+    JsonAssert.assertJsonEquals(
+        "{id:id,error:{message:'badRequest: FAILURE_MESSAGE',code:400}}", getOutput());
   }
 
   public void testBasicBatch() throws Exception {
-    String batchJson =
-        "[{method:test.get,id:'1'},{method:test.get,id:'2'}]";
-    setupRequest(batchJson);
-
-    EasyMock.expect(jsonConverter.convertToJson(TestHandler.GET_RESPONSE))
-        .andStubReturn(new JSONObject(ImmutableMap.of("foo", "bar")));
-
-    JSONArray result = new JSONArray("[{id:'1',data:{foo:'bar'}}," + "{id:'2',data:{foo:'bar'}}]");
-    PrintWriter writerMock = mockControl.createMock(PrintWriter.class);
-    EasyMock.expect(res.getWriter()).andReturn(writerMock);
-    writerMock.write(EasyMock.eq(result.toString()));
+    setupRequest("[{method:test.get,id:'1'},{method:test.get,id:'2'}]");
+
+    EasyMock.expect(res.getWriter()).andReturn(writer);
     EasyMock.expectLastCall();
 
     mockControl.replay();
     servlet.service(req, res);
-    mockControl.verify();
-    mockControl.reset();
+
+    JsonAssert.assertJsonEquals("[{id:'1',data:{foo:'bar'}},{id:'2',data:{foo:'bar'}}]",
+        getOutput());
   }
 
   public void testGetExecution() throws Exception {
@@ -163,19 +156,14 @@
     EasyMock.expect(req.getCharacterEncoding()).andStubReturn("UTF-8");
     res.setCharacterEncoding("UTF-8");
 
-    EasyMock.expect(jsonConverter.convertToJson(TestHandler.GET_RESPONSE))
-        .andReturn(new JSONObject(ImmutableMap.of("foo", "bar")));
-
-    JSONObject result = new JSONObject("{id:'1',data:{foo:'bar'}}");
-    PrintWriter writerMock = mockControl.createMock(PrintWriter.class);
-    EasyMock.expect(res.getWriter()).andReturn(writerMock);
-    writerMock.write(EasyMock.eq(result.toString()));
+    EasyMock.expect(res.getWriter()).andReturn(writer);
     EasyMock.expectLastCall();
 
     mockControl.replay();
     servlet.service(req, res);
     mockControl.verify();
-    mockControl.reset();
+
+    JsonAssert.assertJsonEquals("{id:'1',data:{foo:'bar'}}", getOutput());
   }
 
   private void setupRequest(String json) throws IOException {

Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/RestfulCollectionTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/RestfulCollectionTest.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/RestfulCollectionTest.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/RestfulCollectionTest.java Thu Feb 12 23:12:32 2009
@@ -18,6 +18,7 @@
 package org.apache.shindig.protocol;
 
 import com.google.common.collect.Lists;
+
 import junit.framework.TestCase;
 
 import java.util.List;
@@ -58,4 +59,4 @@
     assertEquals(totalResults, collection.getTotalResults());
   }
 
-}
\ No newline at end of file
+}

Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/TestHandler.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/TestHandler.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/TestHandler.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/TestHandler.java Thu Feb 12 23:12:32 2009
@@ -52,7 +52,7 @@
   }
 
   @Operation(httpMethods = "GET")
-  public String get(RequestItem req) {
+  public Object get(RequestItem req) {
     if (mock != null) {
       return mock.get(req);
     }
@@ -60,7 +60,7 @@
   }
 
   @Operation(httpMethods = "GET", path = "/overridden/method")
-  public String overridden(RequestItem req) {
+  public Object overridden(RequestItem req) {
     if (mock != null) {
       return mock.get(req);
     }
@@ -68,7 +68,7 @@
   }
 
   @Operation(name="override.rpcname", httpMethods = "")
-  public String overriddenRpc(RequestItem req) {
+  public Object overriddenRpc(RequestItem req) {
     if (mock != null) {
       return mock.get(req);
     }

Modified: incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanJsonConverterTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanJsonConverterTest.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanJsonConverterTest.java (original)
+++ incubator/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanJsonConverterTest.java Thu Feb 12 23:12:32 2009
@@ -17,45 +17,28 @@
  */
 package org.apache.shindig.protocol.conversion;
 
-import org.apache.shindig.common.util.JsonConversionUtilTest;
 import org.apache.shindig.protocol.model.TestModel;
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.inject.Guice;
+
 import junit.framework.TestCase;
-import org.json.JSONArray;
-import org.json.JSONObject;
 
 import java.util.ArrayList;
 import java.util.Map;
 import java.util.Map.Entry;
 
 public class BeanJsonConverterTest extends TestCase {
-  private TestModel.Car car;
   private BeanJsonConverter beanJsonConverter;
 
   @Override
   public void setUp() throws Exception {
     super.setUp();
-    car = new TestModel.Car();
     beanJsonConverter = new BeanJsonConverter(Guice.createInjector());
   }
 
-  public void testToJsonOnInheritedClass() throws Exception {
-    TestModel.ExpensiveCar roller = new TestModel.ExpensiveCar();
-    JSONObject result = (JSONObject) beanJsonConverter.convertToJson(roller);
-    assertEquals(roller.getCost(), result.getInt("cost"));
-    assertEquals(roller.getParkingTickets().size(), result.getJSONObject("parkingTickets").length());
-  }
-
-  public void testCarToJson() throws Exception {
-    JSONObject result = (JSONObject) beanJsonConverter.convertToJson(car);
-    JsonConversionUtilTest.assertJsonEquals(new JSONObject(TestModel.Car.DEFAULT_JSON), result);
-  }
-
-
   public void testJsonToCar() throws Exception {
     String carJson = "{engine:[{value:DIESEL},{value:TURBO}],parkingTickets:{SF:$137,NY:'$301'}," +
             "passengers:[{gender:female,name:'Mum'}, {gender:male,name:'Dad'}]}";
@@ -76,49 +59,6 @@
     assertEquals(dad.getName(), "Dad");
   }
 
-  public void testMapsToJson() throws Exception {
-    Map<String, Map<String, String>> map = Maps.newHashMap();
-
-    Map<String, String> item1Map = Maps.newHashMap();
-    item1Map.put("value", "1");
-
-    // Null values shouldn't cause exceptions
-    item1Map.put("value2", null);
-    map.put("item1", item1Map);
-
-    Map<String, String> item2Map = Maps.newHashMap();
-    item2Map.put("value", "2");
-    map.put("item2", item2Map);
-
-    JSONObject jsonMap = (JSONObject) beanJsonConverter.convertToJson(map);
-
-    assertEquals("1", jsonMap.getJSONObject("item1").getString("value"));
-    assertEquals("2", jsonMap.getJSONObject("item2").getString("value"));
-  }
-
-  @SuppressWarnings("unchecked")
-  public void testListsToJson() throws Exception {
-    Map<String, String> item1Map = Maps.newHashMap();
-    item1Map.put("value", "1");
-
-    Map<String, String> item2Map = Maps.newHashMap();
-    item2Map.put("value", "2");
-
-    JSONArray jsonArray = (JSONArray) beanJsonConverter.convertToJson(
-        Lists.newArrayList(item1Map, item2Map));
-
-    assertEquals("1", ((JSONObject) jsonArray.get(0)).getString("value"));
-    assertEquals("2", ((JSONObject) jsonArray.get(1)).getString("value"));
-  }
-
-  public void testArrayToJson() throws Exception {
-    String[] colors = {"blue", "green", "aquamarine"};
-    JSONArray jsonArray = (JSONArray) beanJsonConverter.convertToJson(colors);
-
-    assertEquals(colors.length, jsonArray.length());
-    assertEquals(colors[0], jsonArray.get(0));
-  }
-
   @SuppressWarnings("unchecked")
   public void testJsonToMap() throws Exception {
     String jsonActivity = "{count : 0, favoriteColor : 'yellow'}";

Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java?rev=743921&r1=743920&r2=743921&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/opensocial/util/JsonConverterPerformancePerf.java Thu Feb 12 23:12:32 2009
@@ -17,8 +17,6 @@
  */
 package org.apache.shindig.social.opensocial.util;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.apache.shindig.protocol.conversion.BeanJsonConverter;
 import org.apache.shindig.protocol.conversion.BeanJsonLibConverter;
 import org.apache.shindig.protocol.conversion.jsonlib.JsonLibTestsGuiceModule;
@@ -38,8 +36,11 @@
 import com.google.common.collect.Lists;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import junit.framework.TestCase;
-import org.json.JSONObject;
 
 public class JsonConverterPerformancePerf extends TestCase {
 
@@ -176,42 +177,42 @@
         + average(personStart, personEnd, TEST_SIZE));
   }
 
-  public void testToJsonOnInheritedClassOutput() throws Exception {
-    SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
-    for (int i = 0; i < TEST_SIZE; i++) {
-      spa[i] = new SpecialPerson(String.valueOf(i), "robot", "nonsense");
-    }
-    Runtime r = Runtime.getRuntime();
-    String[] output = new String[TEST_SIZE];
-    r.gc();
-    long memstart = r.totalMemory() - r.freeMemory();
-    long startOutput = System.currentTimeMillis();
-    for (int i = 0; i < TEST_SIZE; i++) {
-      output[i] = ((JSONObject) beanJsonConverter.convertToJson(spa[i])).toString();
-    }
-    long endOutput = System.currentTimeMillis();
-    long memend = r.totalMemory() - r.freeMemory();
-    String[] serializeOutput = new String[TEST_SIZE];
-    char[] source = output[0].toCharArray();
-    r.gc();
-
-    long stringsizeStart = r.totalMemory() - r.freeMemory();
-
-    for (int i = 0; i < TEST_SIZE; i++) {
-      serializeOutput[i] = new String(source);
-    }
-    long stringsizeEnd = r.totalMemory() - r.freeMemory();
-
-    log
-        .info("ORG JSON Lib Output "
-            + average(startOutput, endOutput, TEST_SIZE)
-            + " ms/conversion, "
-            + (average(memstart, memend, TEST_SIZE) - average(stringsizeStart, stringsizeEnd,
-                TEST_SIZE)) + " heap bytes/conversion, output packet consumed on average "
-            + average(stringsizeStart, stringsizeEnd, TEST_SIZE) + " for a string length of "
-            + output[0].length());
-    log.info("Output Was [" + output[0] + ']');
-  }
+//  public void testToJsonOnInheritedClassOutput() throws Exception {
+//    SpecialPerson[] spa = new SpecialPerson[TEST_SIZE];
+//    for (int i = 0; i < TEST_SIZE; i++) {
+//      spa[i] = new SpecialPerson(String.valueOf(i), "robot", "nonsense");
+//    }
+//    Runtime r = Runtime.getRuntime();
+//    String[] output = new String[TEST_SIZE];
+//    r.gc();
+//    long memstart = r.totalMemory() - r.freeMemory();
+//    long startOutput = System.currentTimeMillis();
+//    for (int i = 0; i < TEST_SIZE; i++) {
+//      output[i] = ((JSONObject) beanJsonConverter.convertToJson(spa[i])).toString();
+//    }
+//    long endOutput = System.currentTimeMillis();
+//    long memend = r.totalMemory() - r.freeMemory();
+//    String[] serializeOutput = new String[TEST_SIZE];
+//    char[] source = output[0].toCharArray();
+//    r.gc();
+//
+//    long stringsizeStart = r.totalMemory() - r.freeMemory();
+//
+//    for (int i = 0; i < TEST_SIZE; i++) {
+//      serializeOutput[i] = new String(source);
+//    }
+//    long stringsizeEnd = r.totalMemory() - r.freeMemory();
+//
+//    log
+//        .info("ORG JSON Lib Output "
+//            + average(startOutput, endOutput, TEST_SIZE)
+//            + " ms/conversion, "
+//            + (average(memstart, memend, TEST_SIZE) - average(stringsizeStart, stringsizeEnd,
+//                TEST_SIZE)) + " heap bytes/conversion, output packet consumed on average "
+//            + average(stringsizeStart, stringsizeEnd, TEST_SIZE) + " for a string length of "
+//            + output[0].length());
+//    log.info("Output Was [" + output[0] + ']');
+//  }
 
   /**
    * @param endOutput