diff --git a/src/main/java/org/apache/commons/beanutils2/BeanUtils.java b/src/main/java/org/apache/commons/beanutils2/BeanUtils.java index ba2c0eacf..7f2e39e41 100644 --- a/src/main/java/org/apache/commons/beanutils2/BeanUtils.java +++ b/src/main/java/org/apache/commons/beanutils2/BeanUtils.java @@ -1,441 +1,443 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.beanutils2; - -import java.lang.reflect.InvocationTargetException; -import java.util.Map; - - - -/** - *

Utility methods for populating JavaBeans properties via reflection.

- * - *

The implementations are provided by {@link BeanUtilsBean}. - * These static utility methods use the default instance. - * More sophisticated behavior can be provided by using a {@code BeanUtilsBean} instance.

- * - * @see BeanUtilsBean - */ - -public class BeanUtils { - - - - - - - - - - - /** - *

Clone a bean based on the available property getters and setters, - * even if the bean class itself does not implement Cloneable.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean to be cloned - * @return the cloned bean - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InstantiationException if a new instance of the bean's - * class cannot be instantiated - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#cloneBean - */ - public static Object cloneBean(final Object bean) - throws IllegalAccessException, InstantiationException, - InvocationTargetException, NoSuchMethodException { - - return BeanUtilsBean.getInstance().cloneBean(bean); - - } - - - /** - *

Copy property values from the origin bean to the destination bean - * for all cases where the property names are the same.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param dest Destination bean whose properties are modified - * @param orig Origin bean whose properties are retrieved - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws IllegalArgumentException if the {@code dest} or - * {@code orig argument is null or if the dest} - * property type is different from the source type and the relevant - * converter has not been registered. - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @see BeanUtilsBean#copyProperties - */ - public static void copyProperties(final Object dest, final Object orig) - throws IllegalAccessException, InvocationTargetException { - - BeanUtilsBean.getInstance().copyProperties(dest, orig); - } - - - /** - *

Copy the specified property value to the specified destination bean, - * performing any type conversion that is required.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean on which setting is to be performed - * @param name Property name (can be nested/indexed/mapped/combo) - * @param value Value to be set - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @see BeanUtilsBean#copyProperty - */ - public static void copyProperty(final Object bean, final String name, final Object value) - throws IllegalAccessException, InvocationTargetException { - - BeanUtilsBean.getInstance().copyProperty(bean, name, value); - } - - - /** - *

Return the entire set of properties for which the specified bean - * provides a read method.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose properties are to be extracted - * @return Map of property descriptors - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#describe - */ - public static Map describe(final Object bean) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().describe(bean); - } - - - /** - *

Return the value of the specified array property of the specified - * bean, as a String array.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name Name of the property to be extracted - * @return The array property value - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getArrayProperty - */ - public static String[] getArrayProperty(final Object bean, final String name) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getArrayProperty(bean, name); - } - - - /** - *

Return the value of the specified indexed property of the specified - * bean, as a String.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name {@code propertyname[index]} of the property value - * to be extracted - * @return The indexed property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getIndexedProperty(Object, String) - */ - public static String getIndexedProperty(final Object bean, final String name) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getIndexedProperty(bean, name); - - } - - - /** - * Return 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 included in the property name expression - * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name Simple property name of the property value to be extracted - * @param index Index of the property value to be extracted - * @return The indexed property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getIndexedProperty(Object, String, int) - */ - public static String getIndexedProperty(final Object bean, - final String name, final int index) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getIndexedProperty(bean, name, index); - - } - - - /** - *

Return the value of the specified indexed property of the specified - * bean, as a String.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name {@code propertyname(index)} of the property value - * to be extracted - * @return The mapped property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getMappedProperty(Object, String) - */ - public static String getMappedProperty(final Object bean, final String name) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getMappedProperty(bean, name); - - } - - - /** - *

Return the value of the specified mapped property of the specified - * bean, as a String.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name Simple property name of the property value to be extracted - * @param key Lookup key of the property value to be extracted - * @return The mapped property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getMappedProperty(Object, String, String) - */ - public static String getMappedProperty(final Object bean, - final String name, final String key) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getMappedProperty(bean, name, key); - - } - - - /** - *

Return the value of the (possibly nested) property of the specified - * name, for the specified bean, as a String.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name Possibly nested name of the property to be extracted - * @return The nested property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws IllegalArgumentException if a nested reference to a - * property returns null - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getNestedProperty - */ - public static String getNestedProperty(final Object bean, final String name) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getNestedProperty(bean, name); - - } - - - /** - *

Return the value of the specified property of the specified bean, - * no matter which property reference format is used, as a String.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name Possibly indexed and/or nested name of the property - * to be extracted - * @return The property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getProperty - */ - public static String getProperty(final Object bean, final String name) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getProperty(bean, name); - - } - - - /** - *

Return the value of the specified simple property of the specified - * bean, converted to a String.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean whose property is to be extracted - * @param name Name of the property to be extracted - * @return The property's value, converted to a String - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @throws NoSuchMethodException if an accessor method for this - * property cannot be found - * @see BeanUtilsBean#getSimpleProperty - */ - public static String getSimpleProperty(final Object bean, final String name) - throws IllegalAccessException, InvocationTargetException, - NoSuchMethodException { - - return BeanUtilsBean.getInstance().getSimpleProperty(bean, name); - - } - - - /** - *

Populate the JavaBeans properties of the specified bean, based on - * the specified name/value pairs.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean JavaBean whose properties are being populated - * @param properties Map keyed by property name, with the - * corresponding (String or String[]) value(s) to be set - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @see BeanUtilsBean#populate - */ - public static void populate(final Object bean, final Map properties) - throws IllegalAccessException, InvocationTargetException { - - BeanUtilsBean.getInstance().populate(bean, properties); - } - - - /** - *

Set the specified property value, performing type conversions as - * required to conform to the type of the destination property.

- * - *

For more details see {@code BeanUtilsBean}.

- * - * @param bean Bean on which setting is to be performed - * @param name Property name (can be nested/indexed/mapped/combo) - * @param value Value to be set - * - * @throws IllegalAccessException if the caller does not have - * access to the property accessor method - * @throws InvocationTargetException if the property accessor method - * throws an exception - * @see BeanUtilsBean#setProperty - */ - public static void setProperty(final Object bean, final String name, final Object value) - throws IllegalAccessException, InvocationTargetException { - - BeanUtilsBean.getInstance().setProperty(bean, name, value); - } - - /** - * If we're running on JDK 1.4 or later, initialize the cause for the given throwable. - * - * @param throwable The throwable. - * @param cause The cause of the throwable. - * @return true if the cause was initialized, otherwise false. - * @since 1.8.0 - */ - public static boolean initCause(final Throwable throwable, final Throwable cause) { - return BeanUtilsBean.getInstance().initCause(throwable, cause); - } - - /** - * Create a cache. - * @param the key type of the cache - * @param the value type of the cache - * @return a new cache - * @since 1.8.0 - */ - public static Map createCache() { - return new WeakFastHashMap<>(); - } -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.beanutils2; + +import org.apache.commons.logging.impl.WeakHashtable; + +import java.lang.reflect.InvocationTargetException; +import java.util.Map; + + + +/** + *

Utility methods for populating JavaBeans properties via reflection.

+ * + *

The implementations are provided by {@link BeanUtilsBean}. + * These static utility methods use the default instance. + * More sophisticated behavior can be provided by using a {@code BeanUtilsBean} instance.

+ * + * @see BeanUtilsBean + */ + +public class BeanUtils { + + + + + + + + + + + /** + *

Clone a bean based on the available property getters and setters, + * even if the bean class itself does not implement Cloneable.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean to be cloned + * @return the cloned bean + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InstantiationException if a new instance of the bean's + * class cannot be instantiated + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#cloneBean + */ + public static Object cloneBean(final Object bean) + throws IllegalAccessException, InstantiationException, + InvocationTargetException, NoSuchMethodException { + + return BeanUtilsBean.getInstance().cloneBean(bean); + + } + + + /** + *

Copy property values from the origin bean to the destination bean + * for all cases where the property names are the same.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param dest Destination bean whose properties are modified + * @param orig Origin bean whose properties are retrieved + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws IllegalArgumentException if the {@code dest} or + * {@code orig
argument is null or if the dest} + * property type is different from the source type and the relevant + * converter has not been registered. + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @see BeanUtilsBean#copyProperties + */ + public static void copyProperties(final Object dest, final Object orig) + throws IllegalAccessException, InvocationTargetException { + + BeanUtilsBean.getInstance().copyProperties(dest, orig); + } + + + /** + *

Copy the specified property value to the specified destination bean, + * performing any type conversion that is required.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean on which setting is to be performed + * @param name Property name (can be nested/indexed/mapped/combo) + * @param value Value to be set + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @see BeanUtilsBean#copyProperty + */ + public static void copyProperty(final Object bean, final String name, final Object value) + throws IllegalAccessException, InvocationTargetException { + + BeanUtilsBean.getInstance().copyProperty(bean, name, value); + } + + + /** + *

Return the entire set of properties for which the specified bean + * provides a read method.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose properties are to be extracted + * @return Map of property descriptors + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#describe + */ + public static Map describe(final Object bean) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().describe(bean); + } + + + /** + *

Return the value of the specified array property of the specified + * bean, as a String array.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name Name of the property to be extracted + * @return The array property value + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getArrayProperty + */ + public static String[] getArrayProperty(final Object bean, final String name) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getArrayProperty(bean, name); + } + + + /** + *

Return the value of the specified indexed property of the specified + * bean, as a String.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name {@code propertyname[index]} of the property value + * to be extracted + * @return The indexed property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getIndexedProperty(Object, String) + */ + public static String getIndexedProperty(final Object bean, final String name) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getIndexedProperty(bean, name); + + } + + + /** + * Return 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 included in the property name expression + * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name Simple property name of the property value to be extracted + * @param index Index of the property value to be extracted + * @return The indexed property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getIndexedProperty(Object, String, int) + */ + public static String getIndexedProperty(final Object bean, + final String name, final int index) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getIndexedProperty(bean, name, index); + + } + + + /** + *

Return the value of the specified indexed property of the specified + * bean, as a String.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name {@code propertyname(index)} of the property value + * to be extracted + * @return The mapped property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getMappedProperty(Object, String) + */ + public static String getMappedProperty(final Object bean, final String name) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getMappedProperty(bean, name); + + } + + + /** + *

Return the value of the specified mapped property of the specified + * bean, as a String.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name Simple property name of the property value to be extracted + * @param key Lookup key of the property value to be extracted + * @return The mapped property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getMappedProperty(Object, String, String) + */ + public static String getMappedProperty(final Object bean, + final String name, final String key) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getMappedProperty(bean, name, key); + + } + + + /** + *

Return the value of the (possibly nested) property of the specified + * name, for the specified bean, as a String.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name Possibly nested name of the property to be extracted + * @return The nested property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws IllegalArgumentException if a nested reference to a + * property returns null + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getNestedProperty + */ + public static String getNestedProperty(final Object bean, final String name) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getNestedProperty(bean, name); + + } + + + /** + *

Return the value of the specified property of the specified bean, + * no matter which property reference format is used, as a String.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name Possibly indexed and/or nested name of the property + * to be extracted + * @return The property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getProperty + */ + public static String getProperty(final Object bean, final String name) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getProperty(bean, name); + + } + + + /** + *

Return the value of the specified simple property of the specified + * bean, converted to a String.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean whose property is to be extracted + * @param name Name of the property to be extracted + * @return The property's value, converted to a String + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @throws NoSuchMethodException if an accessor method for this + * property cannot be found + * @see BeanUtilsBean#getSimpleProperty + */ + public static String getSimpleProperty(final Object bean, final String name) + throws IllegalAccessException, InvocationTargetException, + NoSuchMethodException { + + return BeanUtilsBean.getInstance().getSimpleProperty(bean, name); + + } + + + /** + *

Populate the JavaBeans properties of the specified bean, based on + * the specified name/value pairs.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean JavaBean whose properties are being populated + * @param properties Map keyed by property name, with the + * corresponding (String or String[]) value(s) to be set + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @see BeanUtilsBean#populate + */ + public static void populate(final Object bean, final Map properties) + throws IllegalAccessException, InvocationTargetException { + + BeanUtilsBean.getInstance().populate(bean, properties); + } + + + /** + *

Set the specified property value, performing type conversions as + * required to conform to the type of the destination property.

+ * + *

For more details see {@code BeanUtilsBean}.

+ * + * @param bean Bean on which setting is to be performed + * @param name Property name (can be nested/indexed/mapped/combo) + * @param value Value to be set + * + * @throws IllegalAccessException if the caller does not have + * access to the property accessor method + * @throws InvocationTargetException if the property accessor method + * throws an exception + * @see BeanUtilsBean#setProperty + */ + public static void setProperty(final Object bean, final String name, final Object value) + throws IllegalAccessException, InvocationTargetException { + + BeanUtilsBean.getInstance().setProperty(bean, name, value); + } + + /** + * If we're running on JDK 1.4 or later, initialize the cause for the given throwable. + * + * @param throwable The throwable. + * @param cause The cause of the throwable. + * @return true if the cause was initialized, otherwise false. + * @since 1.8.0 + */ + public static boolean initCause(final Throwable throwable, final Throwable cause) { + return BeanUtilsBean.getInstance().initCause(throwable, cause); + } + + /** + * Create a cache. + * @param the key type of the cache + * @param the value type of the cache + * @return a new cache + * @since 1.8.0 + */ + public static Map createCache() { + return new WeakHashtable(); + } +} diff --git a/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java b/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java index 54117cd75..b0891f901 100644 --- a/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java +++ b/src/main/java/org/apache/commons/beanutils2/ConvertUtilsBean.java @@ -25,6 +25,7 @@ import java.net.URL; import java.nio.file.Path; import java.sql.Timestamp; +import java.util.Map; import java.time.Duration; import java.time.LocalDate; import java.time.LocalDateTime; @@ -82,6 +83,8 @@ import org.apache.commons.beanutils2.converters.ZonedDateTimeConverter; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.impl.WeakHashtable; + /** *

Utility methods for converting String scalar values to objects of the @@ -190,8 +193,8 @@ protected static ConvertUtilsBean getInstance() { * The set of {@link Converter}s that can be used to convert Strings * into objects of a specified Class, keyed by the destination Class. */ - private final WeakFastHashMap, Converter> converters = - new WeakFastHashMap<>(); + private final Map, Converter> converters = + new WeakHashtable(); /** * The {@code Log} instance for this class. @@ -202,9 +205,9 @@ protected static ConvertUtilsBean getInstance() { /** Construct a bean with standard converters registered */ public ConvertUtilsBean() { - converters.setFast(false); +// converters.setFast(false); deregister(); - converters.setFast(true); +// converters.setFast(true); } diff --git a/src/main/java/org/apache/commons/beanutils2/PropertyUtilsBean.java b/src/main/java/org/apache/commons/beanutils2/PropertyUtilsBean.java index fb12188cb..506ae2adf 100644 --- a/src/main/java/org/apache/commons/beanutils2/PropertyUtilsBean.java +++ b/src/main/java/org/apache/commons/beanutils2/PropertyUtilsBean.java @@ -34,6 +34,7 @@ import org.apache.commons.beanutils2.expression.Resolver; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.impl.WeakHashtable; /** * Utility methods for using Java Reflection APIs to facilitate generic @@ -108,8 +109,8 @@ protected static PropertyUtilsBean getInstance() { * The cache of PropertyDescriptor arrays for beans we have already * introspected, keyed by the java.lang.Class of this object. */ - private WeakFastHashMap, BeanIntrospectionData> descriptorsCache = null; - private WeakFastHashMap, Map> mappedDescriptorsCache = null; + private Map, BeanIntrospectionData> descriptorsCache = null; + private Map, Map> mappedDescriptorsCache = null; /** An empty object array */ private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; @@ -124,10 +125,10 @@ protected static PropertyUtilsBean getInstance() { /** Base constructor */ public PropertyUtilsBean() { - descriptorsCache = new WeakFastHashMap<>(); - descriptorsCache.setFast(true); - mappedDescriptorsCache = new WeakFastHashMap<>(); - mappedDescriptorsCache.setFast(true); + descriptorsCache = new WeakHashtable(); +// descriptorsCache.setFast(true); + mappedDescriptorsCache = new WeakHashtable(); +// mappedDescriptorsCache.setFast(true); introspectors = new CopyOnWriteArrayList<>(); resetBeanIntrospectors(); } diff --git a/src/test/java/org/apache/commons/beanutils2/performance/WeakFastHashMapTest.java b/src/test/java/org/apache/commons/beanutils2/performance/WeakFastHashMapTest.java new file mode 100644 index 000000000..0f65d2beb --- /dev/null +++ b/src/test/java/org/apache/commons/beanutils2/performance/WeakFastHashMapTest.java @@ -0,0 +1,96 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.beanutils2.performance; + +import org.apache.commons.beanutils2.WeakFastHashMap; +import org.apache.commons.logging.impl.WeakHashtable; + + +import java.util.Map; +import java.util.Objects; +import java.util.Random; +import java.util.TreeSet; + + +public class WeakFastHashMapTest { + static final TreeSet treeSet = new TreeSet<>(); + static final Random random = new Random(); + static final WeakFastHashMap weakFastHashMap = new WeakFastHashMap<>(); + static final Map weakHashtable = new WeakHashtable(); + + static final int INIT_SIZE = 50000; + static final double WRITE_CHANCE = 0.01; + static final double READ_NON_EXIST_CHANCE = 0.30; + + public static void main(String[] args) { + for (int i = 0; i < INIT_SIZE; i++) { + writeRandom(); + } + System.out.println("init over"); + + weakFastHashMap.setFast(true); + + for (int i = 0; ; i++) { + if (i % 100000 == 0) { + System.out.println("running> i : " + i + " size: " + treeSet.size()); + } + double ifWrite = random.nextDouble(); + if (ifWrite < WRITE_CHANCE) { + writeRandom(); + } else { + double ifNonExist = random.nextDouble(); + if (ifNonExist < READ_NON_EXIST_CHANCE) { + readNonExist(); + } else { + readExist(); + } + } + } + } + + public static void writeRandom() { + Integer nowKey = random.nextInt() * random.nextInt(); + Integer nowValue = random.nextInt() * random.nextInt(); + treeSet.add(nowKey); + weakFastHashMap.put(nowKey, nowValue); + weakHashtable.put(nowKey, nowValue); + } + + public static void readExist() { + Integer nowKey = null; + while (nowKey == null) { + nowKey = treeSet.lower(random.nextInt() * random.nextInt()); + } + read(nowKey); + } + + public static void readNonExist() { + Integer nowKey = random.nextInt() * random.nextInt(); + while (treeSet.contains(nowKey)) { + nowKey = random.nextInt() * random.nextInt(); + } + read(nowKey); + } + + public static void read(Integer nowKey) { + Integer value1 = weakFastHashMap.get(nowKey); + Integer value2 = weakHashtable.get(nowKey); + if (!Objects.equals(value1, value2)) { + System.out.println("not equal! nowKey : " + nowKey + " value1 : " + value1 + " value2 : " + value2); + } + } +}