KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > 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.collections;
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
37 /**
38  * An implementation of Map for JavaBeans which uses introspection to
39  * get and put properties in the bean.
40  * <p>
41  * If an exception occurs during attempts to get or set a property then the
42  * property is considered non existent in the Map
43  *
44  * @since Commons Collections 1.0
45  * @version $Revision: 1.29 $ $Date: 2004/02/18 01:15:42 $
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     public String JavaDoc toString() {
162         return "BeanMap<" + String.valueOf(bean) + ">";
163     }
164     
165     /**
166      * Clone this bean map using the following process:
167      *
168      * <ul>
169      * <li>If there is no underlying bean, return a cloned BeanMap without a
170      * bean.
171      *
172      * <li>Since there is an underlying bean, try to instantiate a new bean of
173      * the same type using Class.newInstance().
174      *
175      * <li>If the instantiation fails, throw a CloneNotSupportedException
176      *
177      * <li>Clone the bean map and set the newly instantiated bean as the
178      * underlying bean for the bean map.
179      *
180      * <li>Copy each property that is both readable and writable from the
181      * existing object to a cloned bean map.
182      *
183      * <li>If anything fails along the way, throw a
184      * CloneNotSupportedException.
185      *
186      * <ul>
187      */

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

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

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

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

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

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

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

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

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

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

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

445     /**
446      * Returns the type of the property with the given name.
447      *
448      * @param name the name of the property
449      * @return the type of the property, or <code>null</code> if no such
450      * property exists
451      */

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

463     public Iterator JavaDoc keyIterator() {
464         return readMethods.keySet().iterator();
465     }
466
467     /**
468      * Convenience method for getting an iterator over the values.
469      *
470      * @return an iterator over the values
471      */

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

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

514     /**
515      * Returns the bean currently being operated on. The return value may
516      * be null if this map is empty.
517      *
518      * @return the bean being operated on by this map
519      */

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

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

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

551     public Method JavaDoc getWriteMethod(String JavaDoc name) {
552         return (Method JavaDoc) writeMethods.get(name);
553     }
554
555
556     // Implementation methods
557
//-------------------------------------------------------------------------
558

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

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

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

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

636     protected void firePropertyChange( Object JavaDoc key, Object JavaDoc oldValue, Object JavaDoc newValue ) {
637     }
638
639     // Implementation classes
640
//-------------------------------------------------------------------------
641

642     /**
643      * Map entry used by {@link BeanMap}.
644      */

645     protected static class MyMapEntry extends AbstractMapEntry {
646         private BeanMap owner;
647         
648         /**
649          * Constructs a new <code>MyMapEntry</code>.
650          *
651          * @param owner the BeanMap this entry belongs to
652          * @param key the key for this entry
653          * @param value the value for this entry
654          */

655         protected MyMapEntry( BeanMap owner, Object JavaDoc key, Object JavaDoc value ) {
656             super( key, value );
657             this.owner = owner;
658         }
659
660         /**
661          * Sets the value.
662          *
663          * @param value the new value for the entry
664          * @return the old value for the entry
665          */

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

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

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

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

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

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