001    /*
002    @license.text@
003     */
004    package com.hammurapi.convert;
005    
006    import java.io.File;
007    import java.io.FileInputStream;
008    import java.io.FileReader;
009    import java.io.InputStream;
010    import java.io.InputStreamReader;
011    import java.io.Reader;
012    import java.lang.reflect.Constructor;
013    import java.math.BigDecimal;
014    import java.net.URL;
015    import java.util.ArrayList;
016    import java.util.Collection;
017    import java.util.Collections;
018    import java.util.List;
019    
020    import com.hammurapi.util.Context;
021    
022    
023    
024    /**
025     * @author Pavel Vlasov
026     * @version $Revision: 1.7 $
027     */
028    public class FoundationAtomicConvertersBundle implements AtomicConvertersBundle {
029    
030            private List<AtomicConverter<? extends Object,? extends Object>> converters=new ArrayList<AtomicConverter<? extends Object,? extends Object>>();
031            
032            public Collection<AtomicConverter<? extends Object,? extends Object>> getConverters() {
033                    return Collections.unmodifiableCollection(converters);
034            }
035    
036        /**
037         * Creates new composite converter populated by default with some generic converters.
038         */
039            @SuppressWarnings("unchecked")
040            public FoundationAtomicConvertersBundle() {
041                    addConverter(Number.class, byte.class, "byteValue", null);
042                    addConverter(Number.class, double.class, "doubleValue", null);
043                    addConverter(Number.class, float.class, "floatValue", null);
044                    addConverter(Number.class, int.class, "intValue", null);
045                    addConverter(Number.class, long.class, "longValue", null);
046                    addConverter(Number.class, short.class, "shortValue", null);
047                    
048                    addConverter(Number.class, Byte.class, "byteValue", null);
049                    addConverter(Number.class, Double.class, "doubleValue", null);
050                    addConverter(Number.class, Float.class, "floatValue", null);
051                    addConverter(Number.class, Integer.class, "intValue", null);
052                    addConverter(Number.class, Long.class, "longValue", null);
053                    addConverter(Number.class, Short.class, "shortValue", null);
054                    
055                    addConverter(Boolean.class, boolean.class, "booleanValue", null);
056                    
057                    converters.addAll(ReflectionConverter.discoverConstructorConverters(String.class));
058                    converters.addAll(ReflectionConverter.discoverConstructorConverters(Integer.class));
059                    converters.addAll(ReflectionConverter.discoverConstructorConverters(Long.class));
060                    converters.addAll(ReflectionConverter.discoverConstructorConverters(Double.class));
061                    converters.addAll(ReflectionConverter.discoverConstructorConverters(Float.class));
062                    converters.addAll(ReflectionConverter.discoverConstructorConverters(Byte.class));
063                    converters.addAll(ReflectionConverter.discoverConstructorConverters(Short.class));
064                    converters.addAll(ReflectionConverter.discoverConstructorConverters(BigDecimal.class));
065                    
066                    try {
067                            addConverter(File.class, Reader.class, null, FileReader.class.getConstructor(File.class));
068                            addConverter(File.class, InputStream.class, null, FileInputStream.class.getConstructor(File.class));
069                            addConverter(InputStream.class, Reader.class, null, InputStreamReader.class.getConstructor(InputStream.class));
070                            addConverter(URL.class, InputStream.class, "openStream", null);
071                    } catch (SecurityException e) {
072                            throw new ConversionException(e);
073                    } catch (NoSuchMethodException e) {
074                            throw new ConversionException(e);
075                    }
076                    
077                    converters.add(new AtomicConverterBase(String.class, boolean.class) {
078    
079                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
080                                    if (source==null) {
081                                            return Boolean.FALSE;
082                                    }
083                                    
084                                    String str = ((String) source).trim();
085                                    if (str.length()==0 || "no".equalsIgnoreCase(str) || "false".equalsIgnoreCase(str) || "0".equals(source) || "".equals(source)) {
086                                            return Boolean.FALSE;
087                                    } else if ("yes".equalsIgnoreCase(str) || "true".equalsIgnoreCase(str) || "1".equals(source) || "on".equals(source)) {
088                                            return Boolean.TRUE;
089                                    } 
090                                    
091                                    return null;
092                            }
093                            
094                    });
095                    
096                    converters.add(new AtomicConverterBase<String,Class>(String.class, Class.class) {
097    
098                            public Class convert(String source, Converter master, Context context, ClassLoader classLoader) {
099                                    if (source==null) {
100                                            return null;
101                                    }
102                                    
103                                    try {
104                                            return classLoader.loadClass(source.trim());
105                                    } catch (ClassNotFoundException e) {
106                                            throw new ConversionException(e);
107                                    }
108                            }
109                            
110                    });
111                    
112                    converters.add(new AtomicConverterBase(String.class, byte.class) {
113    
114                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
115                                    return new Byte((String) source);
116                            }
117                            
118                    });
119                    
120                    converters.add(new AtomicConverterBase(String.class, double.class) {
121    
122                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
123                                    return new Double((String) source);
124                            }
125                            
126                    });
127                    
128                    converters.add(new AtomicConverterBase(String.class, float.class) {
129    
130                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
131                                    return new Float((String) source);
132                            }
133                            
134                    });
135                    
136    
137                    converters.add(new AtomicConverterBase(String.class, int.class) {
138    
139                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
140                                    return new Integer((String) source);
141                            }
142                            
143                    });
144                    
145    
146                    converters.add(new AtomicConverterBase(String.class, long.class) {
147    
148                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
149                                    return new Long((String) source);
150                            }
151                            
152                    });
153                    
154    
155                    converters.add(new AtomicConverterBase(String.class, short.class) {
156    
157                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
158                                    return new Short((String) source);
159                            }
160                            
161                    });
162                                    
163                    converters.add(new AtomicConverterBase(String.class, Class.class) {
164    
165                            public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
166                                    try {
167                                            return Class.forName((String) source);
168                                    } catch (ClassNotFoundException e) {
169                                            throw new ConversionException(e);
170                                    }
171                            }
172                            
173                    });             
174                    
175        }
176                    
177            private <S, T> void  addConverter(Class<S> source, Class<T> target, String accessor, Constructor<? extends T> constructor) {
178                    try {
179                            converters.add(new ReflectionConverter<S, T>(accessor==null ? null : source.getMethod(accessor), constructor));
180                    } catch (Exception e) {
181                            throw new ConversionException(e);
182                    }
183            }
184                    
185    }