in src/main/java/org/apache/commons/beanutils2/BeanUtilsBean.java [333:440]
public void copyProperty(final Object bean, String name, Object value) throws IllegalAccessException, InvocationTargetException {
// Trace logging (if enabled)
if (LOG.isTraceEnabled()) {
final StringBuilder sb = new StringBuilder(" copyProperty(");
sb.append(bean);
sb.append(", ");
sb.append(name);
sb.append(", ");
if (value == null) {
sb.append("<NULL>");
} else if (value instanceof String) {
sb.append((String) value);
} else if (value instanceof String[]) {
final String[] values = (String[]) value;
sb.append('[');
for (int i = 0; i < values.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(values[i]);
}
sb.append(']');
} else {
sb.append(value.toString());
}
sb.append(')');
LOG.trace(sb.toString());
}
// Resolve any nested expression to get the actual target bean
Object target = bean;
final Resolver resolver = getPropertyUtils().getResolver();
while (resolver.hasNested(name)) {
try {
target = getPropertyUtils().getProperty(target, resolver.next(name));
name = resolver.remove(name);
} catch (final NoSuchMethodException e) {
return; // Skip this property setter
}
}
if (LOG.isTraceEnabled()) {
LOG.trace(" Target bean = " + target);
LOG.trace(" Target name = " + name);
}
// Declare local variables we will require
final String propName = resolver.getProperty(name); // Simple name of target property
Class<?> type = null; // Java type of target property
final int index = resolver.getIndex(name); // Indexed subscript value (if any)
final String key = resolver.getKey(name); // Mapped key value (if any)
// Calculate the target property type
if (target instanceof DynaBean) {
final DynaClass dynaClass = ((DynaBean) target).getDynaClass();
final DynaProperty dynaProperty = dynaClass.getDynaProperty(propName);
if (dynaProperty == null) {
return; // Skip this property setter
}
type = dynaPropertyType(dynaProperty, value);
} else {
PropertyDescriptor descriptor = null;
try {
descriptor = getPropertyUtils().getPropertyDescriptor(target, name);
if (descriptor == null) {
return; // Skip this property setter
}
} catch (final NoSuchMethodException e) {
return; // Skip this property setter
}
type = descriptor.getPropertyType();
if (type == null) {
// Most likely an indexed setter on a POJB only
if (LOG.isTraceEnabled()) {
LOG.trace(" target type for property '" + propName + "' is null, so skipping the setter");
}
return;
}
}
if (LOG.isTraceEnabled()) {
LOG.trace(" target propName=" + propName + ", type=" + type + ", index=" + index + ", key=" + key);
}
// Convert the specified value to the required type and store it
if (index >= 0) { // Destination must be indexed
value = convertForCopy(value, type.getComponentType());
try {
getPropertyUtils().setIndexedProperty(target, propName, index, value);
} catch (final NoSuchMethodException e) {
throw new InvocationTargetException(e, "Cannot set " + propName);
}
} else if (key != null) { // Destination must be mapped
// Maps do not know what the preferred data type is,
// so perform no conversions at all
// FIXME - should we create or support a TypedMap?
try {
getPropertyUtils().setMappedProperty(target, propName, key, value);
} catch (final NoSuchMethodException e) {
throw new InvocationTargetException(e, "Cannot set " + propName);
}
} else { // Destination must be simple
value = convertForCopy(value, type);
try {
getPropertyUtils().setSimpleProperty(target, propName, value);
} catch (final NoSuchMethodException e) {
throw new InvocationTargetException(e, "Cannot set " + propName);
}
}
}