propertyutilsbean.java

来自「JAVA 文章管理系统源码」· Java 代码 · 共 1,626 行 · 第 1/5 页

JAVA
1,626
字号
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * Utility methods for using Java Reflection APIs to facilitate generic
 * property getter and setter operations on Java objects.  Much of this
 * code was originally included in <code>BeanUtils</code>, but has been
 * separated because of the volume of code involved.
 * <p>
 * In general, the objects that are examined and modified using these
 * methods are expected to conform to the property getter and setter method
 * naming conventions described in the JavaBeans Specification (Version 1.0.1).
 * No data type conversions are performed, and there are no usage of any
 * <code>PropertyEditor</code> classes that have been registered, although
 * a convenient way to access the registered classes themselves is included.
 * <p>
 * For the purposes of this class, five formats for referencing a particular
 * property value of a bean are defined, with the layout of an identifying
 * String in parentheses:
 * <ul>
 * <li><strong>Simple (<code>name</code>)</strong> - The specified
 *     <code>name</code> identifies an individual property of a particular
 *     JavaBean.  The name of the actual getter or setter method to be used
 *     is determined using standard JavaBeans instrospection, so that (unless
 *     overridden by a <code>BeanInfo</code> class, a property named "xyz"
 *     will have a getter method named <code>getXyz()</code> or (for boolean
 *     properties only) <code>isXyz()</code>, and a setter method named
 *     <code>setXyz()</code>.</li>
 * <li><strong>Nested (<code>name1.name2.name3</code>)</strong> The first
 *     name element is used to select a property getter, as for simple
 *     references above.  The object returned for this property is then
 *     consulted, using the same approach, for a property getter for a
 *     property named <code>name2</code>, and so on.  The property value that
 *     is ultimately retrieved or modified is the one identified by the
 *     last name element.</li>
 * <li><strong>Indexed (<code>name[index]</code>)</strong> - The underlying
 *     property value is assumed to be an array, or this JavaBean is assumed
 *     to have indexed property getter and setter methods.  The appropriate
 *     (zero-relative) entry in the array is selected.  <code>List</code>
 *     objects are now also supported for read/write.  You simply need to define
 *     a getter that returns the <code>List</code></li>
 * <li><strong>Mapped (<code>name(key)</code>)</strong> - The JavaBean
 *     is assumed to have an property getter and setter methods with an
 *     additional attribute of type <code>java.lang.String</code>.</li>
 * <li><strong>Combined (<code>name1.name2[index].name3(key)</code>)</strong> -
 *     Combining mapped, nested, and indexed references is also
 *     supported.</li>
 * </ul>
 *
 * @author Craig R. McClanahan
 * @author Ralph Schaer
 * @author Chris Audley
 * @author Rey Fran鏾is
 * @author Gregor Ra齧an
 * @author Jan Sorensen
 * @author Scott Sanders
 * @version $Revision: 1.14.2.1 $ $Date: 2004/07/27 21:31:00 $
 * @see PropertyUtils
 * @since 1.7
 */

public class PropertyUtilsBean {

    // --------------------------------------------------------- Class Methods

    protected static PropertyUtilsBean getInstance() {
        return BeanUtilsBean.getInstance().getPropertyUtils();
    }

    // --------------------------------------------------------- Variables

    /**
     * The cache of PropertyDescriptor arrays for beans we have already
     * introspected, keyed by the java.lang.Class of this object.
     */
    private FastHashMap descriptorsCache = null;
    private FastHashMap mappedDescriptorsCache = null;

    /** Log instance */
    private Log log = LogFactory.getLog(PropertyUtils.class);

    // ---------------------------------------------------------- Constructors

    /** Base constructor */
    public PropertyUtilsBean() {
        descriptorsCache = new FastHashMap();
        descriptorsCache.setFast(true);
        mappedDescriptorsCache = new FastHashMap();
        mappedDescriptorsCache.setFast(true);
    }


    // --------------------------------------------------------- Public Methods


    /**
     * Clear any cached property descriptors information for all classes
     * loaded by any class loaders.  This is useful in cases where class
     * loaders are thrown away to implement class reloading.
     */
    public void clearDescriptors() {

        descriptorsCache.clear();
        mappedDescriptorsCache.clear();
        Introspector.flushCaches();

    }


    /**
     * <p>Copy property values from the "origin" bean to the "destination" bean
     * for all cases where the property names are the same (even though the
     * actual getter and setter methods might have been customized via
     * <code>BeanInfo</code> classes).  No conversions are performed on the
     * actual property values -- it is assumed that the values retrieved from
     * the origin bean are assignment-compatible with the types expected by
     * the destination bean.</p>
     *
     * <p>If the origin "bean" is actually a <code>Map</code>, it is assumed
     * to contain String-valued <strong>simple</strong> property names as the keys, pointing
     * at the corresponding property values that will be set in the destination
     * bean.<strong>Note</strong> that this method is intended to perform
     * a "shallow copy" of the properties and so complex properties
     * (for example, nested ones) will not be copied.</p>
     *
     * @param dest Destination bean whose properties are modified
     * @param orig Origin bean whose properties are retrieved
     *
     * @exception IllegalAccessException if the caller does not have
     *  access to the property accessor method
     * @exception IllegalArgumentException if the <code>dest</code> or
     *  <code>orig</code> argument is null
     * @exception InvocationTargetException if the property accessor method
     *  throws an exception
     * @exception NoSuchMethodException if an accessor method for this
     *  propety cannot be found
     */
    public 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 (dest is a standard JavaBean) */ {
                    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 = (String) names.next();
                if (dest instanceof DynaBean) {
                    if (isWriteable(dest, name)) {
                        Object value = ((Map) orig).get(name);
                        ((DynaBean) dest).set(name, value);
                    }
                } else /* if (dest is a standard JavaBean) */ {
                    if (isWriteable(dest, name)) {
                        Object value = ((Map) orig).get(name);
                        setSimpleProperty(dest, name, value);
                    }
                }
            }
        } else /* if (orig is a standard JavaBean) */ {
            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 (dest is a standard JavaBean) */ {
                        if (isWriteable(dest, name)) {
                            Object value = getSimpleProperty(orig, name);
                            if(value != null && ! value.equals("") ){
                              setSimpleProperty(dest, name, value);
                            }
                        }
                    }
                }
            }
        }

    }

    public void copyPropertiesNull(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 (dest is a standard JavaBean) */ {
            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 = (String) names.next();
        if (dest instanceof DynaBean) {
            if (isWriteable(dest, name)) {
                Object value = ((Map) orig).get(name);
                ((DynaBean) dest).set(name, value);
            }
        } else /* if (dest is a standard JavaBean) */ {
            if (isWriteable(dest, name)) {
                Object value = ((Map) orig).get(name);
                setSimpleProperty(dest, name, value);
            }
        }
    }
} else /* if (orig is a standard JavaBean) */ {
    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 (dest is a standard JavaBean) */ {
                if (isWriteable(dest, name)) {
                    Object value = getSimpleProperty(orig, name);
                    
                      setSimpleProperty(dest, name, value);
                    
                }
            }
        }
    }
}

}


    /**
     * <p>Return the entire set of properties for which the specified bean
     * provides a read method.  This map contains the unconverted property
     * values for all properties for which a read method is provided
     * (i.e. where the <code>getReadMethod()</code> returns non-null).</p>
     *
     * <p><strong>FIXME</strong> - Does not account for mapped properties.</p>
     *
     * @param bean Bean whose properties are to be extracted
     *
     * @exception IllegalAccessException if the caller does not have
     *  access to the property accessor method
     * @exception IllegalArgumentException if <code>bean</code> is null
     * @exception InvocationTargetException if the property accessor method

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?