KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > inversoft > util > typeconverter > TypeConverterRegistry


1 /*
2  * Copyright (c) 2003, Inversoft
3  *
4  * This software is distribuable under the GNU Lesser General Public License.
5  * For more information visit gnu.org.
6  */

7 package com.inversoft.util.typeconverter;
8
9
10 import java.util.Hashtable JavaDoc;
11 import java.util.Map JavaDoc;
12
13 import com.inversoft.util.ReflectionException;
14 import com.inversoft.util.ReflectionTools;
15
16
17 /**
18  * This class is the manager for all the TypeConverters. It
19  * uses a Hashtable to store the converters and therefore is
20  * thread safe. A converter for a given type will be retrieved
21  * when the manager is queried for that type and all sub class
22  * of that type, unless another converter is registered for
23  * a sub class of the type. For example, registering a convert
24  * for the type Number would ensure that Integer, Double, Float,
25  * etc. used that converter for conversions. If a converter
26  * was registered for Number and another converter for Double,
27  * the converter for Number would handle all sub-class of
28  * Number (Integer, etc.) except Double.
29  *
30  * @author bpontarelli
31  */

32 public class TypeConverterRegistry {
33
34     private static Map JavaDoc converters = new Hashtable JavaDoc();
35
36     // Initialize the basic type converters including Number, String and Boolean
37
static {
38         Object JavaDoc obj;
39
40         try {
41             obj = ReflectionTools.instantiate("com.inversoft.util.typeconverter.converters.BooleanTypeConverter");
42             converters.put(Boolean JavaDoc.class, obj);
43             converters.put(Boolean.TYPE, obj);
44         } catch (ReflectionException re) {
45             System.err.println("WARNING - boolean type converter not found");
46         }
47
48         try {
49             obj = ReflectionTools.instantiate("com.inversoft.util.typeconverter.converters.NumberTypeConverter");
50             converters.put(Number JavaDoc.class, obj);
51             converters.put(Byte.TYPE, obj);
52             converters.put(Double.TYPE, obj);
53             converters.put(Float.TYPE, obj);
54             converters.put(Integer.TYPE, obj);
55             converters.put(Long.TYPE, obj);
56             converters.put(Short.TYPE, obj);
57         } catch (ReflectionException re) {
58             System.err.println("WARNING - Number type converter not found");
59         }
60
61         try {
62             obj = ReflectionTools.instantiate("com.inversoft.util.typeconverter.converters.CharacterTypeConverter");
63             converters.put(Character JavaDoc.class, obj);
64             converters.put(Character.TYPE, obj);
65         } catch (ReflectionException re) {
66             System.err.println("WARNING - character type converter not found");
67         }
68
69         try {
70             obj = ReflectionTools.instantiate("com.inversoft.util.typeconverter.BaseTypeConverter");
71             converters.put(String JavaDoc.class, obj);
72         } catch (ReflectionException re) {
73             System.err.println("WARNING - String type converter not found");
74         }
75     }
76
77     /** Static class */
78     private TypeConverterRegistry() {
79     }
80
81     /**
82      * <p>
83      * Returns the type converter for the given type. This converter is either
84      * the converter associated with the given type of associated with a super
85      * class of the given type (not interfaces). This principal also works with
86      * arrays. If the type is an array, then what happens is that the array type
87      * is asked for its component type using the method getComponentType and this
88      * type is used to query the manager. So, the converter registered for Number
89      * is returned Double[] is queried (because Double is queried and since no
90      * converter was register for it, then Number is checked).
91      * </p>
92      *
93      * <p>
94      * Normal types work the exact same way. First the type is checked and then
95      * its parents are checked until Object is reached, in which case null is
96      * returned.
97      * </p>
98      *
99      * <p>
100      * Primitive values are treated as their wrapper classes. So, if int.class
101      * is passed into this method (queried) then either a converter registered
102      * for Integer, or Number or null is returned depending on what converters
103      * have been registered so far.
104      * </p>
105      *
106      * @param type The type to start with when looking for converters
107      * @return The converter or null if one was not found
108      */

109     public static TypeConverter lookup(Class JavaDoc type) {
110         Class JavaDoc localType = type;
111         TypeConverter converter = null;
112
113         // If it is an array, just use the component type because TypeConverters
114
// can convert to arrays
115
if (localType.isArray()) {
116             localType = localType.getComponentType();
117         }
118
119         // The local type becomes null when it is an interface or a primitive and the
120
// super class is asked for
121
while (localType != null && localType != Object JavaDoc.class) {
122             converter = (TypeConverter) converters.get(localType);
123             if (converter == null) {
124                 localType = localType.getSuperclass();
125             } else {
126                 break;
127             }
128         }
129
130         // I'm not sure about this yet
131
/*
132         if (converter == null) {
133             Class [] interfaces = type.getInterfaces();
134             TypeConverter interfaceConverter;
135
136             for (int i = 0; i < interfaces.length; i++) {
137                 interfaceConverter = getTypeConverter(interfaces[i]);
138                 if (interfaceConverter != null) {
139                     break;
140                 }
141             }
142         }
143         */

144
145         return converter;
146     }
147
148     /**
149      * Registers the given converter with the given type
150      *
151      * @param type The type to register the converter for
152      * @param converter The convert to register with the given type
153      * @return The converter that was already registered with the given type
154      * or null if this is the first converter being registered for
155      * that type
156      */

157     public static TypeConverter register(Class JavaDoc type, TypeConverter converter) {
158         return (TypeConverter) converters.put(type, converter);
159     }
160
161     /**
162      * Unregisters the given converter with the given type
163      *
164      * @param type The type to unregister the converter
165      * @return The converter that was registered with the given type or null
166      * if no converter was registered for the given type
167      */

168     public static TypeConverter unregister(Class JavaDoc type) {
169         return (TypeConverter) converters.remove(type);
170     }
171 }
Popular Tags