You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ibatis.apache.org by cb...@apache.org on 2009/06/21 23:07:00 UTC

svn commit: r787092 - in /ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection: BaseDynamicObject.java BeanDynamicObject.java DynamicObject.java MapDynamicObject.java MetaObject.java

Author: cbegin
Date: Sun Jun 21 21:07:00 2009
New Revision: 787092

URL: http://svn.apache.org/viewvc?rev=787092&view=rev
Log:
refactored MetaObject to support pluggable dynamic objects.

Added:
    ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BaseDynamicObject.java
    ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BeanDynamicObject.java
    ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DynamicObject.java
    ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MapDynamicObject.java
Modified:
    ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BaseDynamicObject.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BaseDynamicObject.java?rev=787092&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BaseDynamicObject.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BaseDynamicObject.java Sun Jun 21 21:07:00 2009
@@ -0,0 +1,84 @@
+package org.apache.ibatis.reflection;
+
+import java.util.*;
+
+public abstract class BaseDynamicObject implements DynamicObject {
+
+  protected static final Object[] NO_ARGUMENTS = new Object[0];
+  protected MetaObject metaObject;
+
+  protected BaseDynamicObject(MetaObject metaObject) {
+    this.metaObject = metaObject;
+  }
+
+  protected Object resolveCollection(PropertyTokenizer prop, Object object) {
+    if ("".equals(prop.getName())) {
+      return object;
+    } else {
+      return metaObject.getValue(prop.getName());
+    }
+  }
+
+  protected Object getCollectionValue(PropertyTokenizer prop, Object collection) {
+    if (collection instanceof Map) {
+      return ((Map) collection).get(prop.getIndex());
+    } else {
+      int i = Integer.parseInt(prop.getIndex());
+      if (collection instanceof List) {
+        return ((List) collection).get(i);
+      } else if (collection instanceof Object[]) {
+        return ((Object[]) collection)[i];
+      } else if (collection instanceof char[]) {
+        return ((char[]) collection)[i];
+      } else if (collection instanceof boolean[]) {
+        return ((boolean[]) collection)[i];
+      } else if (collection instanceof byte[]) {
+        return ((byte[]) collection)[i];
+      } else if (collection instanceof double[]) {
+        return ((double[]) collection)[i];
+      } else if (collection instanceof float[]) {
+        return ((float[]) collection)[i];
+      } else if (collection instanceof int[]) {
+        return ((int[]) collection)[i];
+      } else if (collection instanceof long[]) {
+        return ((long[]) collection)[i];
+      } else if (collection instanceof short[]) {
+        return ((short[]) collection)[i];
+      } else {
+        throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
+      }
+    }
+  }
+
+  protected void setCollectionValue(PropertyTokenizer prop, Object collection, Object value) {
+    if (collection instanceof Map) {
+      ((Map) collection).put(prop.getIndex(), value);
+    } else {
+      int i = Integer.parseInt(prop.getIndex());
+      if (collection instanceof List) {
+        ((List) collection).set(i, value);
+      } else if (collection instanceof Object[]) {
+        ((Object[]) collection)[i] = value;
+      } else if (collection instanceof char[]) {
+        ((char[]) collection)[i] = (Character) value;
+      } else if (collection instanceof boolean[]) {
+        ((boolean[]) collection)[i] = (Boolean) value;
+      } else if (collection instanceof byte[]) {
+        ((byte[]) collection)[i] = (Byte) value;
+      } else if (collection instanceof double[]) {
+        ((double[]) collection)[i] = (Double) value;
+      } else if (collection instanceof float[]) {
+        ((float[]) collection)[i] = (Float) value;
+      } else if (collection instanceof int[]) {
+        ((int[]) collection)[i] = (Integer) value;
+      } else if (collection instanceof long[]) {
+        ((long[]) collection)[i] = (Long) value;
+      } else if (collection instanceof short[]) {
+        ((short[]) collection)[i] = (Short) value;
+      } else {
+        throw new ReflectionException("The '" + prop.getName() + "' property of " + collection + " is not a List or Array.");
+      }
+    }
+  }
+
+}
\ No newline at end of file

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BeanDynamicObject.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BeanDynamicObject.java?rev=787092&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BeanDynamicObject.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/BeanDynamicObject.java Sun Jun 21 21:07:00 2009
@@ -0,0 +1,129 @@
+package org.apache.ibatis.reflection;
+
+public class BeanDynamicObject extends BaseDynamicObject {
+
+  private Object object;
+  private MetaClass metaClass;
+
+  public BeanDynamicObject(MetaObject metaObject, Object object) {
+    super(metaObject);
+    this.object = object;
+    this.metaClass = MetaClass.forClass(object.getClass());
+  }
+
+  public Object get(PropertyTokenizer prop) {
+    if (prop.getIndex() != null) {
+      Object collection = resolveCollection(prop, object);
+      return getCollectionValue(prop, collection);
+    } else {
+      return getBeanProperty(prop, object);
+    }
+  }
+
+  public void set(PropertyTokenizer prop, Object value) {
+    if (prop.getIndex() != null) {
+      Object collection = resolveCollection(prop, object);
+      setCollectionValue(prop, collection, value);
+    } else {
+      setBeanProperty(prop, object, value);
+    }
+  }
+
+  public String findProperty(String name) {
+    return metaClass.findProperty(name);
+  }
+
+  public String[] getGetterNames() {
+    return metaClass.getGetterNames();
+  }
+
+  public String[] getSetterNames() {
+    return metaClass.getSetterNames();
+  }
+
+  public Class getSetterType(String name) {
+    PropertyTokenizer prop = new PropertyTokenizer(name);
+    if (prop.hasNext()) {
+      MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
+      if (metaValue == MetaObject.NULL_META_OBJECT) {
+        return metaClass.getSetterType(name);
+      } else {
+        return metaValue.getSetterType(prop.getChildren());
+      }
+    } else {
+      return metaClass.getSetterType(name);
+    }
+  }
+
+  public Class getGetterType(String name) {
+    PropertyTokenizer prop = new PropertyTokenizer(name);
+    if (prop.hasNext()) {
+      MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
+      if (metaValue == MetaObject.NULL_META_OBJECT) {
+        return metaClass.getGetterType(name);
+      } else {
+        return metaValue.getGetterType(prop.getChildren());
+      }
+    } else {
+      return metaClass.getGetterType(name);
+    }
+  }
+
+  public boolean hasSetter(String name) {
+    PropertyTokenizer prop = new PropertyTokenizer(name);
+    if (prop.hasNext()) {
+      MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
+      if (metaValue == MetaObject.NULL_META_OBJECT) {
+        return metaClass.hasSetter(name);
+      } else {
+        return metaValue.hasSetter(prop.getChildren());
+      }
+    } else {
+      return metaClass.hasSetter(name);
+    }
+  }
+
+  public boolean hasGetter(String name) {
+    PropertyTokenizer prop = new PropertyTokenizer(name);
+    if (prop.hasNext()) {
+      MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
+      if (metaValue == MetaObject.NULL_META_OBJECT) {
+        return metaClass.hasGetter(name);
+      } else {
+        return metaValue.hasGetter(prop.getChildren());
+      }
+    } else {
+      return metaClass.hasGetter(name);
+    }
+  }
+
+  private Object getBeanProperty(PropertyTokenizer prop, Object object) {
+    try {
+      Invoker method = metaClass.getGetInvoker(prop.getName());
+      try {
+        return method.invoke(object, NO_ARGUMENTS);
+      } catch (Throwable t) {
+        throw ExceptionUtil.unwrapThrowable(t);
+      }
+    } catch (RuntimeException e) {
+      throw e;
+    } catch (Throwable t) {
+      throw new ReflectionException("Could not get property '" + prop.getName() + "' from " + object + ".  Cause: " + t.toString(), t);
+    }
+  }
+
+  private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
+    try {
+      Invoker method = metaClass.getSetInvoker(prop.getName());
+      Object[] params = {value};
+      try {
+        method.invoke(object, params);
+      } catch (Throwable t) {
+        throw ExceptionUtil.unwrapThrowable(t);
+      }
+    } catch (Throwable t) {
+      throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object + "' with value '" + value + "' Cause: " + t.toString(), t);
+    }
+  }
+
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DynamicObject.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DynamicObject.java?rev=787092&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DynamicObject.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/DynamicObject.java Sun Jun 21 21:07:00 2009
@@ -0,0 +1,23 @@
+package org.apache.ibatis.reflection;
+
+public interface DynamicObject {
+
+  Object get(PropertyTokenizer prop);
+
+  void set(PropertyTokenizer prop, Object value);
+
+  String findProperty(String name);
+
+  String[] getGetterNames();
+
+  String[] getSetterNames();
+
+  Class getSetterType(String name);
+
+  Class getGetterType(String name);
+
+  boolean hasSetter(String name);
+
+  boolean hasGetter(String name);
+  
+}

Added: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MapDynamicObject.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MapDynamicObject.java?rev=787092&view=auto
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MapDynamicObject.java (added)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MapDynamicObject.java Sun Jun 21 21:07:00 2009
@@ -0,0 +1,59 @@
+package org.apache.ibatis.reflection;
+
+import java.util.Map;
+
+public class MapDynamicObject extends BaseDynamicObject {
+
+  private Map map;
+
+  public MapDynamicObject(MetaObject metaObject, Map map) {
+    super(metaObject);
+    this.map = map;
+  }
+
+  public Object get(PropertyTokenizer prop) {
+    if (prop.getIndex() != null) {
+      Object collection = resolveCollection(prop, map);
+      return getCollectionValue(prop, collection);
+    } else {
+      return map.get(prop.getName());
+    }
+  }
+
+  public void set(PropertyTokenizer prop, Object value) {
+    if (prop.getIndex() != null) {
+      Object collection = resolveCollection(prop, map);
+      setCollectionValue(prop, collection, value);
+    } else {
+      map.put(prop.getName(), value);
+    }
+  }
+
+  public String findProperty(String name) {
+    return name;
+  }
+
+  public String[] getGetterNames() {
+    return (String[]) ((Map) map).keySet().toArray(new String[map.size()]);
+  }
+
+  public String[] getSetterNames() {
+    return (String[]) ((Map) map).keySet().toArray(new String[map.size()]);
+  }
+
+  public Class getSetterType(String name) {
+    return map.get(name) == null ? Object.class : map.get(name).getClass();
+  }
+
+  public Class getGetterType(String name) {
+    return map.get(name) == null ? Object.class : map.get(name).getClass();
+  }
+
+  public boolean hasSetter(String name) {
+    return true;
+  }
+
+  public boolean hasGetter(String name) {
+    return true;
+  }
+}

Modified: ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java
URL: http://svn.apache.org/viewvc/ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java?rev=787092&r1=787091&r2=787092&view=diff
==============================================================================
--- ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java (original)
+++ ibatis/trunk/java/ibatis-3/ibatis-3-core/src/main/java/org/apache/ibatis/reflection/MetaObject.java Sun Jun 21 21:07:00 2009
@@ -1,22 +1,24 @@
 package org.apache.ibatis.reflection;
 
-import java.util.*;
+import java.util.Map;
 
 public class MetaObject {
 
-  private Object object;
-  private MetaClass metaClass;
-  private ObjectFactory objectFactory;
-
-  private static final Object[] NO_ARGUMENTS = new Object[0];
   private static final ObjectFactory DEFAULT_OBJECT_FACTORY = new DefaultObjectFactory();
+  protected static final MetaObject NULL_META_OBJECT = new MetaObject(NullObject.class, DEFAULT_OBJECT_FACTORY);
 
-  public static final MetaObject NULL_META_OBJECT = new MetaObject(NullObject.class, DEFAULT_OBJECT_FACTORY);
+  private DynamicObject dynamicObject;
+  private ObjectFactory objectFactory;
 
   private MetaObject(Object object, ObjectFactory objectFactory) {
-    this.object = object;
-    this.metaClass = MetaClass.forClass(object.getClass());
     this.objectFactory = objectFactory;
+    if (object instanceof DynamicObject) {
+      this.dynamicObject = (DynamicObject) object;
+    } else if (object instanceof Map) {
+      this.dynamicObject = new MapDynamicObject(this, (Map)object);
+    } else {
+      this.dynamicObject = new BeanDynamicObject(this, object);
+    }
   }
 
   public static MetaObject forObject(Object object, ObjectFactory objectFactory) {
@@ -31,91 +33,32 @@
     return forObject(object, DEFAULT_OBJECT_FACTORY);
   }
 
-  public MetaObject metaObjectForProperty(String name) {
-    Object value = getValue(name);
-    return MetaObject.forObject(value);
-  }
-
   public String findProperty(String propName) {
-    if (object instanceof Map)
-      return propName;
-    return metaClass.findProperty(propName);
+    return dynamicObject.findProperty(propName);
   }
 
   public String[] getGetterNames() {
-    if (object instanceof Map)
-      return (String[]) ((Map) object).keySet().toArray(new String[((Map) object).size()]);
-    return metaClass.getGetterNames();
+    return dynamicObject.getGetterNames();
   }
 
   public String[] getSetterNames() {
-    if (object instanceof Map)
-      return (String[]) ((Map) object).keySet().toArray(new String[((Map) object).size()]);
-    return metaClass.getSetterNames();
+    return dynamicObject.getSetterNames();
   }
 
   public Class getSetterType(String name) {
-    if (object instanceof Map)
-      return ((Map) object).get(name) == null ? Object.class : ((Map) object).get(name).getClass();
-    PropertyTokenizer prop = new PropertyTokenizer(name);
-    if (prop.hasNext()) {
-      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
-      if (metaValue == MetaObject.NULL_META_OBJECT) {
-        return metaClass.getSetterType(name);
-      } else {
-        return metaValue.getSetterType(prop.getChildren());
-      }
-    } else {
-      return metaClass.getSetterType(name);
-    }
+    return dynamicObject.getSetterType(name);
   }
 
   public Class getGetterType(String name) {
-    if (object instanceof Map)
-      return ((Map) object).get(name) == null ? Object.class : ((Map) object).get(name).getClass();
-    PropertyTokenizer prop = new PropertyTokenizer(name);
-    if (prop.hasNext()) {
-      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
-      if (metaValue == MetaObject.NULL_META_OBJECT) {
-        return metaClass.getGetterType(name);
-      } else {
-        return metaValue.getGetterType(prop.getChildren());
-      }
-    } else {
-      return metaClass.getGetterType(name);
-    }
+    return dynamicObject.getGetterType(name);
   }
 
   public boolean hasSetter(String name) {
-    if (object instanceof Map)
-      return true;
-    PropertyTokenizer prop = new PropertyTokenizer(name);
-    if (prop.hasNext()) {
-      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
-      if (metaValue == MetaObject.NULL_META_OBJECT) {
-        return metaClass.hasSetter(name);
-      } else {
-        return metaValue.hasSetter(prop.getChildren());
-      }
-    } else {
-      return metaClass.hasSetter(name);
-    }
+    return dynamicObject.hasSetter(name);
   }
 
   public boolean hasGetter(String name) {
-    if (object instanceof Map)
-      return true;
-    PropertyTokenizer prop = new PropertyTokenizer(name);
-    if (prop.hasNext()) {
-      MetaObject metaValue = metaObjectForProperty(prop.getIndexedName());
-      if (metaValue == MetaObject.NULL_META_OBJECT) {
-        return metaClass.hasGetter(name);
-      } else {
-        return metaValue.hasGetter(prop.getChildren());
-      }
-    } else {
-      return metaClass.hasGetter(name);
-    }
+    return dynamicObject.hasGetter(name);
   }
 
   public Object getValue(String name) {
@@ -128,7 +71,7 @@
         return metaValue.getValue(prop.getChildren());
       }
     } else {
-      return getProperty(prop, object);
+      return dynamicObject.get(prop);
     }
   }
 
@@ -144,7 +87,7 @@
           try {
             Object newObject = objectFactory.create(type);
             metaValue = MetaObject.forObject(newObject);
-            setProperty(prop, object, newObject);
+            dynamicObject.set(prop, newObject);
           } catch (Exception e) {
             throw new ReflectionException("Cannot set value of property '" + name + "' because '" + name + "' is null and cannot be instantiated on instance of " + type.getName() + ". Cause:" + e.toString(), e);
           }
@@ -152,143 +95,13 @@
       }
       metaValue.setValue(prop.getChildren(), value);
     } else {
-      setProperty(prop, object, value);
-    }
-
-  }
-
-  private Object getProperty(PropertyTokenizer prop, Object object) {
-    if (prop.getIndex() != null) {
-      return getIndexedProperty(prop, object);
-    } else {
-      return getBeanOrMapProperty(prop, object);
-    }
-  }
-
-  private Object getBeanOrMapProperty(PropertyTokenizer prop, Object object) {
-    if (object instanceof Map) {
-      return ((Map) object).get(prop.getName());
-    } else {
-      return getBeanProperty(prop, object);
-    }
-  }
-
-  private void setProperty(PropertyTokenizer prop, Object object, Object value) {
-    if (prop.getIndex() != null) {
-      setIndexedProperty(prop, object, value);
-    } else if (object instanceof Map) {
-      ((Map) object).put(prop.getName(), value);
-    } else {
-      setBeanProperty(prop, object, value);
-    }
-  }
-
-  private Object getBeanProperty(PropertyTokenizer prop, Object object) {
-    try {
-      Invoker method = metaClass.getGetInvoker(prop.getName());
-      try {
-        return method.invoke(object, NO_ARGUMENTS);
-      } catch (Throwable t) {
-        throw ExceptionUtil.unwrapThrowable(t);
-      }
-    } catch (RuntimeException e) {
-      throw e;
-    } catch (Throwable t) {
-      throw new ReflectionException("Could not get property '" + prop.getName() + "' from " + object + ".  Cause: " + t.toString(), t);
-    }
-  }
-
-  private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) {
-    try {
-      Invoker method = metaClass.getSetInvoker(prop.getName());
-      Object[] params = {value};
-      try {
-        method.invoke(object, params);
-      } catch (Throwable t) {
-        throw ExceptionUtil.unwrapThrowable(t);
-      }
-    } catch (Throwable t) {
-      throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object + "' with value '"+value+"' Cause: " + t.toString(), t);
-    }
-  }
-
-  private Object resolveCollection(PropertyTokenizer prop, Object object) {
-    if ("".equals(prop.getName())) {
-      return object;
-    } else {
-      return getBeanOrMapProperty(prop, object);
+      dynamicObject.set(prop, value);
     }
   }
 
-  private Object getIndexedProperty(PropertyTokenizer prop, Object object) {
-    Object collection = resolveCollection(prop, object);
-    if (collection instanceof Map) {
-      return ((Map) collection).get(prop.getIndex());
-    }
-    return getListValue(prop, collection);
-  }
-
-  private Object getListValue(PropertyTokenizer prop, Object list) {
-    int i = Integer.parseInt(prop.getIndex());
-    if (list instanceof List) {
-      return ((List) list).get(i);
-    } else if (list instanceof Object[]) {
-      return ((Object[]) list)[i];
-    } else if (list instanceof char[]) {
-      return ((char[]) list)[i];
-    } else if (list instanceof boolean[]) {
-      return ((boolean[]) list)[i];
-    } else if (list instanceof byte[]) {
-      return ((byte[]) list)[i];
-    } else if (list instanceof double[]) {
-      return ((double[]) list)[i];
-    } else if (list instanceof float[]) {
-      return ((float[]) list)[i];
-    } else if (list instanceof int[]) {
-      return ((int[]) list)[i];
-    } else if (list instanceof long[]) {
-      return ((long[]) list)[i];
-    } else if (list instanceof short[]) {
-      return ((short[]) list)[i];
-    } else {
-      throw new ReflectionException("The '" + prop.getName() + "' property of " + list + " is not a List or Array.");
-    }
-  }
-
-  private void setIndexedProperty(PropertyTokenizer prop, Object object, Object value) {
-    Object collection = resolveCollection(prop, object);
-    if (collection instanceof Map) {
-      ((Map) collection).put(prop.getIndex(), value);
-    } else {
-      setListValue(prop, collection, value);
-    }
-  }
-
-  private void setListValue(PropertyTokenizer prop, Object list, Object value) {
-    int i = Integer.parseInt(prop.getIndex());
-    if (list instanceof List) {
-      ((List) list).set(i, value);
-    } else if (list instanceof Object[]) {
-      ((Object[]) list)[i] = value;
-    } else if (list instanceof char[]) {
-      ((char[]) list)[i] = (Character) value;
-    } else if (list instanceof boolean[]) {
-      ((boolean[]) list)[i] = (Boolean) value;
-    } else if (list instanceof byte[]) {
-      ((byte[]) list)[i] = (Byte) value;
-    } else if (list instanceof double[]) {
-      ((double[]) list)[i] = (Double) value;
-    } else if (list instanceof float[]) {
-      ((float[]) list)[i] = (Float) value;
-    } else if (list instanceof int[]) {
-      ((int[]) list)[i] = (Integer) value;
-    } else if (list instanceof long[]) {
-      ((long[]) list)[i] = (Long) value;
-    } else if (list instanceof short[]) {
-      ((short[]) list)[i] = (Short) value;
-    } else {
-      throw new ReflectionException("The '" + prop.getName() + "' property of " + list + " is not a List or Array.");
-    }
+  public MetaObject metaObjectForProperty(String name) {
+    Object value = getValue(name);
+    return MetaObject.forObject(value);
   }
 
   private static class NullObject {