KickJava   Java API By Example, From Geeks To Geeks.

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


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 import java.beans.BeanInfo JavaDoc;
19 import java.beans.IntrospectionException JavaDoc;
20 import java.beans.Introspector JavaDoc;
21 import java.beans.PropertyDescriptor JavaDoc;
22 import java.lang.reflect.Constructor JavaDoc;
23 import java.lang.reflect.InvocationTargetException JavaDoc;
24 import java.lang.reflect.Method JavaDoc;
25 import java.util.AbstractMap JavaDoc;
26 import java.util.AbstractSet JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Collection JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Set JavaDoc;
32
33 import org.apache.commons.collections.list.UnmodifiableList;
34 import org.apache.commons.collections.keyvalue.AbstractMapEntry;
35 import org.apache.commons.collections.set.UnmodifiableSet;
36 import org.apache.commons.collections.Transformer;
37
38 /**
39  * An implementation of Map for JavaBeans which uses introspection to
40  * get and put properties in the bean.
41  * <p>
42  * If an exception occurs during attempts to get or set a property then the
43  * property is considered non existent in the Map
44  *
45  * @version $Revision: 1.2.2.2 $ $Date: 2004/06/22 21:07:02 $
46  *
47  * @author James Strachan
48  * @author Stephen Colebourne
49  */

50 public class BeanMap extends AbstractMap JavaDoc implements Cloneable JavaDoc {
51
52     private transient Object JavaDoc bean;
53
54     private transient HashMap JavaDoc readMethods = new HashMap JavaDoc();
55     private transient HashMap JavaDoc writeMethods = new HashMap JavaDoc();
56     private transient HashMap JavaDoc types = new HashMap JavaDoc();
57
58     /**
59      * An empty array. Used to invoke accessors via reflection.
60      */

61     public static final Object JavaDoc[] NULL_ARGUMENTS = {};
62
63     /**
64      * Maps primitive Class types to transformers. The transformer
65      * transform strings into the appropriate primitive wrapper.
66      */

67     public static HashMap JavaDoc defaultTransformers = new HashMap JavaDoc();
68     
69     static {
70         defaultTransformers.put(
71             Boolean.TYPE,
72             new Transformer() {
73                 public Object JavaDoc transform( Object JavaDoc input ) {
74                     return Boolean.valueOf( input.toString() );
75                 }
76             }
77         );
78         defaultTransformers.put(
79             Character.TYPE,
80             new Transformer() {
81                 public Object JavaDoc transform( Object JavaDoc input ) {
82                     return new Character JavaDoc( input.toString().charAt( 0 ) );
83                 }
84             }
85         );
86         defaultTransformers.put(
87             Byte.TYPE,
88             new Transformer() {
89                 public Object JavaDoc transform( Object JavaDoc input ) {
90                     return Byte.valueOf( input.toString() );
91                 }
92             }
93         );
94         defaultTransformers.put(
95             Short.TYPE,
96             new Transformer() {
97                 public Object JavaDoc transform( Object JavaDoc input ) {
98                     return Short.valueOf( input.toString() );
99                 }
100             }
101         );
102         defaultTransformers.put(
103             Integer.TYPE,
104             new Transformer() {
105                 public Object JavaDoc transform( Object JavaDoc input ) {
106                     return Integer.valueOf( input.toString() );
107                 }
108             }
109         );
110         defaultTransformers.put(
111             Long.TYPE,
112             new Transformer() {
113                 public Object JavaDoc transform( Object JavaDoc input ) {
114                     return Long.valueOf( input.toString() );
115                 }
116             }
117         );
118         defaultTransformers.put(
119             Float.TYPE,
120             new Transformer() {
121                 public Object JavaDoc transform( Object JavaDoc input ) {
122                     return Float.valueOf( input.toString() );
123                 }
124             }
125         );
126         defaultTransformers.put(
127             Double.TYPE,
128             new Transformer() {
129                 public Object JavaDoc transform( Object JavaDoc input ) {
130                     return Double.valueOf( input.toString() );
131                 }
132             }
133         );
134     }
135     
136     
137     // Constructors
138
//-------------------------------------------------------------------------
139

140     /**
141      * Constructs a new empty <code>BeanMap</code>.
142      */

143     public BeanMap() {
144     }
145
146     /**
147      * Constructs a new <code>BeanMap</code> that operates on the
148      * specified bean. If the given bean is <code>null</code>, then
149      * this map will be empty.
150      *
151      * @param bean the bean for this map to operate on
152      */

153     public BeanMap(Object JavaDoc bean) {
154         this.bean = bean;
155         initialise();
156     }
157
158     // Map interface
159
//-------------------------------------------------------------------------
160

161     /**
162      * Renders a string representation of this object.
163      * @return a <code>String</code> representation of this object
164      */

165     public String JavaDoc toString() {
166         return "BeanMap<" + String.valueOf(bean) + ">";
167     }
168     
169     /**
170      * Clone this bean map using the following process:
171      *
172      * <ul>
173      * <li>If there is no underlying bean, return a cloned BeanMap without a
174      * bean.
175      *
176      * <li>Since there is an underlying bean, try to instantiate a new bean of
177      * the same type using Class.newInstance().
178      *
179      * <li>If the instantiation fails, throw a CloneNotSupportedException
180      *
181      * <li>Clone the bean map and set the newly instantiated bean as the
182      * underlying bean for the bean map.
183      *
184      * <li>Copy each property that is both readable and writable from the
185      * existing object to a cloned bean map.
186      *
187      * <li>If anything fails along the way, throw a
188      * CloneNotSupportedException.
189      *
190      * <ul>
191      */

192     public Object JavaDoc clone() throws CloneNotSupportedException JavaDoc {
193         BeanMap newMap = (BeanMap)super.clone();
194
195         if(bean == null) {
196             // no bean, just an empty bean map at the moment. return a newly
197
// cloned and empty bean map.
198
return newMap;
199         }
200
201         Object JavaDoc newBean = null;
202         Class JavaDoc beanClass = null;
203         try {
204             beanClass = bean.getClass();
205             newBean = beanClass.newInstance();
206         } catch (Exception JavaDoc e) {
207             // unable to instantiate
208
throw new CloneNotSupportedException JavaDoc
209                 ("Unable to instantiate the underlying bean \"" +
210                  beanClass.getName() + "\": " + e);
211         }
212             
213         try {
214             newMap.setBean(newBean);
215         } catch (Exception JavaDoc exception) {
216             throw new CloneNotSupportedException JavaDoc
217                 ("Unable to set bean in the cloned bean map: " +
218                  exception);
219         }
220             
221         try {
222             // copy only properties that are readable and writable. If its
223
// not readable, we can't get the value from the old map. If
224
// its not writable, we can't write a value into the new map.
225
Iterator JavaDoc readableKeys = readMethods.keySet().iterator();
226             while(readableKeys.hasNext()) {
227                 Object JavaDoc key = readableKeys.next();
228                 if(getWriteMethod(key) != null) {
229                     newMap.put(key, get(key));
230                 }
231             }
232         } catch (Exception JavaDoc exception) {
233             throw new CloneNotSupportedException JavaDoc
234                 ("Unable to copy bean values to cloned bean map: " +
235                  exception);
236         }
237
238         return newMap;
239     }
240
241     /**
242      * Puts all of the writable properties from the given BeanMap into this
243      * BeanMap. Read-only and Write-only properties will be ignored.
244      *
245      * @param map the BeanMap whose properties to put
246      */

247     public void putAllWriteable(BeanMap map) {
248         Iterator JavaDoc readableKeys = map.readMethods.keySet().iterator();
249         while (readableKeys.hasNext()) {
250             Object JavaDoc key = readableKeys.next();
251             if (getWriteMethod(key) != null) {
252                 this.put(key, map.get(key));
253             }
254         }
255     }
256
257
258     /**
259      * This method reinitializes the bean map to have default values for the
260      * bean's properties. This is accomplished by constructing a new instance
261      * of the bean which the map uses as its underlying data source. This
262      * behavior for <code>clear()</code> differs from the Map contract in that
263      * the mappings are not actually removed from the map (the mappings for a
264      * BeanMap are fixed).
265      */

266     public void clear() {
267         if(bean == null) return;
268
269         Class JavaDoc beanClass = null;
270         try {
271             beanClass = bean.getClass();
272             bean = beanClass.newInstance();
273         }
274         catch (Exception JavaDoc e) {
275             throw new UnsupportedOperationException JavaDoc( "Could not create new instance of class: " + beanClass );
276         }
277     }
278
279     /**
280      * Returns true if the bean defines a property with the given name.
281      * <p>
282      * The given name must be a <code>String</code>; if not, this method
283      * returns false. This method will also return false if the bean
284      * does not define a property with that name.
285      * <p>
286      * Write-only properties will not be matched as the test operates against
287      * property read methods.
288      *
289      * @param name the name of the property to check
290      * @return false if the given name is null or is not a <code>String</code>;
291      * false if the bean does not define a property with that name; or
292      * true if the bean does define a property with that name
293      */

294     public boolean containsKey(Object JavaDoc name) {
295         Method JavaDoc method = getReadMethod(name);
296         return method != null;
297     }
298
299     /**
300      * Returns true if the bean defines a property whose current value is
301      * the given object.
302      *
303      * @param value the value to check
304      * @return false true if the bean has at least one property whose
305      * current value is that object, false otherwise
306      */

307     public boolean containsValue(Object JavaDoc value) {
308         // use default implementation
309
return super.containsValue(value);
310     }
311
312     /**
313      * Returns the value of the bean's property with the given name.
314      * <p>
315      * The given name must be a {@link String} and must not be
316      * null; otherwise, this method returns <code>null</code>.
317      * If the bean defines a property with the given name, the value of
318      * that property is returned. Otherwise, <code>null</code> is
319      * returned.
320      * <p>
321      * Write-only properties will not be matched as the test operates against
322      * property read methods.
323      *
324      * @param name the name of the property whose value to return
325      * @return the value of the property with that name
326      */

327     public Object JavaDoc get(Object JavaDoc name) {
328         if ( bean != null ) {
329             Method JavaDoc method = getReadMethod( name );
330             if ( method != null ) {
331                 try {
332                     return method.invoke( bean, NULL_ARGUMENTS );
333                 }
334                 catch ( IllegalAccessException JavaDoc e ) {
335                     logWarn( e );
336                 }
337                 catch ( IllegalArgumentException JavaDoc e ) {
338                     logWarn( e );
339                 }
340                 catch ( InvocationTargetException JavaDoc e ) {
341                     logWarn( e );
342                 }
343                 catch ( NullPointerException JavaDoc e ) {
344                     logWarn( e );
345                 }
346             }
347         }
348         return null;
349     }
350
351     /**
352      * Sets the bean property with the given name to the given value.
353      *
354      * @param name the name of the property to set
355      * @param value the value to set that property to
356      * @return the previous value of that property
357      * @throws IllegalArgumentException if the given name is null;
358      * if the given name is not a {@link String}; if the bean doesn't
359      * define a property with that name; or if the bean property with
360      * that name is read-only
361      */

362     public Object JavaDoc put(Object JavaDoc name, Object JavaDoc value) throws IllegalArgumentException JavaDoc, ClassCastException JavaDoc {
363         if ( bean != null ) {
364             Object JavaDoc oldValue = get( name );
365             Method JavaDoc method = getWriteMethod( name );
366             if ( method == null ) {
367                 throw new IllegalArgumentException JavaDoc( "The bean of type: "+ bean.getClass().getName() + " has no property called: " + name );
368             }
369             try {
370                 Object JavaDoc[] arguments = createWriteMethodArguments( method, value );
371                 method.invoke( bean, arguments );
372
373                 Object JavaDoc newValue = get( name );
374                 firePropertyChange( name, oldValue, newValue );
375             }
376             catch ( InvocationTargetException JavaDoc e ) {
377                 logInfo( e );
378                 throw new IllegalArgumentException JavaDoc( e.getMessage() );
379             }
380             catch ( IllegalAccessException JavaDoc e ) {
381                 logInfo( e );
382                 throw new IllegalArgumentException JavaDoc( e.getMessage() );
383             }
384             return oldValue;
385         }
386         return null;
387     }
388                     
389     /**
390      * Returns the number of properties defined by the bean.
391      *
392      * @return the number of properties defined by the bean
393      */

394     public int size() {
395         return readMethods.size();
396     }
397
398     
399     /**
400      * Get the keys for this BeanMap.
401      * <p>
402      * Write-only properties are <b>not</b> included in the returned set of
403      * property names, although it is possible to set their value and to get
404      * their type.
405      *
406      * @return BeanMap keys. The Set returned by this method is not
407      * modifiable.
408      */

409     public Set JavaDoc keySet() {
410         return UnmodifiableSet.decorate(readMethods.keySet());
411     }
412
413     /**
414      * Gets a Set of MapEntry objects that are the mappings for this BeanMap.
415      * <p>
416      * Each MapEntry can be set but not removed.
417      *
418      * @return the unmodifiable set of mappings
419      */

420     public Set JavaDoc entrySet() {
421         return UnmodifiableSet.decorate(new AbstractSet JavaDoc() {
422             public Iterator JavaDoc iterator() {
423                 return entryIterator();
424             }
425             public int size() {
426               return BeanMap.this.readMethods.size();
427             }
428         });
429     }
430
431     /**
432      * Returns the values for the BeanMap.
433      *
434      * @return values for the BeanMap. The returned collection is not
435      * modifiable.
436      */

437     public Collection JavaDoc values() {
438         ArrayList JavaDoc answer = new ArrayList JavaDoc( readMethods.size() );
439         for ( Iterator JavaDoc iter = valueIterator(); iter.hasNext(); ) {
440             answer.add( iter.next() );
441         }
442         return UnmodifiableList.decorate(answer);
443     }
444
445
446     // Helper methods
447
//-------------------------------------------------------------------------
448

449     /**
450      * Returns the type of the property with the given name.
451      *
452      * @param name the name of the property
453      * @return the type of the property, or <code>null</code> if no such
454      * property exists
455      */

456     public Class JavaDoc getType(String JavaDoc name) {
457         return (Class JavaDoc) types.get( name );
458     }
459
460     /**
461      * Convenience method for getting an iterator over the keys.
462      * <p>
463      * Write-only properties will not be returned in the iterator.
464      *
465      * @return an iterator over the keys
466      */

467     public Iterator JavaDoc keyIterator() {
468         return readMethods.keySet().iterator();
469     }
470
471     /**
472      * Convenience method for getting an iterator over the values.
473      *
474      * @return an iterator over the values
475      */

476     public Iterator JavaDoc valueIterator() {
477         final Iterator JavaDoc iter = keyIterator();
478         return new Iterator JavaDoc() {
479             public boolean hasNext() {
480                 return iter.hasNext();
481             }
482             public Object JavaDoc next() {
483                 Object JavaDoc key = iter.next();
484                 return get(key);
485             }
486             public void remove() {
487                 throw new UnsupportedOperationException JavaDoc( "remove() not supported for BeanMap" );
488             }
489         };
490     }
491
492     /**
493      * Convenience method for getting an iterator over the entries.
494      *
495      * @return an iterator over the entries
496      */

497     public Iterator JavaDoc entryIterator() {
498         final Iterator JavaDoc iter = keyIterator();
499         return new Iterator JavaDoc() {
500             public boolean hasNext() {
501                 return iter.hasNext();
502             }
503             public Object JavaDoc next() {
504                 Object JavaDoc key = iter.next();
505                 Object JavaDoc value = get(key);
506                 return new Entry( BeanMap.this, key, value );
507             }
508             public void remove() {
509                 throw new UnsupportedOperationException JavaDoc( "remove() not supported for BeanMap" );
510             }
511         };
512     }
513
514
515     // Properties
516
//-------------------------------------------------------------------------
517

518     /**
519      * Returns the bean currently being operated on. The return value may
520      * be null if this map is empty.
521      *
522      * @return the bean being operated on by this map
523      */

524     public Object JavaDoc getBean() {
525         return bean;
526     }
527
528     /**
529      * Sets the bean to be operated on by this map. The given value may
530      * be null, in which case this map will be empty.
531      *
532      * @param newBean the new bean to operate on
533      */

534     public void setBean( Object JavaDoc newBean ) {
535         bean = newBean;
536         reinitialise();
537     }
538
539     /**
540      * Returns the accessor for the property with the given name.
541      *
542      * @param name the name of the property
543      * @return the accessor method for the property, or null
544      */

545     public Method JavaDoc getReadMethod(String JavaDoc name) {
546         return (Method JavaDoc) readMethods.get(name);
547     }
548
549     /**
550      * Returns the mutator for the property with the given name.
551      *
552      * @param name the name of the property
553      * @return the mutator method for the property, or null
554      */

555     public Method JavaDoc getWriteMethod(String JavaDoc name) {
556         return (Method JavaDoc) writeMethods.get(name);
557     }
558
559
560     // Implementation methods
561
//-------------------------------------------------------------------------
562

563     /**
564      * Returns the accessor for the property with the given name.
565      *
566      * @param name the name of the property
567      * @return null if the name is null; null if the name is not a
568      * {@link String}; null if no such property exists; or the accessor
569      * method for that property
570      */

571     protected Method JavaDoc getReadMethod( Object JavaDoc name ) {
572         return (Method JavaDoc) readMethods.get( name );
573     }
574
575     /**
576      * Returns the mutator for the property with the given name.
577      *
578      * @param name the name of the
579      * @return null if the name is null; null if the name is not a
580      * {@link String}; null if no such property exists; null if the
581      * property is read-only; or the mutator method for that property
582      */

583     protected Method JavaDoc getWriteMethod( Object JavaDoc name ) {
584         return (Method JavaDoc) writeMethods.get( name );
585     }
586
587     /**
588      * Reinitializes this bean. Called during {@link #setBean(Object)}.
589      * Does introspection to find properties.
590      */

591     protected void reinitialise() {
592         readMethods.clear();
593         writeMethods.clear();
594         types.clear();
595         initialise();
596     }
597
598     private void initialise() {
599         if(getBean() == null) return;
600
601         Class JavaDoc beanClass = getBean().getClass();
602         try {
603             //BeanInfo beanInfo = Introspector.getBeanInfo( bean, null );
604
BeanInfo JavaDoc beanInfo = Introspector.getBeanInfo( beanClass );
605             PropertyDescriptor JavaDoc[] propertyDescriptors = beanInfo.getPropertyDescriptors();
606             if ( propertyDescriptors != null ) {
607                 for ( int i = 0; i < propertyDescriptors.length; i++ ) {
608                     PropertyDescriptor JavaDoc propertyDescriptor = propertyDescriptors[i];
609                     if ( propertyDescriptor != null ) {
610                         String JavaDoc name = propertyDescriptor.getName();
611                         Method JavaDoc readMethod = propertyDescriptor.getReadMethod();
612                         Method JavaDoc writeMethod = propertyDescriptor.getWriteMethod();
613                         Class JavaDoc aType = propertyDescriptor.getPropertyType();
614
615                         if ( readMethod != null ) {
616                             readMethods.put( name, readMethod );
617                         }
618                         if ( writeMethods != null ) {
619                             writeMethods.put( name, writeMethod );
620                         }
621                         types.put( name, aType );
622                     }
623                 }
624             }
625         }
626         catch ( IntrospectionException JavaDoc e ) {
627             logWarn( e );
628         }
629     }
630
631     /**
632      * Called during a successful {@link #put(Object,Object)} operation.
633      * Default implementation does nothing. Override to be notified of
634      * property changes in the bean caused by this map.
635      *
636      * @param key the name of the property that changed
637      * @param oldValue the old value for that property
638      * @param newValue the new value for that property
639      */

640     protected void firePropertyChange( Object JavaDoc key, Object JavaDoc oldValue, Object JavaDoc newValue ) {
641     }
642
643     // Implementation classes
644
//-------------------------------------------------------------------------
645

646     /**
647      * Map entry used by {@link BeanMap}.
648      */

649     protected static class Entry extends AbstractMapEntry {
650         private BeanMap owner;
651         
652         /**
653          * Constructs a new <code>Entry</code>.
654          *
655          * @param owner the BeanMap this entry belongs to
656          * @param key the key for this entry
657          * @param value the value for this entry
658          */

659         protected Entry( BeanMap owner, Object JavaDoc key, Object JavaDoc value ) {
660             super( key, value );
661             this.owner = owner;
662         }
663
664         /**
665          * Sets the value.
666          *
667          * @param value the new value for the entry
668          * @return the old value for the entry
669          */

670         public Object JavaDoc setValue(Object JavaDoc value) {
671             Object JavaDoc key = getKey();
672             Object JavaDoc oldValue = owner.get( key );
673
674             owner.put( key, value );
675             Object JavaDoc newValue = owner.get( key );
676             super.setValue( newValue );
677             return oldValue;
678         }
679     }
680
681     /**
682      * Creates an array of parameters to pass to the given mutator method.
683      * If the given object is not the right type to pass to the method
684      * directly, it will be converted using {@link #convertType(Class,Object)}.
685      *
686      * @param method the mutator method
687      * @param value the value to pass to the mutator method
688      * @return an array containing one object that is either the given value
689      * or a transformed value
690      * @throws IllegalAccessException if {@link #convertType(Class,Object)}
691      * raises it
692      * @throws IllegalArgumentException if any other exception is raised
693      * by {@link #convertType(Class,Object)}
694      */

695     protected Object JavaDoc[] createWriteMethodArguments( Method JavaDoc method, Object JavaDoc value ) throws IllegalAccessException JavaDoc, ClassCastException JavaDoc {
696         try {
697             if ( value != null ) {
698                 Class JavaDoc[] types = method.getParameterTypes();
699                 if ( types != null && types.length > 0 ) {
700                     Class JavaDoc paramType = types[0];
701                     if ( ! paramType.isAssignableFrom( value.getClass() ) ) {
702                         value = convertType( paramType, value );
703                     }
704                 }
705             }
706             Object JavaDoc[] answer = { value };
707             return answer;
708         }
709         catch ( InvocationTargetException JavaDoc e ) {
710             logInfo( e );
711             throw new IllegalArgumentException JavaDoc( e.getMessage() );
712         }
713         catch ( InstantiationException JavaDoc e ) {
714             logInfo( e );
715             throw new IllegalArgumentException JavaDoc( e.getMessage() );
716         }
717     }
718
719     /**
720      * Converts the given value to the given type. First, reflection is
721      * is used to find a public constructor declared by the given class
722      * that takes one argument, which must be the precise type of the
723      * given value. If such a constructor is found, a new object is
724      * created by passing the given value to that constructor, and the
725      * newly constructed object is returned.<P>
726      *
727      * If no such constructor exists, and the given type is a primitive
728      * type, then the given value is converted to a string using its
729      * {@link Object#toString() toString()} method, and that string is
730      * parsed into the correct primitive type using, for instance,
731      * {@link Integer#valueOf(String)} to convert the string into an
732      * <code>int</code>.<P>
733      *
734      * If no special constructor exists and the given type is not a
735      * primitive type, this method returns the original value.
736      *
737      * @param newType the type to convert the value to
738      * @param value the value to convert
739      * @return the converted value
740      * @throws NumberFormatException if newType is a primitive type, and
741      * the string representation of the given value cannot be converted
742      * to that type
743      * @throws InstantiationException if the constructor found with
744      * reflection raises it
745      * @throws InvocationTargetException if the constructor found with
746      * reflection raises it
747      * @throws IllegalAccessException never
748      * @throws IllegalArgumentException never
749      */

750     protected Object JavaDoc convertType( Class JavaDoc newType, Object JavaDoc value )
751         throws InstantiationException JavaDoc, IllegalAccessException JavaDoc, IllegalArgumentException JavaDoc, InvocationTargetException JavaDoc {
752         
753         // try call constructor
754
Class JavaDoc[] types = { value.getClass() };
755         try {
756             Constructor JavaDoc constructor = newType.getConstructor( types );
757             Object JavaDoc[] arguments = { value };
758             return constructor.newInstance( arguments );
759         }
760         catch ( NoSuchMethodException JavaDoc e ) {
761             // try using the transformers
762
Transformer transformer = getTypeTransformer( newType );
763             if ( transformer != null ) {
764                 return transformer.transform( value );
765             }
766             return value;
767         }
768     }
769
770     /**
771      * Returns a transformer for the given primitive type.
772      *
773      * @param aType the primitive type whose transformer to return
774      * @return a transformer that will convert strings into that type,
775      * or null if the given type is not a primitive type
776      */

777     protected Transformer getTypeTransformer( Class JavaDoc aType ) {
778         return (Transformer) defaultTransformers.get( aType );
779     }
780
781     /**
782      * Logs the given exception to <code>System.out</code>. Used to display
783      * warnings while accessing/mutating the bean.
784      *
785      * @param ex the exception to log
786      */

787     protected void logInfo(Exception JavaDoc ex) {
788         // Deliberately do not use LOG4J or Commons Logging to avoid dependencies
789
System.out.println( "INFO: Exception: " + ex );
790     }
791
792     /**
793      * Logs the given exception to <code>System.err</code>. Used to display
794      * errors while accessing/mutating the bean.
795      *
796      * @param ex the exception to log
797      */

798     protected void logWarn(Exception JavaDoc ex) {
799         // Deliberately do not use LOG4J or Commons Logging to avoid dependencies
800
System.out.println( "WARN: Exception: " + ex );
801         ex.printStackTrace();
802     }
803 }
804
Popular Tags