KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > beanutils > BasicDynaBean


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
17
18 package org.apache.commons.beanutils;
19
20
21 import java.io.Serializable JavaDoc;
22 import java.lang.reflect.Array JavaDoc;
23 import java.util.HashMap JavaDoc;
24 import java.util.List JavaDoc;
25 import java.util.Map JavaDoc;
26
27
28 /**
29  * <p>Minimal implementation of the <code>DynaBean</code> interface. Can be
30  * used as a convenience base class for more sophisticated implementations.</p>
31  *
32  * <p><strong>IMPLEMENTATION NOTE</strong> - Instances of this class that are
33  * accessed from multiple threads simultaneously need to be synchronized.</p>
34  *
35  * <p><strong>IMPLEMENTATION NOTE</strong> - Instances of this class can be
36  * successfully serialized and deserialized <strong>ONLY</strong> if all
37  * property values are <code>Serializable</code>.</p>
38  *
39  * @author Craig McClanahan
40  * @version $Revision: 1.11 $ $Date: 2004/02/28 13:18:33 $
41  */

42
43 public class BasicDynaBean implements DynaBean, Serializable JavaDoc {
44
45
46     // ---------------------------------------------------------- Constructors
47

48
49     /**
50      * Construct a new <code>DynaBean</code> associated with the specified
51      * <code>DynaClass</code> instance.
52      *
53      * @param dynaClass The DynaClass we are associated with
54      */

55     public BasicDynaBean(DynaClass dynaClass) {
56
57         super();
58         this.dynaClass = dynaClass;
59
60     }
61
62
63     // ---------------------------------------------------- Instance Variables
64

65
66     /**
67      * The <code>DynaClass</code> "base class" that this DynaBean
68      * is associated with.
69      */

70     protected DynaClass dynaClass = null;
71
72
73     /**
74      * The set of property values for this DynaBean, keyed by property name.
75      */

76     protected HashMap JavaDoc values = new HashMap JavaDoc();
77
78
79     // ------------------------------------------------------ DynaBean Methods
80

81
82     /**
83      * Does the specified mapped property contain a value for the specified
84      * key value?
85      *
86      * @param name Name of the property to check
87      * @param key Name of the key to check
88      *
89      * @exception IllegalArgumentException if there is no property
90      * of the specified name
91      */

92     public boolean contains(String JavaDoc name, String JavaDoc key) {
93
94         Object JavaDoc value = values.get(name);
95         if (value == null) {
96             throw new NullPointerException JavaDoc
97                     ("No mapped value for '" + name + "(" + key + ")'");
98         } else if (value instanceof Map JavaDoc) {
99             return (((Map JavaDoc) value).containsKey(key));
100         } else {
101             throw new IllegalArgumentException JavaDoc
102                     ("Non-mapped property for '" + name + "(" + key + ")'");
103         }
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      *
113      * @exception IllegalArgumentException if there is no property
114      * of the specified name
115      */

116     public Object JavaDoc get(String JavaDoc name) {
117
118         // Return any non-null value for the specified property
119
Object JavaDoc value = values.get(name);
120         if (value != null) {
121             return (value);
122         }
123
124         // Return a null value for a non-primitive property
125
Class JavaDoc type = getDynaProperty(name).getType();
126         if (!type.isPrimitive()) {
127             return (value);
128         }
129
130         // Manufacture default values for primitive properties
131
if (type == Boolean.TYPE) {
132             return (Boolean.FALSE);
133         } else if (type == Byte.TYPE) {
134             return (new Byte JavaDoc((byte) 0));
135         } else if (type == Character.TYPE) {
136             return (new Character JavaDoc((char) 0));
137         } else if (type == Double.TYPE) {
138             return (new Double JavaDoc((double) 0.0));
139         } else if (type == Float.TYPE) {
140             return (new Float JavaDoc((float) 0.0));
141         } else if (type == Integer.TYPE) {
142             return (new Integer JavaDoc((int) 0));
143         } else if (type == Long.TYPE) {
144             return (new Long JavaDoc((int) 0));
145         } else if (type == Short.TYPE) {
146             return (new Short JavaDoc((short) 0));
147         } else {
148             return (null);
149         }
150
151     }
152
153
154     /**
155      * Return the value of an indexed property with the specified name.
156      *
157      * @param name Name of the property whose value is to be retrieved
158      * @param index Index of the value to be retrieved
159      *
160      * @exception IllegalArgumentException if there is no property
161      * of the specified name
162      * @exception IllegalArgumentException if the specified property
163      * exists, but is not indexed
164      * @exception IndexOutOfBoundsException if the specified index
165      * is outside the range of the underlying property
166      * @exception NullPointerException if no array or List has been
167      * initialized for this property
168      */

169     public Object JavaDoc get(String JavaDoc name, int index) {
170
171         Object JavaDoc value = values.get(name);
172         if (value == null) {
173             throw new NullPointerException JavaDoc
174                     ("No indexed value for '" + name + "[" + index + "]'");
175         } else if (value.getClass().isArray()) {
176             return (Array.get(value, index));
177         } else if (value instanceof List JavaDoc) {
178             return ((List JavaDoc) value).get(index);
179         } else {
180             throw new IllegalArgumentException JavaDoc
181                     ("Non-indexed property for '" + name + "[" + index + "]'");
182         }
183
184     }
185
186
187     /**
188      * Return the value of a mapped property with the specified name,
189      * or <code>null</code> if there is no value for the specified key.
190      *
191      * @param name Name of the property whose value is to be retrieved
192      * @param key Key of the value to be retrieved
193      *
194      * @exception IllegalArgumentException if there is no property
195      * of the specified name
196      * @exception IllegalArgumentException if the specified property
197      * exists, but is not mapped
198      */

199     public Object JavaDoc get(String JavaDoc name, String JavaDoc key) {
200
201         Object JavaDoc value = values.get(name);
202         if (value == null) {
203             throw new NullPointerException JavaDoc
204                     ("No mapped value for '" + name + "(" + key + ")'");
205         } else if (value instanceof Map JavaDoc) {
206             return (((Map JavaDoc) value).get(key));
207         } else {
208             throw new IllegalArgumentException JavaDoc
209                     ("Non-mapped property for '" + name + "(" + key + ")'");
210         }
211
212     }
213
214
215     /**
216      * Return the <code>DynaClass</code> instance that describes the set of
217      * properties available for this DynaBean.
218      */

219     public DynaClass getDynaClass() {
220
221         return (this.dynaClass);
222
223     }
224
225
226     /**
227      * Remove any existing value for the specified key on the
228      * specified mapped property.
229      *
230      * @param name Name of the property for which a value is to
231      * be removed
232      * @param key Key of the value to be removed
233      *
234      * @exception IllegalArgumentException if there is no property
235      * of the specified name
236      */

237     public void remove(String JavaDoc name, String JavaDoc key) {
238
239         Object JavaDoc value = values.get(name);
240         if (value == null) {
241             throw new NullPointerException JavaDoc
242                     ("No mapped value for '" + name + "(" + key + ")'");
243         } else if (value instanceof Map JavaDoc) {
244             ((Map JavaDoc) value).remove(key);
245         } else {
246             throw new IllegalArgumentException JavaDoc
247                     ("Non-mapped property for '" + name + "(" + key + ")'");
248         }
249
250     }
251
252
253     /**
254      * Set the value of a simple property with the specified name.
255      *
256      * @param name Name of the property whose value is to be set
257      * @param value Value to which this property is to be set
258      *
259      * @exception ConversionException if the specified value cannot be
260      * converted to the type required for this property
261      * @exception IllegalArgumentException if there is no property
262      * of the specified name
263      * @exception NullPointerException if an attempt is made to set a
264      * primitive property to null
265      */

266     public void set(String JavaDoc name, Object JavaDoc value) {
267
268         DynaProperty descriptor = getDynaProperty(name);
269         if (value == null) {
270             if (descriptor.getType().isPrimitive()) {
271                 throw new NullPointerException JavaDoc
272                         ("Primitive value for '" + name + "'");
273             }
274         } else if (!isAssignable(descriptor.getType(), value.getClass())) {
275             throw new ConversionException
276                     ("Cannot assign value of type '" +
277                     value.getClass().getName() +
278                     "' to property '" + name + "' of type '" +
279                     descriptor.getType().getName() + "'");
280         }
281         values.put(name, value);
282
283     }
284
285
286     /**
287      * Set the value of an indexed property with the specified name.
288      *
289      * @param name Name of the property whose value is to be set
290      * @param index Index of the property to be set
291      * @param value Value to which this property is to be set
292      *
293      * @exception ConversionException if the specified value cannot be
294      * converted to the type required for this property
295      * @exception IllegalArgumentException if there is no property
296      * of the specified name
297      * @exception IllegalArgumentException if the specified property
298      * exists, but is not indexed
299      * @exception IndexOutOfBoundsException if the specified index
300      * is outside the range of the underlying property
301      */

302     public void set(String JavaDoc name, int index, Object JavaDoc value) {
303
304         Object JavaDoc prop = values.get(name);
305         if (prop == null) {
306             throw new NullPointerException JavaDoc
307                     ("No indexed value for '" + name + "[" + index + "]'");
308         } else if (prop.getClass().isArray()) {
309             Array.set(prop, index, value);
310         } else if (prop instanceof List JavaDoc) {
311             try {
312                 ((List JavaDoc) prop).set(index, value);
313             } catch (ClassCastException JavaDoc e) {
314                 throw new ConversionException(e.getMessage());
315             }
316         } else {
317             throw new IllegalArgumentException JavaDoc
318                     ("Non-indexed property for '" + name + "[" + index + "]'");
319         }
320
321     }
322
323
324     /**
325      * Set the value of a mapped property with the specified name.
326      *
327      * @param name Name of the property whose value is to be set
328      * @param key Key of the property to be set
329      * @param value Value to which this property is to be set
330      *
331      * @exception ConversionException if the specified value cannot be
332      * converted to the type required for this property
333      * @exception IllegalArgumentException if there is no property
334      * of the specified name
335      * @exception IllegalArgumentException if the specified property
336      * exists, but is not mapped
337      */

338     public void set(String JavaDoc name, String JavaDoc key, Object JavaDoc value) {
339
340         Object JavaDoc prop = values.get(name);
341         if (prop == null) {
342             throw new NullPointerException JavaDoc
343                     ("No mapped value for '" + name + "(" + key + ")'");
344         } else if (prop instanceof Map JavaDoc) {
345             ((Map JavaDoc) prop).put(key, value);
346         } else {
347             throw new IllegalArgumentException JavaDoc
348                     ("Non-mapped property for '" + name + "(" + key + ")'");
349         }
350
351     }
352
353
354     // ------------------------------------------------------ Protected Methods
355

356
357     /**
358      * Return the property descriptor for the specified property name.
359      *
360      * @param name Name of the property for which to retrieve the descriptor
361      *
362      * @exception IllegalArgumentException if this is not a valid property
363      * name for our DynaClass
364      */

365     protected DynaProperty getDynaProperty(String JavaDoc name) {
366
367         DynaProperty descriptor = getDynaClass().getDynaProperty(name);
368         if (descriptor == null) {
369             throw new IllegalArgumentException JavaDoc
370                     ("Invalid property name '" + name + "'");
371         }
372         return (descriptor);
373
374     }
375
376
377     /**
378      * Is an object of the source class assignable to the destination class?
379      *
380      * @param dest Destination class
381      * @param source Source class
382      */

383     protected boolean isAssignable(Class JavaDoc dest, Class JavaDoc source) {
384
385         if (dest.isAssignableFrom(source) ||
386                 ((dest == Boolean.TYPE) && (source == Boolean JavaDoc.class)) ||
387                 ((dest == Byte.TYPE) && (source == Byte JavaDoc.class)) ||
388                 ((dest == Character.TYPE) && (source == Character JavaDoc.class)) ||
389                 ((dest == Double.TYPE) && (source == Double JavaDoc.class)) ||
390                 ((dest == Float.TYPE) && (source == Float JavaDoc.class)) ||
391                 ((dest == Integer.TYPE) && (source == Integer JavaDoc.class)) ||
392                 ((dest == Long.TYPE) && (source == Long JavaDoc.class)) ||
393                 ((dest == Short.TYPE) && (source == Short JavaDoc.class))) {
394             return (true);
395         } else {
396             return (false);
397         }
398
399     }
400
401
402 }
403
Popular Tags