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 {