001/* 002@license.text@ 003 */ 004package com.hammurapi.convert; 005 006import java.io.ByteArrayInputStream; 007import java.io.ByteArrayOutputStream; 008import java.io.File; 009import java.io.FileInputStream; 010import java.io.FileOutputStream; 011import java.io.FileReader; 012import java.io.FileWriter; 013import java.io.IOException; 014import java.io.InputStream; 015import java.io.InputStreamReader; 016import java.io.Reader; 017import java.io.StringReader; 018import java.io.StringWriter; 019import java.lang.reflect.Constructor; 020import java.math.BigDecimal; 021import java.net.URL; 022import java.util.ArrayList; 023import java.util.Collection; 024import java.util.Collections; 025import java.util.List; 026 027import com.hammurapi.common.Context; 028 029/** 030 * @author Pavel Vlasov 031 * @version $Revision: 1.7 $ 032 */ 033public class FoundationAtomicConvertersBundle implements AtomicConvertersBundle { 034 035 private List<AtomicConverter<? extends Object,? extends Object>> converters=new ArrayList<AtomicConverter<? extends Object,? extends Object>>(); 036 037 public Collection<AtomicConverter<? extends Object,? extends Object>> getConverters() { 038 return Collections.unmodifiableCollection(converters); 039 } 040 041 /** 042 * Creates new composite converter populated by default with some generic converters. 043 */ 044 @SuppressWarnings("unchecked") 045 public FoundationAtomicConvertersBundle() { 046 addConverter(Number.class, byte.class, "byteValue", null); 047 addConverter(Number.class, double.class, "doubleValue", null); 048 addConverter(Number.class, float.class, "floatValue", null); 049 addConverter(Number.class, int.class, "intValue", null); 050 addConverter(Number.class, long.class, "longValue", null); 051 addConverter(Number.class, short.class, "shortValue", null); 052 053 addConverter(Number.class, Byte.class, "byteValue", null); 054 addConverter(Number.class, Double.class, "doubleValue", null); 055 addConverter(Number.class, Float.class, "floatValue", null); 056 addConverter(Number.class, Integer.class, "intValue", null); 057 addConverter(Number.class, Long.class, "longValue", null); 058 addConverter(Number.class, Short.class, "shortValue", null); 059 060 addConverter(Object.class, String.class, "toString", null); 061 062 063 addConverter(Boolean.class, boolean.class, "booleanValue", null); 064 065 converters.addAll(ReflectionConverter.discoverConstructorConverters(String.class)); 066 converters.addAll(ReflectionConverter.discoverConstructorConverters(Integer.class)); 067 converters.addAll(ReflectionConverter.discoverConstructorConverters(Long.class)); 068 converters.addAll(ReflectionConverter.discoverConstructorConverters(Double.class)); 069 converters.addAll(ReflectionConverter.discoverConstructorConverters(Float.class)); 070 converters.addAll(ReflectionConverter.discoverConstructorConverters(Byte.class)); 071 converters.addAll(ReflectionConverter.discoverConstructorConverters(Short.class)); 072 converters.addAll(ReflectionConverter.discoverConstructorConverters(BigDecimal.class)); 073 074 try { 075 addConverter(File.class, FileReader.class, null, FileReader.class.getConstructor(File.class)); 076 addConverter(File.class, FileInputStream.class, null, FileInputStream.class.getConstructor(File.class)); 077 078 addConverter(File.class, FileOutputStream.class, null, FileOutputStream.class.getConstructor(File.class)); 079 addConverter(File.class, FileWriter.class, null, FileWriter.class.getConstructor(File.class)); 080 081 addConverter(InputStream.class, InputStreamReader.class, null, InputStreamReader.class.getConstructor(InputStream.class)); 082 addConverter(URL.class, InputStream.class, "openStream", null); 083 } catch (SecurityException e) { 084 throw new ConversionException(e); 085 } catch (NoSuchMethodException e) { 086 throw new ConversionException(e); 087 } 088 089 converters.add(new AtomicConverterBase(String.class, boolean.class) { 090 091 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 092 if (source==null) { 093 return Boolean.FALSE; 094 } 095 096 String str = ((String) source).trim(); 097 if (str.length()==0 || "no".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str) || "0".equals(source) || "".equals(source)) { 098 return Boolean.FALSE; 099 } else if ("yes".equalsIgnoreCase(str) || "true".equalsIgnoreCase(str) || "1".equals(source) || "on".equals(source)) { 100 return Boolean.TRUE; 101 } 102 103 return null; 104 } 105 106 }); 107 108 converters.add(new AtomicConverterBase<String,Class>(String.class, Class.class) { 109 110 public Class convert(String source, Converter master, Context context, ClassLoader classLoader) { 111 if (source==null) { 112 return null; 113 } 114 115 try { 116 return classLoader.loadClass(source.trim()); 117 } catch (ClassNotFoundException e) { 118 throw new ConversionException(e); 119 } 120 } 121 122 }); 123 124 converters.add(new AtomicConverterBase<ByteArrayOutputStream,byte[]>(ByteArrayOutputStream.class, byte[].class) { 125 126 @Override 127 public byte[] convert(ByteArrayOutputStream source, Converter master, Context context, ClassLoader classLoader) { 128 if (source==null) { 129 return null; 130 } 131 132 try { 133 source.close(); 134 } catch (IOException e) { 135 throw new ConversionException(e); 136 } 137 138 return source.toByteArray(); 139 } 140 141 }); 142 143 converters.add(new AtomicConverterBase<ByteArrayOutputStream,InputStream>(ByteArrayOutputStream.class, InputStream.class) { 144 145 @Override 146 public InputStream convert(ByteArrayOutputStream source, Converter master, Context context, ClassLoader classLoader) { 147 if (source==null) { 148 return null; 149 } 150 151 try { 152 source.close(); 153 } catch (IOException e) { 154 throw new ConversionException(e); 155 } 156 157 return new ByteArrayInputStream(source.toByteArray()); 158 } 159 160 }); 161 162 converters.add(new AtomicConverterBase<StringWriter,String>(StringWriter.class, String.class) { 163 164 @Override 165 public String convert(StringWriter source, Converter master, Context context, ClassLoader classLoader) { 166 if (source==null) { 167 return null; 168 } 169 170 try { 171 source.close(); 172 } catch (IOException e) { 173 throw new ConversionException(e); 174 } 175 176 return source.toString(); 177 } 178 179 }); 180 181 converters.add(new AtomicConverterBase<StringWriter, Reader>(StringWriter.class, Reader.class) { 182 183 @Override 184 public Reader convert(StringWriter source, Converter master, Context context, ClassLoader classLoader) { 185 if (source==null) { 186 return null; 187 } 188 189 try { 190 source.close(); 191 } catch (IOException e) { 192 throw new ConversionException(e); 193 } 194 195 return new StringReader(source.toString()); 196 } 197 198 }); 199 200 converters.add(new AtomicConverterBase(String.class, byte.class) { 201 202 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 203 return new Byte((String) source); 204 } 205 206 }); 207 208 converters.add(new AtomicConverterBase(String.class, double.class) { 209 210 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 211 return new Double((String) source); 212 } 213 214 }); 215 216 converters.add(new AtomicConverterBase(String.class, float.class) { 217 218 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 219 return new Float((String) source); 220 } 221 222 }); 223 224 225 converters.add(new AtomicConverterBase(String.class, int.class) { 226 227 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 228 return new Integer((String) source); 229 } 230 231 }); 232 233 234 converters.add(new AtomicConverterBase(String.class, long.class) { 235 236 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 237 return new Long((String) source); 238 } 239 240 }); 241 242 243 converters.add(new AtomicConverterBase(String.class, short.class) { 244 245 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 246 return new Short((String) source); 247 } 248 249 }); 250 251 converters.add(new AtomicConverterBase(String.class, Class.class) { 252 253 public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) { 254 try { 255 return Class.forName((String) source); 256 } catch (ClassNotFoundException e) { 257 throw new ConversionException(e); 258 } 259 } 260 261 }); 262 263 } 264 265 private <S, T> void addConverter(Class<S> source, Class<T> target, String accessor, Constructor<? extends T> constructor) { 266 try { 267 converters.add(new ReflectionConverter<S, T>(accessor==null ? null : source.getMethod(accessor), constructor)); 268 } catch (Exception e) { 269 throw new ConversionException(e); 270 } 271 } 272 273}