View Javadoc

1   /*******************************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   *******************************************************************************/
19  package org.apache.commons.convert;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.Reader;
24  import java.nio.ByteBuffer;
25  import java.nio.charset.Charset;
26  import java.sql.Blob;
27  import java.sql.Clob;
28  import java.text.DecimalFormat;
29  import java.text.SimpleDateFormat;
30  import java.util.Locale;
31  import java.util.UUID;
32  import java.util.regex.Pattern;
33  
34  /** Miscellaneous Converter classes. */
35  public class MiscConverters implements ConverterLoader {
36  
37      public void loadConverters() {
38          Converters.loadContainedConverters(MiscConverters.class);
39          Converters.registerConverter(new GenericToStringConverter<Locale>(Locale.class));
40          Converters.registerConverter(new GenericToStringConverter<UUID>(UUID.class));
41          Converters.registerConverter(new GenericToStringConverter<Pattern>(Pattern.class));
42      }
43  
44      /**
45       * An object that converts a <code>java.sql.Blob</code> to a
46       * byte array.
47       */
48      public static class BlobToByteArray extends AbstractConverter<Blob, byte[]> {
49          public BlobToByteArray() {
50              super(Blob.class, byte[].class);
51          }
52  
53          public byte[] convert(Blob obj) throws ConversionException {
54              InputStream inStream = null;
55              try {
56                  inStream = obj.getBinaryStream();
57                  int blobLength = (int) obj.length();
58                  byte[] byteBuffer = new byte[blobLength];
59                  int offset = 0;
60                  int bytesRead = inStream.read(byteBuffer, offset, blobLength);
61                  while (bytesRead > 0) {
62                      offset += bytesRead;
63                      bytesRead = inStream.read(byteBuffer, offset, blobLength);
64                  }
65                  return byteBuffer;
66              } catch (Exception e) {
67                  throw new ConversionException(e);
68              }
69              finally {
70                  if (inStream != null) {
71                      try {
72                          inStream.close();
73                      } catch (IOException e) {}
74                  }
75              }
76          }
77      }
78  
79      /**
80       * An object that converts a byte array to a
81       * <code>ByteBuffer</code>.
82       */
83      public static class ByteArrayToByteBuffer extends AbstractConverter<byte[], ByteBuffer> {
84          public ByteArrayToByteBuffer() {
85              super(byte[].class, ByteBuffer.class);
86          }
87  
88          public ByteBuffer convert(byte[] obj) throws ConversionException {
89              try {
90                  return ByteBuffer.wrap(obj);
91              } catch (Exception e) {
92                  throw new ConversionException(e);
93              }
94          }
95      }
96  
97      /**
98       * An object that converts a <code>ByteBuffer</code> to a
99       * byte array.
100      */
101     public static class ByteBufferToByteArray extends AbstractConverter<ByteBuffer, byte[]> {
102         public ByteBufferToByteArray() {
103             super(ByteBuffer.class, byte[].class);
104         }
105 
106         public byte[] convert(ByteBuffer obj) throws ConversionException {
107             try {
108                 return obj.hasArray() ? obj.array() : null;
109             } catch (Exception e) {
110                 throw new ConversionException(e);
111             }
112         }
113     }
114 
115     /**
116      * An object that converts a <code>Charset</code> to a
117      * character set name <code>String</code>.
118      */
119     public static class CharsetToString extends AbstractConverter<Charset, String> {
120         public CharsetToString() {
121             super(Charset.class, String.class);
122         }
123 
124         public String convert(Charset obj) throws ConversionException {
125             return obj.name();
126         }
127     }
128 
129     /**
130      * An object that converts a <code>java.sql.Clob</code> to a
131      * <code>String</code>.
132      */
133     public static class ClobToString extends AbstractConverter<Clob, String> {
134         public ClobToString() {
135             super(Clob.class, String.class);
136         }
137 
138         public String convert(Clob obj) throws ConversionException {
139             Reader clobReader = null;
140             try {
141                 clobReader = obj.getCharacterStream();
142                 int clobLength = (int) obj.length();
143                 char[] charBuffer = new char[clobLength];
144                 int offset = 0;
145                 int charsRead = clobReader.read(charBuffer, offset, clobLength);
146                 while (charsRead > 0) {
147                     offset += charsRead;
148                     charsRead = clobReader.read(charBuffer, offset, clobLength);
149                 }
150                 return new String(charBuffer);
151             } catch (Exception e) {
152                 throw new ConversionException(e);
153             }
154             finally {
155                 if (clobReader != null) {
156                     try {
157                         clobReader.close();
158                     } catch (IOException e) {}
159                 }
160             }
161         }
162     }
163 
164     /**
165      * An object that converts a <code>DecimalFormat</code> to a
166      * format pattern <code>String</code>.
167      */
168     public static class DecimalFormatToString extends AbstractConverter<DecimalFormat, String> {
169         public DecimalFormatToString() {
170             super(DecimalFormat.class, String.class);
171         }
172 
173         public String convert(DecimalFormat obj) throws ConversionException {
174             return obj.toPattern();
175         }
176     }
177 
178     public static class EnumToString extends AbstractConverter<Enum<?>, String> {
179         public EnumToString() {
180             super(Enum.class, String.class);
181         }
182 
183         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
184             return Enum.class.isAssignableFrom(sourceClass) && String.class.isAssignableFrom(targetClass);
185         }
186 
187         public String convert(Enum<?> obj) throws ConversionException {
188             return obj.toString();
189         }
190 
191         public Class<? super Enum<?>> getSourceClass() {
192             return null;
193         }
194     }
195 
196     /**
197      * A class used for testing <code>ConverterLoader</code>
198      * implementations.
199      */
200     public static class NotAConverter {
201         protected NotAConverter() {
202             throw new Error("Should not be loaded");
203         }
204     }
205 
206     /**
207      * An object that converts a <code>SimpleDateFormat</code> to a
208      * format pattern <code>String</code>.
209      */
210     public static class SimpleDateFormatToString extends AbstractConverter<SimpleDateFormat, String> {
211         public SimpleDateFormatToString() {
212             super(SimpleDateFormat.class, String.class);
213         }
214 
215         public String convert(SimpleDateFormat obj) throws ConversionException {
216             return obj.toPattern();
217         }
218     }
219 
220     /**
221      * An object that converts a character set name <code>String</code> to a
222      * <code>Charset</code>.
223      */
224     public static class StringToCharset extends AbstractConverter<String, Charset> {
225         public StringToCharset() {
226             super(String.class, Charset.class);
227         }
228 
229         public Charset convert(String obj) throws ConversionException {
230             return Charset.forName(obj);
231         }
232     }
233 
234     /**
235      * An object that converts a format pattern <code>String</code> to a
236      * <code>DecimalFormat</code>.
237      */
238     public static class StringToDecimalFormat extends AbstractConverter<String, DecimalFormat> {
239         public StringToDecimalFormat() {
240             super(String.class, DecimalFormat.class);
241         }
242 
243         public DecimalFormat convert(String obj) throws ConversionException {
244             return new DecimalFormat(obj);
245         }
246     }
247 
248     private static class StringToEnum<E extends Enum<E>> extends AbstractConverter<String, E> {
249         public StringToEnum() {
250             super(String.class, Enum.class);
251         }
252 
253         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
254             return String.class.isAssignableFrom(sourceClass) && Enum.class.isAssignableFrom(targetClass);
255         }
256 
257         public E convert(String obj) throws ConversionException {
258             throw new UnsupportedOperationException();
259         }
260 
261         public Class<? super Enum> getTargetClass() {
262             return null;
263         }
264     }
265 
266     public static class StringToEnumConverterCreator implements ConverterCreator, ConverterLoader {
267         public <S, T> Converter<S, T> createConverter(Class<S> sourceClass, Class<T> targetClass) {
268             if (String.class == sourceClass && Enum.class.isAssignableFrom(targetClass)) {
269                 return Util.cast(new StringToEnum());
270             } else {
271                 return null;
272             }
273         }
274 
275         public void loadConverters() {
276             Converters.registerCreator(this);
277         }
278     }
279 
280     /**
281      * An object that converts a <code>Locale</code> ID
282      * <code>String</code> to a <code>Locale</code>.
283      */
284     public static class StringToLocale extends AbstractConverter<String, Locale> {
285         public StringToLocale() {
286             super(String.class, Locale.class);
287         }
288 
289         public Locale convert(String obj) throws ConversionException {
290             return new Locale(obj);
291         }
292     }
293 
294     /**
295      * An object that converts a pattern <code>String</code> to a
296      * <code>Pattern</code>.
297      */
298     public static class StringToRegexPattern extends AbstractConverter<String, Pattern> {
299         public StringToRegexPattern() {
300             super(String.class, Pattern.class);
301         }
302 
303         public Pattern convert(String obj) throws ConversionException {
304             return Pattern.compile(obj);
305         }
306     }
307 
308     /**
309      * An object that converts a format <code>String</code> to a
310      * <code>SimpleDateFormat</code>.
311      */
312     public static class StringToSimpleDateFormat extends AbstractConverter<String, SimpleDateFormat> {
313         public StringToSimpleDateFormat() {
314             super(String.class, SimpleDateFormat.class);
315         }
316 
317         public SimpleDateFormat convert(String obj) throws ConversionException {
318             return new SimpleDateFormat(obj);
319         }
320     }
321 
322     /**
323      * An object that converts a UUID <code>String</code> to a
324      * <code>UUID</code>.
325      */
326     public static class StringToUUID extends AbstractConverter<String, UUID> {
327         public StringToUUID() {
328             super(String.class, UUID.class);
329         }
330 
331         public UUID convert(String obj) throws ConversionException {
332             return UUID.fromString(obj);
333         }
334     }
335 }