    001/*
    002 * Licensed to the Apache Software Foundation (ASF) under one or more
    003 * contributor license agreements.  See the NOTICE file distributed with
    004 * this work for additional information regarding copyright ownership.
    005 * The ASF licenses this file to You under the Apache License, Version 2.0
    006 * (the "License"); you may not use this file except in compliance with
    007 * the License.  You may obtain a copy of the License at
    008 *
    009 *      http://www.apache.org/licenses/LICENSE-2.0
    010 *
    011 * Unless required by applicable law or agreed to in writing, software
    012 * distributed under the License is distributed on an "AS IS" BASIS,
    013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014 * See the License for the specific language governing permissions and
    015 * limitations under the License.
    016 */
    017
    018package org.apache.commons.beanutils;
    019
    020import java.beans.PropertyDescriptor;
    021import java.lang.reflect.InvocationTargetException;
    022import java.lang.reflect.Method;
    023import java.util.Map;
    024
    025import org.apache.commons.collections.FastHashMap;
    026
    027/**
    028 * <p>Utility methods for using Java Reflection APIs to facilitate generic
    029 * property getter and setter operations on Java objects.</p>
    030 *
    031 * <p>The implementations for these methods are provided by <code>PropertyUtilsBean</code>.
    032 * For more details see {@link PropertyUtilsBean}.</p>
    033 *
    034 * @see PropertyUtilsBean
    035 * @see org.apache.commons.beanutils.expression.Resolver
    036 */
    037
    038public class PropertyUtils {
    039
    040    /**
    041     * The delimiter that preceeds the zero-relative subscript for an
    042     * indexed reference.
    043     *
    044     * @deprecated The notation used for property name expressions is now
    045     * dependant on the {@link org.apache.commons.beanutils.expression.Resolver}
    046     * implementation being used.
    047     */
    048    @Deprecated
    049    public static final char INDEXED_DELIM = '[';
    050
    051    /**
    052     * The delimiter that follows the zero-relative subscript for an
    053     * indexed reference.
    054     *
    055     * @deprecated The notation used for property name expressions is now
    056     * dependant on the {@link org.apache.commons.beanutils.expression.Resolver}
    057     * implementation being used.
    058     */
    059    @Deprecated
    060    public static final char INDEXED_DELIM2 = ']';
    061
    062    /**
    063     * The delimiter that preceeds the key of a mapped property.
    064     *
    065     * @deprecated The notation used for property name expressions is now
    066     * dependant on the {@link org.apache.commons.beanutils.expression.Resolver}
    067     * implementation being used.
    068     */
    069    @Deprecated
    070    public static final char MAPPED_DELIM = '(';
    071
    072    /**
    073     * The delimiter that follows the key of a mapped property.
    074     *
    075     * @deprecated The notation used for property name expressions is now
    076     * dependant on the {@link org.apache.commons.beanutils.expression.Resolver}
    077     * implementation being used.
    078     */
    079    @Deprecated
    080    public static final char MAPPED_DELIM2 = ')';
    081
    082    /**
    083     * The delimiter that separates the components of a nested reference.
    084     *
    085     * @deprecated The notation used for property name expressions is now
    086     * dependant on the {@link org.apache.commons.beanutils.expression.Resolver}
    087     * implementation being used.
    088     */
    089    @Deprecated
    090    public static final char NESTED_DELIM = '.';
    091
    092    /**
    093     * The debugging detail level for this component.
    094     *
    095     * Note that this static variable will have unexpected side-effects if
    096     * this class is deployed in a shared classloader within a container.
    097     * However as it is actually completely ignored by this class due to its
    098     * deprecated status, it doesn't do any actual harm.
    099     *
    100     * @deprecated The <code>debug</code> static property is no longer used
    101     */
    102    @Deprecated
    103    private static int debug;
    104
    105    /**
    106     * Adds a <code>BeanIntrospector</code>. This object is invoked when the
    107     * property descriptors of a class need to be obtained.
    108     *
    109     * @param introspector the <code>BeanIntrospector</code> to be added (must
    110     *        not be <strong>null</strong>
    111     * @throws IllegalArgumentException if the argument is <strong>null</strong>
    112     * @since 1.9
    113     */
    114    public static void addBeanIntrospector(final BeanIntrospector introspector) {
    115        PropertyUtilsBean.getInstance().addBeanIntrospector(introspector);
    116    }
    117
    118    /**
    119     * Clear any cached property descriptors information for all classes
    120     * loaded by any class loaders.  This is useful in cases where class
    121     * loaders are thrown away to implement class reloading.
    122     *
    123     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    124     *
    125     * @see PropertyUtilsBean#clearDescriptors
    126     */
    127    public static void clearDescriptors() {
    128
    129        PropertyUtilsBean.getInstance().clearDescriptors();
    130
    131    }
    132
    133    /**
    134     * <p>Copy property values from the "origin" bean to the "destination" bean
    135     * for all cases where the property names are the same (even though the
    136     * actual getter and setter methods might have been customized via
    137     * <code>BeanInfo</code> classes).</p>
    138     *
    139     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    140     *
    141     * @param dest Destination bean whose properties are modified
    142     * @param orig Origin bean whose properties are retrieved
    143     * @throws IllegalAccessException if the caller does not have
    144     *  access to the property accessor method
    145     * @throws IllegalArgumentException if the <code>dest</code> or
    146     *  <code>orig</code> argument is null
    147     * @throws InvocationTargetException if the property accessor method
    148     *  throws an exception
    149     * @throws NoSuchMethodException if an accessor method for this
    150     *  propety cannot be found
    151     * @see PropertyUtilsBean#copyProperties
    152     */
    153    public static void copyProperties(final Object dest, final Object orig)
    154            throws IllegalAccessException, InvocationTargetException,
    155            NoSuchMethodException {
    156
    157        PropertyUtilsBean.getInstance().copyProperties(dest, orig);
    158    }
    159
    160    /**
    161     * <p>Return the entire set of properties for which the specified bean
    162     * provides a read method.</p>
    163     *
    164     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    165     *
    166     * @param bean Bean whose properties are to be extracted
    167     * @return The set of properties for the bean
    168     * @throws IllegalAccessException if the caller does not have
    169     *  access to the property accessor method
    170     * @throws IllegalArgumentException if <code>bean</code> is null
    171     * @throws InvocationTargetException if the property accessor method
    172     *  throws an exception
    173     * @throws NoSuchMethodException if an accessor method for this
    174     *  propety cannot be found
    175     * @see PropertyUtilsBean#describe
    176     */
    177    public static Map<String, Object> describe(final Object bean)
    178            throws IllegalAccessException, InvocationTargetException,
    179            NoSuchMethodException {
    180
    181        return PropertyUtilsBean.getInstance().describe(bean);
    182
    183    }
    184
    185    /**
    186     * The <code>debug</code> static property is no longer used
    187     * @return debug property
    188     * @deprecated The <code>debug</code> static property is no longer used
    189     */
    190    @Deprecated
    191    public static int getDebug() {
    192        return debug;
    193    }
    194
    195    /**
    196     * <p>Return the value of the specified indexed property of the specified
    197     * bean, with no type conversions.</p>
    198     *
    199     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    200     *
    201     * @param bean Bean whose property is to be extracted
    202     * @param name <code>propertyname[index]</code> of the property value
    203     *  to be extracted
    204     * @return the indexed property value
    205     * @throws IndexOutOfBoundsException if the specified index
    206     *  is outside the valid range for the underlying property
    207     * @throws IllegalAccessException if the caller does not have
    208     *  access to the property accessor method
    209     * @throws IllegalArgumentException if <code>bean</code> or
    210     *  <code>name</code> is null
    211     * @throws InvocationTargetException if the property accessor method
    212     *  throws an exception
    213     * @throws NoSuchMethodException if an accessor method for this
    214     *  propety cannot be found
    215     * @see PropertyUtilsBean#getIndexedProperty(Object,String)
    216     */
    217    public static Object getIndexedProperty(final Object bean, final String name)
    218            throws IllegalAccessException, InvocationTargetException,
    219            NoSuchMethodException {
    220
    221        return PropertyUtilsBean.getInstance().getIndexedProperty(bean, name);
    222
    223    }
    224
    225    /**
    226     * <p>Return the value of the specified indexed property of the specified
    227     * bean, with no type conversions.</p>
    228     *
    229     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    230     *
    231     * @param bean Bean whose property is to be extracted
    232     * @param name Simple property name of the property value to be extracted
    233     * @param index Index of the property value to be extracted
    234     * @return the indexed property value
    235     * @throws IndexOutOfBoundsException if the specified index
    236     *  is outside the valid range for the underlying property
    237     * @throws IllegalAccessException if the caller does not have
    238     *  access to the property accessor method
    239     * @throws IllegalArgumentException if <code>bean</code> or
    240     *  <code>name</code> is null
    241     * @throws InvocationTargetException if the property accessor method
    242     *  throws an exception
    243     * @throws NoSuchMethodException if an accessor method for this
    244     *  propety cannot be found
    245     * @see PropertyUtilsBean#getIndexedProperty(Object,String, int)
    246     */
    247    public static Object getIndexedProperty(final Object bean,
    248                                            final String name, final int index)
    249            throws IllegalAccessException, InvocationTargetException,
    250            NoSuchMethodException {
    251
    252        return PropertyUtilsBean.getInstance().getIndexedProperty(bean, name, index);
    253    }
    254
    255    /**
    256     * <p>Return the value of the specified mapped property of the
    257     * specified bean, with no type conversions.</p>
    258     *
    259     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    260     *
    261     * @param bean Bean whose property is to be extracted
    262     * @param name <code>propertyname(key)</code> of the property value
    263     *  to be extracted
    264     * @return the mapped property value
    265     * @throws IllegalAccessException if the caller does not have
    266     *  access to the property accessor method
    267     * @throws InvocationTargetException if the property accessor method
    268     *  throws an exception
    269     * @throws NoSuchMethodException if an accessor method for this
    270     *  propety cannot be found
    271     * @see PropertyUtilsBean#getMappedProperty(Object,String)
    272     */
    273    public static Object getMappedProperty(final Object bean, final String name)
    274            throws IllegalAccessException, InvocationTargetException,
    275            NoSuchMethodException {
    276
    277        return PropertyUtilsBean.getInstance().getMappedProperty(bean, name);
    278
    279    }
    280
    281    /**
    282     * <p>Return the value of the specified mapped property of the specified
    283     * bean, with no type conversions.</p>
    284     *
    285     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    286     *
    287     * @param bean Bean whose property is to be extracted
    288     * @param name Mapped property name of the property value to be extracted
    289     * @param key Key of the property value to be extracted
    290     * @return the mapped property value
    291     * @throws IllegalAccessException if the caller does not have
    292     *  access to the property accessor method
    293     * @throws InvocationTargetException if the property accessor method
    294     *  throws an exception
    295     * @throws NoSuchMethodException if an accessor method for this
    296     *  propety cannot be found
    297     * @see PropertyUtilsBean#getMappedProperty(Object,String, String)
    298     */
    299    public static Object getMappedProperty(final Object bean,
    300                                           final String name, final String key)
    301            throws IllegalAccessException, InvocationTargetException,
    302            NoSuchMethodException {
    303
    304        return PropertyUtilsBean.getInstance().getMappedProperty(bean, name, key);
    305
    306    }
    307
    308    /**
    309     * <p>Return the mapped property descriptors for this bean class.</p>
    310     *
    311     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    312     *
    313     * @param beanClass Bean class to be introspected
    314     * @return the mapped property descriptors
    315     * @see PropertyUtilsBean#getMappedPropertyDescriptors(Class)
    316     * @deprecated This method should not be exposed
    317     */
    318    @Deprecated
    319    public static FastHashMap getMappedPropertyDescriptors(final Class<?> beanClass) {
    320
    321        return PropertyUtilsBean.getInstance().getMappedPropertyDescriptors(beanClass);
    322
    323    }
    324
    325    /**
    326     * <p>Return the mapped property descriptors for this bean.</p>
    327     *
    328     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    329     *
    330     * @param bean Bean to be introspected
    331     * @return the mapped property descriptors
    332     * @see PropertyUtilsBean#getMappedPropertyDescriptors(Object)
    333     * @deprecated This method should not be exposed
    334     */
    335    @Deprecated
    336    public static FastHashMap getMappedPropertyDescriptors(final Object bean) {
    337
    338        return PropertyUtilsBean.getInstance().getMappedPropertyDescriptors(bean);
    339
    340    }
    341
    342    /**
    343     * <p>Return the value of the (possibly nested) property of the specified
    344     * name, for the specified bean, with no type conversions.</p>
    345     *
    346     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    347     *
    348     * @param bean Bean whose property is to be extracted
    349     * @param name Possibly nested name of the property to be extracted
    350     * @return the nested property value
    351     * @throws IllegalAccessException if the caller does not have
    352     *  access to the property accessor method
    353     * @throws IllegalArgumentException if <code>bean</code> or
    354     *  <code>name</code> is null
    355     * @throws NestedNullException if a nested reference to a
    356     *  property returns null
    357     * @throws InvocationTargetException
    358     * if the property accessor method throws an exception
    359     * @throws NoSuchMethodException if an accessor method for this
    360     *  propety cannot be found
    361     * @see PropertyUtilsBean#getNestedProperty
    362     */
    363    public static Object getNestedProperty(final Object bean, final String name)
    364            throws IllegalAccessException, InvocationTargetException,
    365            NoSuchMethodException {
    366
    367        return PropertyUtilsBean.getInstance().getNestedProperty(bean, name);
    368
    369    }
    370
    371    /**
    372     * <p>Return the value of the specified property of the specified bean,
    373     * no matter which property reference format is used, with no
    374     * type conversions.</p>
    375     *
    376     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    377     *
    378     * @param bean Bean whose property is to be extracted
    379     * @param name Possibly indexed and/or nested name of the property
    380     *  to be extracted
    381     * @return the property value
    382     * @throws IllegalAccessException if the caller does not have
    383     *  access to the property accessor method
    384     * @throws IllegalArgumentException if <code>bean</code> or
    385     *  <code>name</code> is null
    386     * @throws InvocationTargetException if the property accessor method
    387     *  throws an exception
    388     * @throws NoSuchMethodException if an accessor method for this
    389     *  propety cannot be found
    390     * @see PropertyUtilsBean#getProperty
    391     */
    392    public static Object getProperty(final Object bean, final String name)
    393            throws IllegalAccessException, InvocationTargetException,
    394            NoSuchMethodException {
    395
    396        return PropertyUtilsBean.getInstance().getProperty(bean, name);
    397
    398    }
    399
    400    /**
    401     * <p>Retrieve the property descriptor for the specified property of the
    402     * specified bean, or return <code>null</code> if there is no such
    403     * descriptor.</p>
    404     *
    405     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    406     *
    407     * @param bean Bean for which a property descriptor is requested
    408     * @param name Possibly indexed and/or nested name of the property for
    409     *  which a property descriptor is requested
    410     * @return the property descriptor
    411     * @throws IllegalAccessException if the caller does not have
    412     *  access to the property accessor method
    413     * @throws IllegalArgumentException if <code>bean</code> or
    414     *  <code>name</code> is null
    415     * @throws IllegalArgumentException if a nested reference to a
    416     *  property returns null
    417     * @throws InvocationTargetException if the property accessor method
    418     *  throws an exception
    419     * @throws NoSuchMethodException if an accessor method for this
    420     *  propety cannot be found
    421     * @see PropertyUtilsBean#getPropertyDescriptor
    422     */
    423    public static PropertyDescriptor getPropertyDescriptor(final Object bean,
    424                                                           final String name)
    425            throws IllegalAccessException, InvocationTargetException,
    426            NoSuchMethodException {
    427
    428        return PropertyUtilsBean.getInstance().getPropertyDescriptor(bean, name);
    429
    430    }
    431
    432    /**
    433     * <p>Retrieve the property descriptors for the specified class,
    434     * introspecting and caching them the first time a particular bean class
    435     * is encountered.</p>
    436     *
    437     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    438     *
    439     * @param beanClass Bean class for which property descriptors are requested
    440     * @return the property descriptors
    441     * @throws IllegalArgumentException if <code>beanClass</code> is null
    442     * @see PropertyUtilsBean#getPropertyDescriptors(Class)
    443     */
    444    public static PropertyDescriptor[]
    445            getPropertyDescriptors(final Class<?> beanClass) {
    446
    447        return PropertyUtilsBean.getInstance().getPropertyDescriptors(beanClass);
    448
    449    }
    450
    451    /**
    452     * <p>Retrieve the property descriptors for the specified bean,
    453     * introspecting and caching them the first time a particular bean class
    454     * is encountered.</p>
    455     *
    456     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    457     *
    458     * @param bean Bean for which property descriptors are requested
    459     * @return the property descriptors
    460     * @throws IllegalArgumentException if <code>bean</code> is null
    461     * @see PropertyUtilsBean#getPropertyDescriptors(Object)
    462     */
    463    public static PropertyDescriptor[] getPropertyDescriptors(final Object bean) {
    464
    465        return PropertyUtilsBean.getInstance().getPropertyDescriptors(bean);
    466
    467    }
    468
    469    /**
    470     * <p>Return the Java Class repesenting the property editor class that has
    471     * been registered for this property (if any).</p>
    472     *
    473     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    474     *
    475     * @param bean Bean for which a property descriptor is requested
    476     * @param name Possibly indexed and/or nested name of the property for
    477     *  which a property descriptor is requested
    478     * @return the property editor class
    479     * @throws IllegalAccessException if the caller does not have
    480     *  access to the property accessor method
    481     * @throws IllegalArgumentException if <code>bean</code> or
    482     *  <code>name</code> is null
    483     * @throws IllegalArgumentException if a nested reference to a
    484     *  property returns null
    485     * @throws InvocationTargetException if the property accessor method
    486     *  throws an exception
    487     * @throws NoSuchMethodException if an accessor method for this
    488     *  propety cannot be found
    489     * @see PropertyUtilsBean#getPropertyEditorClass(Object,String)
    490     */
    491    public static Class<?> getPropertyEditorClass(final Object bean, final String name)
    492            throws IllegalAccessException, InvocationTargetException,
    493            NoSuchMethodException {
    494
    495        return PropertyUtilsBean.getInstance().getPropertyEditorClass(bean, name);
    496
    497    }
    498
    499    /**
    500     * <p>Return the Java Class representing the property type of the specified
    501     * property, or <code>null</code> if there is no such property for the
    502     * specified bean.</p>
    503     *
    504     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    505     *
    506     * @param bean Bean for which a property descriptor is requested
    507     * @param name Possibly indexed and/or nested name of the property for
    508     *  which a property descriptor is requested
    509     * @return The property type
    510     * @throws IllegalAccessException if the caller does not have
    511     *  access to the property accessor method
    512     * @throws IllegalArgumentException if <code>bean</code> or
    513     *  <code>name</code> is null
    514     * @throws IllegalArgumentException if a nested reference to a
    515     *  property returns null
    516     * @throws InvocationTargetException if the property accessor method
    517     *  throws an exception
    518     * @throws NoSuchMethodException if an accessor method for this
    519     *  propety cannot be found
    520     * @see PropertyUtilsBean#getPropertyType(Object, String)
    521     */
    522    public static Class<?> getPropertyType(final Object bean, final String name)
    523            throws IllegalAccessException, InvocationTargetException,
    524            NoSuchMethodException {
    525
    526        return PropertyUtilsBean.getInstance().getPropertyType(bean, name);
    527    }
    528
    529    /**
    530     * <p>Return an accessible property getter method for this property,
    531     * if there is one; otherwise return <code>null</code>.</p>
    532     *
    533     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    534     *
    535     * @param descriptor Property descriptor to return a getter for
    536     * @return The read method
    537     * @see PropertyUtilsBean#getReadMethod(PropertyDescriptor)
    538     */
    539    public static Method getReadMethod(final PropertyDescriptor descriptor) {
    540
    541        return PropertyUtilsBean.getInstance().getReadMethod(descriptor);
    542
    543    }
    544
    545    /**
    546     * <p>Return the value of the specified simple property of the specified
    547     * bean, with no type conversions.</p>
    548     *
    549     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    550     *
    551     * @param bean Bean whose property is to be extracted
    552     * @param name Name of the property to be extracted
    553     * @return The property value
    554     * @throws IllegalAccessException if the caller does not have
    555     *  access to the property accessor method
    556     * @throws IllegalArgumentException if <code>bean</code> or
    557     *  <code>name</code> is null
    558     * @throws IllegalArgumentException if the property name
    559     *  is nested or indexed
    560     * @throws InvocationTargetException if the property accessor method
    561     *  throws an exception
    562     * @throws NoSuchMethodException if an accessor method for this
    563     *  propety cannot be found
    564     * @see PropertyUtilsBean#getSimpleProperty
    565     */
    566    public static Object getSimpleProperty(final Object bean, final String name)
    567            throws IllegalAccessException, InvocationTargetException,
    568            NoSuchMethodException {
    569
    570        return PropertyUtilsBean.getInstance().getSimpleProperty(bean, name);
    571
    572    }
    573
    574    /**
    575     * <p>Return an accessible property setter method for this property,
    576     * if there is one; otherwise return <code>null</code>.</p>
    577     *
    578     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    579     *
    580     * @param descriptor Property descriptor to return a setter for
    581     * @return The write method
    582     * @see PropertyUtilsBean#getWriteMethod(PropertyDescriptor)
    583     */
    584    public static Method getWriteMethod(final PropertyDescriptor descriptor) {
    585
    586        return PropertyUtilsBean.getInstance().getWriteMethod(descriptor);
    587
    588    }
    589
    590    /**
    591     * <p>Return <code>true</code> if the specified property name identifies
    592     * a readable property on the specified bean; otherwise, return
    593     * <code>false</code>.</p>
    594     *
    595     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    596     *
    597     * @param bean Bean to be examined (may be a {@link DynaBean}
    598     * @param name Property name to be evaluated
    599     * @return <code>true</code> if the property is readable,
    600     * otherwise <code>false</code>
    601     *
    602     * @throws IllegalArgumentException if <code>bean</code>
    603     *  or <code>name</code> is <code>null</code>
    604     * @see PropertyUtilsBean#isReadable
    605     * @since BeanUtils 1.6
    606     */
    607    public static boolean isReadable(final Object bean, final String name) {
    608
    609        return PropertyUtilsBean.getInstance().isReadable(bean, name);
    610    }
    611
    612    /**
    613     * <p>Return <code>true</code> if the specified property name identifies
    614     * a writeable property on the specified bean; otherwise, return
    615     * <code>false</code>.</p>
    616     *
    617     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    618     *
    619     * @param bean Bean to be examined (may be a {@link DynaBean}
    620     * @param name Property name to be evaluated
    621     * @return <code>true</code> if the property is writeable,
    622     * otherwise <code>false</code>
    623     *
    624     * @throws IllegalArgumentException if <code>bean</code>
    625     *  or <code>name</code> is <code>null</code>
    626     * @see PropertyUtilsBean#isWriteable
    627     * @since BeanUtils 1.6
    628     */
    629    public static boolean isWriteable(final Object bean, final String name) {
    630
    631        return PropertyUtilsBean.getInstance().isWriteable(bean, name);
    632    }
    633
    634    /**
    635     * Removes the specified <code>BeanIntrospector</code>.
    636     *
    637     * @param introspector the <code>BeanIntrospector</code> to be removed
    638     * @return <strong>true</strong> if the <code>BeanIntrospector</code> existed and
    639     *         could be removed, <strong>false</strong> otherwise
    640     * @since 1.9
    641     */
    642    public static boolean removeBeanIntrospector(final BeanIntrospector introspector) {
    643        return PropertyUtilsBean.getInstance().removeBeanIntrospector(
    644                introspector);
    645    }
    646
    647    /**
    648     * Resets the registered {@link BeanIntrospector} objects to the initial default
    649     * state.
    650     *
    651     * @since 1.9
    652     */
    653    public static void resetBeanIntrospectors() {
    654        PropertyUtilsBean.getInstance().resetBeanIntrospectors();
    655    }
    656
    657    /**
    658     * The <code>debug</code> static property is no longer used
    659     * @param newDebug debug property
    660     * @deprecated The <code>debug</code> static property is no longer used
    661     */
    662    @Deprecated
    663    public static void setDebug(final int newDebug) {
    664        debug = newDebug;
    665    }
    666
    667    /**
    668     * <p>Sets the value of the specified indexed property of the specified
    669     * bean, with no type conversions.</p>
    670     *
    671     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    672     *
    673     * @param bean Bean whose property is to be set
    674     * @param name Simple property name of the property value to be set
    675     * @param index Index of the property value to be set
    676     * @param value Value to which the indexed property element is to be set
    677     * @throws IndexOutOfBoundsException if the specified index
    678     *  is outside the valid range for the underlying property
    679     * @throws IllegalAccessException if the caller does not have
    680     *  access to the property accessor method
    681     * @throws IllegalArgumentException if <code>bean</code> or
    682     *  <code>name</code> is null
    683     * @throws InvocationTargetException if the property accessor method
    684     *  throws an exception
    685     * @throws NoSuchMethodException if an accessor method for this
    686     *  propety cannot be found
    687     * @see PropertyUtilsBean#setIndexedProperty(Object, String, Object)
    688     */
    689    public static void setIndexedProperty(final Object bean, final String name,
    690                                          final int index, final Object value)
    691            throws IllegalAccessException, InvocationTargetException,
    692            NoSuchMethodException {
    693
    694        PropertyUtilsBean.getInstance().setIndexedProperty(bean, name, index, value);
    695    }
    696
    697    /**
    698     * <p>Sets the value of the specified indexed property of the specified
    699     * bean, with no type conversions.</p>
    700     *
    701     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    702     *
    703     * @param bean Bean whose property is to be modified
    704     * @param name <code>propertyname[index]</code> of the property value
    705     *  to be modified
    706     * @param value Value to which the specified property element
    707     *  should be set
    708     *
    709     * @throws IndexOutOfBoundsException if the specified index
    710     *  is outside the valid range for the underlying property
    711     * @throws IllegalAccessException if the caller does not have
    712     *  access to the property accessor method
    713     * @throws IllegalArgumentException if <code>bean</code> or
    714     *  <code>name</code> is null
    715     * @throws InvocationTargetException if the property accessor method
    716     *  throws an exception
    717     * @throws NoSuchMethodException if an accessor method for this
    718     *  propety cannot be found
    719     * @see PropertyUtilsBean#setIndexedProperty(Object, String, Object)
    720     */
    721    public static void setIndexedProperty(final Object bean, final String name,
    722                                          final Object value)
    723            throws IllegalAccessException, InvocationTargetException,
    724            NoSuchMethodException {
    725
    726        PropertyUtilsBean.getInstance().setIndexedProperty(bean, name, value);
    727
    728    }
    729
    730    /**
    731     * <p>Sets the value of the specified mapped property of the
    732     * specified bean, with no type conversions.</p>
    733     *
    734     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    735     *
    736     * @param bean Bean whose property is to be set
    737     * @param name <code>propertyname(key)</code> of the property value
    738     *  to be set
    739     * @param value The property value to be set
    740     * @throws IllegalAccessException if the caller does not have
    741     *  access to the property accessor method
    742     * @throws InvocationTargetException if the property accessor method
    743     *  throws an exception
    744     * @throws NoSuchMethodException if an accessor method for this
    745     *  propety cannot be found
    746     * @see PropertyUtilsBean#setMappedProperty(Object, String, Object)
    747     */
    748    public static void setMappedProperty(final Object bean, final String name,
    749                                         final Object value)
    750            throws IllegalAccessException, InvocationTargetException,
    751            NoSuchMethodException {
    752
    753        PropertyUtilsBean.getInstance().setMappedProperty(bean, name, value);
    754    }
    755
    756    /**
    757     * <p>Sets the value of the specified mapped property of the specified
    758     * bean, with no type conversions.</p>
    759     *
    760     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    761     *
    762     * @param bean Bean whose property is to be set
    763     * @param name Mapped property name of the property value to be set
    764     * @param key Key of the property value to be set
    765     * @param value The property value to be set
    766     * @throws IllegalAccessException if the caller does not have
    767     *  access to the property accessor method
    768     * @throws InvocationTargetException if the property accessor method
    769     *  throws an exception
    770     * @throws NoSuchMethodException if an accessor method for this
    771     *  propety cannot be found
    772     * @see PropertyUtilsBean#setMappedProperty(Object, String, String, Object)
    773     */
    774    public static void setMappedProperty(final Object bean, final String name,
    775                                         final String key, final Object value)
    776            throws IllegalAccessException, InvocationTargetException,
    777            NoSuchMethodException {
    778
    779        PropertyUtilsBean.getInstance().setMappedProperty(bean, name, key, value);
    780    }
    781
    782    /**
    783     * <p>Sets the value of the (possibly nested) property of the specified
    784     * name, for the specified bean, with no type conversions.</p>
    785     *
    786     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    787     *
    788     * @param bean Bean whose property is to be modified
    789     * @param name Possibly nested name of the property to be modified
    790     * @param value Value to which the property is to be set
    791     * @throws IllegalAccessException if the caller does not have
    792     *  access to the property accessor method
    793     * @throws IllegalArgumentException if <code>bean</code> or
    794     *  <code>name</code> is null
    795     * @throws IllegalArgumentException if a nested reference to a
    796     *  property returns null
    797     * @throws InvocationTargetException if the property accessor method
    798     *  throws an exception
    799     * @throws NoSuchMethodException if an accessor method for this
    800     *  propety cannot be found
    801     * @see PropertyUtilsBean#setNestedProperty
    802     */
    803    public static void setNestedProperty(final Object bean,
    804                                         final String name, final Object value)
    805            throws IllegalAccessException, InvocationTargetException,
    806            NoSuchMethodException {
    807
    808        PropertyUtilsBean.getInstance().setNestedProperty(bean, name, value);
    809    }
    810
    811    /**
    812     * <p>Set the value of the specified property of the specified bean,
    813     * no matter which property reference format is used, with no
    814     * type conversions.</p>
    815     *
    816     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    817     *
    818     * @param bean Bean whose property is to be modified
    819     * @param name Possibly indexed and/or nested name of the property
    820     *  to be modified
    821     * @param value Value to which this property is to be set
    822     * @throws IllegalAccessException if the caller does not have
    823     *  access to the property accessor method
    824     * @throws IllegalArgumentException if <code>bean</code> or
    825     *  <code>name</code> is null
    826     * @throws InvocationTargetException if the property accessor method
    827     *  throws an exception
    828     * @throws NoSuchMethodException if an accessor method for this
    829     *  propety cannot be found
    830     * @see PropertyUtilsBean#setProperty
    831     */
    832    public static void setProperty(final Object bean, final String name, final Object value)
    833            throws IllegalAccessException, InvocationTargetException,
    834            NoSuchMethodException {
    835
    836        PropertyUtilsBean.getInstance().setProperty(bean, name, value);
    837
    838    }
    839
    840    /**
    841     * <p>Set the value of the specified simple property of the specified bean,
    842     * with no type conversions.</p>
    843     *
    844     * <p>For more details see <code>PropertyUtilsBean</code>.</p>
    845     *
    846     * @param bean Bean whose property is to be modified
    847     * @param name Name of the property to be modified
    848     * @param value Value to which the property should be set
    849     * @throws IllegalAccessException if the caller does not have
    850     *  access to the property accessor method
    851     * @throws IllegalArgumentException if <code>bean</code> or
    852     *  <code>name</code> is null
    853     * @throws IllegalArgumentException if the property name is
    854     *  nested or indexed
    855     * @throws InvocationTargetException if the property accessor method
    856     *  throws an exception
    857     * @throws NoSuchMethodException if an accessor method for this
    858     *  propety cannot be found
    859     * @see PropertyUtilsBean#setSimpleProperty
    860     */
    861    public static void setSimpleProperty(final Object bean,
    862                                         final String name, final Object value)
    863            throws IllegalAccessException, InvocationTargetException,
    864            NoSuchMethodException {
    865
    866        PropertyUtilsBean.getInstance().setSimpleProperty(bean, name, value);
    867    }
    868
    869    /**
    870     * Deprecated, all methods are static.
    871     *
    872     * @deprecated Will be private in 2.0.
    873     */
    874    @Deprecated
    875    public PropertyUtils() {
    876        // empty
    877    }
    878}