集册 Java实例教程 在指定对象上设置指定属性。

在指定对象上设置指定属性。

欢马劈雪     最近更新时间:2020-01-02 10:19:05

436
在指定对象上设置指定属性。

/*

 * The contents of this file are subject to the Sapient Public License

 * Version 1.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://carbon.sf.net/License.html.

 *

 * Software distributed under the License is distributed on an "AS IS" basis,

 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for

 * the specific language governing rights and limitations under the License.

 *

 * The Original Code is The Carbon Component Framework.

 *

 * The Initial Developer of the Original Code is Sapient Corporation

 *

 * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.

 *//*from 时 代 J     a    v  a - nowjava.com*/

//package com.nowjava;

import java.beans.BeanInfo;

import java.beans.IntrospectionException;

import java.beans.Introspector;

import java.beans.PropertyDescriptor;

import java.lang.reflect.InvocationTargetException;

import java.lang.reflect.Method;

import java.util.StringTokenizer;


public class Main {

    public static void main(String[] argv) throws Exception {

        Object bean = "nowjava.com";

        String propertyNames = "nowjava.com";

        Object value = "nowjava.com";

        setObjectAttribute(bean, propertyNames, value);

    }


    /**

     * String used to separate multiple properties inside of embedded

     * beans.

     */

    private static final String PROPERTY_SEPARATOR = ".";

    /**

     * an empty object array used for null parameter method reflection

     */

    private static Object[] NO_ARGUMENTS_ARRAY = new Object[] {};//时代Java 提供


    /**

     * <p>Sets the specified attribute on the specified object.  For example,

     * <code>getObjectAttribute(o, "address.line1", value)</code> will call

     * <code>o.getAddress().setLine1(value)</code>.<p>

     *

     * <p>The attribute specified may contain as many levels as you like. If at

     * any time a null reference is acquired by calling one of the successive

     * getter methods, then a <code>NullPointerException</code> is thrown.</p>

     *

     * @param bean the bean to call the getters on

     * @param propertyNames the name of the attribute(s) to set.  If this is

     *        null or the empty string, then an exception is thrown.

     * @param value the value of the object to set on the bean property

     *

     * @throws PropertyNotFoundException indicates the the given property

     *         could not be found on the bean

     * @throws IllegalArgumentException if the supplied parameter is not of

     *   a valid type

     * @throws NoSuchMethodException never

     * @throws IllegalAccessException if a getter or setter method is

     *   not public or property is read-only.

     * @throws InvocationTargetException if a specified getter method throws an

     *   exception.

     */

    public static void setObjectAttribute(Object bean,

            String propertyNames, Object value)

            throws IllegalAccessException, IllegalArgumentException,

            InvocationTargetException, NoSuchMethodException {


        Object result = bean;

        String propertyName = propertyNames;


        // Check if this has some embedded properties.  If it does, use the

        // getObjectAttribute to get the proper object to call this on.

        int indexOfLastPropertySeparator = propertyName

                .lastIndexOf(PROPERTY_SEPARATOR);


        if (indexOfLastPropertySeparator >= 0) {

            String embeddedProperties = propertyName.substring(0,

                    indexOfLastPropertySeparator);


            // Grab the final property name after the last property separator

            propertyName = propertyName

                    .substring(indexOfLastPropertySeparator

                            + PROPERTY_SEPARATOR.length());


            result = getObjectAttribute(result, embeddedProperties);

        }


        Class resultClass = result.getClass();


        PropertyDescriptor propertyDescriptor = getPropertyDescriptor(

                propertyName, resultClass);


        Method writeMethod = propertyDescriptor.getWriteMethod();

        if (writeMethod == null) {

            throw new IllegalAccessException(

                    "User is attempting to write "

                            + "to a property that has no write method.  This is likely "

                            + "a read-only bean property.  Caused by property ["

                            + propertyName + "] on class [" + resultClass

                            + "]");

        }


        writeMethod.invoke(result, new Object[] { value });

    }


    /**

     * <p>Gets the specified attribute from the specified object.  For example,

     * <code>getObjectAttribute(o, "address.line1")</code> will return

     * the result of calling <code>o.getAddress().getLine1()</code>.<p>

     *

     * <p>The attribute specified may contain as many levels as you like. If at

     * any time a null reference is acquired by calling one of the successive

     * getter methods, then the return value from this method is also null.</p>

     *

     * <p>When reading from a boolean property the underlying bean introspector

     * first looks for an is&lt;Property&gt; read method, not finding one it will

     * still look for a get&lt;Property&gt; read method.  Not finding either, the

     * property is considered write-only.</p>

     *

     * @param bean the bean to set the property on

     * @param propertyNames the name of the propertie(s) to retrieve.  If this is

     *        null or the empty string, then <code>bean</code> will be returned.

     * @return the object value of the bean attribute

     *

     * @throws PropertyNotFoundException indicates the the given property

     *         could not be found on the bean

     * @throws NoSuchMethodException Not thrown

     * @throws InvocationTargetException if a specified getter method throws an

     *   exception.

     * @throws IllegalAccessException if a getter method is

     *   not public or property is write-only.

     */

    public static Object getObjectAttribute(Object bean,

            String propertyNames) throws NoSuchMethodException,

            InvocationTargetException, IllegalAccessException {


        Object result = bean;


        StringTokenizer propertyTokenizer = new StringTokenizer(

                propertyNames, PROPERTY_SEPARATOR);


        // Run through the tokens, calling get methods and

        // replacing result with the new object each time.

        // If the result equals null, then simply return null.

        while (propertyTokenizer.hasMoreElements() && result != null) {

            Class resultClass = result.getClass();

            String currentPropertyName = propertyTokenizer.nextToken();


            PropertyDescriptor propertyDescriptor = getPropertyDescriptor(

                    currentPropertyName, resultClass);


            Method readMethod = propertyDescriptor.getReadMethod();

            if (readMethod == null) {

                throw new IllegalAccessException(

                        "User is attempting to "

                                + "read from a property that has no read method.  "

                                + " This is likely a write-only bean property.  Caused "

                                + "by property [" + currentPropertyName

                                + "] on class [" + resultClass + "]");

            }


            result = readMethod.invoke(result, NO_ARGUMENTS_ARRAY);

        }


        return result;

    }


    /**

     * Retrieves a property descriptor object for a given property.

     * <p>

     * Uses the classes in <code>java.beans</code> to get back

     * a descriptor for a property.  Read-only and write-only

     * properties will have a slower return time.

     * </p>

     *

     * @param propertyName The programmatic name of the property

     * @param beanClass The Class object for the target bean.

     *                  For example sun.beans.OurButton.class.

     * @return a PropertyDescriptor for a property that follows the

     *         standard Java naming conventions.

     * @throws PropertyNotFoundException indicates that the property

     *         could not be found on the bean class.

     */

    private static final PropertyDescriptor getPropertyDescriptor(

            String propertyName, Class beanClass) {


        PropertyDescriptor resultPropertyDescriptor = null;


        char[] pNameArray = propertyName.toCharArray();

        pNameArray[0] = Character.toLowerCase(pNameArray[0]);

        propertyName = new String(pNameArray);


        try {

            resultPropertyDescriptor = new PropertyDescriptor(propertyName,

                    beanClass);

        } catch (IntrospectionException e1) {

            
展开阅读全文