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

COVERAGE SUMMARY FOR SOURCE FILE [ReflectiveEventHandler.java]

nameclass, %method, %block, %line, %
ReflectiveEventHandler.java100% (2/2)93%  (14/15)86%  (250/290)92%  (49/53)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ReflectiveEventHandler100% (1/1)92%  (12/13)85%  (235/275)92%  (47/51)
getInstance (): Object 0%   (0/1)0%   (0/3)0%   (0/1)
post (EventDispatchContext, Object []): void 100% (1/1)82%  (116/142)90%  (19/21)
ReflectiveEventHandler (Object, int, Method, Class [], Handler, Class, Predic... 100% (1/1)84%  (59/70)94%  (16/17)
consumes (): boolean 100% (1/1)100% (4/4)100% (1/1)
getCardinality (): int 100% (1/1)100% (4/4)100% (1/1)
getContext (): Object 100% (1/1)100% (3/3)100% (1/1)
getMethod (): Method 100% (1/1)100% (3/3)100% (1/1)
getMode (): EventHandlerBase$Mode 100% (1/1)100% (4/4)100% (1/1)
getPredicate (): Predicate 100% (1/1)100% (3/3)100% (1/1)
getPriority (): Integer 100% (1/1)100% (5/5)100% (1/1)
isOneOff (): boolean 100% (1/1)100% (4/4)100% (1/1)
reset (): void 100% (1/1)100% (9/9)100% (3/3)
toString (): String 100% (1/1)100% (21/21)100% (1/1)
     
class ReflectiveEventHandler$1100% (1/1)100% (2/2)100% (15/15)100% (3/3)
ReflectiveEventHandler$1 (ReflectiveEventHandler, EventDispatchContext): void 100% (1/1)100% (9/9)100% (2/2)
invoke (Object, Method, Object []): Object 100% (1/1)100% (6/6)100% (1/1)

1package com.hammurapi.eventbus;
2 
3import java.lang.reflect.InvocationHandler;
4import java.lang.reflect.Method;
5import java.lang.reflect.Proxy;
6 
7import com.hammurapi.extract.CommutativeAnd;
8import com.hammurapi.extract.Predicate;
9import com.hammurapi.extract.True;
10 
11public final class ReflectiveEventHandler<E, C, H extends EventBus.Handle<E,Integer,C>, S extends EventStore<E,Integer,C,H,S>> implements EventHandler<E, Integer, C, H, S> {
12        private final C instance;
13        private final int offset;
14        private final Method mthd;
15        private final Class<E>[] pt;
16        private final Handler ha;
17        private Class<E> eventType;
18        private Class<?> contextType;
19        private Predicate<E,C> predicate;
20 
21        ReflectiveEventHandler(
22                        C instance, 
23                        int offset, 
24                        Method mthd,
25                        Class<E>[] pt, 
26                        Handler ha, 
27                        Class<E> eventType,
28                        Predicate<E,C>... predicates) {
29                
30                this.instance = instance;
31                this.offset = offset;
32                this.mthd = mthd;
33                this.pt = pt;
34                this.ha = ha;
35                this.eventType = eventType;
36                if (offset>0) {
37                        contextType=mthd.getParameterTypes()[0];
38                        if (!contextType.isInterface()) {
39                                throw new IllegalArgumentException("Event dispatch context parameter type should be interface: "+mthd);                                
40                        }
41                }
42                
43                if (predicates.length==0) {
44                        predicate = True.getInstance();
45                } else if (predicates.length==1) {
46                        predicate = predicates[0];
47                } else {
48                        predicate = new CommutativeAnd<E,C>(0, null, predicates).normalize();
49                }                        
50        }
51        
52        public Method getMethod() {
53                return mthd;
54        }
55        
56        public C getInstance() {
57                return instance;
58        }
59 
60        @Override
61        public boolean consumes() {
62                return ha.consumes();
63        }
64 
65        @Override
66        public int getCardinality() {
67                return pt.length;
68        }
69 
70        @Override
71        public C getContext() {
72                return instance;
73        }
74 
75        @Override
76        public Integer getPriority() {
77                return ha.priority();
78        }
79 
80        @SuppressWarnings("unchecked")
81        @Override
82        public void post(final EventDispatchContext<E, Integer, C, H, S> context, E... events) {
83                int expectedEventsLength = pt.length;
84                if (events.length!=expectedEventsLength) {
85                        throw new EventDispatchException("Expected "+expectedEventsLength+" input events for method "+mthd+", got "+events.length);
86                }
87                Object[] args = new Object[pt.length+offset];
88                if (offset>0) {
89                        if (contextType.isInstance(context)) {
90                                args[0] = context;
91                        } else {
92                                // Dynamic proxy for event dispatch context.
93                                InvocationHandler ih = new InvocationHandler() {
94                                        
95                                        @Override
96                                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
97                                                return method.invoke(context, args);
98                                        }
99                                };
100                                
101                                Class<?>[] contextInterfaces = context.getClass().getInterfaces();
102                                Class<?>[] proxyInterfaces = new Class[contextInterfaces.length+1];
103                                System.arraycopy(contextInterfaces, 0, proxyInterfaces, 0, contextInterfaces.length);
104                                proxyInterfaces[contextInterfaces.length] = contextType;
105                                args[0] = Proxy.newProxyInstance(contextType.getClassLoader(), proxyInterfaces, ih);
106                        }
107                }
108                for (int i=0; i<events.length; ++i) {
109                        args[i+offset] = events[i];
110                }
111                try {
112                        Object toPost = mthd.invoke(instance, args);
113                        if (eventType.isInstance(toPost)) {
114                                context.post((E) toPost);
115                        }
116                } catch (Exception e) {
117                        throw new EventDispatchException("Failed to invoke event handler method "+mthd+": "+e, e);
118                }
119        }
120 
121        @Override
122        public void reset() {
123                if (instance instanceof Resettable) {
124                        ((Resettable) instance).reset();
125                }                                                
126        }
127 
128        @Override
129        public String toString() {
130                return "Reflective Handler(cardinality = "+getCardinality()+", method = "+mthd+", instance = "+instance+")";
131        }
132 
133        @Override
134        public boolean isOneOff() {
135                return ha.oneOff();
136        }
137 
138        @Override
139        public com.hammurapi.eventbus.EventHandlerBase.Mode getMode() {
140                return ha.mode();
141        }
142 
143        @Override
144        public Predicate<E, C> getPredicate() {
145                return predicate;
146        }
147}

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