001/*
002@license.text@
003 */
004package com.hammurapi.convert;
005
006import java.lang.reflect.Method;
007import java.util.ArrayList;
008import java.util.Collection;
009
010import com.hammurapi.common.Context;
011
012
013
014/**
015 * @author Pavel Vlasov
016 */
017public abstract class AbstractReflectiveAtomicConvertersBundle implements AtomicConvertersBundle {
018
019        @SuppressWarnings("unchecked")
020        @Override
021        public Collection<AtomicConverter<? extends Object, ? extends Object>> getConverters() {
022                Collection<AtomicConverter<? extends Object, ? extends Object>> ret = new ArrayList<AtomicConverter<? extends Object,? extends Object>>();
023                Z: for (final Method m: this.getClass().getMethods()) {                                         
024                        Class<?>[] pta = m.getParameterTypes();
025                        Class<Object> targetType = (Class<Object>) m.getReturnType();
026                        if (m.getAnnotation(ConverterMethod.class)!=null && !void.class.equals(targetType) && pta.length>0) {
027                                for (int i=1; i<pta.length; ++i) {
028                                        if (!(Context.class.equals(pta[i]) || Converter.class.equals(pta[i]))) {
029                                                continue Z;
030                                        }
031                                }
032                                Class<Object> sourceType = (Class<Object>) pta[0];
033                                AtomicConverterBase<Object, Object> converter = new AtomicConverterBase<Object, Object>(sourceType, targetType) {
034                                        
035                                        @Override
036                                        public Object convert(Object source, Converter master, Context context, ClassLoader classLoader) {
037                                                try {
038                                                        Class<?>[] pt = m.getParameterTypes();
039                                                        Object[] args = new Object[pt.length];
040                                                        args[0] = source;
041                                                        for (int i=1; i<pt.length; ++i) {
042                                                                if (Context.class.equals(pt[i])) {
043                                                                        args[i] = context;
044                                                                } else if (Converter.class.equals(pt[i])) {
045                                                                        args[i] = master;
046                                                                }                                                                                       
047                                                        }
048                                                        return m.invoke(AbstractReflectiveAtomicConvertersBundle.this, args);
049                                                } catch (Exception e) {
050                                                        throw new ConversionException(e);
051                                                }
052                                        }
053                                };
054                                ret.add(converter);
055                        }
056                }
057                return ret;
058        }
059
060                
061}