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;
  17. /**
  18. * <p>Implementation of <code>DynaBean</code> that wraps a standard JavaBean
  19. * instance, so that DynaBean APIs can be used to access its properties.</p>
  20. *
  21. * <p>
  22. * The most common use cases for this class involve wrapping an existing java bean.
  23. * (This makes it different from the typical use cases for other <code>DynaBean</code>'s.)
  24. * For example:
  25. * </p>
  26. * <code><pre>
  27. * Object aJavaBean = ...;
  28. * ...
  29. * DynaBean db = new WrapDynaBean(aJavaBean);
  30. * ...
  31. * </pre></code>
  32. *
  33. * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation does not
  34. * support the <code>contains()</code> and <code>remove()</code> methods.</p>
  35. *
  36. * @author Craig McClanahan
  37. * @version $Revision: 1.9 $ $Date: 2004/02/28 13:18:34 $
  38. */
  39. public class WrapDynaBean implements DynaBean {
  40. // ---------------------------------------------------------- Constructors
  41. /**
  42. * Construct a new <code>DynaBean</code> associated with the specified
  43. * JavaBean instance.
  44. *
  45. * @param instance JavaBean instance to be wrapped
  46. */
  47. public WrapDynaBean(Object instance) {
  48. super();
  49. this.instance = instance;
  50. this.dynaClass = WrapDynaClass.createDynaClass(instance.getClass());
  51. }
  52. // ---------------------------------------------------- Instance Variables
  53. /**
  54. * The <code>DynaClass</code> "base class" that this DynaBean
  55. * is associated with.
  56. */
  57. protected WrapDynaClass dynaClass = null;
  58. /**
  59. * The JavaBean instance wrapped by this WrapDynaBean.
  60. */
  61. protected Object instance = null;
  62. // ------------------------------------------------------ DynaBean Methods
  63. /**
  64. * Does the specified mapped property contain a value for the specified
  65. * key value?
  66. *
  67. * @param name Name of the property to check
  68. * @param key Name of the key to check
  69. *
  70. * @exception IllegalArgumentException if there is no property
  71. * of the specified name
  72. */
  73. public boolean contains(String name, String key) {
  74. throw new UnsupportedOperationException
  75. ("WrapDynaBean does not support contains()");
  76. }
  77. /**
  78. * Return the value of a simple property with the specified name.
  79. *
  80. * @param name Name of the property whose value is to be retrieved
  81. *
  82. * @exception IllegalArgumentException if there is no property
  83. * of the specified name
  84. */
  85. public Object get(String name) {
  86. Object value = null;
  87. try {
  88. value = PropertyUtils.getSimpleProperty(instance, name);
  89. } catch (Throwable t) {
  90. throw new IllegalArgumentException
  91. ("Property '" + name + "' has no read method");
  92. }
  93. return (value);
  94. }
  95. /**
  96. * Return the value of an indexed property with the specified name.
  97. *
  98. * @param name Name of the property whose value is to be retrieved
  99. * @param index Index of the value to be retrieved
  100. *
  101. * @exception IllegalArgumentException if there is no property
  102. * of the specified name
  103. * @exception IllegalArgumentException if the specified property
  104. * exists, but is not indexed
  105. * @exception IndexOutOfBoundsException if the specified index
  106. * is outside the range of the underlying property
  107. * @exception NullPointerException if no array or List has been
  108. * initialized for this property
  109. */
  110. public Object get(String name, int index) {
  111. Object value = null;
  112. try {
  113. value = PropertyUtils.getIndexedProperty(instance, name, index);
  114. } catch (IndexOutOfBoundsException e) {
  115. throw e;
  116. } catch (Throwable t) {
  117. throw new IllegalArgumentException
  118. ("Property '" + name + "' has no indexed read method");
  119. }
  120. return (value);
  121. }
  122. /**
  123. * Return the value of a mapped property with the specified name,
  124. * or <code>null</code> if there is no value for the specified key.
  125. *
  126. * @param name Name of the property whose value is to be retrieved
  127. * @param key Key of the value to be retrieved
  128. *
  129. * @exception IllegalArgumentException if there is no property
  130. * of the specified name
  131. * @exception IllegalArgumentException if the specified property
  132. * exists, but is not mapped
  133. */
  134. public Object get(String name, String key) {
  135. Object value = null;
  136. try {
  137. value = PropertyUtils.getMappedProperty(instance, name, key);
  138. } catch (Throwable t) {
  139. throw new IllegalArgumentException
  140. ("Property '" + name + "' has no mapped read method");
  141. }
  142. return (value);
  143. }
  144. /**
  145. * Return the <code>DynaClass</code> instance that describes the set of
  146. * properties available for this DynaBean.
  147. */
  148. public DynaClass getDynaClass() {
  149. return (this.dynaClass);
  150. }
  151. /**
  152. * Remove any existing value for the specified key on the
  153. * specified mapped property.
  154. *
  155. * @param name Name of the property for which a value is to
  156. * be removed
  157. * @param key Key of the value to be removed
  158. *
  159. * @exception IllegalArgumentException if there is no property
  160. * of the specified name
  161. */
  162. public void remove(String name, String key) {
  163. throw new UnsupportedOperationException
  164. ("WrapDynaBean does not support remove()");
  165. }
  166. /**
  167. * Set the value of a simple property with the specified name.
  168. *
  169. * @param name Name of the property whose value is to be set
  170. * @param value Value to which this property is to be set
  171. *
  172. * @exception ConversionException if the specified value cannot be
  173. * converted to the type required for this property
  174. * @exception IllegalArgumentException if there is no property
  175. * of the specified name
  176. * @exception NullPointerException if an attempt is made to set a
  177. * primitive property to null
  178. */
  179. public void set(String name, Object value) {
  180. try {
  181. PropertyUtils.setSimpleProperty(instance, name, value);
  182. } catch (Throwable t) {
  183. throw new IllegalArgumentException
  184. ("Property '" + name + "' has no write method");
  185. }
  186. }
  187. /**
  188. * Set the value of an indexed property with the specified name.
  189. *
  190. * @param name Name of the property whose value is to be set
  191. * @param index Index of the property to be set
  192. * @param value Value to which this property is to be set
  193. *
  194. * @exception ConversionException if the specified value cannot be
  195. * converted to the type required for this property
  196. * @exception IllegalArgumentException if there is no property
  197. * of the specified name
  198. * @exception IllegalArgumentException if the specified property
  199. * exists, but is not indexed
  200. * @exception IndexOutOfBoundsException if the specified index
  201. * is outside the range of the underlying property
  202. */
  203. public void set(String name, int index, Object value) {
  204. try {
  205. PropertyUtils.setIndexedProperty(instance, name, index, value);
  206. } catch (IndexOutOfBoundsException e) {
  207. throw e;
  208. } catch (Throwable t) {
  209. throw new IllegalArgumentException
  210. ("Property '" + name + "' has no indexed write method");
  211. }
  212. }
  213. /**
  214. * Set the value of a mapped property with the specified name.
  215. *
  216. * @param name Name of the property whose value is to be set
  217. * @param key Key of the property to be set
  218. * @param value Value to which this property is to be set
  219. *
  220. * @exception ConversionException if the specified value cannot be
  221. * converted to the type required for this property
  222. * @exception IllegalArgumentException if there is no property
  223. * of the specified name
  224. * @exception IllegalArgumentException if the specified property
  225. * exists, but is not mapped
  226. */
  227. public void set(String name, String key, Object value) {
  228. try {
  229. PropertyUtils.setMappedProperty(instance, name, key, value);
  230. } catch (Throwable t) {
  231. throw new IllegalArgumentException
  232. ("Property '" + name + "' has no mapped write method");
  233. }
  234. }
  235. /**
  236. * Gets the bean instance wrapped by this DynaBean.
  237. * For most common use cases,
  238. * this object should already be known
  239. * and this method safely be ignored.
  240. * But some creators of frameworks using <code>DynaBean</code>'s may
  241. * find this useful.
  242. *
  243. * @return the java bean Object wrapped by this <code>DynaBean</code>
  244. */
  245. public Object getInstance() {
  246. return instance;
  247. }
  248. // ------------------------------------------------------ Protected Methods
  249. /**
  250. * Return the property descriptor for the specified property name.
  251. *
  252. * @param name Name of the property for which to retrieve the descriptor
  253. *
  254. * @exception IllegalArgumentException if this is not a valid property
  255. * name for our DynaClass
  256. */
  257. protected DynaProperty getDynaProperty(String name) {
  258. DynaProperty descriptor = getDynaClass().getDynaProperty(name);
  259. if (descriptor == null) {
  260. throw new IllegalArgumentException
  261. ("Invalid property name '" + name + "'");
  262. }
  263. return (descriptor);
  264. }
  265. }