1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.beanutils;
20
21 import java.io.Serializable;
22 import java.lang.reflect.InvocationTargetException;
23
24
25 /***
26 * <p>Implementation of <code>DynaBean</code> that wraps a standard JavaBean
27 * instance, so that DynaBean APIs can be used to access its properties.</p>
28 *
29 * <p>
30 * The most common use cases for this class involve wrapping an existing java bean.
31 * (This makes it different from the typical use cases for other <code>DynaBean</code>'s.)
32 * For example:
33 * </p>
34 * <code><pre>
35 * Object aJavaBean = ...;
36 * ...
37 * DynaBean db = new WrapDynaBean(aJavaBean);
38 * ...
39 * </pre></code>
40 *
41 * <p><strong>IMPLEMENTATION NOTE</strong> - This implementation does not
42 * support the <code>contains()</code> and <code>remove()</code> methods.</p>
43 *
44 * @author Craig McClanahan
45 * @version $Revision: 555824 $ $Date: 2007-07-13 01:27:15 +0100 (Fri, 13 Jul 2007) $
46 */
47
48 public class WrapDynaBean implements DynaBean, Serializable {
49
50
51
52
53
54 /***
55 * Construct a new <code>DynaBean</code> associated with the specified
56 * JavaBean instance.
57 *
58 * @param instance JavaBean instance to be wrapped
59 */
60 public WrapDynaBean(Object instance) {
61
62 super();
63 this.instance = instance;
64 this.dynaClass = (WrapDynaClass)getDynaClass();
65
66 }
67
68
69
70
71
72 /***
73 * The <code>DynaClass</code> "base class" that this DynaBean
74 * is associated with.
75 */
76 protected transient WrapDynaClass dynaClass = null;
77
78
79 /***
80 * The JavaBean instance wrapped by this WrapDynaBean.
81 */
82 protected Object instance = null;
83
84
85
86
87
88 /***
89 * Does the specified mapped property contain a value for the specified
90 * key value?
91 *
92 * @param name Name of the property to check
93 * @param key Name of the key to check
94 * @return <code>true<code> if the mapped property contains a value for
95 * the specified key, otherwise <code>false</code>
96 *
97 * @exception IllegalArgumentException if there is no property
98 * of the specified name
99 */
100 public boolean contains(String name, String key) {
101
102 throw new UnsupportedOperationException
103 ("WrapDynaBean does not support contains()");
104
105 }
106
107
108 /***
109 * Return the value of a simple property with the specified name.
110 *
111 * @param name Name of the property whose value is to be retrieved
112 * @return The property's value
113 *
114 * @exception IllegalArgumentException if there is no property
115 * of the specified name
116 */
117 public Object get(String name) {
118
119 Object value = null;
120 try {
121 value = PropertyUtils.getSimpleProperty(instance, name);
122 } catch (InvocationTargetException ite) {
123 Throwable cause = ite.getTargetException();
124 throw new IllegalArgumentException
125 ("Error reading property '" + name +
126 "' nested exception - " + cause);
127 } catch (Throwable t) {
128 throw new IllegalArgumentException
129 ("Error reading property '" + name +
130 "', exception - " + t);
131 }
132 return (value);
133
134 }
135
136
137 /***
138 * Return the value of an indexed property with the specified name.
139 *
140 * @param name Name of the property whose value is to be retrieved
141 * @param index Index of the value to be retrieved
142 * @return The indexed property's value
143 *
144 * @exception IllegalArgumentException if there is no property
145 * of the specified name
146 * @exception IllegalArgumentException if the specified property
147 * exists, but is not indexed
148 * @exception IndexOutOfBoundsException if the specified index
149 * is outside the range of the underlying property
150 * @exception NullPointerException if no array or List has been
151 * initialized for this property
152 */
153 public Object get(String name, int index) {
154
155 Object value = null;
156 try {
157 value = PropertyUtils.getIndexedProperty(instance, name, index);
158 } catch (IndexOutOfBoundsException e) {
159 throw e;
160 } catch (InvocationTargetException ite) {
161 Throwable cause = ite.getTargetException();
162 throw new IllegalArgumentException
163 ("Error reading indexed property '" + name +
164 "' nested exception - " + cause);
165 } catch (Throwable t) {
166 throw new IllegalArgumentException
167 ("Error reading indexed property '" + name +
168 "', exception - " + t);
169 }
170 return (value);
171
172 }
173
174
175 /***
176 * Return the value of a mapped property with the specified name,
177 * or <code>null</code> if there is no value for the specified key.
178 *
179 * @param name Name of the property whose value is to be retrieved
180 * @param key Key of the value to be retrieved
181 * @return The mapped property's value
182 *
183 * @exception IllegalArgumentException if there is no property
184 * of the specified name
185 * @exception IllegalArgumentException if the specified property
186 * exists, but is not mapped
187 */
188 public Object get(String name, String key) {
189
190 Object value = null;
191 try {
192 value = PropertyUtils.getMappedProperty(instance, name, key);
193 } catch (InvocationTargetException ite) {
194 Throwable cause = ite.getTargetException();
195 throw new IllegalArgumentException
196 ("Error reading mapped property '" + name +
197 "' nested exception - " + cause);
198 } catch (Throwable t) {
199 throw new IllegalArgumentException
200 ("Error reading mapped property '" + name +
201 "', exception - " + t);
202 }
203 return (value);
204
205 }
206
207
208 /***
209 * Return the <code>DynaClass</code> instance that describes the set of
210 * properties available for this DynaBean.
211 * @return The associated DynaClass
212 */
213 public DynaClass getDynaClass() {
214
215 if (dynaClass == null) {
216 dynaClass = WrapDynaClass.createDynaClass(instance.getClass());
217 }
218
219 return (this.dynaClass);
220
221 }
222
223
224 /***
225 * Remove any existing value for the specified key on the
226 * specified mapped property.
227 *
228 * @param name Name of the property for which a value is to
229 * be removed
230 * @param key Key of the value to be removed
231 *
232 * @exception IllegalArgumentException if there is no property
233 * of the specified name
234 */
235 public void remove(String name, String key) {
236
237
238 throw new UnsupportedOperationException
239 ("WrapDynaBean does not support remove()");
240
241 }
242
243
244 /***
245 * Set the value of a simple property with the specified name.
246 *
247 * @param name Name of the property whose value is to be set
248 * @param value Value to which this property is to be set
249 *
250 * @exception ConversionException if the specified value cannot be
251 * converted to the type required for this property
252 * @exception IllegalArgumentException if there is no property
253 * of the specified name
254 * @exception NullPointerException if an attempt is made to set a
255 * primitive property to null
256 */
257 public void set(String name, Object value) {
258
259 try {
260 PropertyUtils.setSimpleProperty(instance, name, value);
261 } catch (InvocationTargetException ite) {
262 Throwable cause = ite.getTargetException();
263 throw new IllegalArgumentException
264 ("Error setting property '" + name +
265 "' nested exception -" + cause);
266 } catch (Throwable t) {
267 throw new IllegalArgumentException
268 ("Error setting property '" + name +
269 "', exception - " + t);
270 }
271
272 }
273
274
275 /***
276 * Set the value of an indexed property with the specified name.
277 *
278 * @param name Name of the property whose value is to be set
279 * @param index Index of the property to be set
280 * @param value Value to which this property is to be set
281 *
282 * @exception ConversionException if the specified value cannot be
283 * converted to the type required for this property
284 * @exception IllegalArgumentException if there is no property
285 * of the specified name
286 * @exception IllegalArgumentException if the specified property
287 * exists, but is not indexed
288 * @exception IndexOutOfBoundsException if the specified index
289 * is outside the range of the underlying property
290 */
291 public void set(String name, int index, Object value) {
292
293 try {
294 PropertyUtils.setIndexedProperty(instance, name, index, value);
295 } catch (IndexOutOfBoundsException e) {
296 throw e;
297 } catch (InvocationTargetException ite) {
298 Throwable cause = ite.getTargetException();
299 throw new IllegalArgumentException
300 ("Error setting indexed property '" + name +
301 "' nested exception - " + cause);
302 } catch (Throwable t) {
303 throw new IllegalArgumentException
304 ("Error setting indexed property '" + name +
305 "', exception - " + t);
306 }
307
308 }
309
310
311 /***
312 * Set the value of a mapped property with the specified name.
313 *
314 * @param name Name of the property whose value is to be set
315 * @param key Key of the property to be set
316 * @param value Value to which this property is to be set
317 *
318 * @exception ConversionException if the specified value cannot be
319 * converted to the type required for this property
320 * @exception IllegalArgumentException if there is no property
321 * of the specified name
322 * @exception IllegalArgumentException if the specified property
323 * exists, but is not mapped
324 */
325 public void set(String name, String key, Object value) {
326
327 try {
328 PropertyUtils.setMappedProperty(instance, name, key, value);
329 } catch (InvocationTargetException ite) {
330 Throwable cause = ite.getTargetException();
331 throw new IllegalArgumentException
332 ("Error setting mapped property '" + name +
333 "' nested exception - " + cause);
334 } catch (Throwable t) {
335 throw new IllegalArgumentException
336 ("Error setting mapped property '" + name +
337 "', exception - " + t);
338 }
339
340 }
341
342 /***
343 * Gets the bean instance wrapped by this DynaBean.
344 * For most common use cases,
345 * this object should already be known
346 * and this method safely be ignored.
347 * But some creators of frameworks using <code>DynaBean</code>'s may
348 * find this useful.
349 *
350 * @return the java bean Object wrapped by this <code>DynaBean</code>
351 */
352 public Object getInstance() {
353 return instance;
354 }
355
356
357
358
359
360 /***
361 * Return the property descriptor for the specified property name.
362 *
363 * @param name Name of the property for which to retrieve the descriptor
364 * @return The descriptor for the specified property
365 *
366 * @exception IllegalArgumentException if this is not a valid property
367 * name for our DynaClass
368 */
369 protected DynaProperty getDynaProperty(String name) {
370
371 DynaProperty descriptor = getDynaClass().getDynaProperty(name);
372 if (descriptor == null) {
373 throw new IllegalArgumentException
374 ("Invalid property name '" + name + "'");
375 }
376 return (descriptor);
377
378 }
379
380
381 }