View Javadoc

1   /*
2    *  Copyright 2010 Stephen Colebourne
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.joda.convert;
17  
18  import java.io.File;
19  import java.math.BigDecimal;
20  import java.math.BigInteger;
21  import java.net.InetAddress;
22  import java.net.MalformedURLException;
23  import java.net.URI;
24  import java.net.URL;
25  import java.net.UnknownHostException;
26  import java.text.ParseException;
27  import java.text.SimpleDateFormat;
28  import java.util.Calendar;
29  import java.util.Currency;
30  import java.util.Date;
31  import java.util.GregorianCalendar;
32  import java.util.Locale;
33  import java.util.TimeZone;
34  import java.util.UUID;
35  import java.util.concurrent.atomic.AtomicBoolean;
36  import java.util.concurrent.atomic.AtomicInteger;
37  import java.util.concurrent.atomic.AtomicLong;
38  
39  /**
40   * Conversion between JDK classes and a {@code String}.
41   */
42  enum JDKStringConverter implements StringConverter<Object> {
43  
44      /**
45       * String converter.
46       */
47      STRING(String.class) {
48          public Object convertFromString(Class<?> cls, String str) {
49              return str;
50          }
51      },
52      /**
53       * CharSequence converter.
54       */
55      CHAR_SEQUENCE(CharSequence.class) {
56          public Object convertFromString(Class<?> cls, String str) {
57              return str;
58          }
59      },
60      /**
61       * StringBuffer converter.
62       */
63      STRING_BUFFER(StringBuffer.class) {
64          public Object convertFromString(Class<?> cls, String str) {
65              return new StringBuffer(str);
66          }
67      },
68      /**
69       * StringBuilder converter.
70       */
71      STRING_BUILDER(StringBuilder.class) {
72          public Object convertFromString(Class<?> cls, String str) {
73              return new StringBuilder(str);
74          }
75      },
76      /**
77       * Long converter.
78       */
79      LONG(Long.class) {
80          public Object convertFromString(Class<?> cls, String str) {
81              return new Long(str);
82          }
83      },
84  
85      /**
86       * Integer converter.
87       */
88      INTEGER(Integer.class) {
89          public Object convertFromString(Class<?> cls, String str) {
90              return new Integer(str);
91          }
92      },
93  
94      /**
95       * Short converter.
96       */
97      SHORT (Short.class) {
98          public Object convertFromString(Class<?> cls, String str) {
99              return new Short(str);
100         }
101     },
102 
103     /**
104      * Byte converter.
105      */
106     BYTE(Byte.class) {
107         public Object convertFromString(Class<?> cls, String str) {
108             return new Byte(str);
109         }
110     },
111     /**
112      * Character converter.
113      */
114     CHARACTER(Character.class) {
115         public Object convertFromString(Class<?> cls, String str) {
116             if (str.length() != 1) {
117                 throw new IllegalArgumentException("Character value must be a string length 1");
118             }
119             return new Character(str.charAt(0));
120         }
121     },
122     /**
123      * Boolean converter.
124      */
125     BOOLEAN(Boolean.class) {
126         public Object convertFromString(Class<?> cls, String str) {
127             if ("true".equalsIgnoreCase(str)) {
128                 return Boolean.TRUE;
129             }
130             if ("false".equalsIgnoreCase(str)) {
131                 return Boolean.FALSE;
132             }
133             throw new IllegalArgumentException("Boolean value must be 'true' or 'false', case insensitive");
134         }
135     },
136     /**
137      * Double converter.
138      */
139     DOUBLE(Double.class) {
140         public Object convertFromString(Class<?> cls, String str) {
141             return new Double(str);
142         }
143     },
144     /**
145      * Float converter.
146      */
147     FLOAT(Float.class) {
148         public Object convertFromString(Class<?> cls, String str) {
149             return new Float(str);
150         }
151     },
152     /**
153      * BigInteger converter.
154      */
155     BIG_INTEGER(BigInteger.class) {
156         public Object convertFromString(Class<?> cls, String str) {
157             return new BigInteger(str);
158         }
159     },
160     /**
161      * BigDecimal converter.
162      */
163     BIG_DECIMAL(BigDecimal.class) {
164         public Object convertFromString(Class<?> cls, String str) {
165             return new BigDecimal(str);
166         }
167     },
168     /**
169      * AtomicLong converter.
170      */
171     ATOMIC_LONG(AtomicLong.class) {
172         public Object convertFromString(Class<?> cls, String str) {
173             long val = Long.parseLong(str);
174             return new AtomicLong(val);
175         }
176     },
177     /**
178      * AtomicLong converter.
179      */
180     ATOMIC_INTEGER(AtomicInteger.class) {
181         public Object convertFromString(Class<?> cls, String str) {
182             int val = Integer.parseInt(str);
183             return new AtomicInteger(val);
184         }
185     },
186     /**
187      * AtomicBoolean converter.
188      */
189     ATOMIC_BOOLEAN(AtomicBoolean.class) {
190         public Object convertFromString(Class<?> cls, String str) {
191             if ("true".equalsIgnoreCase(str)) {
192                 return new AtomicBoolean(true);
193             }
194             if ("false".equalsIgnoreCase(str)) {
195                 return new AtomicBoolean(false);
196             }
197             throw new IllegalArgumentException("Boolean value must be 'true' or 'false', case insensitive");
198         }
199     },
200     /**
201      * Locale converter.
202      */
203     LOCALE(Locale.class) {
204         public Object convertFromString(Class<?> cls, String str) {
205             String[] split = str.split("_", 3);
206             switch (split.length) {
207                 case 1:
208                     return new Locale(split[0]);
209                 case 2:
210                     return new Locale(split[0], split[1]);
211                 case 3:
212                     return new Locale(split[0], split[1], split[2]);
213             }
214             throw new IllegalArgumentException("Unable to parse Locale: " + str);
215         }
216     },
217     /**
218      * Class converter.
219      */
220     CLASS(Class.class) {
221         @Override
222         public String convertToString(Object object) {
223             return ((Class<?>) object).getName();
224         }
225         public Object convertFromString(Class<?> cls, String str) {
226             try {
227                 return getClass().getClassLoader().loadClass(str);
228             } catch (ClassNotFoundException ex) {
229                 throw new RuntimeException("Unable to create class: " + str, ex);
230             }
231         }
232     },
233     /**
234      * Package converter.
235      */
236     PACKAGE(Package.class) {
237         @Override
238         public String convertToString(Object object) {
239             return ((Package) object).getName();
240         }
241         public Object convertFromString(Class<?> cls, String str) {
242             return Package.getPackage(str);
243         }
244     },
245     /**
246      * Currency converter.
247      */
248     CURRENCY(Currency.class) {
249         public Object convertFromString(Class<?> cls, String str) {
250             return Currency.getInstance(str);
251         }
252     },
253     /**
254      * TimeZone converter.
255      */
256     TIME_ZONE(TimeZone.class) {
257         @Override
258         public String convertToString(Object object) {
259             return ((TimeZone) object).getID();
260         }
261         public Object convertFromString(Class<?> cls, String str) {
262             return TimeZone.getTimeZone(str);
263         }
264     },
265     /**
266      * UUID converter.
267      */
268     UUID(UUID.class) {
269         public Object convertFromString(Class<?> cls, String str) {
270             return java.util.UUID.fromString(str);
271         }
272     },
273     /**
274      * URL converter.
275      */
276     URL(URL.class) {
277         public Object convertFromString(Class<?> cls, String str) {
278             try {
279                 return new URL(str);
280             } catch (MalformedURLException ex) {
281                 throw new RuntimeException(ex.getMessage(), ex);
282             }
283         }
284     },
285     /**
286      * URI converter.
287      */
288     URI(URI.class) {
289         public Object convertFromString(Class<?> cls, String str) {
290             return java.net.URI.create(str);
291         }
292     },
293     /**
294      * InetAddress converter.
295      */
296     INET_ADDRESS(InetAddress.class) {
297         @Override
298         public String convertToString(Object object) {
299             return ((InetAddress) object).getHostAddress();
300         }
301         public Object convertFromString(Class<?> cls, String str) {
302             try {
303                 return InetAddress.getByName(str);
304             } catch (UnknownHostException ex) {
305                 throw new RuntimeException(ex);
306             }
307         }
308     },
309     /**
310      * File converter.
311      */
312     FILE(File.class) {
313         public Object convertFromString(Class<?> cls, String str) {
314             return new File(str);
315         }
316     },
317     /**
318      * Date converter.
319      */
320     DATE(Date.class) {
321         @Override
322         public String convertToString(Object object) {
323             SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
324             String str = f.format(object);
325             return str.substring(0, 26) + ":" + str.substring(26);
326         }
327         public Object convertFromString(Class<?> cls, String str) {
328             if (str.length() != 29) {
329                 throw new IllegalArgumentException("Unable to parse date: " + str);
330             }
331             str = str.substring(0, 26) + str.substring(27);
332             SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
333             try {
334                 return f.parseObject(str);
335             } catch (ParseException ex) {
336                 throw new RuntimeException(ex);
337             }
338         }
339     },
340     /**
341      * Calendar converter.
342      */
343     CALENDAR(Calendar.class) {
344         @Override
345         public String convertToString(Object object) {
346             if (object instanceof GregorianCalendar == false) {
347                 throw new RuntimeException("Unable to convert calendar as it is not a GregorianCalendar");
348             }
349             GregorianCalendar cal = (GregorianCalendar) object;
350             SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
351             f.setCalendar(cal);
352             String str = f.format(cal.getTime());
353             return str.substring(0, 26) + ":" + str.substring(26) + "[" + cal.getTimeZone().getID() + "]";
354         }
355         public Object convertFromString(Class<?> cls, String str) {
356             if (str.length() < 31 || str.charAt(26) != ':'
357                     || str.charAt(29) != '[' || str.charAt(str.length() - 1) != ']') {
358                 throw new IllegalArgumentException("Unable to parse date: " + str);
359             }
360             TimeZone zone = TimeZone.getTimeZone(str.substring(30, str.length() - 1));
361             str = str.substring(0, 26) + str.substring(27, 29);
362             SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
363             GregorianCalendar cal = new GregorianCalendar(zone);
364             cal.setTimeInMillis(0);
365             f.setCalendar(cal);
366             try {
367                 f.parseObject(str);
368                 return f.getCalendar();
369             } catch (ParseException ex) {
370                 throw new RuntimeException(ex);
371             }
372         }
373     },
374     /**
375      * Enum converter.
376      */
377     ENUM(Enum.class) {
378         @SuppressWarnings("rawtypes")
379         public String convertToString(Object object) {
380             return ((Enum) object).name();  // avoid toString() as that can be overridden
381         }
382         @SuppressWarnings({ "unchecked", "rawtypes" })
383         public Object convertFromString(Class cls, String str) {
384             return Enum.valueOf(cls, str);
385         }
386     },
387     ;
388 
389     /** The type. */
390     private Class<?> type;
391 
392     /**
393      * Creates an enum.
394      * @param type  the type, not null
395      */
396     private JDKStringConverter(Class<?> type) {
397         this.type = type;
398     }
399 
400     /**
401      * Gets the type of the converter.
402      * @return the type, not null
403      */
404     Class<?> getType() {
405         return type;
406     }
407 
408     //-----------------------------------------------------------------------
409     public String convertToString(Object object) {
410         return object.toString();
411     }
412 
413 }