1. /*
  2. * Copyright 2001-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.beanutils.locale;
  17. import org.apache.commons.beanutils.*;
  18. import org.apache.commons.logging.Log;
  19. import org.apache.commons.logging.LogFactory;
  20. import java.beans.IndexedPropertyDescriptor;
  21. import java.beans.PropertyDescriptor;
  22. import java.lang.reflect.InvocationTargetException;
  23. import java.util.Locale;
  24. /**
  25. * <p>Utility methods for populating JavaBeans properties
  26. * via reflection in a locale-dependent manner.</p>
  27. *
  28. * <p>The implementations for these methods are provided by <code>LocaleBeanUtilsBean</code>.
  29. * For more details see {@link LocaleBeanUtilsBean}.</p>
  30. *
  31. * @author Craig R. McClanahan
  32. * @author Ralph Schaer
  33. * @author Chris Audley
  34. * @author Rey François
  35. * @author Gregor Raıman
  36. * @author Yauheny Mikulski
  37. */
  38. public class LocaleBeanUtils extends BeanUtils {
  39. // ----------------------------------------------------- Instance Variables
  40. /** All logging goes through this logger */
  41. private static Log log = LogFactory.getLog(LocaleBeanUtils.class);
  42. /**
  43. * <p>Gets the locale used when no locale is passed.</p>
  44. *
  45. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  46. *
  47. * @see LocaleBeanUtilsBean#getDefaultLocale()
  48. */
  49. public static Locale getDefaultLocale() {
  50. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getDefaultLocale();
  51. }
  52. /**
  53. * <p>Sets the locale used when no locale is passed.</p>
  54. *
  55. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  56. *
  57. * @see LocaleBeanUtilsBean#setDefaultLocale(Locale)
  58. */
  59. public static void setDefaultLocale(Locale locale) {
  60. LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setDefaultLocale(locale);
  61. }
  62. /**
  63. * <p>Gets whether the pattern is localized or not.</p>
  64. *
  65. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  66. *
  67. * @see LocaleBeanUtilsBean#getApplyLocalized()
  68. */
  69. public static boolean getApplyLocalized() {
  70. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getApplyLocalized();
  71. }
  72. /**
  73. * <p>Sets whether the pattern is localized or not.</p>
  74. *
  75. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  76. *
  77. * @see LocaleBeanUtilsBean#setApplyLocalized(boolean)
  78. */
  79. public static void setApplyLocalized(boolean newApplyLocalized) {
  80. LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setApplyLocalized(newApplyLocalized);
  81. }
  82. // --------------------------------------------------------- Public Methods
  83. /**
  84. * <p>Return the value of the specified locale-sensitive indexed property
  85. * of the specified bean, as a String.</p>
  86. *
  87. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  88. *
  89. * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String, String)
  90. */
  91. public static String getIndexedProperty(Object bean, String name, String pattern)
  92. throws IllegalAccessException, InvocationTargetException,
  93. NoSuchMethodException {
  94. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name, pattern);
  95. }
  96. /**
  97. * Return the value of the specified locale-sensitive indexed property
  98. * of the specified bean, as a String using the default convertion pattern of
  99. * the corresponding {@link LocaleConverter}.
  100. *
  101. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  102. *
  103. * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String)
  104. */
  105. public static String getIndexedProperty(Object bean, String name)
  106. throws IllegalAccessException, InvocationTargetException,
  107. NoSuchMethodException {
  108. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name);
  109. }
  110. /**
  111. * <p>Return the value of the specified locale-sensetive indexed property
  112. * of the specified bean, as a String using the specified convertion pattern.</p>
  113. *
  114. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  115. *
  116. * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String, int, String)
  117. */
  118. public static String getIndexedProperty(Object bean,
  119. String name, int index, String pattern)
  120. throws IllegalAccessException, InvocationTargetException,
  121. NoSuchMethodException {
  122. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name, index, pattern);
  123. }
  124. /**
  125. * <p>Return the value of the specified locale-sensetive indexed property
  126. * of the specified bean, as a String using the default convertion pattern of
  127. * the corresponding {@link LocaleConverter}.</p>
  128. *
  129. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  130. *
  131. * @see LocaleBeanUtilsBean#getIndexedProperty(Object, String, int)
  132. */
  133. public static String getIndexedProperty(Object bean,
  134. String name, int index)
  135. throws IllegalAccessException, InvocationTargetException,
  136. NoSuchMethodException {
  137. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getIndexedProperty(bean, name, index);
  138. }
  139. /**
  140. * <p>Return the value of the specified simple locale-sensitive property
  141. * of the specified bean, converted to a String using the specified
  142. * convertion pattern.</p>
  143. *
  144. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  145. *
  146. * @see LocaleBeanUtilsBean#getSimpleProperty(Object, String, String)
  147. */
  148. public static String getSimpleProperty(Object bean, String name, String pattern)
  149. throws IllegalAccessException, InvocationTargetException,
  150. NoSuchMethodException {
  151. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getSimpleProperty(bean, name, pattern);
  152. }
  153. /**
  154. * <p>Return the value of the specified simple locale-sensitive property
  155. * of the specified bean, converted to a String using the default
  156. * convertion pattern of the corresponding {@link LocaleConverter}.</p>
  157. *
  158. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  159. *
  160. * @see LocaleBeanUtilsBean#getSimpleProperty(Object, String)
  161. */
  162. public static String getSimpleProperty(Object bean, String name)
  163. throws IllegalAccessException, InvocationTargetException,
  164. NoSuchMethodException {
  165. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getSimpleProperty(bean, name);
  166. }
  167. /**
  168. * <p>Return the value of the specified mapped locale-sensitive property
  169. * of the specified bean, as a String using the specified convertion pattern.</p>
  170. *
  171. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  172. *
  173. * @see LocaleBeanUtilsBean#getMappedProperty(Object, String, String, String)
  174. */
  175. public static String getMappedProperty(Object bean,
  176. String name, String key, String pattern)
  177. throws IllegalAccessException, InvocationTargetException,
  178. NoSuchMethodException {
  179. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedProperty(bean, name, key, pattern);
  180. }
  181. /**
  182. * <p>Return the value of the specified mapped locale-sensitive property
  183. * of the specified bean, as a String
  184. * The key is specified as a method parameter and must *not* be included
  185. * in the property name expression.</p>
  186. *
  187. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  188. *
  189. * @see LocaleBeanUtilsBean#getMappedProperty(Object, String, String)
  190. */
  191. public static String getMappedProperty(Object bean,
  192. String name, String key)
  193. throws IllegalAccessException, InvocationTargetException,
  194. NoSuchMethodException {
  195. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedProperty(bean, name, key);
  196. }
  197. /**
  198. * <p>Return the value of the specified locale-sensitive mapped property
  199. * of the specified bean, as a String using the specified pattern.</p>
  200. *
  201. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  202. *
  203. * @see LocaleBeanUtilsBean#getMappedPropertyLocale(Object, String, String)
  204. */
  205. public static String getMappedPropertyLocale(Object bean, String name, String pattern)
  206. throws IllegalAccessException, InvocationTargetException,
  207. NoSuchMethodException {
  208. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedPropertyLocale(bean, name, pattern);
  209. }
  210. /**
  211. * <p>Return the value of the specified locale-sensitive mapped property
  212. * of the specified bean, as a String using the default
  213. * convertion pattern of the corresponding {@link LocaleConverter}.</p>
  214. *
  215. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  216. *
  217. * @see LocaleBeanUtilsBean#getMappedProperty(Object, String)
  218. */
  219. public static String getMappedProperty(Object bean, String name)
  220. throws IllegalAccessException, InvocationTargetException,
  221. NoSuchMethodException {
  222. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getMappedProperty(bean, name);
  223. }
  224. /**
  225. * <p>Return the value of the (possibly nested) locale-sensitive property
  226. * of the specified name, for the specified bean,
  227. * as a String using the specified pattern.</p>
  228. *
  229. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  230. *
  231. * @see LocaleBeanUtilsBean#getNestedProperty(Object, String, String)
  232. */
  233. public static String getNestedProperty(Object bean, String name, String pattern)
  234. throws IllegalAccessException, InvocationTargetException,
  235. NoSuchMethodException {
  236. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getNestedProperty(bean, name, pattern);
  237. }
  238. /**
  239. * <p>Return the value of the (possibly nested) locale-sensitive property
  240. * of the specified name.</p>
  241. *
  242. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  243. *
  244. * @see LocaleBeanUtilsBean#getNestedProperty(Object, String)
  245. */
  246. public static String getNestedProperty(Object bean, String name)
  247. throws IllegalAccessException, InvocationTargetException,
  248. NoSuchMethodException {
  249. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getNestedProperty(bean, name);
  250. }
  251. /**
  252. * <p>Return the value of the specified locale-sensitive property
  253. * of the specified bean.</p>
  254. *
  255. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  256. *
  257. * @see LocaleBeanUtilsBean#getProperty(Object, String, String)
  258. */
  259. public static String getProperty(Object bean, String name, String pattern)
  260. throws IllegalAccessException, InvocationTargetException,
  261. NoSuchMethodException {
  262. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getProperty(bean, name, pattern);
  263. }
  264. /**
  265. * <p>Return the value of the specified locale-sensitive property
  266. * of the specified bean.</p>
  267. *
  268. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  269. *
  270. * @see LocaleBeanUtilsBean#getProperty(Object, String)
  271. */
  272. public static String getProperty(Object bean, String name)
  273. throws IllegalAccessException, InvocationTargetException,
  274. NoSuchMethodException {
  275. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().getProperty(bean, name);
  276. }
  277. /**
  278. * <p>Set the specified locale-sensitive property value, performing type
  279. * conversions as required to conform to the type of the destination property
  280. * using the default convertion pattern of the corresponding {@link LocaleConverter}.</p>
  281. *
  282. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  283. *
  284. * @see LocaleBeanUtilsBean#setProperty(Object, String, Object)
  285. */
  286. public static void setProperty(Object bean, String name, Object value)
  287. throws IllegalAccessException, InvocationTargetException {
  288. LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setProperty(bean, name, value);
  289. }
  290. /**
  291. * <p>Set the specified locale-sensitive property value, performing type
  292. * conversions as required to conform to the type of the destination
  293. * property using the specified convertion pattern.</p>
  294. *
  295. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  296. *
  297. * @see LocaleBeanUtilsBean#setProperty(Object, String, Object, String)
  298. */
  299. public static void setProperty(Object bean, String name, Object value, String pattern)
  300. throws IllegalAccessException, InvocationTargetException {
  301. LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().setProperty(bean, name, value, pattern);
  302. }
  303. /**
  304. * <p>Calculate the property type.</p>
  305. *
  306. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  307. *
  308. * @see LocaleBeanUtilsBean#definePropertyType(Object, String, String)
  309. */
  310. protected static Class definePropertyType(Object target, String name, String propName)
  311. throws IllegalAccessException, InvocationTargetException {
  312. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().definePropertyType(target, name, propName);
  313. }
  314. /**
  315. * <p>Convert the specified value to the required type using the
  316. * specified convertion pattern.</p>
  317. *
  318. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  319. *
  320. * @see LocaleBeanUtilsBean#convert(Class, int, Object, String)
  321. */
  322. protected static Object convert(Class type, int index, Object value, String pattern) {
  323. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().convert(type, index, value, pattern);
  324. }
  325. /**
  326. * <p>Convert the specified value to the required type.</p>
  327. *
  328. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  329. *
  330. * @see LocaleBeanUtilsBean#convert(Class, int, Object)
  331. */
  332. protected static Object convert(Class type, int index, Object value) {
  333. return LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().convert(type, index, value);
  334. }
  335. /**
  336. * <p>Invoke the setter method.</p>
  337. *
  338. * <p>For more details see <code>LocaleBeanUtilsBean</code></p>
  339. *
  340. * @see LocaleBeanUtilsBean#invokeSetter(Object, String, String, int, Object)
  341. */
  342. protected static void invokeSetter(Object target, String propName, String key, int index, Object newValue)
  343. throws IllegalAccessException, InvocationTargetException {
  344. LocaleBeanUtilsBean.getLocaleBeanUtilsInstance().invokeSetter(target, propName, key, index, newValue);
  345. }
  346. /**
  347. * Resolve any nested expression to get the actual target bean.
  348. *
  349. * @deprecated moved into <code>LocaleBeanUtilsBean</code>
  350. * @param bean The bean
  351. * @param name The property name
  352. *
  353. * @exception IllegalAccessException if the caller does not have
  354. * access to the property accessor method
  355. * @exception InvocationTargetException if the property accessor method
  356. * throws an exception
  357. */
  358. protected static Descriptor calculate(Object bean, String name)
  359. throws IllegalAccessException, InvocationTargetException {
  360. String propName = null; // Simple name of target property
  361. int index = -1; // Indexed subscript value (if any)
  362. String key = null; // Mapped key value (if any)
  363. Object target = bean;
  364. int delim = name.lastIndexOf(PropertyUtils.NESTED_DELIM);
  365. if (delim >= 0) {
  366. try {
  367. target =
  368. PropertyUtils.getProperty(bean, name.substring(0, delim));
  369. }
  370. catch (NoSuchMethodException e) {
  371. return null; // Skip this property setter
  372. }
  373. name = name.substring(delim + 1);
  374. if (log.isTraceEnabled()) {
  375. log.trace(" Target bean = " + target);
  376. log.trace(" Target name = " + name);
  377. }
  378. }
  379. // Calculate the property name, index, and key values
  380. propName = name;
  381. int i = propName.indexOf(PropertyUtils.INDEXED_DELIM);
  382. if (i >= 0) {
  383. int k = propName.indexOf(PropertyUtils.INDEXED_DELIM2);
  384. try {
  385. index =
  386. Integer.parseInt(propName.substring(i + 1, k));
  387. }
  388. catch (NumberFormatException e) {
  389. ;
  390. }
  391. propName = propName.substring(0, i);
  392. }
  393. int j = propName.indexOf(PropertyUtils.MAPPED_DELIM);
  394. if (j >= 0) {
  395. int k = propName.indexOf(PropertyUtils.MAPPED_DELIM2);
  396. try {
  397. key = propName.substring(j + 1, k);
  398. }
  399. catch (IndexOutOfBoundsException e) {
  400. ;
  401. }
  402. propName = propName.substring(0, j);
  403. }
  404. return new Descriptor(target, name, propName, key, index);
  405. }
  406. /** @deprecated moved into <code>LocaleBeanUtils</code> */
  407. protected static class Descriptor {
  408. private int index = -1; // Indexed subscript value (if any)
  409. private String name;
  410. private String propName; // Simple name of target property
  411. private String key; // Mapped key value (if any)
  412. private Object target;
  413. public Descriptor(Object target, String name, String propName, String key, int index) {
  414. setTarget(target);
  415. setName(name);
  416. setPropName(propName);
  417. setKey(key);
  418. setIndex(index);
  419. }
  420. public Object getTarget() {
  421. return target;
  422. }
  423. public void setTarget(Object target) {
  424. this.target = target;
  425. }
  426. public String getKey() {
  427. return key;
  428. }
  429. public void setKey(String key) {
  430. this.key = key;
  431. }
  432. public int getIndex() {
  433. return index;
  434. }
  435. public void setIndex(int index) {
  436. this.index = index;
  437. }
  438. public String getName() {
  439. return name;
  440. }
  441. public void setName(String name) {
  442. this.name = name;
  443. }
  444. public String getPropName() {
  445. return propName;
  446. }
  447. public void setPropName(String propName) {
  448. this.propName = propName;
  449. }
  450. }
  451. }