708 lines
28 KiB
Java
708 lines
28 KiB
Java
package org.apache.commons.beanutils;
|
|
|
|
import java.beans.BeanInfo;
|
|
import java.beans.IndexedPropertyDescriptor;
|
|
import java.beans.IntrospectionException;
|
|
import java.beans.Introspector;
|
|
import java.beans.PropertyDescriptor;
|
|
import java.lang.reflect.Array;
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.lang.reflect.Method;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import org.apache.commons.collections.FastHashMap;
|
|
|
|
public class PropertyUtils {
|
|
public static final char INDEXED_DELIM = '[';
|
|
|
|
public static final char INDEXED_DELIM2 = ']';
|
|
|
|
public static final char MAPPED_DELIM = '(';
|
|
|
|
public static final char MAPPED_DELIM2 = ')';
|
|
|
|
public static final char NESTED_DELIM = '.';
|
|
|
|
private static int debug = 0;
|
|
|
|
public static int getDebug() {
|
|
return debug;
|
|
}
|
|
|
|
public static void setDebug(int newDebug) {
|
|
debug = newDebug;
|
|
}
|
|
|
|
private static FastHashMap descriptorsCache = null;
|
|
|
|
private static FastHashMap mappedDescriptorsCache = null;
|
|
|
|
static {
|
|
descriptorsCache = new FastHashMap();
|
|
descriptorsCache.setFast(true);
|
|
mappedDescriptorsCache = new FastHashMap();
|
|
mappedDescriptorsCache.setFast(true);
|
|
}
|
|
|
|
public static void clearDescriptors() {
|
|
descriptorsCache.clear();
|
|
mappedDescriptorsCache.clear();
|
|
Introspector.flushCaches();
|
|
}
|
|
|
|
public static void copyProperties(Object dest, Object orig) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (dest == null)
|
|
throw new IllegalArgumentException("No destination bean specified");
|
|
if (orig == null)
|
|
throw new IllegalArgumentException("No origin bean specified");
|
|
if (orig instanceof DynaBean) {
|
|
DynaProperty[] origDescriptors = ((DynaBean)orig).getDynaClass().getDynaProperties();
|
|
for (int i = 0; i < origDescriptors.length; i++) {
|
|
String name = origDescriptors[i].getName();
|
|
if (dest instanceof DynaBean) {
|
|
if (isWriteable(dest, name)) {
|
|
Object value = ((DynaBean)orig).get(name);
|
|
((DynaBean)dest).set(name, value);
|
|
}
|
|
} else if (isWriteable(dest, name)) {
|
|
Object value = ((DynaBean)orig).get(name);
|
|
setSimpleProperty(dest, name, value);
|
|
}
|
|
}
|
|
} else if (orig instanceof Map) {
|
|
Iterator names = ((Map)orig).keySet().iterator();
|
|
while (names.hasNext()) {
|
|
String name = names.next();
|
|
if (dest instanceof DynaBean) {
|
|
if (isWriteable(dest, name)) {
|
|
Object value = ((Map)orig).get(name);
|
|
((DynaBean)dest).set(name, value);
|
|
}
|
|
continue;
|
|
}
|
|
if (isWriteable(dest, name)) {
|
|
Object value = ((Map)orig).get(name);
|
|
setSimpleProperty(dest, name, value);
|
|
}
|
|
}
|
|
} else {
|
|
PropertyDescriptor[] origDescriptors = getPropertyDescriptors(orig);
|
|
for (int i = 0; i < origDescriptors.length; i++) {
|
|
String name = origDescriptors[i].getName();
|
|
if (isReadable(orig, name))
|
|
if (dest instanceof DynaBean) {
|
|
if (isWriteable(dest, name)) {
|
|
Object value = getSimpleProperty(orig, name);
|
|
((DynaBean)dest).set(name, value);
|
|
}
|
|
} else if (isWriteable(dest, name)) {
|
|
Object value = getSimpleProperty(orig, name);
|
|
setSimpleProperty(dest, name, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static Map describe(Object bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
Map description = new HashMap();
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty[] descriptors = ((DynaBean)bean).getDynaClass().getDynaProperties();
|
|
for (int i = 0; i < descriptors.length; i++) {
|
|
String name = descriptors[i].getName();
|
|
description.put(name, getProperty(bean, name));
|
|
}
|
|
} else {
|
|
PropertyDescriptor[] descriptors = getPropertyDescriptors(bean);
|
|
for (int i = 0; i < descriptors.length; i++) {
|
|
String name = descriptors[i].getName();
|
|
if (descriptors[i].getReadMethod() != null)
|
|
description.put(name, getProperty(bean, name));
|
|
}
|
|
}
|
|
return description;
|
|
}
|
|
|
|
public static Object getIndexedProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
int delim = name.indexOf('[');
|
|
int delim2 = name.indexOf(']');
|
|
if (delim < 0 || delim2 <= delim)
|
|
throw new IllegalArgumentException("Invalid indexed property '" + name + "'");
|
|
int index = -1;
|
|
try {
|
|
String subscript = name.substring(delim + 1, delim2);
|
|
index = Integer.parseInt(subscript);
|
|
} catch (NumberFormatException e) {
|
|
throw new IllegalArgumentException("Invalid indexed property '" + name + "'");
|
|
}
|
|
name = name.substring(0, delim);
|
|
return getIndexedProperty(bean, name, index);
|
|
}
|
|
|
|
public static Object getIndexedProperty(Object bean, String name, int index) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
return ((DynaBean)bean).get(name, index);
|
|
}
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
if (descriptor instanceof IndexedPropertyDescriptor) {
|
|
Method method = ((IndexedPropertyDescriptor)descriptor).getIndexedReadMethod();
|
|
if (method != null) {
|
|
Object[] subscript = new Object[1];
|
|
subscript[0] = new Integer(index);
|
|
try {
|
|
return method.invoke(bean, subscript);
|
|
} catch (InvocationTargetException e) {
|
|
if (e.getTargetException() instanceof ArrayIndexOutOfBoundsException)
|
|
throw (ArrayIndexOutOfBoundsException)e.getTargetException();
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
Method readMethod = getReadMethod(descriptor);
|
|
if (readMethod == null)
|
|
throw new NoSuchMethodException("Property '" + name + "' has no getter method");
|
|
Object value = readMethod.invoke(bean, new Object[0]);
|
|
if (!value.getClass().isArray()) {
|
|
if (!(value instanceof List))
|
|
throw new IllegalArgumentException("Property '" + name + "' is not indexed");
|
|
return ((List)value).get(index);
|
|
}
|
|
return Array.get(value, index);
|
|
}
|
|
|
|
public static Object getMappedProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
int delim = name.indexOf('(');
|
|
int delim2 = name.indexOf(')');
|
|
if (delim < 0 || delim2 <= delim)
|
|
throw new IllegalArgumentException("Invalid mapped property '" + name + "'");
|
|
String key = name.substring(delim + 1, delim2);
|
|
name = name.substring(0, delim);
|
|
return getMappedProperty(bean, name, key);
|
|
}
|
|
|
|
public static Object getMappedProperty(Object bean, String name, String key) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (key == null)
|
|
throw new IllegalArgumentException("No key specified");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
return ((DynaBean)bean).get(name, key);
|
|
}
|
|
Object result = null;
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
if (descriptor instanceof MappedPropertyDescriptor) {
|
|
Method readMethod = ((MappedPropertyDescriptor)descriptor).getMappedReadMethod();
|
|
if (readMethod != null) {
|
|
Object[] keyArray = new Object[1];
|
|
keyArray[0] = key;
|
|
result = readMethod.invoke(bean, keyArray);
|
|
} else {
|
|
throw new NoSuchMethodException("Property '" + name + "' has no mapped getter method");
|
|
}
|
|
} else {
|
|
Method readMethod = descriptor.getReadMethod();
|
|
if (readMethod != null) {
|
|
Object invokeResult = readMethod.invoke(bean, new Object[0]);
|
|
if (invokeResult instanceof Map)
|
|
result = ((Map)invokeResult).get(key);
|
|
} else {
|
|
throw new NoSuchMethodException("Property '" + name + "' has no mapped getter method");
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static FastHashMap getMappedPropertyDescriptors(Class beanClass) {
|
|
if (beanClass == null)
|
|
return null;
|
|
return (FastHashMap)mappedDescriptorsCache.get(beanClass);
|
|
}
|
|
|
|
public static FastHashMap getMappedPropertyDescriptors(Object bean) {
|
|
if (bean == null)
|
|
return null;
|
|
return getMappedPropertyDescriptors(bean.getClass());
|
|
}
|
|
|
|
public static Object getNestedProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
int indexOfINDEXED_DELIM = -1;
|
|
int indexOfMAPPED_DELIM = -1;
|
|
int indexOfMAPPED_DELIM2 = -1;
|
|
int indexOfNESTED_DELIM = -1;
|
|
while (true) {
|
|
indexOfNESTED_DELIM = name.indexOf('.');
|
|
indexOfMAPPED_DELIM = name.indexOf('(');
|
|
indexOfMAPPED_DELIM2 = name.indexOf(')');
|
|
if (indexOfMAPPED_DELIM2 >= 0 && indexOfMAPPED_DELIM >= 0 && (indexOfNESTED_DELIM < 0 || indexOfNESTED_DELIM > indexOfMAPPED_DELIM)) {
|
|
indexOfNESTED_DELIM = name.indexOf('.', indexOfMAPPED_DELIM2);
|
|
} else {
|
|
indexOfNESTED_DELIM = name.indexOf('.');
|
|
}
|
|
if (indexOfNESTED_DELIM < 0)
|
|
break;
|
|
String next = name.substring(0, indexOfNESTED_DELIM);
|
|
indexOfINDEXED_DELIM = next.indexOf('[');
|
|
indexOfMAPPED_DELIM = next.indexOf('(');
|
|
if (bean instanceof Map) {
|
|
bean = ((Map)bean).get(next);
|
|
} else if (indexOfMAPPED_DELIM >= 0) {
|
|
bean = getMappedProperty(bean, next);
|
|
} else if (indexOfINDEXED_DELIM >= 0) {
|
|
bean = getIndexedProperty(bean, next);
|
|
} else {
|
|
bean = getSimpleProperty(bean, next);
|
|
}
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("Null property value for '" + name.substring(0, indexOfNESTED_DELIM) + "'");
|
|
name = name.substring(indexOfNESTED_DELIM + 1);
|
|
}
|
|
indexOfINDEXED_DELIM = name.indexOf('[');
|
|
indexOfMAPPED_DELIM = name.indexOf('(');
|
|
if (bean instanceof Map) {
|
|
bean = ((Map)bean).get(name);
|
|
} else if (indexOfMAPPED_DELIM >= 0) {
|
|
bean = getMappedProperty(bean, name);
|
|
} else if (indexOfINDEXED_DELIM >= 0) {
|
|
bean = getIndexedProperty(bean, name);
|
|
} else {
|
|
bean = getSimpleProperty(bean, name);
|
|
}
|
|
return bean;
|
|
}
|
|
|
|
public static Object getProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
return getNestedProperty(bean, name);
|
|
}
|
|
|
|
public static PropertyDescriptor getPropertyDescriptor(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
while (true) {
|
|
int period = name.indexOf('.');
|
|
if (period < 0)
|
|
break;
|
|
String next = name.substring(0, period);
|
|
int indexOfINDEXED_DELIM = next.indexOf('[');
|
|
int indexOfMAPPED_DELIM = next.indexOf('(');
|
|
if (indexOfMAPPED_DELIM >= 0 && (indexOfINDEXED_DELIM < 0 || indexOfMAPPED_DELIM < indexOfINDEXED_DELIM)) {
|
|
bean = getMappedProperty(bean, next);
|
|
} else if (indexOfINDEXED_DELIM >= 0) {
|
|
bean = getIndexedProperty(bean, next);
|
|
} else {
|
|
bean = getSimpleProperty(bean, next);
|
|
}
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("Null property value for '" + name.substring(0, period) + "'");
|
|
name = name.substring(period + 1);
|
|
}
|
|
int left = name.indexOf('[');
|
|
if (left >= 0)
|
|
name = name.substring(0, left);
|
|
left = name.indexOf('(');
|
|
if (left >= 0)
|
|
name = name.substring(0, left);
|
|
if (bean == null || name == null)
|
|
return null;
|
|
PropertyDescriptor[] descriptors = getPropertyDescriptors(bean);
|
|
if (descriptors != null)
|
|
for (int i = 0; i < descriptors.length; i++) {
|
|
if (name.equals(descriptors[i].getName()))
|
|
return descriptors[i];
|
|
}
|
|
PropertyDescriptor result = null;
|
|
FastHashMap mappedDescriptors = getMappedPropertyDescriptors(bean);
|
|
if (mappedDescriptors == null) {
|
|
mappedDescriptors = new FastHashMap();
|
|
mappedDescriptors.setFast(true);
|
|
mappedDescriptorsCache.put(bean.getClass(), mappedDescriptors);
|
|
}
|
|
result = (PropertyDescriptor)mappedDescriptors.get(name);
|
|
if (result == null) {
|
|
try {
|
|
result = new MappedPropertyDescriptor(name, bean.getClass());
|
|
} catch (IntrospectionException ie) {}
|
|
if (result != null)
|
|
mappedDescriptors.put(name, result);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public static PropertyDescriptor[] getPropertyDescriptors(Class beanClass) {
|
|
if (beanClass == null)
|
|
throw new IllegalArgumentException("No bean class specified");
|
|
PropertyDescriptor[] descriptors = null;
|
|
descriptors = (PropertyDescriptor[])descriptorsCache.get(beanClass);
|
|
if (descriptors != null)
|
|
return descriptors;
|
|
BeanInfo beanInfo = null;
|
|
try {
|
|
beanInfo = Introspector.getBeanInfo(beanClass);
|
|
} catch (IntrospectionException e) {
|
|
return new PropertyDescriptor[0];
|
|
}
|
|
descriptors = beanInfo.getPropertyDescriptors();
|
|
if (descriptors == null)
|
|
descriptors = new PropertyDescriptor[0];
|
|
descriptorsCache.put(beanClass, descriptors);
|
|
return descriptors;
|
|
}
|
|
|
|
public static PropertyDescriptor[] getPropertyDescriptors(Object bean) {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
return getPropertyDescriptors(bean.getClass());
|
|
}
|
|
|
|
public static Class getPropertyEditorClass(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor != null)
|
|
return descriptor.getPropertyEditorClass();
|
|
return null;
|
|
}
|
|
|
|
public static Class getPropertyType(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
return null;
|
|
Class type = dynaProperty.getType();
|
|
if (type == null)
|
|
return null;
|
|
if (type.isArray())
|
|
return type.getComponentType();
|
|
return type;
|
|
}
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
return null;
|
|
if (descriptor instanceof IndexedPropertyDescriptor)
|
|
return ((IndexedPropertyDescriptor)descriptor).getIndexedPropertyType();
|
|
if (descriptor instanceof MappedPropertyDescriptor)
|
|
return ((MappedPropertyDescriptor)descriptor).getMappedPropertyType();
|
|
return descriptor.getPropertyType();
|
|
}
|
|
|
|
public static Method getReadMethod(PropertyDescriptor descriptor) {
|
|
return MethodUtils.getAccessibleMethod(descriptor.getReadMethod());
|
|
}
|
|
|
|
public static Object getSimpleProperty(Object bean, String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (name.indexOf('.') >= 0)
|
|
throw new IllegalArgumentException("Nested property names are not allowed");
|
|
if (name.indexOf('[') >= 0)
|
|
throw new IllegalArgumentException("Indexed property names are not allowed");
|
|
if (name.indexOf('(') >= 0)
|
|
throw new IllegalArgumentException("Mapped property names are not allowed");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
return ((DynaBean)bean).get(name);
|
|
}
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
Method readMethod = getReadMethod(descriptor);
|
|
if (readMethod == null)
|
|
throw new NoSuchMethodException("Property '" + name + "' has no getter method");
|
|
Object value = readMethod.invoke(bean, new Object[0]);
|
|
return value;
|
|
}
|
|
|
|
public static Method getWriteMethod(PropertyDescriptor descriptor) {
|
|
return MethodUtils.getAccessibleMethod(descriptor.getWriteMethod());
|
|
}
|
|
|
|
public static boolean isReadable(Object bean, String name) {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (bean instanceof DynaBean)
|
|
return (((DynaBean)bean).getDynaClass().getDynaProperty(name) != null);
|
|
try {
|
|
PropertyDescriptor desc = getPropertyDescriptor(bean, name);
|
|
if (desc != null) {
|
|
Method readMethod = desc.getReadMethod();
|
|
if (readMethod == null && desc instanceof IndexedPropertyDescriptor)
|
|
readMethod = ((IndexedPropertyDescriptor)desc).getIndexedReadMethod();
|
|
return (readMethod != null);
|
|
}
|
|
return false;
|
|
} catch (IllegalAccessException e) {
|
|
return false;
|
|
} catch (InvocationTargetException e) {
|
|
return false;
|
|
} catch (NoSuchMethodException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static boolean isWriteable(Object bean, String name) {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (bean instanceof DynaBean)
|
|
return (((DynaBean)bean).getDynaClass().getDynaProperty(name) != null);
|
|
try {
|
|
PropertyDescriptor desc = getPropertyDescriptor(bean, name);
|
|
if (desc != null) {
|
|
Method writeMethod = desc.getWriteMethod();
|
|
if (writeMethod == null && desc instanceof IndexedPropertyDescriptor)
|
|
writeMethod = ((IndexedPropertyDescriptor)desc).getIndexedWriteMethod();
|
|
return (writeMethod != null);
|
|
}
|
|
return false;
|
|
} catch (IllegalAccessException e) {
|
|
return false;
|
|
} catch (InvocationTargetException e) {
|
|
return false;
|
|
} catch (NoSuchMethodException e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public static void setIndexedProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
int delim = name.indexOf('[');
|
|
int delim2 = name.indexOf(']');
|
|
if (delim < 0 || delim2 <= delim)
|
|
throw new IllegalArgumentException("Invalid indexed property '" + name + "'");
|
|
int index = -1;
|
|
try {
|
|
String subscript = name.substring(delim + 1, delim2);
|
|
index = Integer.parseInt(subscript);
|
|
} catch (NumberFormatException e) {
|
|
throw new IllegalArgumentException("Invalid indexed property '" + name + "'");
|
|
}
|
|
name = name.substring(0, delim);
|
|
setIndexedProperty(bean, name, index, value);
|
|
}
|
|
|
|
public static void setIndexedProperty(Object bean, String name, int index, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
((DynaBean)bean).set(name, index, value);
|
|
return;
|
|
}
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
if (descriptor instanceof IndexedPropertyDescriptor) {
|
|
Method writeMethod = ((IndexedPropertyDescriptor)descriptor).getIndexedWriteMethod();
|
|
if (writeMethod != null) {
|
|
Object[] subscript = new Object[2];
|
|
subscript[0] = new Integer(index);
|
|
subscript[1] = value;
|
|
try {
|
|
writeMethod.invoke(bean, subscript);
|
|
} catch (InvocationTargetException e) {
|
|
if (e.getTargetException() instanceof ArrayIndexOutOfBoundsException)
|
|
throw (ArrayIndexOutOfBoundsException)e.getTargetException();
|
|
throw e;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
Method readMethod = descriptor.getReadMethod();
|
|
if (readMethod == null)
|
|
throw new NoSuchMethodException("Property '" + name + "' has no getter method");
|
|
Object array = readMethod.invoke(bean, new Object[0]);
|
|
if (!array.getClass().isArray()) {
|
|
if (array instanceof List) {
|
|
((List)array).set(index, value);
|
|
} else {
|
|
throw new IllegalArgumentException("Property '" + name + "' is not indexed");
|
|
}
|
|
} else {
|
|
Array.set(array, index, value);
|
|
}
|
|
}
|
|
|
|
public static void setMappedProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
int delim = name.indexOf('(');
|
|
int delim2 = name.indexOf(')');
|
|
if (delim < 0 || delim2 <= delim)
|
|
throw new IllegalArgumentException("Invalid mapped property '" + name + "'");
|
|
String key = name.substring(delim + 1, delim2);
|
|
name = name.substring(0, delim);
|
|
setMappedProperty(bean, name, key, value);
|
|
}
|
|
|
|
public static void setMappedProperty(Object bean, String name, String key, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (key == null)
|
|
throw new IllegalArgumentException("No key specified");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
((DynaBean)bean).set(name, key, value);
|
|
return;
|
|
}
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
if (descriptor instanceof MappedPropertyDescriptor) {
|
|
Method mappedWriteMethod = ((MappedPropertyDescriptor)descriptor).getMappedWriteMethod();
|
|
if (mappedWriteMethod != null) {
|
|
Object[] params = new Object[2];
|
|
params[0] = key;
|
|
params[1] = value;
|
|
mappedWriteMethod.invoke(bean, params);
|
|
} else {
|
|
throw new NoSuchMethodException("Property '" + name + "' has no mapped setter method");
|
|
}
|
|
} else {
|
|
Method readMethod = descriptor.getReadMethod();
|
|
if (readMethod != null) {
|
|
Object invokeResult = readMethod.invoke(bean, new Object[0]);
|
|
if (invokeResult instanceof Map)
|
|
((Map)invokeResult).put(key, value);
|
|
} else {
|
|
throw new NoSuchMethodException("Property '" + name + "' has no mapped getter method");
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void setNestedProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
int indexOfINDEXED_DELIM = -1;
|
|
int indexOfMAPPED_DELIM = -1;
|
|
while (true) {
|
|
int delim = name.indexOf('.');
|
|
if (delim < 0)
|
|
break;
|
|
String next = name.substring(0, delim);
|
|
indexOfINDEXED_DELIM = next.indexOf('[');
|
|
indexOfMAPPED_DELIM = next.indexOf('(');
|
|
if (bean instanceof Map) {
|
|
bean = ((Map)bean).get(next);
|
|
} else if (indexOfMAPPED_DELIM >= 0) {
|
|
bean = getMappedProperty(bean, next);
|
|
} else if (indexOfINDEXED_DELIM >= 0) {
|
|
bean = getIndexedProperty(bean, next);
|
|
} else {
|
|
bean = getSimpleProperty(bean, next);
|
|
}
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("Null property value for '" + name.substring(0, delim) + "'");
|
|
name = name.substring(delim + 1);
|
|
}
|
|
indexOfINDEXED_DELIM = name.indexOf('[');
|
|
indexOfMAPPED_DELIM = name.indexOf('(');
|
|
if (bean instanceof Map) {
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null) {
|
|
((Map)bean).put(name, value);
|
|
} else {
|
|
setSimpleProperty(bean, name, value);
|
|
}
|
|
} else if (indexOfMAPPED_DELIM >= 0) {
|
|
setMappedProperty(bean, name, value);
|
|
} else if (indexOfINDEXED_DELIM >= 0) {
|
|
setIndexedProperty(bean, name, value);
|
|
} else {
|
|
setSimpleProperty(bean, name, value);
|
|
}
|
|
}
|
|
|
|
public static void setProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
setNestedProperty(bean, name, value);
|
|
}
|
|
|
|
public static void setSimpleProperty(Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
|
|
if (bean == null)
|
|
throw new IllegalArgumentException("No bean specified");
|
|
if (name == null)
|
|
throw new IllegalArgumentException("No name specified");
|
|
if (name.indexOf('.') >= 0)
|
|
throw new IllegalArgumentException("Nested property names are not allowed");
|
|
if (name.indexOf('[') >= 0)
|
|
throw new IllegalArgumentException("Indexed property names are not allowed");
|
|
if (name.indexOf('(') >= 0)
|
|
throw new IllegalArgumentException("Mapped property names are not allowed");
|
|
if (bean instanceof DynaBean) {
|
|
DynaProperty dynaProperty = ((DynaBean)bean).getDynaClass().getDynaProperty(name);
|
|
if (dynaProperty == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
((DynaBean)bean).set(name, value);
|
|
return;
|
|
}
|
|
PropertyDescriptor descriptor = getPropertyDescriptor(bean, name);
|
|
if (descriptor == null)
|
|
throw new NoSuchMethodException("Unknown property '" + name + "'");
|
|
Method writeMethod = getWriteMethod(descriptor);
|
|
if (writeMethod == null)
|
|
throw new NoSuchMethodException("Property '" + name + "' has no setter method");
|
|
Object[] values = new Object[1];
|
|
values[0] = value;
|
|
writeMethod.invoke(bean, values);
|
|
}
|
|
}
|