001 /******************************************************************************* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 *******************************************************************************/ 019 package org.apache.commons.convert; 020 021 import java.lang.reflect.Array; 022 import java.lang.reflect.Modifier; 023 import java.util.ArrayList; 024 import java.util.Arrays; 025 import java.util.Collection; 026 import java.util.Iterator; 027 import java.util.List; 028 import java.util.Map; 029 import java.util.HashSet; 030 import java.util.Set; 031 032 /** Collection <code>Converter</code> classes. */ 033 public class CollectionConverters implements ConverterLoader { 034 035 @SuppressWarnings("unchecked") 036 public void loadConverters() { 037 Converters.loadContainedConverters(CollectionConverters.class); 038 Converters.registerConverter(new GenericToStringConverter<Collection>(Collection.class)); 039 Converters.registerConverter(new GenericSingletonToList<Map>(Map.class)); 040 Converters.registerConverter(new GenericSingletonToSet<Map>(Map.class)); 041 } 042 043 private static class ArrayClassToArrayList<S, T> extends AbstractConverter<S, T> { 044 public ArrayClassToArrayList(Class<S> sourceClass, Class<T> targetClass) { 045 super(sourceClass, targetClass); 046 } 047 048 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 049 return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass(); 050 } 051 052 public T convert(S obj) throws ConversionException { 053 List<Object> list = new ArrayList<Object>(); 054 int len = Array.getLength(obj); 055 for (int i = 0; i < len; i++) { 056 list.add(Array.get(obj, i)); 057 } 058 return Util.<T>cast(list); 059 } 060 } 061 062 private static class ArrayClassToHashSet<S, T> extends AbstractConverter<S, T> { 063 public ArrayClassToHashSet(Class<S> sourceClass, Class<T> targetClass) { 064 super(sourceClass, targetClass); 065 } 066 067 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 068 return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass(); 069 } 070 071 public T convert(S obj) throws ConversionException { 072 Set<Object> set = new HashSet<Object>(); 073 int len = Array.getLength(obj); 074 for (int i = 0; i < len; i++) { 075 set.add(Array.get(obj, i)); 076 } 077 return Util.<T>cast(set); 078 } 079 } 080 081 private static class ArrayClassToList<S, T> extends AbstractConverter<S, T> { 082 public ArrayClassToList(Class<S> sourceClass, Class<T> targetClass) { 083 super(sourceClass, targetClass); 084 } 085 086 public boolean canConvert(Class<?> sourceClass, Class<?> targetClass) { 087 return sourceClass == this.getSourceClass() && targetClass == this.getTargetClass(); 088 } 089 090 @SuppressWarnings("unchecked") 091 public T convert(S obj) throws ConversionException { 092 List<Object> list = null; 093 try { 094 list = (List<Object>) this.getTargetClass().newInstance(); 095 } catch (Exception e) { 096 throw new ConversionException(e); 097 } 098 int len = Array.getLength(obj); 099 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 }