public void copyProperty()

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