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/04/18 18:53:14 UTC

svn commit: r649609 - in /incubator/shindig/trunk/java/social-api/src: main/java/org/apache/shindig/social/ main/java/org/apache/shindig/social/opensocial/model/ test/java/org/apache/shindig/social/

Author: doll
Date: Fri Apr 18 09:53:08 2008
New Revision: 649609

URL: http://svn.apache.org/viewvc?rev=649609&view=rev
Log:
SHINDIG-143

Subclasses of person will now have all of their fields as well as all of the Person.java fields outputted into json. To fix this I switched the toJson method from using reflection on fields to using methods. 

Eventually we should use a full json to pojo library if we still need this once we restful is in place, but this fixes the bug for now. 



Modified:
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/AbstractGadgetData.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/DataResponse.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/ResponseItem.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Activity.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Enum.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java
    incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Phone.java
    incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/GadgetDataTest.java

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/AbstractGadgetData.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/AbstractGadgetData.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/AbstractGadgetData.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/AbstractGadgetData.java Fri Apr 18 09:53:08 2008
@@ -21,10 +21,12 @@
 import org.json.JSONException;
 import org.json.JSONObject;
 
-import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.util.List;
 import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
 
 /**
  * Autoconvert a pojo in a JSONObject If a value is set to null will not be
@@ -34,8 +36,9 @@
 // object based on its getters
 public abstract class AbstractGadgetData {
 
-  private static final Class[] EMPTY_PARAM = {};
   private static final Object[] EMPTY_OBJECT = {};
+  private static final String EXCLUDED_GETTER = "class";
+  private static final Pattern GETTER = Pattern.compile("^get([a-zA-Z]+)$");
 
   /**
    * Convert this object to {@link JSONObject} reading Pojo properties
@@ -44,54 +47,53 @@
    */
   public JSONObject toJson() {
     JSONObject toReturn = new JSONObject();
-    Field[] fields = this.getClass().getDeclaredFields();
-    for (Field field : fields) {
-      String errorMessage = "Could not encode the " + field + " field.";
+    Method[] methods = this.getClass().getMethods();
+    for (Method method : methods) {
+      String errorMessage = "Could not encode the " + method + " method.";
       try {
-        putAttribute(toReturn, field,
-            field.getAnnotation(Mandatory.class) != null);
+        putAttribute(toReturn, method,
+            method.getAnnotation(Mandatory.class) != null);
       } catch (JSONException e) {
         throw new RuntimeException(errorMessage, e);
       } catch (IllegalAccessException e) {
         throw new RuntimeException(errorMessage, e);
       } catch (InvocationTargetException e) {
         throw new RuntimeException(errorMessage, e);
-      } catch (NoSuchMethodException e) {
-        throw new RuntimeException(errorMessage, e);
       }
     }
     return toReturn;
   }
 
   /**
-   * Convert java declared attritiue and its value to an entry in the given
+   * Convert java declared method and its value to an entry in the given
    * {@link JSONObject}
    *
    * @param object the json object to put the field value in
-   * @param field the field to encode
+   * @param method the method to encode
    * @param mandatory true if the field is mandatory
-   * @throws IllegalArgumentException
    * @throws JSONException
    * @throws IllegalAccessException
-   * @throws NoSuchMethodException
    * @throws InvocationTargetException
-   * @throws SecurityException
    */
-  private void putAttribute(JSONObject object, Field field, boolean mandatory)
-      throws IllegalArgumentException, JSONException, IllegalAccessException,
-      SecurityException, InvocationTargetException, NoSuchMethodException {
-    String getterName = field.getName();
-    getterName = "get" + getterName.substring(0, 1).toUpperCase()
-        + getterName.substring(1, getterName.length());
-
-    Object val = this.getClass().getMethod(getterName, EMPTY_PARAM).invoke(
-        this, EMPTY_OBJECT);
-    String name = field.getName();
+  private void putAttribute(JSONObject object, Method method, boolean mandatory)
+      throws JSONException, IllegalAccessException, InvocationTargetException {
+    Matcher matcher = GETTER.matcher(method.getName());
+    if (!matcher.matches()) {
+      return;
+    }
+
+    String name = matcher.group();
+    String fieldName = name.substring(3, 4).toLowerCase() + name.substring(4);
+    if (fieldName.equalsIgnoreCase(EXCLUDED_GETTER)) {
+      return;
+    }
+
+    Object val = method.invoke(this, EMPTY_OBJECT);
     if (val != null) {
-      object.put(name, translateObjectToJson(val));
+      object.put(fieldName, translateObjectToJson(val));
     } else {
       if (mandatory) {
-        throw new RuntimeException(name
+        throw new RuntimeException(fieldName
             + " is a mandory value, it should not be null");
       }
     }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/DataResponse.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/DataResponse.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/DataResponse.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/DataResponse.java Fri Apr 18 09:53:08 2008
@@ -25,7 +25,7 @@
  * Represents the response object which gets passed as json to the gadget
  */
 public class DataResponse extends AbstractGadgetData {
-  @Mandatory private List<ResponseItem> responses;
+  private List<ResponseItem> responses;
   private ResponseError error;
 
   public DataResponse(ResponseError error) {
@@ -37,6 +37,7 @@
     this.responses = responses;
   }
 
+  @Mandatory
   public List<ResponseItem> getResponses() {
     return responses;
   }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/ResponseItem.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/ResponseItem.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/ResponseItem.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/ResponseItem.java Fri Apr 18 09:53:08 2008
@@ -27,7 +27,7 @@
 
   // Must be compatible with AbstractSocialData.toJson. This means it should be
   // an AbstractSocialData or a collection of AbstractSocialData
-  @Mandatory private T response;
+  private T response;
 
   public ResponseItem(ResponseError error, String errorMessage, T response) {
     this.error = error;
@@ -55,6 +55,7 @@
     this.errorMessage = errorMessage;
   }
 
+  @Mandatory
   public T getResponse() {
     return response;
   }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Activity.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Activity.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Activity.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Activity.java Fri Apr 18 09:53:08 2008
@@ -62,7 +62,7 @@
   private String body;
   private String bodyId;
   private String externalId;
-  @Mandatory private String id;
+  private String id;
   private Date updated;
   private List<MediaItem> mediaItems;
   private Long postedTime;
@@ -75,7 +75,7 @@
   private String title;
   private String titleId;
   private String url;
-  @Mandatory private String userId;
+  private String userId;
 
   public Activity(String id, String userId) {
     this.id = id;
@@ -114,6 +114,7 @@
     this.externalId = externalId;
   }
 
+  @Mandatory
   public String getId() {
     return id;
   }
@@ -218,6 +219,7 @@
     this.url = url;
   }
 
+  @Mandatory
   public String getUserId() {
     return userId;
   }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Enum.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Enum.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Enum.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Enum.java Fri Apr 18 09:53:08 2008
@@ -30,10 +30,11 @@
  *
  */
 public final class Enum<E extends Enum.EnumKey> extends AbstractGadgetData {
-  @Mandatory private String displayValue;
+  private String displayValue;
   private E key = null;
 
   public interface EnumKey {
+    @Mandatory
     String getDisplayValue();
   }
 

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Person.java Fri Apr 18 09:53:08 2008
@@ -117,7 +117,7 @@
   private String happiestWhen;
   private List<String> heroes;
   private String humor;
-  @Mandatory private String id;
+  private String id;
   private List<String> interests;
   private String jobInterests;
   private List<Organization> jobs;
@@ -127,7 +127,7 @@
   private String lookingFor;
   private List<String> movies;
   private List<String> music;
-  @Mandatory private Name name;
+  private Name name;
   private String nickname;
   private String pets;
   private List<Phone> phoneNumbers;
@@ -314,6 +314,7 @@
     this.humor = humor;
   }
 
+  @Mandatory
   public String getId() {
     return id;
   }
@@ -394,6 +395,7 @@
     this.music = music;
   }
 
+  @Mandatory
   public Name getName() {
     return name;
   }

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Phone.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Phone.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Phone.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/opensocial/model/Phone.java Fri Apr 18 09:53:08 2008
@@ -17,8 +17,8 @@
  */
 package org.apache.shindig.social.opensocial.model;
 
-import org.apache.shindig.social.Mandatory;
 import org.apache.shindig.social.AbstractGadgetData;
+import org.apache.shindig.social.Mandatory;
 
 /**
  * see
@@ -43,7 +43,7 @@
     }
   }
 
-  @Mandatory private String number;
+  private String number;
   private String type;
 
   public Phone(String number, String type) {
@@ -52,6 +52,7 @@
     this.type = type;
   }
 
+  @Mandatory
   public String getNumber() {
     return number;
   }

Modified: incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/GadgetDataTest.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/GadgetDataTest.java?rev=649609&r1=649608&r2=649609&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/GadgetDataTest.java (original)
+++ incubator/shindig/trunk/java/social-api/src/test/java/org/apache/shindig/social/GadgetDataTest.java Fri Apr 18 09:53:08 2008
@@ -57,6 +57,27 @@
     activity.setMediaItems(mediaItems);
   }
 
+  public static class SpecialPerson extends Person {
+    private String newfield;
+
+    public SpecialPerson(String id, String name, String newfield) {
+      super(id, new Name(name));
+      this.newfield = newfield;
+    }
+
+    public String getNewfield() {
+      return newfield;
+    }
+  }
+
+  public void testToJsonOnInheritedClass() throws Exception {
+    SpecialPerson cassie = new SpecialPerson("5", "robot", "nonsense");
+
+    JSONObject result = cassie.toJson();
+    assertEquals(cassie.getId(), result.getString("id"));
+    assertEquals(cassie.getNewfield(), result.getString("newfield"));
+  }
+
   public void testPersonToJson() throws Exception {
     JSONObject result = johnDoe.toJson();
 
@@ -127,6 +148,18 @@
     JSONObject jsonMap = result.getJSONObject("response");
     assertEquals("1", jsonMap.getJSONObject("item1").getString("value"));
     assertEquals("2", jsonMap.getJSONObject("item2").getString("value"));
+  }
+
+  public void testMandatoryFields() throws Exception {
+    Person noIdMan = new Person(null, new Name("noIdMan"));
+    try {
+      noIdMan.toJson();
+      fail("Expected a person without an id to throw an exception");
+    } catch (Exception e) {
+      // The exception should be thrown
+      assertEquals("id is a mandory value, it should not be null",
+          e.getMessage());
+    }
   }
 
 }