Author: lindner
Date: Sun Feb 19 09:09:33 2012
New Revision: 1290973

URL: http://svn.apache.org/viewvc?rev=1290973&view=rev
Log:
convert json reflection code to use a LoadingCache/ImmutableMap

Modified:
    
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonUtil.java
    
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
    
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java

Modified: 
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonUtil.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonUtil.java?rev=1290973&r1=1290972&r2=1290973&view=diff
==============================================================================
--- 
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonUtil.java 
(original)
+++ 
shindig/trunk/java/common/src/main/java/org/apache/shindig/common/JsonUtil.java 
Sun Feb 19 09:09:33 2012
@@ -17,6 +17,10 @@
  */
 package org.apache.shindig.common;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+import com.google.common.collect.ImmutableMap;
 import org.json.JSONObject;
 
 import java.lang.reflect.InvocationTargetException;
@@ -26,8 +30,6 @@ import java.util.Set;
 
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.MapMaker;
-import com.google.common.collect.Maps;
 
 /**
  * JSON utilities that are not specific to either serialization or conversion.
@@ -38,7 +40,23 @@ public final class JsonUtil {
   private static final Set<String> EXCLUDE_METHODS
       = ImmutableSet.of("getClass", "getDeclaringClass");
 
-  private static final Map<Class<?>, Map<String, Method>> GETTERS = new 
MapMaker().makeMap();
+  private static final LoadingCache<Class<?>, Map<String, Method>> GETTERS = 
CacheBuilder
+      .newBuilder()
+      .build(new CacheLoader<Class<?>, Map<String, Method>>() {
+        public Map<String, Method> load(Class<?> clazz) {
+          ImmutableMap.Builder<String,Method> methods = ImmutableMap.builder();
+          
+          for (Method method : clazz.getMethods()) {
+            if (method.getParameterTypes().length == 0) {
+              String name = getPropertyName(method);
+              if (name != null) {
+                methods.put(name, method);
+              }
+            }
+          }
+          return methods.build();
+        }
+      });
 
   /**
    * Gets a property of an Object.  Will return a property value if
@@ -55,7 +73,7 @@ public final class JsonUtil {
       return ((Map<?, ?>) value).get(propertyName);
     } else {
       // Try getter conversion
-      Method method = getGetters(value).get(propertyName);
+      Method method = GETTERS.getUnchecked(value.getClass()).get(propertyName);
       if (method != null) {
         try {
           return method.invoke(value);
@@ -74,28 +92,9 @@ public final class JsonUtil {
     
     return null;
   }
-  
-  static Map<String, Method> getGetters(Object pojo) {
-    Class<?> clazz = pojo.getClass();
 
-    Map<String, Method> methods = GETTERS.get(clazz);
-    if (methods != null) {
-      return methods;
-    }
-    // Ensure consistent method ordering by using a linked hash map.
-    methods = Maps.newHashMap();
-
-    for (Method method : clazz.getMethods()) {
-      if (method.getParameterTypes().length == 0) {
-        String name = getPropertyName(method);
-        if (name != null) {
-          methods.put(name, method);
-        }
-      }
-    }
-
-    GETTERS.put(clazz, methods);
-    return methods;
+  static Map<String, Method> getGetters(Object pojo) {
+    return GETTERS.getUnchecked(pojo.getClass()) ;
   }
 
   private static String getPropertyName(Method method) {

Modified: 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java?rev=1290973&r1=1290972&r2=1290973&view=diff
==============================================================================
--- 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
 (original)
+++ 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanJsonConverter.java
 Sun Feb 19 09:09:33 2012
@@ -32,6 +32,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import org.apache.shindig.common.JsonProperty;
 import org.apache.shindig.common.JsonSerializer;
 import org.apache.shindig.common.uri.Uri;
@@ -47,7 +50,6 @@ import org.json.JSONObject;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
 
@@ -58,8 +60,23 @@ import com.google.inject.Injector;
  */
 public class BeanJsonConverter implements BeanConverter {
 
-  // Only compute the filtered setters once per-class
-  private static final Map<Class<?>, Map<String, Method>> setters = new 
MapMaker().makeMap();
+  // Only compute the filtered SETTERS once per-class
+  private static final LoadingCache<Class<?>, Map<String, Method>> SETTERS = 
CacheBuilder
+      .newBuilder()
+      .build(new CacheLoader<Class<?>, Map<String, Method>>() {
+        public Map<String, Method> load(Class<?> type) {
+          ImmutableMap.Builder<String, Method> builder = 
ImmutableMap.builder();
+          for (Method method : type.getMethods()) {
+            if (method.getParameterTypes().length == 1) {
+              String name = getPropertyName(method);
+              if (name != null) {
+                builder.put(name, method);
+              }
+            }
+          }
+          return builder.build();
+        }
+      });
 
   private final Injector injector;
 
@@ -86,28 +103,6 @@ public class BeanJsonConverter implement
     JsonSerializer.append(buf, pojo);
   }
 
-  private static Map<String, Method> getSetters(Class<?> type) {
-    Map<String, Method> methods = setters.get(type);
-
-    if (methods != null) {
-      return methods;
-    }
-
-    ImmutableMap.Builder<String,Method> builder = ImmutableMap.builder();
-    for (Method method : type.getMethods()) {
-      if (method.getParameterTypes().length == 1) {
-        String name = getPropertyName(method);
-        if (name != null) {
-          builder.put(name, method);
-        }
-      }
-    }
-    methods = builder.build();
-
-    setters.put(type, methods);
-    return methods;
-  }
-
   private static String getPropertyName(Method setter) {
     JsonProperty property = setter.getAnnotation(JsonProperty.class);
     if (property == null) {
@@ -274,7 +269,7 @@ public class BeanJsonConverter implement
       }
     }
   
-    for (Map.Entry<String, Method> entry : 
getSetters(out.getClass()).entrySet()) {
+    for (Map.Entry<String, Method> entry : 
SETTERS.getUnchecked(out.getClass()).entrySet()) {
       Object value = in.opt(entry.getKey());
       if (value != null) {
         Method method = entry.getValue();

Modified: 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java?rev=1290973&r1=1290972&r2=1290973&view=diff
==============================================================================
--- 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java
 (original)
+++ 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/xstream/GuiceBeanProvider.java
 Sun Feb 19 09:09:33 2012
@@ -28,10 +28,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSortedSet;
 import com.google.common.collect.Lists;
-import com.google.common.collect.MapMaker;
 import com.google.inject.Injector;
 import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
 
@@ -42,7 +44,27 @@ public class GuiceBeanProvider {
 
   protected static final Object[] NO_PARAMS = new Object[0];
   private final Comparator<String> propertyNameComparator;
-  private final transient Map<Class<?>, Map<String, PropertyDescriptor>> 
propertyNameCache = new MapMaker().weakKeys().makeMap();
+
+  private final transient LoadingCache<Class<?>, Map<String, 
PropertyDescriptor>> propertyNameCache = CacheBuilder
+      .newBuilder().weakKeys().build(
+          new CacheLoader<Class<?>, Map<String, PropertyDescriptor>>() {
+            public Map<String, PropertyDescriptor> load(Class<?> type) {
+
+              BeanInfo beanInfo;
+              try {
+                beanInfo = Introspector.getBeanInfo(type, Object.class);
+              } catch (IntrospectionException e) {
+                throw new ObjectAccessException("Cannot get BeanInfo of type " 
+ type.getName(), e);
+              }
+
+              ImmutableMap.Builder<String, PropertyDescriptor> nameMapBuilder 
= ImmutableMap.builder();
+              for (PropertyDescriptor descriptor : 
beanInfo.getPropertyDescriptors()) {
+                nameMapBuilder.put(descriptor.getName(), descriptor);
+              }
+              return nameMapBuilder.build();
+            }
+          }
+      );
   private Injector injector;
 
   public GuiceBeanProvider(Injector injector) {
@@ -107,7 +129,7 @@ public class GuiceBeanProvider {
   }
 
   private List<PropertyDescriptor> getSerializableProperties(Object object) {
-    Map<String, PropertyDescriptor> nameMap = getNameMap(object.getClass());
+    Map<String, PropertyDescriptor> nameMap = 
propertyNameCache.getUnchecked(object.getClass());
 
     Set<String> names = (propertyNameComparator == null) ? nameMap.keySet() :
       
ImmutableSortedSet.orderedBy(propertyNameComparator).addAll(nameMap.keySet()).build();
@@ -134,32 +156,7 @@ public class GuiceBeanProvider {
   }
 
   private PropertyDescriptor getProperty(String name, Class<?> type) {
-    return getNameMap(type).get(name);
-  }
-
-  private Map<String, PropertyDescriptor> getNameMap(Class<?> type) {
-    Map<String, PropertyDescriptor> nameMap = propertyNameCache.get(type);
-
-    if (nameMap != null) {
-      return nameMap;
-    }
-
-    ImmutableMap.Builder<String,PropertyDescriptor> nameMapBuilder = 
ImmutableMap.builder();
-
-    BeanInfo beanInfo;
-    try {
-      beanInfo = Introspector.getBeanInfo(type, Object.class);
-    } catch (IntrospectionException e) {
-      throw new ObjectAccessException("Cannot get BeanInfo of type "
-          + type.getName(), e);
-    }
-
-    for (PropertyDescriptor descriptor : beanInfo.getPropertyDescriptors()) {
-        nameMapBuilder.put(descriptor.getName(), descriptor);
-    }
-    nameMap = nameMapBuilder.build();
-    propertyNameCache.put(type, nameMap);
-    return nameMap;
+    return propertyNameCache.getUnchecked(type).get(name);
   }
 
   interface Visitor {


Reply via email to