BeanUtils.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      https://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */

  17. package org.apache.commons.beanutils2;

  18. import java.lang.reflect.InvocationTargetException;
  19. import java.util.Map;

  20. import org.apache.commons.collections4.map.ConcurrentReferenceHashMap;

  21. /**
  22.  * <p>
  23.  * Utility methods for populating JavaBeans properties via reflection.
  24.  * </p>
  25.  *
  26.  * <p>
  27.  * The implementations are provided by {@link BeanUtilsBean}. These static utility methods use the default instance. More sophisticated behavior can be provided
  28.  * by using a {@code BeanUtilsBean} instance.
  29.  * </p>
  30.  *
  31.  * @see BeanUtilsBean
  32.  */
  33. public final class BeanUtils {

  34.     /** An empty class array */
  35.     static final Class<?>[] EMPTY_CLASS_ARRAY = {};

  36.     /** An empty object array */
  37.     static final Object[] EMPTY_OBJECT_ARRAY = {};

  38.     /**
  39.      * <p>
  40.      * Clones a bean based on the available property getters and setters, even if the bean class itself does not implement Cloneable.
  41.      * </p>
  42.      *
  43.      * <p>
  44.      * For more details see {@code BeanUtilsBean}.
  45.      * </p>
  46.      *
  47.      * @param bean Bean to be cloned
  48.      * @return the cloned bean
  49.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  50.      * @throws InstantiationException    if a new instance of the bean's class cannot be instantiated
  51.      * @throws InvocationTargetException if the property accessor method throws an exception
  52.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  53.      * @see BeanUtilsBean#cloneBean
  54.      */
  55.     public static Object cloneBean(final Object bean) throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
  56.         return BeanUtilsBean.getInstance().cloneBean(bean);
  57.     }

  58.     /**
  59.      * <p>
  60.      * Copies property values from the origin bean to the destination bean for all cases where the property names are the same.
  61.      * </p>
  62.      *
  63.      * <p>
  64.      * For more details see {@code BeanUtilsBean}.
  65.      * </p>
  66.      *
  67.      * @param dest Destination bean whose properties are modified
  68.      * @param orig Origin bean whose properties are retrieved
  69.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  70.      * @throws IllegalArgumentException  if the {@code dest} or {@code orig</code> argument is null or if the <code>dest} property type is different from the
  71.      *                                   source type and the relevant converter has not been registered.
  72.      * @throws InvocationTargetException if the property accessor method throws an exception
  73.      * @see BeanUtilsBean#copyProperties
  74.      */
  75.     public static void copyProperties(final Object dest, final Object orig) throws IllegalAccessException, InvocationTargetException {
  76.         BeanUtilsBean.getInstance().copyProperties(dest, orig);
  77.     }

  78.     /**
  79.      * <p>
  80.      * Copy the specified property value to the specified destination bean, performing any type conversion that is required.
  81.      * </p>
  82.      *
  83.      * <p>
  84.      * For more details see {@code BeanUtilsBean}.
  85.      * </p>
  86.      *
  87.      * @param bean  Bean on which setting is to be performed
  88.      * @param name  Property name (can be nested/indexed/mapped/combo)
  89.      * @param value Value to be set
  90.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  91.      * @throws InvocationTargetException if the property accessor method throws an exception
  92.      * @see BeanUtilsBean#copyProperty
  93.      */
  94.     public static void copyProperty(final Object bean, final String name, final Object value) throws IllegalAccessException, InvocationTargetException {
  95.         BeanUtilsBean.getInstance().copyProperty(bean, name, value);
  96.     }

  97.     /**
  98.      * Creates a cache.
  99.      *
  100.      * @param <K> the key type of the cache
  101.      * @param <V> the value type of the cache
  102.      * @return a new cache
  103.      * @since 1.8.0
  104.      */
  105.     public static <K, V> Map<K, V> createCache() {
  106.         return ConcurrentReferenceHashMap.<K, V>builder().get();
  107.         // return new ConcurrentHashMap<>();
  108.     }

  109.     /**
  110.      * <p>
  111.      * Return the entire set of properties for which the specified bean provides a read method.
  112.      * </p>
  113.      *
  114.      * <p>
  115.      * For more details see {@code BeanUtilsBean}.
  116.      * </p>
  117.      *
  118.      * @param bean Bean whose properties are to be extracted
  119.      * @return Map of property descriptors
  120.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  121.      * @throws InvocationTargetException if the property accessor method throws an exception
  122.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  123.      * @see BeanUtilsBean#describe
  124.      */
  125.     public static Map<String, String> describe(final Object bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  126.         return BeanUtilsBean.getInstance().describe(bean);
  127.     }

  128.     /**
  129.      * <p>
  130.      * Return the value of the specified array property of the specified bean, as a String array.
  131.      * </p>
  132.      *
  133.      * <p>
  134.      * For more details see {@code BeanUtilsBean}.
  135.      * </p>
  136.      *
  137.      * @param bean Bean whose property is to be extracted
  138.      * @param name Name of the property to be extracted
  139.      * @return The array property value
  140.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  141.      * @throws InvocationTargetException if the property accessor method throws an exception
  142.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  143.      * @see BeanUtilsBean#getArrayProperty
  144.      */
  145.     public static String[] getArrayProperty(final Object bean, final String name)
  146.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  147.         return BeanUtilsBean.getInstance().getArrayProperty(bean, name);
  148.     }

  149.     /**
  150.      * <p>
  151.      * Return the value of the specified indexed property of the specified bean, as a String.
  152.      * </p>
  153.      *
  154.      * <p>
  155.      * For more details see {@code BeanUtilsBean}.
  156.      * </p>
  157.      *
  158.      * @param bean Bean whose property is to be extracted
  159.      * @param name {@code propertyname[index]} of the property value to be extracted
  160.      * @return The indexed property's value, converted to a String
  161.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  162.      * @throws InvocationTargetException if the property accessor method throws an exception
  163.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  164.      * @see BeanUtilsBean#getIndexedProperty(Object, String)
  165.      */
  166.     public static String getIndexedProperty(final Object bean, final String name)
  167.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  168.         return BeanUtilsBean.getInstance().getIndexedProperty(bean, name);

  169.     }

  170.     /**
  171.      * Gets the value of the specified indexed property of the specified bean, as a String. The index is specified as a method parameter and must *not* be
  172.      * included in the property name expression
  173.      *
  174.      * <p>
  175.      * For more details see {@code BeanUtilsBean}.
  176.      * </p>
  177.      *
  178.      * @param bean  Bean whose property is to be extracted
  179.      * @param name  Simple property name of the property value to be extracted
  180.      * @param index Index of the property value to be extracted
  181.      * @return The indexed property's value, converted to a String
  182.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  183.      * @throws InvocationTargetException if the property accessor method throws an exception
  184.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  185.      * @see BeanUtilsBean#getIndexedProperty(Object, String, int)
  186.      */
  187.     public static String getIndexedProperty(final Object bean, final String name, final int index)
  188.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  189.         return BeanUtilsBean.getInstance().getIndexedProperty(bean, name, index);

  190.     }

  191.     /**
  192.      * <p>
  193.      * Return the value of the specified indexed property of the specified bean, as a String.
  194.      * </p>
  195.      *
  196.      * <p>
  197.      * For more details see {@code BeanUtilsBean}.
  198.      * </p>
  199.      *
  200.      * @param bean Bean whose property is to be extracted
  201.      * @param name {@code propertyname(index)} of the property value to be extracted
  202.      * @return The mapped property's value, converted to a String
  203.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  204.      * @throws InvocationTargetException if the property accessor method throws an exception
  205.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  206.      * @see BeanUtilsBean#getMappedProperty(Object, String)
  207.      */
  208.     public static String getMappedProperty(final Object bean, final String name)
  209.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  210.         return BeanUtilsBean.getInstance().getMappedProperty(bean, name);

  211.     }

  212.     /**
  213.      * <p>
  214.      * Return the value of the specified mapped property of the specified bean, as a String.
  215.      * </p>
  216.      *
  217.      * <p>
  218.      * For more details see {@code BeanUtilsBean}.
  219.      * </p>
  220.      *
  221.      * @param bean Bean whose property is to be extracted
  222.      * @param name Simple property name of the property value to be extracted
  223.      * @param key  Lookup key of the property value to be extracted
  224.      * @return The mapped property's value, converted to a String
  225.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  226.      * @throws InvocationTargetException if the property accessor method throws an exception
  227.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  228.      * @see BeanUtilsBean#getMappedProperty(Object, String, String)
  229.      */
  230.     public static String getMappedProperty(final Object bean, final String name, final String key)
  231.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  232.         return BeanUtilsBean.getInstance().getMappedProperty(bean, name, key);

  233.     }

  234.     /**
  235.      * <p>
  236.      * Return the value of the (possibly nested) property of the specified name, for the specified bean, as a String.
  237.      * </p>
  238.      *
  239.      * <p>
  240.      * For more details see {@code BeanUtilsBean}.
  241.      * </p>
  242.      *
  243.      * @param bean Bean whose property is to be extracted
  244.      * @param name Possibly nested name of the property to be extracted
  245.      * @return The nested property's value, converted to a String
  246.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  247.      * @throws IllegalArgumentException  if a nested reference to a property returns null
  248.      * @throws InvocationTargetException if the property accessor method throws an exception
  249.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  250.      * @see BeanUtilsBean#getNestedProperty
  251.      */
  252.     public static String getNestedProperty(final Object bean, final String name)
  253.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  254.         return BeanUtilsBean.getInstance().getNestedProperty(bean, name);

  255.     }

  256.     /**
  257.      * <p>
  258.      * Return the value of the specified property of the specified bean, no matter which property reference format is used, as a String.
  259.      * </p>
  260.      *
  261.      * <p>
  262.      * For more details see {@code BeanUtilsBean}.
  263.      * </p>
  264.      *
  265.      * @param bean Bean whose property is to be extracted
  266.      * @param name Possibly indexed and/or nested name of the property to be extracted
  267.      * @return The property's value, converted to a String
  268.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  269.      * @throws InvocationTargetException if the property accessor method throws an exception
  270.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  271.      * @see BeanUtilsBean#getProperty
  272.      */
  273.     public static String getProperty(final Object bean, final String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  274.         return BeanUtilsBean.getInstance().getProperty(bean, name);

  275.     }

  276.     /**
  277.      * <p>
  278.      * Return the value of the specified simple property of the specified bean, converted to a String.
  279.      * </p>
  280.      *
  281.      * <p>
  282.      * For more details see {@code BeanUtilsBean}.
  283.      * </p>
  284.      *
  285.      * @param bean Bean whose property is to be extracted
  286.      * @param name Name of the property to be extracted
  287.      * @return The property's value, converted to a String
  288.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  289.      * @throws InvocationTargetException if the property accessor method throws an exception
  290.      * @throws NoSuchMethodException     if an accessor method for this property cannot be found
  291.      * @see BeanUtilsBean#getSimpleProperty
  292.      */
  293.     public static String getSimpleProperty(final Object bean, final String name)
  294.             throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
  295.         return BeanUtilsBean.getInstance().getSimpleProperty(bean, name);

  296.     }

  297.     /**
  298.      * <p>
  299.      * Populate the JavaBeans properties of the specified bean, based on the specified name/value pairs.
  300.      * </p>
  301.      *
  302.      * <p>
  303.      * For more details see {@code BeanUtilsBean}.
  304.      * </p>
  305.      *
  306.      * @param bean       JavaBean whose properties are being populated
  307.      * @param properties Map keyed by property name, with the corresponding (String or String[]) value(s) to be set
  308.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  309.      * @throws InvocationTargetException if the property accessor method throws an exception
  310.      * @see BeanUtilsBean#populate
  311.      */
  312.     public static void populate(final Object bean, final Map<String, ? extends Object> properties) throws IllegalAccessException, InvocationTargetException {
  313.         BeanUtilsBean.getInstance().populate(bean, properties);
  314.     }

  315.     /**
  316.      * <p>
  317.      * Set the specified property value, performing type conversions as required to conform to the type of the destination property.
  318.      * </p>
  319.      *
  320.      * <p>
  321.      * For more details see {@code BeanUtilsBean}.
  322.      * </p>
  323.      *
  324.      * @param bean  Bean on which setting is to be performed
  325.      * @param name  Property name (can be nested/indexed/mapped/combo)
  326.      * @param value Value to be set
  327.      * @throws IllegalAccessException    if the caller does not have access to the property accessor method
  328.      * @throws InvocationTargetException if the property accessor method throws an exception
  329.      * @see BeanUtilsBean#setProperty
  330.      */
  331.     public static void setProperty(final Object bean, final String name, final Object value) throws IllegalAccessException, InvocationTargetException {
  332.         BeanUtilsBean.getInstance().setProperty(bean, name, value);
  333.     }

  334.     private BeanUtils() {
  335.         // empty
  336.     }
  337. }