    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}