EMMA Coverage Report (generated Thu Jan 20 11:39:44 EST 2011)
[all classes][com.hammurapi.convert]

COVERAGE SUMMARY FOR SOURCE FILE [ReflectionConverter.java]

nameclass, %method, %block, %line, %
ReflectionConverter.java100% (1/1)86%  (6/7)65%  (149/228)84%  (31/37)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ReflectionConverter100% (1/1)86%  (6/7)65%  (149/228)84%  (31/37)
toString (): String 0%   (0/1)0%   (0/31)0%   (0/1)
convert (Object, Converter, Context, ClassLoader): Object 100% (1/1)43%  (30/70)56%  (5/9)
discoverConstructorConverters (Class): Collection 100% (1/1)89%  (63/71)92%  (11/12)
<static initializer> 100% (1/1)100% (5/5)100% (2/2)
ReflectionConverter (Method, Constructor): void 100% (1/1)100% (45/45)100% (11/11)
getSourceType (): Class 100% (1/1)100% (3/3)100% (1/1)
getTargetType (): Class 100% (1/1)100% (3/3)100% (1/1)

1package com.hammurapi.convert;
2 
3import java.lang.reflect.Constructor;
4import java.lang.reflect.Method;
5import java.util.ArrayList;
6import java.util.Collection;
7import java.util.logging.Level;
8import java.util.logging.Logger;
9 
10import com.hammurapi.common.Context;
11 
12 
13/**
14 * Converts one type to another using accessor/constructor combination.
15 * @author Pavel
16 *
17 */
18public class ReflectionConverter<S, T> implements AtomicConverter<S, T> {
19        private static final Logger logger = Logger.getLogger(ReflectionConverter.class.getName());
20        
21        Method accessor;
22        Constructor<? extends T> constructor;
23        private Class<? extends T> targetType;
24        private Class<S> sourceType;
25        private boolean singleArg;
26        
27        /**
28         * @param accessor Source object method to invoke to get target type or
29         * constructor parameter for the target type. If it is null, then source itself
30         * is passed to constructor. One of parameters may be null, but not both.
31         * @param constructor Target class constructor which takes one parameter, either
32         * source type or return type of source type accessor.
33         */
34        @SuppressWarnings("unchecked")
35        public ReflectionConverter(Method accessor, Constructor<? extends T> constructor) {
36                super();
37                this.accessor = accessor;
38                this.constructor = constructor;
39                singleArg = constructor!=null && constructor.getParameterTypes().length==1;
40                if (accessor==null) {
41                        sourceType = (Class<S>) constructor.getParameterTypes()[0];
42                } else {
43                        sourceType = (Class<S>) accessor.getDeclaringClass();
44                }
45                
46                if (constructor==null) {
47                        targetType = (Class<T>) accessor.getReturnType();
48                } else {
49                        targetType = constructor.getDeclaringClass();
50                }                
51        }
52        
53        @SuppressWarnings("unchecked")
54        public T convert(S source, Converter master, Context context, ClassLoader classLoader) {
55                try {
56                        Object param = accessor==null ? source : accessor.invoke(source);
57                        if (constructor==null) {
58                                return (T) param;
59                        }
60                        
61                        if (singleArg) {
62                                return constructor.newInstance(new Object[] {param});
63                        }
64                        
65                        return constructor.newInstance(new Object[] {param, context});
66                } catch (Exception e) {
67                        logger.log(Level.FINE, "Cannot convert "+source.getClass().getName()+" to " + constructor.getDeclaringClass()+": "+e, e);
68                        return null;
69                }
70        }
71 
72        public Class<S> getSourceType() {
73                return sourceType;
74        }
75 
76        public Class<? extends T> getTargetType() {
77                return targetType;
78        }
79        
80        /**
81         * Discovers constructor conversions.
82         * @param target Target type
83         * @return Collection of discovered converters.
84         */
85        @SuppressWarnings("unchecked")
86        public static <T> Collection<ReflectionConverter<?, T>> discoverConstructorConverters(Class<T> target) {
87                Collection<ReflectionConverter<?, T>> ret=new ArrayList<ReflectionConverter<?, T>>();
88                if (!target.isInterface()) {
89                        for (int i=0, cc=target.getConstructors().length; i<cc; i++) {
90                                Constructor<?> constructor = target.getConstructors()[i];
91                                Class<?>[] parameterTypes = constructor.getParameterTypes();
92                                if (parameterTypes.length==1 && !target.isAssignableFrom(parameterTypes[0])) {
93                                        
94                                        ret.add(new ReflectionConverter(null, constructor));
95                                } else if (parameterTypes.length==2
96                                                && !target.isAssignableFrom(parameterTypes[0])
97                                                && Context.class.equals(parameterTypes[1])) {
98                                                
99                                        ret.add(new ReflectionConverter(null, constructor));
100                                }
101                        }
102                }
103                return ret;
104        }        
105        
106        public String toString() {
107                return this.getClass().getName() + " ("+sourceType+" -> "+targetType+", accessor: "+accessor+", constructor: "+constructor+")";
108        }
109        
110}

[all classes][com.hammurapi.convert]
EMMA 2.0.5312 EclEmma Fix 2 (C) Vladimir Roubtsov