1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package net.sf.ezmorph.object;
18
19 import java.math.BigDecimal;
20 import java.math.BigInteger;
21
22 import net.sf.ezmorph.MorphException;
23 import net.sf.ezmorph.primitive.ByteMorpher;
24 import net.sf.ezmorph.primitive.DoubleMorpher;
25 import net.sf.ezmorph.primitive.FloatMorpher;
26 import net.sf.ezmorph.primitive.IntMorpher;
27 import net.sf.ezmorph.primitive.LongMorpher;
28 import net.sf.ezmorph.primitive.ShortMorpher;
29
30 import org.apache.commons.lang.builder.EqualsBuilder;
31 import org.apache.commons.lang.builder.HashCodeBuilder;
32
33
34
35
36
37
38
39
40 public final class NumberMorpher extends AbstractObjectMorpher
41 {
42 private Number defaultValue;
43 private Class type;
44
45
46
47
48
49
50
51 public NumberMorpher( Class type )
52 {
53 super( false );
54
55 if( type == null ){
56 throw new MorphException( "Must specify a type" );
57 }
58
59 if( type != Byte.TYPE && type != Short.TYPE && type != Integer.TYPE && type != Long.TYPE
60 && type != Float.TYPE && type != Double.TYPE && !Byte.class.isAssignableFrom( type )
61 && !Short.class.isAssignableFrom( type ) && !Integer.class.isAssignableFrom( type )
62 && !Long.class.isAssignableFrom( type ) && !Float.class.isAssignableFrom( type )
63 && !Double.class.isAssignableFrom( type ) && !BigInteger.class.isAssignableFrom( type )
64 && !BigDecimal.class.isAssignableFrom( type ) ){
65 throw new MorphException( "Must specify a Number subclass" );
66 }
67
68 this.type = type;
69 }
70
71
72
73
74
75
76
77
78
79 public NumberMorpher( Class type, Number defaultValue )
80 {
81 super( true );
82
83 if( type == null ){
84 throw new MorphException( "Must specify a type" );
85 }
86
87 if( type != Byte.TYPE && type != Short.TYPE && type != Integer.TYPE && type != Long.TYPE
88 && type != Float.TYPE && type != Double.TYPE && !Byte.class.isAssignableFrom( type )
89 && !Short.class.isAssignableFrom( type ) && !Integer.class.isAssignableFrom( type )
90 && !Long.class.isAssignableFrom( type ) && !Float.class.isAssignableFrom( type )
91 && !Double.class.isAssignableFrom( type ) && !BigInteger.class.isAssignableFrom( type )
92 && !BigDecimal.class.isAssignableFrom( type ) ){
93 throw new MorphException( "Must specify a Number subclass" );
94 }
95
96 if( defaultValue != null && !type.isInstance( defaultValue ) ){
97 throw new MorphException( "Default value must be of type " + type );
98 }
99
100 this.type = type;
101 setDefaultValue( defaultValue );
102 }
103
104 public boolean equals( Object obj )
105 {
106 if( this == obj ){
107 return true;
108 }
109 if( obj == null ){
110 return false;
111 }
112
113 if( !(obj instanceof NumberMorpher) ){
114 return false;
115 }
116
117 NumberMorpher other = (NumberMorpher) obj;
118 EqualsBuilder builder = new EqualsBuilder();
119 builder.append( type, other.type );
120 if( isUseDefault() && other.isUseDefault() ){
121 builder.append( getDefaultValue(), other.getDefaultValue() );
122 return builder.isEquals();
123 }else if( !isUseDefault() && !other.isUseDefault() ){
124 return builder.isEquals();
125 }else{
126 return false;
127 }
128 }
129
130
131
132
133 public Number getDefaultValue()
134 {
135 return defaultValue;
136 }
137
138 public int hashCode()
139 {
140 HashCodeBuilder builder = new HashCodeBuilder();
141 builder.append( type );
142 if( isUseDefault() ){
143 builder.append( getDefaultValue() );
144 }
145 return builder.toHashCode();
146 }
147
148 public Object morph( Object value )
149 {
150 if( value != null && type.isAssignableFrom( value.getClass() ) ){
151
152 return value;
153 }
154
155 String str = String.valueOf( value )
156 .trim();
157
158 if( !type.isPrimitive()
159 && (value == null || str.length() == 0 || "null".equalsIgnoreCase( str )) ){
160
161 return null;
162 }
163
164 if( isDecimalNumber( type ) ){
165 if( Float.class.isAssignableFrom( type ) || Float.TYPE == type ){
166 return morphToFloat( str );
167 }else if( Double.class.isAssignableFrom( type ) || Double.TYPE == type ){
168 return morphToDouble( str );
169 }else{
170 return morphToBigDecimal( str );
171 }
172 }else{
173 if( Byte.class.isAssignableFrom( type ) || Byte.TYPE == type ){
174 return morphToByte( str );
175 }else if( Short.class.isAssignableFrom( type ) || Short.TYPE == type ){
176 return morphToShort( str );
177 }else if( Integer.class.isAssignableFrom( type ) || Integer.TYPE == type ){
178 return morphToInteger( str );
179 }else if( Long.class.isAssignableFrom( type ) || Long.TYPE == type ){
180 return morphToLong( str );
181 }else{
182 return morphToBigInteger( str );
183 }
184 }
185 }
186
187 public Class morphsTo()
188 {
189 return type;
190 }
191
192
193
194
195
196
197
198
199 public void setDefaultValue( Number defaultValue )
200 {
201 if( defaultValue != null && !type.isInstance( defaultValue ) ){
202 throw new MorphException( "Default value must be of type " + type );
203 }
204 this.defaultValue = defaultValue;
205 }
206
207 private boolean isDecimalNumber( Class type )
208 {
209 return (Double.class.isAssignableFrom( type ) || Float.class.isAssignableFrom( type )
210 || Double.TYPE == type || Float.TYPE == type || BigDecimal.class.isAssignableFrom( type ));
211 }
212
213 private Object morphToBigDecimal( String str )
214 {
215 Object result = null;
216 if( isUseDefault() ){
217 result = new BigDecimalMorpher( (BigDecimal) defaultValue ).morph( str );
218 }else{
219 result = new BigDecimal( str );
220 }
221 return result;
222 }
223
224 private Object morphToBigInteger( String str )
225 {
226 Object result = null;
227 if( isUseDefault() ){
228 result = new BigIntegerMorpher( (BigInteger) defaultValue ).morph( str );
229 }else{
230 result = new BigInteger( str );
231 }
232 return result;
233 }
234
235 private Object morphToByte( String str )
236 {
237 Object result = null;
238 if( isUseDefault() ){
239 if( defaultValue == null ){
240 return (Byte) null;
241 }else{
242 result = new Byte( new ByteMorpher( defaultValue.byteValue() ).morph( str ) );
243 }
244 }else{
245 result = new Byte( new ByteMorpher().morph( str ) );
246 }
247 return result;
248 }
249
250 private Object morphToDouble( String str )
251 {
252 Object result = null;
253 if( isUseDefault() ){
254 if( defaultValue == null ){
255 return (Double) null;
256 }else{
257 result = new Double( new DoubleMorpher( defaultValue.doubleValue() ).morph( str ) );
258 }
259 }else{
260 result = new Double( new DoubleMorpher().morph( str ) );
261 }
262 return result;
263 }
264
265 private Object morphToFloat( String str )
266 {
267 Object result = null;
268 if( isUseDefault() ){
269 if( defaultValue == null ){
270 return (Float) null;
271 }else{
272 result = new Float( new FloatMorpher( defaultValue.floatValue() ).morph( str ) );
273 }
274 }else{
275 result = new Float( new FloatMorpher().morph( str ) );
276 }
277 return result;
278 }
279
280 private Object morphToInteger( String str )
281 {
282 Object result = null;
283 if( isUseDefault() ){
284 if( defaultValue == null ){
285 return (Integer) null;
286 }else{
287 result = new Integer( new IntMorpher( defaultValue.intValue() ).morph( str ) );
288 }
289 }else{
290 result = new Integer( new IntMorpher().morph( str ) );
291 }
292 return result;
293 }
294
295 private Object morphToLong( String str )
296 {
297 Object result = null;
298 if( isUseDefault() ){
299 if( defaultValue == null ){
300 return (Long) null;
301 }else{
302 result = new Long( new LongMorpher( defaultValue.longValue() ).morph( str ) );
303 }
304 }else{
305 result = new Long( new LongMorpher().morph( str ) );
306 }
307 return result;
308 }
309
310 private Object morphToShort( String str )
311 {
312 Object result = null;
313 if( isUseDefault() ){
314 if( defaultValue == null ){
315 return (Short) null;
316 }else{
317 result = new Short( new ShortMorpher( defaultValue.shortValue() ).morph( str ) );
318 }
319 }else{
320 result = new Short( new ShortMorpher().morph( str ) );
321 }
322 return result;
323 }
324 }