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); } }