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 * https://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.lang.reflect.InvocationTargetException; 021import java.util.Map; 022 023/** 024 * <p>Utility methods for populating JavaBeans properties via reflection.</p> 025 * 026 * <p>The implementations are provided by {@link BeanUtilsBean}. 027 * These static utility methods use the default instance. 028 * More sophisticated behavior can be provided by using a <code>BeanUtilsBean</code> instance.</p> 029 * 030 * @see BeanUtilsBean 031 */ 032public class BeanUtils { 033 034 /** 035 * The debugging detail level for this component. 036 * 037 * Note that this static variable will have unexpected side-effects if 038 * this class is deployed in a shared classloader within a container. 039 * However as it is actually completely ignored by this class due to its 040 * deprecated status, it doesn't do any actual harm. 041 * 042 * @deprecated BeanUtils now uses commons-logging for all log messages. 043 * Use your favorite logging tool to configure logging for 044 * this class. 045 */ 046 @Deprecated 047 private static int debug; 048 049 /** 050 * <p>Clone a bean based on the available property getters and setters, 051 * even if the bean class itself does not implement Cloneable.</p> 052 * 053 * <p>For more details see <code>BeanUtilsBean</code>.</p> 054 * 055 * @param bean Bean to be cloned 056 * @return the cloned bean 057 * @throws IllegalAccessException if the caller does not have 058 * access to the property accessor method 059 * @throws InstantiationException if a new instance of the bean's 060 * class cannot be instantiated 061 * @throws InvocationTargetException if the property accessor method 062 * throws an exception 063 * @throws NoSuchMethodException if an accessor method for this 064 * property cannot be found 065 * @see BeanUtilsBean#cloneBean 066 */ 067 public static Object cloneBean(final Object bean) 068 throws IllegalAccessException, InstantiationException, 069 InvocationTargetException, NoSuchMethodException { 070 return BeanUtilsBean.getInstance().cloneBean(bean); 071 } 072 073 /** 074 * <p>Copy property values from the origin bean to the destination bean 075 * for all cases where the property names are the same.</p> 076 * 077 * <p>For more details see <code>BeanUtilsBean</code>.</p> 078 * 079 * @param dest Destination bean whose properties are modified 080 * @param orig Origin bean whose properties are retrieved 081 * @throws IllegalAccessException if the caller does not have 082 * access to the property accessor method 083 * @throws IllegalArgumentException if the <code>dest</code> or 084 * <code>orig</code> argument is null or if the <code>dest</code> 085 * property type is different from the source type and the relevant 086 * converter has not been registered. 087 * @throws InvocationTargetException if the property accessor method 088 * throws an exception 089 * @see BeanUtilsBean#copyProperties 090 */ 091 public static void copyProperties(final Object dest, final Object orig) 092 throws IllegalAccessException, InvocationTargetException { 093 BeanUtilsBean.getInstance().copyProperties(dest, orig); 094 } 095 096 /** 097 * <p>Copy the specified property value to the specified destination bean, 098 * performing any type conversion that is required.</p> 099 * 100 * <p>For more details see <code>BeanUtilsBean</code>.</p> 101 * 102 * @param bean Bean on which setting is to be performed 103 * @param name Property name (can be nested/indexed/mapped/combo) 104 * @param value Value to be set 105 * @throws IllegalAccessException if the caller does not have 106 * access to the property accessor method 107 * @throws InvocationTargetException if the property accessor method 108 * throws an exception 109 * @see BeanUtilsBean#copyProperty 110 */ 111 public static void copyProperty(final Object bean, final String name, final Object value) 112 throws IllegalAccessException, InvocationTargetException { 113 BeanUtilsBean.getInstance().copyProperty(bean, name, value); 114 } 115 116 /** 117 * Create a cache. 118 * @param <K> the key type of the cache 119 * @param <V> the value type of the cache 120 * @return a new cache 121 * @since 1.8.0 122 */ 123 public static <K, V> Map<K, V> createCache() { 124 return new WeakFastHashMap<>(); 125 } 126 127 /** 128 * <p>Return the entire set of properties for which the specified bean 129 * provides a read method.</p> 130 * 131 * <p>For more details see <code>BeanUtilsBean</code>.</p> 132 * 133 * @param bean Bean whose properties are to be extracted 134 * @return Map of property descriptors 135 * @throws IllegalAccessException if the caller does not have 136 * access to the property accessor method 137 * @throws InvocationTargetException if the property accessor method 138 * throws an exception 139 * @throws NoSuchMethodException if an accessor method for this 140 * property cannot be found 141 * @see BeanUtilsBean#describe 142 */ 143 public static Map<String, String> describe(final Object bean) 144 throws IllegalAccessException, InvocationTargetException, 145 NoSuchMethodException { 146 return BeanUtilsBean.getInstance().describe(bean); 147 } 148 149 /** 150 * <p>Return the value of the specified array property of the specified 151 * bean, as a String array.</p> 152 * 153 * <p>For more details see <code>BeanUtilsBean</code>.</p> 154 * 155 * @param bean Bean whose property is to be extracted 156 * @param name Name of the property to be extracted 157 * @return The array property value 158 * @throws IllegalAccessException if the caller does not have 159 * access to the property accessor method 160 * @throws InvocationTargetException if the property accessor method 161 * throws an exception 162 * @throws NoSuchMethodException if an accessor method for this 163 * property cannot be found 164 * @see BeanUtilsBean#getArrayProperty 165 */ 166 public static String[] getArrayProperty(final Object bean, final String name) 167 throws IllegalAccessException, InvocationTargetException, 168 NoSuchMethodException { 169 return BeanUtilsBean.getInstance().getArrayProperty(bean, name); 170 } 171 172 /** 173 * Gets whether a Map is fast. 174 * 175 * @param map The map. 176 * @return Whether it is fast or not. 177 * @since 1.8.0 178 */ 179 public static boolean getCacheFast(final Map<?, ?> map) { 180 if (map instanceof WeakFastHashMap) { 181 return ((WeakFastHashMap<?, ?>) map).getFast(); 182 } 183 return false; 184 } 185 186 /** 187 * The <code>debug</code> static property is no longer used 188 * @return debug property 189 * @deprecated BeanUtils now uses commons-logging for all log messages. 190 * Use your favorite logging tool to configure logging for 191 * this class. 192 */ 193 @Deprecated 194 public static int getDebug() { 195 return debug; 196 } 197 198 /** 199 * <p>Return the value of the specified indexed property of the specified 200 * bean, as a String.</p> 201 * 202 * <p>For more details see <code>BeanUtilsBean</code>.</p> 203 * 204 * @param bean Bean whose property is to be extracted 205 * @param name <code>propertyname[index]</code> of the property value 206 * to be extracted 207 * @return The indexed property's value, converted to a String 208 * @throws IllegalAccessException if the caller does not have 209 * access to the property accessor method 210 * @throws InvocationTargetException if the property accessor method 211 * throws an exception 212 * @throws NoSuchMethodException if an accessor method for this 213 * property cannot be found 214 * @see BeanUtilsBean#getIndexedProperty(Object, String) 215 */ 216 public static String getIndexedProperty(final Object bean, final String name) 217 throws IllegalAccessException, InvocationTargetException, 218 NoSuchMethodException { 219 return BeanUtilsBean.getInstance().getIndexedProperty(bean, name); 220 } 221 222 /** 223 * Return the value of the specified indexed property of the specified 224 * bean, as a String. The index is specified as a method parameter and 225 * must *not* be included in the property name expression 226 * 227 * <p>For more details see <code>BeanUtilsBean</code>.</p> 228 * 229 * @param bean Bean whose property is to be extracted 230 * @param name Simple property name of the property value to be extracted 231 * @param index Index of the property value to be extracted 232 * @return The indexed property's value, converted to a String 233 * @throws IllegalAccessException if the caller does not have 234 * access to the property accessor method 235 * @throws InvocationTargetException if the property accessor method 236 * throws an exception 237 * @throws NoSuchMethodException if an accessor method for this 238 * property cannot be found 239 * @see BeanUtilsBean#getIndexedProperty(Object, String, int) 240 */ 241 public static String getIndexedProperty(final Object bean, 242 final String name, final int index) 243 throws IllegalAccessException, InvocationTargetException, 244 NoSuchMethodException { 245 return BeanUtilsBean.getInstance().getIndexedProperty(bean, name, index); 246 247 } 248 249 /** 250 * <p>Return the value of the specified indexed property of the specified 251 * bean, as a String.</p> 252 * 253 * <p>For more details see <code>BeanUtilsBean</code>.</p> 254 * 255 * @param bean Bean whose property is to be extracted 256 * @param name <code>propertyname(index)</code> of the property value 257 * to be extracted 258 * @return The mapped property's value, converted to a String 259 * @throws IllegalAccessException if the caller does not have 260 * access to the property accessor method 261 * @throws InvocationTargetException if the property accessor method 262 * throws an exception 263 * @throws NoSuchMethodException if an accessor method for this 264 * property cannot be found 265 * @see BeanUtilsBean#getMappedProperty(Object, String) 266 */ 267 public static String getMappedProperty(final Object bean, final String name) 268 throws IllegalAccessException, InvocationTargetException, 269 NoSuchMethodException { 270 return BeanUtilsBean.getInstance().getMappedProperty(bean, name); 271 } 272 273 /** 274 * <p>Return the value of the specified mapped property of the specified 275 * bean, as a String.</p> 276 * 277 * <p>For more details see <code>BeanUtilsBean</code>.</p> 278 * 279 * @param bean Bean whose property is to be extracted 280 * @param name Simple property name of the property value to be extracted 281 * @param key Lookup key of the property value to be extracted 282 * @return The mapped property's value, converted to a String 283 * @throws IllegalAccessException if the caller does not have 284 * access to the property accessor method 285 * @throws InvocationTargetException if the property accessor method 286 * throws an exception 287 * @throws NoSuchMethodException if an accessor method for this 288 * property cannot be found 289 * @see BeanUtilsBean#getMappedProperty(Object, String, String) 290 */ 291 public static String getMappedProperty(final Object bean, 292 final String name, final String key) 293 throws IllegalAccessException, InvocationTargetException, 294 NoSuchMethodException { 295 return BeanUtilsBean.getInstance().getMappedProperty(bean, name, key); 296 297 } 298 299 /** 300 * <p>Return the value of the (possibly nested) property of the specified 301 * name, for the specified bean, as a String.</p> 302 * 303 * <p>For more details see <code>BeanUtilsBean</code>.</p> 304 * 305 * @param bean Bean whose property is to be extracted 306 * @param name Possibly nested name of the property to be extracted 307 * @return The nested property's value, converted to a String 308 * @throws IllegalAccessException if the caller does not have 309 * access to the property accessor method 310 * @throws IllegalArgumentException if a nested reference to a 311 * property returns null 312 * @throws InvocationTargetException if the property accessor method 313 * throws an exception 314 * @throws NoSuchMethodException if an accessor method for this 315 * property cannot be found 316 * @see BeanUtilsBean#getNestedProperty 317 */ 318 public static String getNestedProperty(final Object bean, final String name) 319 throws IllegalAccessException, InvocationTargetException, 320 NoSuchMethodException { 321 return BeanUtilsBean.getInstance().getNestedProperty(bean, name); 322 323 } 324 325 /** 326 * <p>Return the value of the specified property of the specified bean, 327 * no matter which property reference format is used, as a String.</p> 328 * 329 * <p>For more details see <code>BeanUtilsBean</code>.</p> 330 * 331 * @param bean Bean whose property is to be extracted 332 * @param name Possibly indexed and/or nested name of the property 333 * to be extracted 334 * @return The property's value, converted to a String 335 * @throws IllegalAccessException if the caller does not have 336 * access to the property accessor method 337 * @throws InvocationTargetException if the property accessor method 338 * throws an exception 339 * @throws NoSuchMethodException if an accessor method for this 340 * property cannot be found 341 * @see BeanUtilsBean#getProperty 342 */ 343 public static String getProperty(final Object bean, final String name) 344 throws IllegalAccessException, InvocationTargetException, 345 NoSuchMethodException { 346 return BeanUtilsBean.getInstance().getProperty(bean, name); 347 } 348 349 /** 350 * <p>Return the value of the specified simple property of the specified 351 * bean, converted to a String.</p> 352 * 353 * <p>For more details see <code>BeanUtilsBean</code>.</p> 354 * 355 * @param bean Bean whose property is to be extracted 356 * @param name Name of the property to be extracted 357 * @return The property's value, converted to a String 358 * @throws IllegalAccessException if the caller does not have 359 * access to the property accessor method 360 * @throws InvocationTargetException if the property accessor method 361 * throws an exception 362 * @throws NoSuchMethodException if an accessor method for this 363 * property cannot be found 364 * @see BeanUtilsBean#getSimpleProperty 365 */ 366 public static String getSimpleProperty(final Object bean, final String name) 367 throws IllegalAccessException, InvocationTargetException, 368 NoSuchMethodException { 369 return BeanUtilsBean.getInstance().getSimpleProperty(bean, name); 370 } 371 372 /** 373 * If we're running on JDK 1.4 or later, initialize the cause for the given throwable. 374 * 375 * @param throwable The throwable. 376 * @param cause The cause of the throwable. 377 * @return always true in 1.10.0. 378 * @since 1.8.0 379 * @deprecated Use {@link Throwable#initCause(Throwable)}. 380 * @see Throwable#initCause(Throwable) 381 */ 382 @Deprecated 383 public static boolean initCause(final Throwable throwable, final Throwable cause) { 384 throwable.initCause(cause); 385 return true; 386 } 387 388 /** 389 * <p>Populate the JavaBeans properties of the specified bean, based on 390 * the specified name/value pairs.</p> 391 * 392 * <p>For more details see <code>BeanUtilsBean</code>.</p> 393 * 394 * @param bean JavaBean whose properties are being populated 395 * @param properties Map keyed by property name, with the 396 * corresponding (String or String[]) value(s) to be set 397 * 398 * @throws IllegalAccessException if the caller does not have 399 * access to the property accessor method 400 * @throws InvocationTargetException if the property accessor method 401 * throws an exception 402 * @see BeanUtilsBean#populate 403 */ 404 public static void populate(final Object bean, final Map<String, ? extends Object> properties) 405 throws IllegalAccessException, InvocationTargetException { 406 BeanUtilsBean.getInstance().populate(bean, properties); 407 } 408 409 /** 410 * Set whether fast on a Map 411 * @param map The map 412 * @param fast Whether it should be fast or not. 413 * @since 1.8.0 414 */ 415 public static void setCacheFast(final Map<?, ?> map, final boolean fast) { 416 if (map instanceof WeakFastHashMap) { 417 ((WeakFastHashMap<?, ?>)map).setFast(fast); 418 } 419 } 420 421 /** 422 * The <code>debug</code> static property is no longer used 423 * @param newDebug debug property 424 * @deprecated BeanUtils now uses commons-logging for all log messages. 425 * Use your favorite logging tool to configure logging for 426 * this class. 427 */ 428 @Deprecated 429 public static void setDebug(final int newDebug) { 430 debug = newDebug; 431 } 432 433 /** 434 * <p>Set the specified property value, performing type conversions as 435 * required to conform to the type of the destination property.</p> 436 * 437 * <p>For more details see <code>BeanUtilsBean</code>.</p> 438 * 439 * @param bean Bean on which setting is to be performed 440 * @param name Property name (can be nested/indexed/mapped/combo) 441 * @param value Value to be set 442 * @throws IllegalAccessException if the caller does not have 443 * access to the property accessor method 444 * @throws InvocationTargetException if the property accessor method 445 * throws an exception 446 * @see BeanUtilsBean#setProperty 447 */ 448 public static void setProperty(final Object bean, final String name, final Object value) 449 throws IllegalAccessException, InvocationTargetException { 450 BeanUtilsBean.getInstance().setProperty(bean, name, value); 451 } 452 453 /** 454 * Deprecated, all methods are static. 455 * 456 * @deprecated Will be private in 2.0. 457 */ 458 @Deprecated 459 public BeanUtils() { 460 // empty 461 } 462}