KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tapestry > coerce > ValueConverterImpl


1 // Copyright 2004, 2005 The Apache Software Foundation
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
// http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14

15 package org.apache.tapestry.coerce;
16
17 import java.beans.PropertyEditor JavaDoc;
18 import java.beans.PropertyEditorManager JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.List JavaDoc;
22 import java.util.Map JavaDoc;
23
24 import org.apache.hivemind.ApplicationRuntimeException;
25 import org.apache.hivemind.util.ConstructorUtils;
26 import org.apache.hivemind.util.Defense;
27
28 /**
29  * Implementation of {@link org.apache.tapestry.coerce.ValueConverter}. Selects an appropriate type
30  * converter and delegates to it.
31  *
32  * @author Howard M. Lewis Ship
33  * @since 4.0
34  */

35 public class ValueConverterImpl implements ValueConverter
36 {
37     private Map JavaDoc _converterMap = new HashMap JavaDoc();
38
39     /** List of {@link org.apache.tapestry.coerce.TypeConverterContribution}. */
40
41     public List JavaDoc _contributions;
42
43     private Map JavaDoc _primitiveToWrapper = new HashMap JavaDoc();
44
45     private Map JavaDoc _wrapperToPrimitive = new HashMap JavaDoc();
46
47     {
48         store(boolean.class, Boolean JavaDoc.class);
49         store(byte.class, Byte JavaDoc.class);
50         store(short.class, Short JavaDoc.class);
51         store(char.class, Character JavaDoc.class);
52         store(int.class, Integer JavaDoc.class);
53         store(long.class, Long JavaDoc.class);
54         store(float.class, Float JavaDoc.class);
55         store(double.class, Double JavaDoc.class);
56     }
57
58     private void store(Class JavaDoc primitive, Class JavaDoc wrapper)
59     {
60         _primitiveToWrapper.put(primitive, wrapper);
61
62         _wrapperToPrimitive.put(wrapper, primitive);
63     }
64
65     public void initializeService()
66     {
67         Iterator JavaDoc i = _contributions.iterator();
68         while (i.hasNext())
69         {
70             TypeConverterContribution c = (TypeConverterContribution) i.next();
71
72             _converterMap.put(c.getSubjectClass(), c.getConverter());
73         }
74     }
75
76     public Object JavaDoc coerceValue(Object JavaDoc value, Class JavaDoc desiredType)
77     {
78         Defense.notNull(desiredType, "desiredType");
79
80         Class JavaDoc effectiveType = convertType(desiredType);
81
82         // Already the correct type? Go no further!
83

84         if (value != null && effectiveType.isAssignableFrom(value.getClass()))
85             return value;
86         
87         Object JavaDoc result = convertNumberToNumber(value, effectiveType);
88
89         if (result != null)
90             return result;
91
92         result = convertUsingPropertyEditor(value, effectiveType);
93
94         if (result != null)
95             return result;
96
97         TypeConverter converter = (TypeConverter) _converterMap.get(effectiveType);
98
99         // null value and no converter for the given type? Just return null.
100

101         if (value == null && converter == null)
102             return null;
103
104         if (converter == null)
105             throw new ApplicationRuntimeException(CoerceMessages.noConverter(effectiveType));
106
107         return converter.convertValue(value);
108     }
109
110     /**
111      * Attempts to use {@link java.beans.PropertyEditor}to perform a conversion from a string to a
112      * numeric type. Returns null if no property editor can be found.
113      *
114      * @param value
115      * The value to convert
116      * @param targetType
117      * The type to convert to (must be a wrapper type, not a primitive type)
118      */

119
120     private Number JavaDoc convertUsingPropertyEditor(Object JavaDoc value, Class JavaDoc targetType)
121     {
122         // Convert from wrapper type back to primitive type, because
123
// PropertyEditorManager expects primitive types not
124
// wrapper types.
125

126         if (value == null || value.getClass() != String JavaDoc.class
127                 || !Number JavaDoc.class.isAssignableFrom(targetType))
128             return null;
129
130         Class JavaDoc primitiveType = (Class JavaDoc) _wrapperToPrimitive.get(targetType);
131
132         // Note a primitive type.
133

134         if (primitiveType == null)
135             return null;
136
137         // Looks like a conversion from String to Number, let's see.
138

139         PropertyEditor JavaDoc editor = PropertyEditorManager.findEditor(primitiveType);
140
141         // This should not happen, since we've filtered down to just the
142
// primitive types that do have property editors.
143

144         if (editor == null)
145             return null;
146
147         String JavaDoc text = (String JavaDoc) value;
148
149         try
150         {
151             editor.setAsText(text);
152
153             return (Number JavaDoc) editor.getValue();
154         }
155         catch (Exception JavaDoc ex)
156         {
157             throw new ApplicationRuntimeException(CoerceMessages.stringToNumberConversionError(
158                     text,
159                     targetType,
160                     ex), ex);
161         }
162
163     }
164
165     private Number JavaDoc convertNumberToNumber(Object JavaDoc value, Class JavaDoc targetType)
166     {
167         if (value == null || !Number JavaDoc.class.isAssignableFrom(value.getClass())
168                 || !Number JavaDoc.class.isAssignableFrom(targetType))
169             return null;
170
171         String JavaDoc valueAsString = value.toString();
172
173         return (Number JavaDoc) ConstructorUtils.invokeConstructor(targetType, new Object JavaDoc[]
174         { valueAsString });
175     }
176
177     private Class JavaDoc convertType(Class JavaDoc possiblePrimitiveType)
178     {
179         Class JavaDoc wrapperType = (Class JavaDoc) _primitiveToWrapper.get(possiblePrimitiveType);
180
181         return wrapperType == null ? possiblePrimitiveType : wrapperType;
182     }
183
184     public void setContributions(List JavaDoc contributions)
185     {
186         _contributions = contributions;
187     }
188 }
Popular Tags