    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}