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.beanutils2.locale;
019
020import java.lang.reflect.InvocationTargetException;
021import java.util.Locale;
022
023import org.apache.commons.beanutils2.BeanUtils;
024
025/**
026 * <p>
027 * Utility methods for populating JavaBeans properties via reflection in a locale-dependent manner.
028 * </p>
029 *
030 * <p>
031 * The implementations for these methods are provided by {@code LocaleBeanUtilsBean}. For more details see {@link LocaleBeanUtilsBean}.
032 * </p>
033 */
034public class LocaleBeanUtils extends BeanUtils {
035
036    /**
037     * <p>
038     * Converts the specified value to the required type.
039     * </p>
040     *
041     * <p>
042     * For more details see {@code LocaleBeanUtilsBean}
043     * </p>
044     *
045     * @param type  The Java type of target property
046     * @param index The indexed subscript value (if any)
047     * @param value The value to be converted
048     * @return The converted value
049     * @see LocaleBeanUtilsBean#convert(Class, int, Object)
050     */
051    protected static Object convert(final Class<?> type, final int index, final Object value) {
052        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().convert(type, index, value);
053    }
054
055    /**
056     * <p>
057     * Converts the specified value to the required type using the specified conversion pattern.
058     * </p>
059     *
060     * <p>
061     * For more details see {@code LocaleBeanUtilsBean}
062     * </p>
063     *
064     * @param type    The Java type of target property
065     * @param index   The indexed subscript value (if any)
066     * @param value   The value to be converted
067     * @param pattern The conversion pattern
068     * @return The converted value
069     * @see LocaleBeanUtilsBean#convert(Class, int, Object, String)
070     */
071    protected static Object convert(final Class<?> type, final int index, final Object value, final String pattern) {
072        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().convert(type, index, value, pattern);
073    }
074
075    /**
076     * <p>
077     * Calculate the property type.
078     * </p>
079     *
080     * <p>
081     * For more details see {@code LocaleBeanUtilsBean}
082     * </p>
083     *
084     * @param target   The bean
085     * @param name     The property name
086     * @param propName The Simple name of target property
087     * @return The property's type
088     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
089     * @throws InvocationTargetException if the property accessor method throws an exception
090     * @see LocaleBeanUtilsBean#definePropertyType(Object, String, String)
091     */
092    protected static Class<?> definePropertyType(final Object target, final String name, final String propName)
093            throws IllegalAccessException, InvocationTargetException {
094        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().definePropertyType(target, name, propName);
095    }
096
097    /**
098     * <p>
099     * Gets whether the pattern is localized or not.
100     * </p>
101     *
102     * <p>
103     * For more details see {@code LocaleBeanUtilsBean}
104     * </p>
105     *
106     * @return {@code true} if pattern is localized, otherwise {@code false}
107     * @see LocaleBeanUtilsBean#getApplyLocalized()
108     */
109    public static boolean getApplyLocalized() {
110        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getApplyLocalized();
111    }
112
113    /**
114     * <p>
115     * Gets the locale used when no locale is passed.
116     * </p>
117     *
118     * <p>
119     * For more details see {@code LocaleBeanUtilsBean}
120     * </p>
121     *
122     * @return the default locale
123     * @see LocaleBeanUtilsBean#getDefaultLocale()
124     */
125    public static Locale getDefaultLocale() {
126        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getDefaultLocale();
127    }
128
129    /**
130     * Gets the value of the specified locale-sensitive indexed property of the specified bean, as a String using the default conversion pattern of the
131     * corresponding {@link LocaleConverter}.
132     *
133     * <p>
134     * For more details see {@code LocaleBeanUtilsBean}
135     * </p>
136     *
137     * @param bean Bean whose property is to be extracted
138     * @param name {@code propertyname[index]} of the property value to be extracted
139     * @return The indexed property's value, converted to a String
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 LocaleBeanUtilsBean#getIndexedProperty(Object, String)
144     */
145    public static String getIndexedProperty(final Object bean, final String name)
146            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
147        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name);
148    }
149
150    /**
151     * <p>
152     * Return the value of the specified locale-sensitive indexed property of the specified bean, as a String using the default conversion pattern of the
153     * corresponding {@link LocaleConverter}.
154     * </p>
155     *
156     * <p>
157     * For more details see {@code LocaleBeanUtilsBean}
158     * </p>
159     *
160     * @param bean  Bean whose property is to be extracted
161     * @param name  Simple property name of the property value to be extracted
162     * @param index Index of the property value to be extracted
163     * @return The indexed property's value, converted to a String
164     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
165     * @throws InvocationTargetException if the property accessor method throws an exception
166     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
167     * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String, int)
168     */
169    public static String getIndexedProperty(final Object bean, final String name, final int index)
170            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
171        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name, index);
172    }
173
174    /**
175     * <p>
176     * Return the value of the specified locale-sensitive indexed property of the specified bean, as a String using the specified conversion pattern.
177     * </p>
178     *
179     * <p>
180     * For more details see {@code LocaleBeanUtilsBean}
181     * </p>
182     *
183     * @param bean    Bean whose property is to be extracted
184     * @param name    Simple property name of the property value to be extracted
185     * @param index   Index of the property value to be extracted
186     * @param pattern The conversion pattern
187     * @return The indexed property's value, converted to a String
188     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
189     * @throws InvocationTargetException if the property accessor method throws an exception
190     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
191     * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String, int, String)
192     */
193    public static String getIndexedProperty(final Object bean, final String name, final int index, final String pattern)
194            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
195        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name, index, pattern);
196    }
197
198    /**
199     * <p>
200     * Return the value of the specified locale-sensitive indexed property of the specified bean, as a String.
201     * </p>
202     *
203     * <p>
204     * For more details see {@code LocaleBeanUtilsBean}
205     * </p>
206     *
207     * @param bean    Bean whose property is to be extracted
208     * @param name    {@code propertyname[index]} of the property value to be extracted
209     * @param pattern The conversion pattern
210     * @return The indexed property's value, converted to a String
211     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
212     * @throws InvocationTargetException if the property accessor method throws an exception
213     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
214     * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String, String)
215     */
216    public static String getIndexedProperty(final Object bean, final String name, final String pattern)
217            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
218        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name, pattern);
219    }
220
221    /**
222     * <p>
223     * Return the value of the specified locale-sensitive mapped property of the specified bean, as a String using the default conversion pattern of the
224     * corresponding {@link LocaleConverter}.
225     * </p>
226     *
227     * <p>
228     * For more details see {@code LocaleBeanUtilsBean}
229     * </p>
230     *
231     * @param bean Bean whose property is to be extracted
232     * @param name {@code propertyname(index)} of the property value to be extracted
233     * @return The mapped property's value, converted to a String
234     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
235     * @throws InvocationTargetException if the property accessor method throws an exception
236     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
237     * @see LocaleBeanUtilsBean#getMappedProperty(Object, String)
238     */
239    public static String getMappedProperty(final Object bean, final String name)
240            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
241        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedProperty(bean, name);
242    }
243
244    /**
245     * <p>
246     * Return the value of the specified mapped locale-sensitive property of the specified bean, as a String The key is specified as a method parameter and must
247     * *not* be included in the property name expression.
248     * </p>
249     *
250     * <p>
251     * For more details see {@code LocaleBeanUtilsBean}
252     * </p>
253     *
254     * @param bean Bean whose property is to be extracted
255     * @param name Simple property name of the property value to be extracted
256     * @param key  Lookup key of the property value to be extracted
257     * @return The mapped property's value, converted to a String
258     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
259     * @throws InvocationTargetException if the property accessor method throws an exception
260     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
261     * @see LocaleBeanUtilsBean#getMappedProperty(Object, String, String)
262     */
263    public static String getMappedProperty(final Object bean, final String name, final String key)
264            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
265        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedProperty(bean, name, key);
266    }
267
268    /**
269     * <p>
270     * Return the value of the specified mapped locale-sensitive property of the specified bean, as a String using the specified conversion pattern.
271     * </p>
272     *
273     * <p>
274     * For more details see {@code LocaleBeanUtilsBean}
275     * </p>
276     *
277     * @param bean    Bean whose property is to be extracted
278     * @param name    Simple property name of the property value to be extracted
279     * @param key     Lookup key of the property value to be extracted
280     * @param pattern The conversion pattern
281     * @return The mapped property's value, converted to a String
282     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
283     * @throws InvocationTargetException if the property accessor method throws an exception
284     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
285     * @see LocaleBeanUtilsBean#getMappedProperty(Object, String, String, String)
286     */
287    public static String getMappedProperty(final Object bean, final String name, final String key, final String pattern)
288            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
289        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedProperty(bean, name, key, pattern);
290    }
291
292    /**
293     * <p>
294     * Return the value of the specified locale-sensitive mapped property of the specified bean, as a String using the specified pattern.
295     * </p>
296     *
297     * <p>
298     * For more details see {@code LocaleBeanUtilsBean}
299     * </p>
300     *
301     * @param bean    Bean whose property is to be extracted
302     * @param name    {@code propertyname(index)} of the property value to be extracted
303     * @param pattern The conversion pattern
304     * @return The mapped property's value, converted to a String
305     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
306     * @throws InvocationTargetException if the property accessor method throws an exception
307     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
308     * @see LocaleBeanUtilsBean#getMappedPropertyLocale(Object, String, String)
309     */
310    public static String getMappedPropertyLocale(final Object bean, final String name, final String pattern)
311            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
312        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedPropertyLocale(bean, name, pattern);
313    }
314
315    /**
316     * <p>
317     * Return the value of the (possibly nested) locale-sensitive property of the specified name.
318     * </p>
319     *
320     * <p>
321     * For more details see {@code LocaleBeanUtilsBean}
322     * </p>
323     *
324     * @param bean Bean whose property is to be extracted
325     * @param name Possibly nested name of the property to be extracted
326     * @return The nested property's value, converted to a String
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     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
330     * @see LocaleBeanUtilsBean#getNestedProperty(Object, String)
331     */
332    public static String getNestedProperty(final Object bean, final String name)
333            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
334        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getNestedProperty(bean, name);
335    }
336
337    /**
338     * <p>
339     * Return the value of the (possibly nested) locale-sensitive property of the specified name, for the specified bean, as a String using the specified
340     * pattern.
341     * </p>
342     *
343     * <p>
344     * For more details see {@code LocaleBeanUtilsBean}
345     * </p>
346     *
347     * @param bean    Bean whose property is to be extracted
348     * @param name    Possibly nested name of the property to be extracted
349     * @param pattern The conversion pattern
350     * @return The nested property's value, converted to a String
351     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
352     * @throws InvocationTargetException if the property accessor method throws an exception
353     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
354     * @see LocaleBeanUtilsBean#getNestedProperty(Object, String, String)
355     */
356    public static String getNestedProperty(final Object bean, final String name, final String pattern)
357            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
358        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getNestedProperty(bean, name, pattern);
359    }
360
361    /**
362     * <p>
363     * Return the value of the specified locale-sensitive property of the specified bean.
364     * </p>
365     *
366     * <p>
367     * For more details see {@code LocaleBeanUtilsBean}
368     * </p>
369     *
370     * @param bean Bean whose property is to be extracted
371     * @param name Possibly indexed and/or nested name of the property to be extracted
372     * @return The property's value, converted to a String
373     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
374     * @throws InvocationTargetException if the property accessor method throws an exception
375     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
376     * @see LocaleBeanUtilsBean#getProperty(Object, String)
377     */
378    public static String getProperty(final Object bean, final String name) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
379        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getProperty(bean, name);
380    }
381
382    /**
383     * <p>
384     * Return the value of the specified locale-sensitive property of the specified bean.
385     * </p>
386     *
387     * <p>
388     * For more details see {@code LocaleBeanUtilsBean}
389     * </p>
390     *
391     * @param bean    Bean whose property is to be extracted
392     * @param name    Possibly indexed and/or nested name of the property to be extracted
393     * @param pattern The conversion pattern
394     * @return The nested property's value, converted to a String
395     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
396     * @throws InvocationTargetException if the property accessor method throws an exception
397     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
398     * @see LocaleBeanUtilsBean#getProperty(Object, String, String)
399     */
400    public static String getProperty(final Object bean, final String name, final String pattern)
401            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
402        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getProperty(bean, name, pattern);
403    }
404
405    /**
406     * <p>
407     * Return the value of the specified simple locale-sensitive property of the specified bean, converted to a String using the default conversion pattern of
408     * the corresponding {@link LocaleConverter}.
409     * </p>
410     *
411     * <p>
412     * For more details see {@code LocaleBeanUtilsBean}
413     * </p>
414     *
415     * @param bean Bean whose property is to be extracted
416     * @param name Name of the property to be extracted
417     * @return The property's value, converted to a String
418     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
419     * @throws InvocationTargetException if the property accessor method throws an exception
420     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
421     * @see LocaleBeanUtilsBean#getSimpleProperty(Object, String)
422     */
423    public static String getSimpleProperty(final Object bean, final String name)
424            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
425        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getSimpleProperty(bean, name);
426    }
427
428    /**
429     * <p>
430     * Return the value of the specified simple locale-sensitive property of the specified bean, converted to a String using the specified conversion pattern.
431     * </p>
432     *
433     * <p>
434     * For more details see {@code LocaleBeanUtilsBean}
435     * </p>
436     *
437     * @param bean    Bean whose property is to be extracted
438     * @param name    Name of the property to be extracted
439     * @param pattern The conversion pattern
440     * @return The property's value, converted to a String
441     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
442     * @throws InvocationTargetException if the property accessor method throws an exception
443     * @throws NoSuchMethodException     if an accessor method for this property cannot be found
444     * @see LocaleBeanUtilsBean#getSimpleProperty(Object, String, String)
445     */
446    public static String getSimpleProperty(final Object bean, final String name, final String pattern)
447            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
448        return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getSimpleProperty(bean, name, pattern);
449    }
450
451    /**
452     * <p>
453     * Invoke the setter method.
454     * </p>
455     *
456     * <p>
457     * For more details see {@code LocaleBeanUtilsBean}
458     * </p>
459     *
460     * @param target   The bean
461     * @param propName The Simple name of target property
462     * @param key      The Mapped key value (if any)
463     * @param index    The indexed subscript value (if any)
464     * @param newValue The value to be set
465     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
466     * @throws InvocationTargetException if the property accessor method throws an exception
467     * @see LocaleBeanUtilsBean#invokeSetter(Object, String, String, int, Object)
468     */
469    protected static void invokeSetter(final Object target, final String propName, final String key, final int index, final Object newValue)
470            throws IllegalAccessException, InvocationTargetException {
471        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().invokeSetter(target, propName, key, index, newValue);
472    }
473
474    /**
475     * <p>
476     * Sets whether the pattern is localized or not.
477     * </p>
478     *
479     * <p>
480     * For more details see {@code LocaleBeanUtilsBean}
481     * </p>
482     *
483     * @param newApplyLocalized {@code true} if pattern is localized, otherwise {@code false}
484     * @see LocaleBeanUtilsBean#setApplyLocalized(boolean)
485     */
486    public static void setApplyLocalized(final boolean newApplyLocalized) {
487        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setApplyLocalized(newApplyLocalized);
488    }
489
490    /**
491     * <p>
492     * Sets the locale used when no locale is passed.
493     * </p>
494     *
495     * <p>
496     * For more details see {@code LocaleBeanUtilsBean}
497     * </p>
498     *
499     * @param locale the default locale
500     * @see LocaleBeanUtilsBean#setDefaultLocale(Locale)
501     */
502    public static void setDefaultLocale(final Locale locale) {
503        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setDefaultLocale(locale);
504    }
505
506    /**
507     * <p>
508     * Set the specified locale-sensitive property value, performing type conversions as required to conform to the type of the destination property using the
509     * default conversion pattern of the corresponding {@link LocaleConverter}.
510     * </p>
511     *
512     * <p>
513     * For more details see {@code LocaleBeanUtilsBean}
514     * </p>
515     *
516     * @param bean  Bean on which setting is to be performed
517     * @param name  Property name (can be nested/indexed/mapped/combo)
518     * @param value Value to be set
519     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
520     * @throws InvocationTargetException if the property accessor method throws an exception
521     * @see LocaleBeanUtilsBean#setProperty(Object, String, Object)
522     */
523    public static void setProperty(final Object bean, final String name, final Object value) throws IllegalAccessException, InvocationTargetException {
524        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setProperty(bean, name, value);
525    }
526
527    /**
528     * <p>
529     * Set the specified locale-sensitive property value, performing type conversions as required to conform to the type of the destination property using the
530     * specified conversion pattern.
531     * </p>
532     *
533     * <p>
534     * For more details see {@code LocaleBeanUtilsBean}
535     * </p>
536     *
537     * @param bean    Bean on which setting is to be performed
538     * @param name    Property name (can be nested/indexed/mapped/combo)
539     * @param value   Value to be set
540     * @param pattern The conversion pattern
541     * @throws IllegalAccessException    if the caller does not have access to the property accessor method
542     * @throws InvocationTargetException if the property accessor method throws an exception
543     * @see LocaleBeanUtilsBean#setProperty(Object, String, Object, String)
544     */
545    public static void setProperty(final Object bean, final String name, final Object value, final String pattern)
546            throws IllegalAccessException, InvocationTargetException {
547        LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setProperty(bean, name, value, pattern);
548    }
549}