You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@shindig.apache.org by li...@apache.org on 2008/10/01 01:08:39 UTC

svn commit: r700626 - /incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java

Author: lindner
Date: Tue Sep 30 16:08:39 2008
New Revision: 700626

URL: http://svn.apache.org/viewvc?rev=700626&view=rev
Log:
SHINDIG-633 - Speed up JSON serialization, get rid of the regexes and cache the method lists per class

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

Modified: incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java?rev=700626&r1=700625&r2=700626&view=diff
==============================================================================
--- incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java (original)
+++ incubator/shindig/trunk/java/social-api/src/main/java/org/apache/shindig/social/core/util/BeanJsonConverter.java Tue Sep 30 16:08:39 2008
@@ -42,6 +42,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -53,8 +54,13 @@
 
   private static final Object[] EMPTY_OBJECT = {};
   private static final Set<String> EXCLUDED_FIELDS = Sets.newHashSet("class", "declaringclass");
-  private static final Pattern GETTER = Pattern.compile("^get([a-zA-Z]+)$");
-  private static final Pattern SETTER = Pattern.compile("^set([a-zA-Z]+)$");
+  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();
+
   private Injector injector;
 
   @Inject
@@ -134,7 +140,13 @@
    * @return A JSONObject representing this pojo
    */
   private JSONObject convertMethodsToJson(Object pojo) {
-    List<MethodPair> availableGetters = getMatchingMethods(pojo, GETTER);
+    List<MethodPair> availableGetters;
+
+    availableGetters = GETTER_METHODS.get(pojo.getClass());
+    if (availableGetters == null) {
+      availableGetters = getMatchingMethods(pojo, GETTER_PREFIX);
+      GETTER_METHODS.putIfAbsent(pojo.getClass(), availableGetters);
+    }
 
     JSONObject toReturn = new JSONObject();
     for (MethodPair getter : availableGetters) {
@@ -168,18 +180,21 @@
     }
   }
 
-  private List<MethodPair> getMatchingMethods(Object pojo, Pattern pattern) {
-    List<MethodPair> availableGetters = Lists.newArrayList();
 
+  private List<MethodPair> getMatchingMethods(Object pojo, String prefix) {
+
+    List<MethodPair> availableGetters = Lists.newArrayList();
     Method[] methods = pojo.getClass().getMethods();
     for (Method method : methods) {
-      Matcher matcher = pattern.matcher(method.getName());
-      if (!matcher.matches()) {
+      String name = method.getName();
+      if (!method.getName().startsWith(prefix)) {
         continue;
       }
+      int prefixlen = prefix.length();
 
-      String name = matcher.group();
-      String fieldName = name.substring(3, 4).toLowerCase() + name.substring(4);
+      String fieldName = name.substring(prefixlen, prefixlen+1).toLowerCase() +
+          name.substring(prefixlen + 1);
+      
       if (EXCLUDED_FIELDS.contains(fieldName.toLowerCase())) {
         continue;
       }
@@ -234,7 +249,13 @@
 
     } else {
       JSONObject jsonObject = new JSONObject(json);
-      List<MethodPair> methods = getMatchingMethods(pojo, SETTER);
+      List<MethodPair> methods;
+      methods = SETTER_METHODS.get(pojo.getClass());
+      if (methods == null) {
+        methods = getMatchingMethods(pojo, SETTER_PREFIX);
+        SETTER_METHODS.putIfAbsent(pojo.getClass(), methods);
+      }
+
       for (MethodPair setter : methods) {
         if (jsonObject.has(setter.fieldName)) {
           callSetterWithValue(pojo, setter.method, jsonObject, setter.fieldName);