2009/05/20 - Apache Shale has been retired.
For more information, please explore the Attic.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.shale.test.el;
19
20 import java.math.BigDecimal;
21 import java.math.BigInteger;
22 import javax.el.ELContext;
23 import javax.el.ExpressionFactory;
24 import javax.el.MethodExpression;
25 import javax.el.ValueExpression;
26
27 /***
28 * <p>Mock implementation of <code>ExpressionFactory</code>.</p>
29 *
30 * @since 1.0.4
31 */
32 public class MockExpressionFactory extends ExpressionFactory {
33
34
35
36
37
38 /*** Creates a new instance of MockExpressionFactory */
39 public MockExpressionFactory() {
40 }
41
42
43
44
45
46 /***
47 * <p>Literal numeric value for zero.</p>
48 */
49 private static final Integer ZERO = new Integer(0);
50
51
52
53
54
55
56
57
58
59 /*** {@inheritDoc} */
60 public Object coerceToType(Object object, Class targetType) {
61
62
63 if ((targetType == null) || Object.class.equals(targetType)) {
64 return object;
65 }
66
67
68 if (String.class.equals(targetType)) {
69 if (object == null) {
70 return "";
71 } else if (object instanceof String) {
72 return (String) object;
73 } else {
74 return object.toString();
75 }
76 }
77
78
79 if (isNumeric(targetType)) {
80 if (object == null) {
81 return coerce(ZERO, targetType);
82 } else if ("".equals(object)) {
83 return coerce(ZERO, targetType);
84 } else if (object instanceof String) {
85 return coerce((String) object, targetType);
86 } else if (isNumeric(object.getClass())) {
87 return coerce((Number) object, targetType);
88 }
89 throw new IllegalArgumentException("Cannot convert " + object + " to Number");
90 }
91
92
93 if (Boolean.class.equals(targetType) || (Boolean.TYPE == targetType)) {
94 if (object == null) {
95 return Boolean.FALSE;
96 } else if ("".equals(object)) {
97 return Boolean.FALSE;
98 } else if ((object instanceof Boolean) || (object.getClass() == Boolean.TYPE)) {
99 return (Boolean) object;
100 } else if (object instanceof String) {
101 return Boolean.valueOf((String) object);
102 }
103 throw new IllegalArgumentException("Cannot convert " + object + " to Boolean");
104 }
105
106
107 if (Character.class.equals(targetType) || (Character.TYPE == targetType)) {
108 if (object == null) {
109 return new Character((char) 0);
110 } else if ("".equals(object)) {
111 return new Character((char) 0);
112 } else if (object instanceof String) {
113 return new Character(((String) object).charAt(0));
114 } else if (isNumeric(object.getClass())) {
115 return new Character((char) ((Number) object).shortValue());
116 } else if ((object instanceof Character) || (object.getClass() == Character.TYPE)) {
117 return (Character) object;
118 }
119 throw new IllegalArgumentException("Cannot convert " + object + " to Character");
120 }
121
122
123 if ((object != null) && targetType.isAssignableFrom(object.getClass())) {
124 return object;
125 }
126
127
128 throw new IllegalArgumentException("Cannot convert " + object + " to " + targetType.getName());
129
130 }
131
132
133 /*** {@inheritDoc} */
134 public MethodExpression createMethodExpression(ELContext context,
135 String expression,
136 Class expectedType,
137 Class[] signature) {
138
139 return new MockMethodExpression(expression, signature, expectedType);
140
141 }
142
143
144 /*** {@inheritDoc} */
145 public ValueExpression createValueExpression(ELContext context,
146 String expression,
147 Class expectedType) {
148
149 return new MockValueExpression(expression, expectedType);
150
151 }
152
153
154 /*** {@inheritDoc} */
155 public ValueExpression createValueExpression(Object instance,
156 Class expectedType) {
157
158 return new MockVariableValueExpression(instance, expectedType);
159
160 }
161
162
163
164
165
166 /***
167 * <p>Coerce the specified value to the specified Number subclass.</p>
168 *
169 * @param value Value to be coerced
170 * @param type Destination type
171 */
172 private Number coerce(Number value, Class type) {
173
174 if ((type == Byte.TYPE) || (type == Byte.class)) {
175 return new Byte(value.byteValue());
176 } else if ((type == Double.TYPE) || (type == Double.class)) {
177 return new Double(value.doubleValue());
178 } else if ((type == Float.TYPE) || (type == Float.class)) {
179 return new Float(value.floatValue());
180 } else if ((type == Integer.TYPE) || (type == Integer.class)) {
181 return new Integer(value.intValue());
182 } else if ((type == Long.TYPE) || (type == Long.class)) {
183 return new Long(value.longValue());
184 } else if ((type == Short.TYPE) || (type == Short.class)) {
185 return new Short(value.shortValue());
186 } else if (type == BigDecimal.class) {
187 if (value instanceof BigDecimal) {
188 return (BigDecimal) value;
189 } else if (value instanceof BigInteger) {
190 return new BigDecimal((BigInteger) value);
191 } else {
192 return new BigDecimal(((Number) value).doubleValue());
193 }
194 } else if (type == BigInteger.class) {
195 if (value instanceof BigInteger) {
196 return (BigInteger) value;
197 } else if (value instanceof BigDecimal) {
198 return ((BigDecimal) value).toBigInteger();
199 } else {
200 return BigInteger.valueOf(((Number) value).longValue());
201 }
202 }
203 throw new IllegalArgumentException("Cannot convert " + value + " to " + type.getName());
204
205 }
206
207
208 /***
209 * <p>Coerce the specified value to the specified Number subclass.</p>
210 *
211 * @param value Value to be coerced
212 * @param type Destination type
213 */
214 private Number coerce(String value, Class type) {
215
216 if ((type == Byte.TYPE) || (type == Byte.class)) {
217 return Byte.valueOf(value);
218 } else if ((type == Double.TYPE) || (type == Double.class)) {
219 return Double.valueOf(value);
220 } else if ((type == Float.TYPE) || (type == Float.class)) {
221 return Float.valueOf(value);
222 } else if ((type == Integer.TYPE) || (type == Integer.class)) {
223 return Integer.valueOf(value);
224 } else if ((type == Long.TYPE) || (type == Long.class)) {
225 return Long.valueOf(value);
226 } else if ((type == Short.TYPE) || (type == Short.class)) {
227 return Short.valueOf(value);
228 } else if (type == BigDecimal.class) {
229 return new BigDecimal(value);
230 } else if (type == BigInteger.class) {
231 return new BigInteger(value);
232 }
233 throw new IllegalArgumentException("Cannot convert " + value + " to " + type.getName());
234
235 }
236
237
238 /***
239 * <p>Return <code>true</code> if the specified type is numeric.</p>
240 *
241 * @param type Type to check
242 */
243 private boolean isNumeric(Class type) {
244
245 return
246 (type == Byte.TYPE) || (type == Byte.class)
247 || (type == Double.TYPE) || (type == Double.class)
248 || (type == Float.TYPE) || (type == Float.class)
249 || (type == Integer.TYPE) || (type == Integer.class)
250 || (type == Long.TYPE) || (type == Long.class)
251 || (type == Short.TYPE) || (type == Short.class)
252 || (type == BigDecimal.class) || (type == BigInteger.class);
253
254 }
255
256
257 }