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.lang.reflect.Array;
22  import java.lang.reflect.Modifier;
23  import java.util.ArrayList;
24  import java.util.Arrays;
25  import java.util.Collection;
26  import java.util.Iterator;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.HashSet;
30  import java.util.Set;
31  
32  /** Collection <code>Converter</code> classes. */
33  public class CollectionConverters implements ConverterLoader {
34  
35      @SuppressWarnings("unchecked")
36      public void loadConverters() {
37          Converters.loadContainedConverters(CollectionConverters.class);
38          Converters.registerConverter(new GenericToStringConverter<Collection>(Collection.class));
39          Converters.registerConverter(new GenericSingletonToList<Map>(Map.class));
40          Converters.registerConverter(new GenericSingletonToSet<Map>(Map.class));
41      }
42  
43      private static class ArrayClassToArrayList<S, T> extends AbstractConverter<S, T> {
44          public ArrayClassToArrayList(Class<S> sourceClass, Class<T> targetClass) {
45              super(sourceClass, targetClass);
46          }
47  
48          public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
49              return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
50          }
51  
52          public T convert(S obj) throws ConversionException {
53              List<Object> list = new ArrayList<Object>();
54              int len = Array.getLength(obj);
55              for (int i = 0; i < len; i++) {
56                  list.add(Array.get(obj, i));
57              }
58              return Util.<T>cast(list);
59          }
60      }
61  
62      private static class ArrayClassToHashSet<S, T> extends AbstractConverter<S, T> {
63          public ArrayClassToHashSet(Class<S> sourceClass, Class<T> targetClass) {
64              super(sourceClass, targetClass);
65          }
66  
67          public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
68              return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
69          }
70  
71          public T convert(S obj) throws ConversionException {
72              Set<Object> set = new HashSet<Object>();
73              int len = Array.getLength(obj);
74              for (int i = 0; i < len; i++) {
75                  set.add(Array.get(obj, i));
76              }
77              return Util.<T>cast(set);
78          }
79      }
80  
81      private static class ArrayClassToList<S, T> extends AbstractConverter<S, T> {
82          public ArrayClassToList(Class<S> sourceClass, Class<T> targetClass) {
83              super(sourceClass, targetClass);
84          }
85  
86          public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
87              return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
88          }
89  
90          @SuppressWarnings("unchecked")
91          public T convert(S obj) throws ConversionException {
92              List<Object> list = null;
93              try {
94                  list = (List<Object>) this.getTargetClass().newInstance();
95              } catch (Exception e) {
96                  throw new ConversionException(e);
97              }
98              int len = Array.getLength(obj);
99              for (int i = 0; i < len; i++) {
100                 list.add(Array.get(obj, i));
101             }
102             return Util.<T>cast(list);
103         }
104     }
105 
106     private static class ArrayClassToSet<S, T> extends AbstractConverter<S, T> {
107         public ArrayClassToSet(Class<S> sourceClass, Class<T> targetClass) {
108             super(sourceClass, targetClass);
109         }
110 
111         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
112             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
113         }
114 
115         @SuppressWarnings("unchecked")
116         public T convert(S obj) throws ConversionException {
117             Set<Object> set = new HashSet<Object>();
118             try {
119                 set = (Set<Object>) this.getTargetClass().newInstance();
120             } catch (Exception e) {
121                 throw new ConversionException(e);
122             }
123             int len = Array.getLength(obj);
124             for (int i = 0; i < len; i++) {
125                 set.add(Array.get(obj, i));
126             }
127             return Util.<T>cast(set);
128         }
129     }
130 
131     public static class ArrayCreator implements ConverterCreator, ConverterLoader {
132         @SuppressWarnings("unchecked")
133         public <S, T> Converter<S, T> createConverter(Class<S> sourceClass, Class<T> targetClass) {
134             if (!targetClass.isArray()) {
135                return null;
136             }
137             if (!Collection.class.isAssignableFrom(sourceClass)) {
138                return null;
139             }
140             if (targetClass.getComponentType() == Boolean.TYPE) {
141                 return Util.cast(new CollectionToBooleanArray(sourceClass, targetClass));
142             }
143             if (targetClass.getComponentType() == Byte.TYPE) {
144                 return Util.cast(new CollectionToByteArray(sourceClass, targetClass));
145             }
146             if (targetClass.getComponentType() == Character.TYPE) {
147                 return Util.cast(new CollectionToCharArray(sourceClass, targetClass));
148             }
149             if (targetClass.getComponentType() == Double.TYPE) {
150                 return Util.cast(new CollectionToDoubleArray(sourceClass, targetClass));
151             }
152             if (targetClass.getComponentType() == Float.TYPE) {
153                 return Util.cast(new CollectionToFloatArray(sourceClass, targetClass));
154             }
155             if (targetClass.getComponentType() == Integer.TYPE) {
156                 return Util.cast(new CollectionToIntArray(sourceClass, targetClass));
157             }
158             if (targetClass.getComponentType() == Long.TYPE) {
159                 return Util.cast(new CollectionToLongArray(sourceClass, targetClass));
160             }
161             if (targetClass.getComponentType() == Short.TYPE) {
162                 return Util.cast(new CollectionToShortArray(sourceClass, targetClass));
163             }
164             return Util.cast(new CollectionToObjectArray(sourceClass, targetClass));
165         }
166 
167         public void loadConverters() {
168             Converters.registerCreator(this);
169         }
170     }
171 
172     /**
173      * An object that converts an array to a <code>List</code>.
174      */
175     public static class ArrayToList<T> extends AbstractConverter<T[], List<T>> {
176         public ArrayToList() {
177             super(Object[].class, List.class);
178         }
179 
180         @Override
181         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
182             if (!sourceClass.isArray()) {
183                 return false;
184             }
185             if (!List.class.isAssignableFrom(targetClass)) {
186                 return false;
187             }
188             if (Object[].class.isAssignableFrom(sourceClass)) {
189                 return true;
190             }
191             return false;
192         }
193 
194         /**
195          * Returns a <code>List</code> that contains the elements in
196          * <code>obj</code>.
197          */
198         public List<T> convert(T[] obj) throws ConversionException {
199             return Arrays.asList(obj);
200         }
201     }
202 
203     @SuppressWarnings("unchecked")
204     private static class CollectionToBooleanArray<T> extends AbstractConverter<Collection, T> {
205         public CollectionToBooleanArray(Class<Collection> sourceClass, Class<T> targetClass) {
206             super(sourceClass, targetClass);
207         }
208 
209         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
210             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
211         }
212 
213         public T convert(Collection obj) throws ConversionException {
214             boolean[] array = new boolean[obj.size()];
215             int index = 0;
216             Iterator<Boolean> iterator = obj.iterator();
217             while (iterator.hasNext()) {
218                 array[index] = iterator.next().booleanValue();
219                 index++;
220             }
221             return Util.<T>cast(array);
222         }
223     }
224 
225     @SuppressWarnings("unchecked")
226     private static class CollectionToByteArray<T> extends AbstractConverter<Collection, T> {
227         public CollectionToByteArray(Class<Collection> sourceClass, Class<T> targetClass) {
228             super(sourceClass, targetClass);
229         }
230 
231         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
232             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
233         }
234 
235         public T convert(Collection obj) throws ConversionException {
236             byte[] array = new byte[obj.size()];
237             int index = 0;
238             Iterator<Byte> iterator = obj.iterator();
239             while (iterator.hasNext()) {
240                 array[index] = iterator.next().byteValue();
241                 index++;
242             }
243             return Util.<T>cast(array);
244         }
245     }
246 
247     @SuppressWarnings("unchecked")
248     private static class CollectionToCharArray<T> extends AbstractConverter<Collection, T> {
249         public CollectionToCharArray(Class<Collection> sourceClass, Class<T> targetClass) {
250             super(sourceClass, targetClass);
251         }
252 
253         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
254             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
255         }
256 
257         public T convert(Collection obj) throws ConversionException {
258             char[] array = new char[obj.size()];
259             int index = 0;
260             Iterator<Character> iterator = obj.iterator();
261             while (iterator.hasNext()) {
262                 array[index] = iterator.next().charValue();
263                 index++;
264             }
265             return Util.<T>cast(array);
266         }
267     }
268 
269     @SuppressWarnings("unchecked")
270     private static class CollectionToDoubleArray<T> extends AbstractConverter<Collection, T> {
271         public CollectionToDoubleArray(Class<Collection> sourceClass, Class<T> targetClass) {
272             super(sourceClass, targetClass);
273         }
274 
275         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
276             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
277         }
278 
279         public T convert(Collection obj) throws ConversionException {
280             double[] array = new double[obj.size()];
281             int index = 0;
282             Iterator<Double> iterator = obj.iterator();
283             while (iterator.hasNext()) {
284                 array[index] = iterator.next().doubleValue();
285                 index++;
286             }
287             return Util.<T>cast(array);
288         }
289     }
290 
291     @SuppressWarnings("unchecked")
292     private static class CollectionToFloatArray<T> extends AbstractConverter<Collection, T> {
293         public CollectionToFloatArray(Class<Collection> sourceClass, Class<T> targetClass) {
294             super(sourceClass, targetClass);
295         }
296 
297         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
298             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
299         }
300 
301         public T convert(Collection obj) throws ConversionException {
302             float[] array = new float[obj.size()];
303             int index = 0;
304             Iterator<Float> iterator = obj.iterator();
305             while (iterator.hasNext()) {
306                 array[index] = iterator.next().floatValue();
307                 index++;
308             }
309             return Util.<T>cast(array);
310         }
311     }
312 
313     @SuppressWarnings("unchecked")
314     private static class CollectionToIntArray<T> extends AbstractConverter<Collection, T> {
315         public CollectionToIntArray(Class<Collection> sourceClass, Class<T> targetClass) {
316             super(sourceClass, targetClass);
317         }
318 
319         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
320             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
321         }
322 
323         public T convert(Collection obj) throws ConversionException {
324             int[] array = new int[obj.size()];
325             int index = 0;
326             Iterator<Integer> iterator = obj.iterator();
327             while (iterator.hasNext()) {
328                 array[index] = iterator.next().intValue();
329                 index++;
330             }
331             return Util.<T>cast(array);
332         }
333     }
334 
335     @SuppressWarnings("unchecked")
336     private static class CollectionToLongArray<T> extends AbstractConverter<Collection, T> {
337         public CollectionToLongArray(Class<Collection> sourceClass, Class<T> targetClass) {
338             super(sourceClass, targetClass);
339         }
340 
341         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
342             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
343         }
344 
345         public T convert(Collection obj) throws ConversionException {
346             long[] array = new long[obj.size()];
347             int index = 0;
348             Iterator<Long> iterator = obj.iterator();
349             while (iterator.hasNext()) {
350                 array[index] = iterator.next().longValue();
351                 index++;
352             }
353             return Util.<T>cast(array);
354         }
355     }
356 
357     @SuppressWarnings("unchecked")
358     private static class CollectionToObjectArray<T> extends AbstractConverter<Collection, T> {
359         public CollectionToObjectArray(Class<Collection> sourceClass, Class<T> targetClass) {
360             super(sourceClass, targetClass);
361         }
362 
363         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
364             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
365         }
366 
367         public T convert(Collection obj) throws ConversionException {
368             return Util.<T>cast(obj.toArray());
369         }
370     }
371 
372     @SuppressWarnings("unchecked")
373     private static class CollectionToShortArray<T> extends AbstractConverter<Collection, T> {
374         public CollectionToShortArray(Class<Collection> sourceClass, Class<T> targetClass) {
375             super(sourceClass, targetClass);
376         }
377 
378         public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) {
379             return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass();
380         }
381 
382         public T convert(Collection obj) throws ConversionException {
383             short[] array = new short[obj.size()];
384             int index = 0;
385             Iterator<Short> iterator = obj.iterator();
386             while (iterator.hasNext()) {
387                 array[index] = iterator.next().shortValue();
388                 index++;
389             }
390             return Util.<T>cast(array);
391         }
392     }
393 
394     public static class ListCreator implements ConverterCreator, ConverterLoader {
395         public <S, T> Converter<S, T> createConverter(Class<S> sourceClass, Class<T> targetClass) {
396             if (!sourceClass.isArray()) {
397                return null;
398             }
399             if (!List.class.isAssignableFrom(targetClass)) {
400                return null;
401             }
402             if (!(sourceClass.getComponentType() instanceof Object)) {
403                 return null;
404             }
405             if ((targetClass.getModifiers() & Modifier.ABSTRACT) == 0) {
406                 return Util.cast(new ArrayClassToList<S, T>(sourceClass, targetClass));
407             } else {
408                 return Util.cast(new ArrayClassToArrayList<S, T>(sourceClass, targetClass));
409             }
410         }
411 
412         public void loadConverters() {
413             Converters.registerCreator(this);
414         }
415     }
416 
417     public static class SetCreator implements ConverterCreator, ConverterLoader {
418         public <S, T> Converter<S, T> createConverter(Class<S> sourceClass, Class<T> targetClass) {
419             if (!sourceClass.isArray()) {
420                return null;
421             }
422             if (!Set.class.isAssignableFrom(targetClass)) {
423                return null;
424             }
425             if (!(sourceClass.getComponentType() instanceof Object)) {
426                 return null;
427             }
428             if ((targetClass.getModifiers() & Modifier.ABSTRACT) == 0) {
429                 return Util.cast(new ArrayClassToSet<S, T>(sourceClass, targetClass));
430             } else {
431                 return Util.cast(new ArrayClassToHashSet<S, T>(sourceClass, targetClass));
432             }
433         }
434 
435         public void loadConverters() {
436             Converters.registerCreator(this);
437         }
438     }
439 }