Author: zhoresh
Date: Sat Sep 18 00:46:22 2010
New Revision: 998378

URL: http://svn.apache.org/viewvc?rev=998378&view=rev
Log:
Ref: http://codereview.appspot.com/2242041/
Improve BeanDelegator for easy overwrite

Modified:
    
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java
    
shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanDelegatorTest.java

Modified: 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java?rev=998378&r1=998377&r2=998378&view=diff
==============================================================================
--- 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java
 (original)
+++ 
shindig/trunk/java/common/src/main/java/org/apache/shindig/protocol/conversion/BeanDelegator.java
 Sat Sep 18 00:46:22 2010
@@ -87,12 +87,37 @@ public class BeanDelegator {
    */
   public Object createDelegator(Object source) {
     if (source == null || delegatedClasses == null) {
+      return source;
+    }
+
+    if (delegatedClasses.containsKey(source.getClass())) {
+      Class<?> apiInterface = delegatedClasses.get(source.getClass());
+
+      return createDelegator(source, apiInterface);
+    }
+    return source;
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T> T createDelegator(Object source, Class<T> apiInterface) {
+    return createDelegator(source, apiInterface, EMPTY_FIELDS);
+  }
+
+  @SuppressWarnings("unchecked")
+  public <T> T createDelegator(Object source, Class<T> apiInterface,
+                               Map<String, Object> extraFields) {
+
+    if (source == null) {
       return null;
     }
 
+    if (apiInterface.isPrimitive() || 
apiInterface.isAssignableFrom(source.getClass())) {
+      return (T) source;
+    }
+
     // For enum, return the converted enum
     if (source instanceof Enum<?> && 
delegatedClasses.containsKey(source.getClass())) {
-      return convertEnum((Enum<?>) source);
+      return (T) convertEnum((Enum<?>) source);
     }
 
     // Proxy each item in a map (map key is not proxied)
@@ -103,11 +128,11 @@ public class BeanDelegator {
         // Convert Map:
         ImmutableMap.Builder<Object, Object> mapBuilder = 
ImmutableMap.builder();
         for (Map.Entry<?, ?> entry : mapSource.entrySet()) {
-          mapBuilder.put(entry.getKey(), createDelegator(entry.getValue()));
+          mapBuilder.put(entry.getKey(), createDelegator(entry.getValue(), 
apiInterface));
         }
-        return mapBuilder.build();
+        return (T) mapBuilder.build();
       } else {
-        return source;
+        return (T) source;
       }
     }
 
@@ -119,30 +144,13 @@ public class BeanDelegator {
         // Convert Map:
         ImmutableList.Builder<Object> listBuilder = ImmutableList.builder();
         for (Object entry : listSource) {
-          listBuilder.add(createDelegator(entry));
+          listBuilder.add(createDelegator(entry, apiInterface));
         }
-        return listBuilder.build();
+        return (T) listBuilder.build();
       } else {
-        return source;
+        return (T) source;
       }
     }
-
-    if (delegatedClasses.containsKey(source.getClass())) {
-      Class<?> apiInterface = delegatedClasses.get(source.getClass());
-
-      return createDelegator(source, apiInterface);
-    }
-    return source;
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T> T createDelegator(Object source, Class<T> apiInterface) {
-    return createDelegator(source, apiInterface, EMPTY_FIELDS);
-  }
-
-  @SuppressWarnings("unchecked")
-  public <T> T createDelegator(Object source, Class<T> apiInterface,
-                               Map<String, Object> extraFields) {
     return (T) Proxy.newProxyInstance( apiInterface.getClassLoader(),
       new Class[] { apiInterface }, new DelegateInvocationHandler(source, 
extraFields));
   }
@@ -189,7 +197,7 @@ public class BeanDelegator {
         Method sourceMethod = sourceClass.getMethod(
             method.getName(), method.getParameterTypes());
         Object result = sourceMethod.invoke(source, args);
-        return createDelegator(result);
+        return createDelegator(result, getParameterizedReturnType(method));
       } catch (NoSuchMethodException e) {
         // Will throw unsupported method below
       } catch (IllegalArgumentException e) {
@@ -203,6 +211,21 @@ public class BeanDelegator {
     }
   }
 
+  private Class<?> getParameterizedReturnType(Method method) {
+    Type type = method.getGenericReturnType();
+    if (type instanceof ParameterizedType) {
+      ParameterizedType paramType = (ParameterizedType) type;
+
+      if (List.class.isAssignableFrom((Class<?>) paramType.getRawType())) {
+        type = paramType.getActualTypeArguments()[0];
+      } else if (Map.class.isAssignableFrom((Class<?>) 
paramType.getRawType())) {
+        type = paramType.getActualTypeArguments()[1];
+      }
+    }
+    return (Class<?>) type;
+  }
+
+
   /**
    * Validate all proxied classes to see that all required functions are 
implemented.
    * Throws exception if failed validation.

Modified: 
shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanDelegatorTest.java
URL: 
http://svn.apache.org/viewvc/shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanDelegatorTest.java?rev=998378&r1=998377&r2=998378&view=diff
==============================================================================
--- 
shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanDelegatorTest.java
 (original)
+++ 
shindig/trunk/java/common/src/test/java/org/apache/shindig/protocol/conversion/BeanDelegatorTest.java
 Sat Sep 18 00:46:22 2010
@@ -27,7 +27,6 @@ import org.apache.shindig.protocol.conve
 import org.junit.Before;
 import org.junit.Test;
 
-import java.beans.BeanInfo;
 import java.util.List;
 import java.util.Map;
 


Reply via email to