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