KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * Copyright 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 import java.util.List JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Date JavaDoc;
23 import java.lang.reflect.Array JavaDoc;
24 import java.math.BigDecimal JavaDoc;
25 import java.math.BigInteger JavaDoc;
26 import java.io.Serializable JavaDoc;
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29
30 /**
31  * <p>DynaBean which automatically adds properties to the <code>DynaClass</code>
32  * and provides <i>Lazy List</i> and <i>Lazy Map</i> features.</p>
33  *
34  * <p>DynaBeans deal with three types of properties - <i>simple</i>, <i>indexed</i> and <i>mapped</i> and
35  * have the following <code>get()</code> and <code>set()</code> methods for
36  * each of these types:</p>
37  * <ul>
38  * <li><i>Simple</i> property methods - <code>get(name)</code> and <code>set(name, value)</code></li>
39  * <li><i>Indexed</i> property methods - <code>get(name, index)</code> and <code>set(name, index, value)</code></li>
40  * <li><i>Mapped</i> property methods - <code>get(name, key)</code> and <code>set(name, key, value)</code></li>
41  * </ul>
42  *
43  * <p><b><u>Getting Property Values</u></b></p>
44  * <p>Calling any of the <code>get()</code> methods, for a property which
45  * doesn't exist, returns <code>null</code> in this implementation.</p>
46  *
47  * <p><b><u>Setting Simple Properties</u></b></p>
48  * <p>The <code>LazyDynaBean</code> will automatically add a property to the <code>DynaClass</code>
49  * if it doesn't exist when the <code>set(name, value)</code> method is called.</p>
50  *
51  * <code>DynaBean myBean = new LazyDynaBean();</code></br>
52  * <code>myBean.set("myProperty", "myValue");</code></br>
53  *
54  * <p><b><u>Setting Indexed Properties</u></b></p>
55  * <p>If the property <b>doesn't</b> exist, the <code>LazyDynaBean</code> will automatically add
56  * a property with an <code>ArrayList</code> type to the <code>DynaClass</code> when
57  * the <code>set(name, index, value)</code> method is called.
58  * It will also instantiate a new <code>ArrayList</code> and automatically <i>grow</i>
59  * the <code>List</code> so that it is big enough to accomodate the index being set.
60  * <code>ArrayList</code> is the default indexed property that LazyDynaBean uses but
61  * this can be easily changed by overriding the <code>newIndexedProperty(name)</code>
62  * method.</p>
63  *
64  * <code>DynaBean myBean = new LazyDynaBean();</code></br>
65  * <code>myBean.set("myIndexedProperty", 0, "myValue1");</code></br>
66  * <code>myBean.set("myIndexedProperty", 1, "myValue2");</code></br>
67  *
68  * <p>If the indexed property <b>does</b> exist in the <code>DynaClass</code> but is set to
69  * <code>null</code> in the <code>LazyDynaBean</code>, then it will instantiate a
70  * new <code>List</code> or <code>Array</code> as specified by the property's type
71  * in the <code>DynaClass</code> and automatically <i>grow</i> the <code>List</code>
72  * or <code>Array</code> so that it is big enough to accomodate the index being set.</p>
73  *
74  * <code>DynaBean myBean = new LazyDynaBean();</code></br>
75  * <code>MutableDynaClass myClass = (MutableDynaClass)myBean.getDynaClass();</code></br>
76  * <code>myClass.add("myIndexedProperty", int[].class);</code></br>
77  * <code>myBean.set("myIndexedProperty", 0, new Integer(10));</code></br>
78  * <code>myBean.set("myIndexedProperty", 1, new Integer(20));</code></br>
79  *
80  * <p><b><u>Setting Mapped Properties</u></b></p>
81  * <p>If the property <b>doesn't</b> exist, the <code>LazyDynaBean</code> will automatically add
82  * a property with a <code>HashMap</code> type to the <code>DynaClass</code> and
83  * instantiate a new <code>HashMap</code> in the DynaBean when the
84  * <code>set(name, key, value)</code> method is called. <code>HashMap</code> is the default
85  * mapped property that LazyDynaBean uses but this can be easily changed by overriding
86  * the <code>newMappedProperty(name)</code> method.</p>
87  *
88  * <code>DynaBean myBean = new LazyDynaBean();</code></br>
89  * <code>myBean.set("myMappedProperty", "myKey", "myValue");</code></br>
90  *
91  * <p>If the mapped property <b>does</b> exist in the <code>DynaClass</code> but is set to
92  * <code>null</code> in the <code>LazyDynaBean</code>, then it will instantiate a
93  * new <code>Map</code> as specified by the property's type in the <code>DynaClass</code>.</p>
94  *
95  * <code>DynaBean myBean = new LazyDynaBean();</code></br>
96  * <code>MutableDynaClass myClass = (MutableDynaClass)myBean.getDynaClass();</code></br>
97  * <code>myClass.add("myMappedProperty", TreeMap.class);</code></br>
98  * <code>myBean.set("myMappedProperty", "myKey", "myValue");</code></br>
99  *
100  * <p><b><u><i>Restricted</i> DynaClass</u></b></p>
101  * <p><code>MutableDynaClass</code> have a facility to <i>restrict</i> the <code>DynaClass</code>
102  * so that its properties cannot be modified. If the <code>MutableDynaClass</code> is
103  * restricted then calling any of the <code>set()</code> methods for a property which
104  * doesn't exist will result in a <code>IllegalArgumentException</code> being thrown.</p>
105  *
106  * @see LazyDynaClass
107  * @author Niall Pemberton
108  */

109 public class LazyDynaBean implements DynaBean, Serializable JavaDoc {
110
111
112    /**
113     * Commons Logging
114     */

115     private static Log logger = LogFactory.getLog(LazyDynaBean.class);
116
117     protected static final BigInteger JavaDoc BigInteger_ZERO = new BigInteger JavaDoc("0");
118     protected static final BigDecimal JavaDoc BigDecimal_ZERO = new BigDecimal JavaDoc("0");
119     protected static final Character JavaDoc Character_SPACE = new Character JavaDoc(' ');
120     protected static final Byte JavaDoc Byte_ZERO = new Byte JavaDoc((byte)0);
121     protected static final Short JavaDoc Short_ZERO = new Short JavaDoc((short)0);
122     protected static final Integer JavaDoc Integer_ZERO = new Integer JavaDoc(0);
123     protected static final Long JavaDoc Long_ZERO = new Long JavaDoc((long)0);
124     protected static final Float JavaDoc Float_ZERO = new Float JavaDoc((byte)0);
125     protected static final Double JavaDoc Double_ZERO = new Double JavaDoc((byte)0);
126
127     /**
128      * The <code>MutableDynaClass</code> "base class" that this DynaBean
129      * is associated with.
130      */

131     protected Map JavaDoc values;
132
133     /**
134      * The <code>MutableDynaClass</code> "base class" that this DynaBean
135      * is associated with.
136      */

137     protected MutableDynaClass dynaClass;
138
139
140     // ------------------- Constructors ----------------------------------
141

142     /**
143      * Construct a new <code>LazyDynaBean</code> with a <code>LazyDynaClass</code> instance.
144      */

145     public LazyDynaBean() {
146         this(new LazyDynaClass());
147     }
148
149     /**
150      * Construct a new <code>LazyDynaBean</code> with a <code>LazyDynaClass</code> instance.
151      *
152      * @param name Name of this DynaBean class
153      */

154     public LazyDynaBean(String JavaDoc name) {
155         this(new LazyDynaClass(name));
156     }
157
158     /**
159      * Construct a new <code>DynaBean</code> associated with the specified
160      * <code>DynaClass</code> instance - if its not a <code>MutableDynaClass</code>
161      * then a new <code>LazyDynaClass</code> is created and the properties copied.
162      *
163      * @param dynaClass The DynaClass we are associated with
164      */

165     public LazyDynaBean(DynaClass dynaClass) {
166
167         values = newMap();
168
169         if (dynaClass instanceof MutableDynaClass) {
170             this.dynaClass = (MutableDynaClass)dynaClass;
171         } else {
172             this.dynaClass = new LazyDynaClass(dynaClass.getName(), dynaClass.getDynaProperties());
173         }
174
175     }
176
177
178     // ------------------- Public Methods ----------------------------------
179

180     /**
181      * Return the Map backing this <code>DynaBean</code>
182      */

183     public Map JavaDoc getMap() {
184         return values;
185     }
186
187     /**
188      * <p>Return the size of an indexed or mapped property.</p>
189      *
190      * @param name Name of the property
191      * @exception IllegalArgumentException if no property name is specified
192      */

193     public int size(String JavaDoc name) {
194
195         if (name == null) {
196             throw new IllegalArgumentException JavaDoc("No property name specified");
197         }
198
199         Object JavaDoc value = values.get(name);
200         if (value == null) {
201             return 0;
202         }
203
204         if (value instanceof Map JavaDoc) {
205             return ((Map JavaDoc)value).size();
206         }
207
208         if (value instanceof List JavaDoc) {
209             return ((List JavaDoc)value).size();
210         }
211
212         if ((value.getClass().isArray())) {
213             return Array.getLength(value);
214         }
215
216         return 0;
217
218     }
219
220     // ------------------- DynaBean Methods ----------------------------------
221

222     /**
223      * Does the specified mapped property contain a value for the specified
224      * key value?
225      *
226      * @param name Name of the property to check
227      * @param key Name of the key to check
228      *
229      * @exception IllegalArgumentException if no property name is specified
230      */

231     public boolean contains(String JavaDoc name, String JavaDoc key) {
232
233         if (name == null) {
234             throw new IllegalArgumentException JavaDoc("No property name specified");
235         }
236
237         Object JavaDoc value = values.get(name);
238         if (value == null) {
239             return false;
240         }
241
242         if (value instanceof Map JavaDoc) {
243             return (((Map JavaDoc) value).containsKey(key));
244         }
245
246         return false;
247
248     }
249
250     /**
251      * <p>Return the value of a simple property with the specified name.</p>
252      *
253      * <p><strong>N.B.</strong> Returns <code>null</code> if there is no property
254      * of the specified name.</p>
255      *
256      * @param name Name of the property whose value is to be retrieved.
257      * @exception IllegalArgumentException if no property name is specified
258      */

259     public Object JavaDoc get(String JavaDoc name) {
260
261         if (name == null) {
262             throw new IllegalArgumentException JavaDoc("No property name specified");
263         }
264
265         // Value found
266
Object JavaDoc value = values.get(name);
267         if (value != null) {
268             return value;
269         }
270
271         // Property doesn't exist
272
if (!isDynaProperty(name)) {
273             return null;
274         }
275
276         // Property doesn't exist
277
value = createProperty(name, dynaClass.getDynaProperty(name).getType());
278
279         if (value != null) {
280             set(name, value);
281         }
282
283         return value;
284
285     }
286
287     /**
288      * <p>Return the value of an indexed property with the specified name.</p>
289      *
290      * <p><strong>N.B.</strong> Returns <code>null</code> if there is no 'indexed'
291      * property of the specified name.</p>
292      *
293      * @param name Name of the property whose value is to be retrieved
294      * @param index Index of the value to be retrieved
295      *
296      * @exception IllegalArgumentException if the specified property
297      * exists, but is not indexed
298      * @exception IndexOutOfBoundsException if the specified index
299      * is outside the range of the underlying property
300      */

301     public Object JavaDoc get(String JavaDoc name, int index) {
302
303         // If its not a property, then create default indexed property
304
if (!isDynaProperty(name)) {
305             set(name, defaultIndexedProperty(name));
306         }
307
308         // Get the indexed property
309
Object JavaDoc indexedProperty = get(name);
310
311         // Check that the property is indexed
312
if (!dynaClass.getDynaProperty(name).isIndexed()) {
313             throw new IllegalArgumentException JavaDoc
314                 ("Non-indexed property for '" + name + "[" + index + "]' "
315                                       + dynaClass.getDynaProperty(name).getName());
316         }
317
318         // Grow indexed property to appropriate size
319
indexedProperty = growIndexedProperty(name, indexedProperty, index);
320
321         // Return the indexed value
322
if (indexedProperty.getClass().isArray()) {
323             return Array.get(indexedProperty, index);
324         } else if (indexedProperty instanceof List JavaDoc) {
325             return ((List JavaDoc)indexedProperty).get(index);
326         } else {
327             throw new IllegalArgumentException JavaDoc
328                 ("Non-indexed property for '" + name + "[" + index + "]' "
329                                   + indexedProperty.getClass().getName());
330         }
331
332     }
333
334     /**
335      * <p>Return the value of a mapped property with the specified name.</p>
336      *
337      * <p><strong>N.B.</strong> Returns <code>null</code> if there is no 'mapped'
338      * property of the specified name.</p>
339      *
340      * @param name Name of the property whose value is to be retrieved
341      * @param key Key of the value to be retrieved
342      *
343      * @exception IllegalArgumentException if the specified property
344      * exists, but is not mapped
345      */

346     public Object JavaDoc get(String JavaDoc name, String JavaDoc key) {
347
348         // If its not a property, then create default mapped property
349
if (!isDynaProperty(name)) {
350             set(name, defaultMappedProperty(name));
351         }
352
353         // Get the mapped property
354
Object JavaDoc mappedProperty = get(name);
355
356         // Check that the property is mapped
357
if (!dynaClass.getDynaProperty(name).isMapped()) {
358             throw new IllegalArgumentException JavaDoc
359                 ("Non-mapped property for '" + name + "(" + key + ")' "
360                             + dynaClass.getDynaProperty(name).getType().getName());
361         }
362
363         // Get the value from the Map
364
if (mappedProperty instanceof Map JavaDoc) {
365             return (((Map JavaDoc) mappedProperty).get(key));
366         } else {
367             throw new IllegalArgumentException JavaDoc
368               ("Non-mapped property for '" + name + "(" + key + ")'"
369                                   + mappedProperty.getClass().getName());
370         }
371
372     }
373
374
375     /**
376      * Return the <code>DynaClass</code> instance that describes the set of
377      * properties available for this DynaBean.
378      */

379     public DynaClass getDynaClass() {
380         return (DynaClass)dynaClass;
381     }
382
383     /**
384      * Remove any existing value for the specified key on the
385      * specified mapped property.
386      *
387      * @param name Name of the property for which a value is to
388      * be removed
389      * @param key Key of the value to be removed
390      *
391      * @exception IllegalArgumentException if there is no property
392      * of the specified name
393      */

394     public void remove(String JavaDoc name, String JavaDoc key) {
395
396         if (name == null) {
397             throw new IllegalArgumentException JavaDoc("No property name specified");
398         }
399
400         Object JavaDoc value = values.get(name);
401         if (value == null) {
402             return;
403         }
404
405         if (value instanceof Map JavaDoc) {
406             ((Map JavaDoc) value).remove(key);
407         } else {
408             throw new IllegalArgumentException JavaDoc
409                     ("Non-mapped property for '" + name + "(" + key + ")'"
410                             + value.getClass().getName());
411         }
412
413     }
414
415     /**
416      * Set the value of a simple property with the specified name.
417      *
418      * @param name Name of the property whose value is to be set
419      * @param value Value to which this property is to be set
420      *
421      * @exception IllegalArgumentException if this is not an existing property
422      * name for our DynaClass and the MutableDynaClass is restricted
423      * @exception ConversionException if the specified value cannot be
424      * converted to the type required for this property
425      * @exception NullPointerException if an attempt is made to set a
426      * primitive property to null
427      */

428     public void set(String JavaDoc name, Object JavaDoc value) {
429
430         // If the property doesn't exist, then add it
431
if (!isDynaProperty(name)) {
432
433             if (dynaClass.isRestricted()) {
434                 throw new IllegalArgumentException JavaDoc
435                     ("Invalid property name '" + name + "' (DynaClass is restricted)");
436             }
437             if (value == null) {
438                 dynaClass.add(name);
439             } else {
440                 dynaClass.add(name, value.getClass());
441             }
442
443         }
444
445         DynaProperty descriptor = dynaClass.getDynaProperty(name);
446
447         if (value == null) {
448             if (descriptor.getType().isPrimitive()) {
449                 throw new NullPointerException JavaDoc
450                         ("Primitive value for '" + name + "'");
451             }
452         } else if (!isAssignable(descriptor.getType(), value.getClass())) {
453             throw new ConversionException
454                     ("Cannot assign value of type '" +
455                     value.getClass().getName() +
456                     "' to property '" + name + "' of type '" +
457                     descriptor.getType().getName() + "'");
458         }
459
460         // Set the property's value
461
values.put(name, value);
462
463     }
464
465     /**
466      * Set the value of an indexed property with the specified name.
467      *
468      * @param name Name of the property whose value is to be set
469      * @param index Index of the property to be set
470      * @param value Value to which this property is to be set
471      *
472      * @exception ConversionException if the specified value cannot be
473      * converted to the type required for this property
474      * @exception IllegalArgumentException if there is no property
475      * of the specified name
476      * @exception IllegalArgumentException if the specified property
477      * exists, but is not indexed
478      * @exception IndexOutOfBoundsException if the specified index
479      * is outside the range of the underlying property
480      */

481     public void set(String JavaDoc name, int index, Object JavaDoc value) {
482
483         // If its not a property, then create default indexed property
484
if (!isDynaProperty(name)) {
485             set(name, defaultIndexedProperty(name));
486         }
487
488         // Get the indexed property
489
Object JavaDoc indexedProperty = get(name);
490
491         // Check that the property is indexed
492
if (!dynaClass.getDynaProperty(name).isIndexed()) {
493             throw new IllegalArgumentException JavaDoc
494                 ("Non-indexed property for '" + name + "[" + index + "]'"
495                             + dynaClass.getDynaProperty(name).getType().getName());
496         }
497
498         // Grow indexed property to appropriate size
499
indexedProperty = growIndexedProperty(name, indexedProperty, index);
500
501         // Set the value in an array
502
if (indexedProperty.getClass().isArray()) {
503             Array.set(indexedProperty, index, value);
504         } else if (indexedProperty instanceof List JavaDoc) {
505             ((List JavaDoc)indexedProperty).set(index, value);
506         } else {
507             throw new IllegalArgumentException JavaDoc
508                 ("Non-indexed property for '" + name + "[" + index + "]' "
509                             + indexedProperty.getClass().getName());
510         }
511
512     }
513
514     /**
515      * Set the value of a mapped property with the specified name.
516      *
517      * @param name Name of the property whose value is to be set
518      * @param key Key of the property to be set
519      * @param value Value to which this property is to be set
520      *
521      * @exception ConversionException if the specified value cannot be
522      * converted to the type required for this property
523      * @exception IllegalArgumentException if there is no property
524      * of the specified name
525      * @exception IllegalArgumentException if the specified property
526      * exists, but is not mapped
527      */

528     public void set(String JavaDoc name, String JavaDoc key, Object JavaDoc value) {
529
530         // If the 'mapped' property doesn't exist, then add it
531
if (!isDynaProperty(name)) {
532             set(name, defaultMappedProperty(name));
533         }
534
535         // Get the mapped property
536
Object JavaDoc mappedProperty = get(name);
537
538         // Check that the property is mapped
539
if (!dynaClass.getDynaProperty(name).isMapped()) {
540             throw new IllegalArgumentException JavaDoc
541                 ("Non-mapped property for '" + name + "(" + key + ")'"
542                             + dynaClass.getDynaProperty(name).getType().getName());
543         }
544
545         // Set the value in the Map
546
((Map JavaDoc)mappedProperty).put(key, value);
547
548     }
549
550     // ------------------- protected Methods ----------------------------------
551

552     protected Object JavaDoc growIndexedProperty(String JavaDoc name, Object JavaDoc indexedProperty, int index) {
553
554         // Grow a List to the appropriate size
555
if (indexedProperty instanceof List JavaDoc) {
556
557             List JavaDoc list = (List JavaDoc)indexedProperty;
558             while (index >= list.size()) {
559                 list.add(null);
560             }
561
562         }
563
564         // Grow an Array to the appropriate size
565
if ((indexedProperty.getClass().isArray())) {
566
567             int length = Array.getLength(indexedProperty);
568             if (index >= length) {
569                 Class JavaDoc componentType = indexedProperty.getClass().getComponentType();
570                 Object JavaDoc newArray = Array.newInstance(componentType, (index + 1));
571                 System.arraycopy(indexedProperty, 0, newArray, 0, length);
572                 indexedProperty = newArray;
573                 set(name, indexedProperty);
574                 int newLength = Array.getLength(indexedProperty);
575                 for (int i = length; i < newLength; i++) {
576                     Array.set(indexedProperty, i, createProperty(name+"["+i+"]", componentType));
577                 }
578             }
579         }
580
581         return indexedProperty;
582
583     }
584
585     /**
586      * Create a new Instance of a Property
587      */

588     protected Object JavaDoc createProperty(String JavaDoc name, Class JavaDoc type) {
589
590         // Create Lists, arrays or DynaBeans
591
if (type.isArray() || List JavaDoc.class.isAssignableFrom(type)) {
592             return createIndexedProperty(name, type);
593         }
594
595         if (Map JavaDoc.class.isAssignableFrom(type)) {
596             return createMappedProperty(name, type);
597         }
598
599         if (DynaBean.class.isAssignableFrom(type)) {
600             return createDynaBeanProperty(name, type);
601         }
602
603         if (type.isPrimitive()) {
604             return createPrimitiveProperty(name, type);
605         }
606
607         if (Number JavaDoc.class.isAssignableFrom(type)) {
608             return createNumberProperty(name, type);
609         }
610
611         return createOtherProperty(name, type);
612
613     }
614
615     /**
616      * Create a new Instance of an 'Indexed' Property
617      */

618     protected Object JavaDoc createIndexedProperty(String JavaDoc name, Class JavaDoc type) {
619
620         // Create the indexed object
621
Object JavaDoc indexedProperty = null;
622
623         if (type == null) {
624
625             indexedProperty = defaultIndexedProperty(name);
626
627         } else if (type.isArray()) {
628
629             indexedProperty = Array.newInstance(type.getComponentType(), 0);
630
631         } else if (List JavaDoc.class.isAssignableFrom(type)) {
632             if (type.isInterface()) {
633                 indexedProperty = defaultIndexedProperty(name);
634             } else {
635                 try {
636                     indexedProperty = type.newInstance();
637                 }
638                 catch (Exception JavaDoc ex) {
639                     throw new IllegalArgumentException JavaDoc
640                         ("Error instantiating indexed property of type '" +
641                                    type.getName() + "' for '" + name + "' " + ex);
642                 }
643             }
644         } else {
645
646             throw new IllegalArgumentException JavaDoc
647                     ("Non-indexed property of type '" + type.getName() + "' for '" + name + "'");
648         }
649
650         return indexedProperty;
651
652     }
653
654     /**
655      * Create a new Instance of a 'Mapped' Property
656      */

657     protected Object JavaDoc createMappedProperty(String JavaDoc name, Class JavaDoc type) {
658
659         // Create the mapped object
660
Object JavaDoc mappedProperty = null;
661
662         if (type == null) {
663
664             mappedProperty = defaultMappedProperty(name);
665
666         } else if (type.isInterface()) {
667
668             mappedProperty = defaultMappedProperty(name);
669
670         } else if (Map JavaDoc.class.isAssignableFrom(type)) {
671             try {
672                 mappedProperty = type.newInstance();
673             }
674             catch (Exception JavaDoc ex) {
675                 throw new IllegalArgumentException JavaDoc
676                     ("Error instantiating mapped property of type '" + type.getName() + "' for '" + name + "' " + ex);
677             }
678         } else {
679
680             throw new IllegalArgumentException JavaDoc
681                     ("Non-mapped property of type '" + type.getName() + "' for '" + name + "'");
682         }
683
684         return mappedProperty;
685
686     }
687
688     /**
689      * Create a new Instance of a 'Mapped' Property
690      */

691     protected Object JavaDoc createDynaBeanProperty(String JavaDoc name, Class JavaDoc type) {
692         try {
693             return type.newInstance();
694         }
695         catch (Exception JavaDoc ex) {
696             if (logger.isWarnEnabled()) {
697                 logger.warn("Error instantiating DynaBean property of type '" + type.getName() + "' for '" + name + "' " + ex);
698             }
699             return null;
700         }
701     }
702
703     /**
704      * Create a new Instance of a 'Primitive' Property
705      */

706     protected Object JavaDoc createPrimitiveProperty(String JavaDoc name, Class JavaDoc type) {
707
708         if (type == Boolean.TYPE) {
709             return Boolean.FALSE;
710         } else if (type == Integer.TYPE) {
711             return Integer_ZERO;
712         } else if (type == Long.TYPE) {
713             return Long_ZERO;
714         } else if (type == Double.TYPE) {
715             return Double_ZERO;
716         } else if (type == Float.TYPE) {
717             return Float_ZERO;
718         } else if (type == Byte.TYPE) {
719             return Byte_ZERO;
720         } else if (type == Short.TYPE) {
721             return Short_ZERO;
722         } else if (type == Character.TYPE) {
723             return Character_SPACE;
724         } else {
725             return null;
726         }
727
728     }
729
730     /**
731      * Create a new Instance of a 'Primitive' Property
732      */

733     protected Object JavaDoc createNumberProperty(String JavaDoc name, Class JavaDoc type) {
734
735         return null;
736
737     }
738
739     /**
740      * Create a new Instance of a 'Mapped' Property
741      */

742     protected Object JavaDoc createOtherProperty(String JavaDoc name, Class JavaDoc type) {
743
744         if (type == String JavaDoc.class || type == Boolean JavaDoc.class ||
745             type == Character JavaDoc.class || Date JavaDoc.class.isAssignableFrom(type)) {
746             return null;
747         }
748
749         try {
750             return type.newInstance();
751         }
752         catch (Exception JavaDoc ex) {
753             if (logger.isWarnEnabled()) {
754                 logger.warn("Error instantiating property of type '" + type.getName() + "' for '" + name + "' " + ex);
755             }
756             return null;
757         }
758     }
759
760     /**
761      * <p>Creates a new <code>ArrayList</code> for an 'indexed' property
762      * which doesn't exist.</p>
763      *
764      * <p>This method shouls be overriden if an alternative <code>List</code>
765      * or <code>Array</code> implementation is required for 'indexed' properties.</p>
766      *
767      * @param name Name of the 'indexed property.
768      */

769     protected Object JavaDoc defaultIndexedProperty(String JavaDoc name) {
770         return new ArrayList JavaDoc();
771     }
772
773     /**
774      * <p>Creates a new <code>HashMap</code> for a 'mapped' property
775      * which doesn't exist.</p>
776      *
777      * <p>This method can be overriden if an alternative <code>Map</code>
778      * implementation is required for 'mapped' properties.</p>
779      *
780      * @param name Name of the 'mapped property.
781      */

782     protected Map JavaDoc defaultMappedProperty(String JavaDoc name) {
783         return new HashMap JavaDoc();
784     }
785
786     /**
787      * Indicates if there is a property with the specified name.
788      */

789     protected boolean isDynaProperty(String JavaDoc name) {
790
791         if (name == null) {
792             throw new IllegalArgumentException JavaDoc("No property name specified");
793         }
794
795         // Handle LazyDynaClasses
796
if (dynaClass instanceof LazyDynaClass) {
797             return ((LazyDynaClass)dynaClass).isDynaProperty(name);
798         }
799
800         // Handle other MutableDynaClass
801
return dynaClass.getDynaProperty(name) == null ? false : true;
802
803     }
804
805     /**
806      * Is an object of the source class assignable to the destination class?
807      *
808      * @param dest Destination class
809      * @param source Source class
810      */

811     protected boolean isAssignable(Class JavaDoc dest, Class JavaDoc source) {
812
813         if (dest.isAssignableFrom(source) ||
814                 ((dest == Boolean.TYPE) && (source == Boolean JavaDoc.class)) ||
815                 ((dest == Byte.TYPE) && (source == Byte JavaDoc.class)) ||
816                 ((dest == Character.TYPE) && (source == Character JavaDoc.class)) ||
817                 ((dest == Double.TYPE) && (source == Double JavaDoc.class)) ||
818                 ((dest == Float.TYPE) && (source == Float JavaDoc.class)) ||
819                 ((dest == Integer.TYPE) && (source == Integer JavaDoc.class)) ||
820                 ((dest == Long.TYPE) && (source == Long JavaDoc.class)) ||
821                 ((dest == Short.TYPE) && (source == Short JavaDoc.class))) {
822             return (true);
823         } else {
824             return (false);
825         }
826
827     }
828
829     /**
830      * <p>Creates a new instance of the <code>Map</code>.</p>
831      */

832     protected Map JavaDoc newMap() {
833         return new HashMap JavaDoc();
834     }
835
836 }
837
Popular Tags