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

COVERAGE SUMMARY FOR SOURCE FILE [LocalSynapse.java]

nameclass, %method, %block, %line, %
LocalSynapse.java0%   (0/3)0%   (0/20)0%   (0/486)0%   (0/92)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class LocalSynapse0%   (0/1)0%   (0/8)0%   (0/438)0%   (0/81)
LocalSynapse (boolean, ClassLoader, Converter, Context, long, long, TimeUnit,... 0%   (0/1)0%   (0/38)0%   (0/13)
_invoke (Object, Invocation, ExecutorService, Object [], int, Collection): void 0%   (0/1)0%   (0/95)0%   (0/14)
convert (Object, int): Object 0%   (0/1)0%   (0/44)0%   (0/6)
getParameterTypes (): Class [] 0%   (0/1)0%   (0/4)0%   (0/1)
getReturnType (): Class 0%   (0/1)0%   (0/2)0%   (0/1)
invoke (Object, Invocation, ExecutorService): Future 0%   (0/1)0%   (0/174)0%   (0/32)
preparePropertySet (ExecutorService, PropertySet): PropertySet 0%   (0/1)0%   (0/73)0%   (0/11)
setInvocable (Invocable): void 0%   (0/1)0%   (0/8)0%   (0/3)
     
class LocalSynapse$10%   (0/1)0%   (0/6)0%   (0/21)0%   (0/7)
LocalSynapse$1 (LocalSynapse, Collection): void 0%   (0/1)0%   (0/9)0%   (0/2)
cancel (boolean): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
get (): Iterable 0%   (0/1)0%   (0/3)0%   (0/1)
get (long, TimeUnit): Iterable 0%   (0/1)0%   (0/3)0%   (0/1)
isCancelled (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
isDone (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
     
class LocalSynapse$20%   (0/1)0%   (0/6)0%   (0/27)0%   (0/7)
LocalSynapse$2 (LocalSynapse, Exception): void 0%   (0/1)0%   (0/9)0%   (0/2)
cancel (boolean): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
get (): Iterable 0%   (0/1)0%   (0/6)0%   (0/1)
get (long, TimeUnit): Iterable 0%   (0/1)0%   (0/6)0%   (0/1)
isCancelled (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
isDone (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)

1package com.hammurapi.common.concurrent;
2 
3import java.util.ArrayList;
4import java.util.Arrays;
5import java.util.Collection;
6import java.util.concurrent.ExecutionException;
7import java.util.concurrent.ExecutorService;
8import java.util.concurrent.Future;
9import java.util.concurrent.ScheduledExecutorService;
10import java.util.concurrent.TimeUnit;
11 
12import com.hammurapi.common.Context;
13import com.hammurapi.convert.ConversionException;
14import com.hammurapi.convert.Converter;
15 
16/**
17 * Synapse which operates within JVM.
18 * @author Pavel Vlasov
19 *
20 * @param <R>
21 */
22public class LocalSynapse<C, R> implements Synapse<C, R, String> {
23        
24        // TODO - Option whether to chain property set or not, e.g. no chaining for service calls
25        // TODO - Option to provide sub-set path so the invocable sees only the subset of invoker's property set.
26        
27        private long delay;
28        private long period;
29        private TimeUnit timeUnit;
30        private Invocable<C, R, String> invocable;
31        private ClassLoader classLoader;
32        private Class<?>[] parameterTypes;
33        private boolean async;
34        private boolean chainPropertySet;
35        private String psPrefix;
36        private Converter converter;
37        private Context context;
38 
39//        /**
40//         * Creates synapse without delay and without repetitive execution.
41//         */
42//        public LocalSynapse(boolean async, ClassLoader classLoader) {
43//                this(async,classLoader,0,0,null,true,null);
44//        }
45        
46        public LocalSynapse(
47                        boolean async, 
48                        ClassLoader classLoader, 
49                        Converter converter,
50                        Context context,
51                        long delay, 
52                        long period, 
53                        TimeUnit timeUnit,
54                        boolean chainPropertySet,
55                        String psPrefix) {
56                this.async = async;
57                this.classLoader = classLoader;
58                if (this.classLoader==null) {
59                        this.classLoader = this.getClass().getClassLoader();
60                }
61                this.delay = delay;
62                this.period = period;
63                this.timeUnit = timeUnit;        
64                this.chainPropertySet = chainPropertySet;
65                this.psPrefix = psPrefix;
66                this.converter = converter;
67                this.context = context;
68        }
69        
70        @Override
71        public void setInvocable(Invocable<C, R, String> invocable) {
72                this.invocable = invocable;
73                this.parameterTypes = invocable.getParameterTypes();
74        }
75        
76        @Override
77        public Future<Iterable<R>> invoke(final C context, final Invocation<String> invocation, ExecutorService executorService) {
78                // TODO - control invocation chain, substitute invocation and add invocation chain element.
79                // Synchronous invocation
80                if (async || executorService==null) {
81                        if (timeUnit!=null && (delay>0 || period>0)) {
82                                throw new InvocationException("Cannot schedule invocations");
83                        }
84                        
85                        final Collection<R> ret = new ArrayList<R>();
86                        try {
87                                boolean hasArgumentIterators = false;
88                                boolean needsConversion = false;
89                                int idx=0;
90                                for (Object arg: invocation.getArguments()) {
91                                        if (arg instanceof ArgumentIterator) {
92                                                hasArgumentIterators = true;
93                                                break;
94                                        }                                        
95                                        if (arg!=null && !parameterTypes[idx].isInstance(arg)) {
96                                                needsConversion = true;
97                                        }
98                                        ++idx;
99                                }
100                                
101                                if (hasArgumentIterators) {
102                                        Object[] args = Arrays.copyOf(invocation.getArguments(), invocation.getArguments().length);
103                                        _invoke(context, invocation, executorService, args, 0, ret);                                         
104                                } else {
105                                        if (needsConversion) {
106                                                final Object[] args = Arrays.copyOf(invocation.getArguments(), invocation.getArguments().length);
107                                                for (int i=0; i<args.length; ++i) {
108                                                        args[i] = convert(args[i], i);
109                                                }
110                                                InvocationImpl<String> iv = new InvocationImpl<String>(invocation);
111                                                iv.setPropertySet(preparePropertySet(executorService, invocation.getPropertySet()));
112                                                ret.add(invocable.invoke(context, iv, executorService));
113                                        } else {
114                                                ret.add(invocable.invoke(context, invocation, executorService));
115                                        }
116                                }
117                                
118                                return new Future<Iterable<R>>() {
119        
120                                        @Override
121                                        public boolean cancel(boolean mayInterruptIfRunning) {
122                                                return false;
123                                        }
124        
125                                        @Override
126                                        public boolean isCancelled() {
127                                                return false;
128                                        }
129        
130                                        @Override
131                                        public boolean isDone() {
132                                                return true;
133                                        }
134        
135                                        @Override
136                                        public Iterable<R> get() {
137                                                return ret; 
138                                        }
139        
140                                        @Override
141                                        public Iterable<R> get(long timeout, TimeUnit unit) {
142                                                return ret;  
143                                        }                                
144                                };
145                        } catch (final Exception e) {
146                                return new Future<Iterable<R>>() {
147                                        
148                                        @Override
149                                        public boolean cancel(boolean mayInterruptIfRunning) {
150                                                return false;
151                                        }
152        
153                                        @Override
154                                        public boolean isCancelled() {
155                                                return false;
156                                        }
157        
158                                        @Override
159                                        public boolean isDone() {
160                                                return true;
161                                        }
162        
163                                        @Override
164                                        public Iterable<R> get() throws ExecutionException {
165                                                throw new ExecutionException(e); 
166                                        }
167        
168                                        @Override
169                                        public Iterable<R> get(long timeout, TimeUnit unit) throws ExecutionException {
170                                                throw new ExecutionException(e); 
171                                        }                                
172                                };
173                                
174                        }
175                }
176                
177                if (timeUnit==null || (delay<=0 && period<=0)) {
178                        // TODO - Asynchronous invocations.
179                        
180                        
181                }
182                
183                if (!(executorService instanceof ScheduledExecutorService)) {
184                        throw new InvocationException("Cannot schedule invocations - executor service is not a ScheduledExecutorService");
185                }
186                
187                // TODO Scheduled invocations.
188                return null;
189        }
190 
191        private PropertySet<String> preparePropertySet(ExecutorService executorService, PropertySet<String> propertySet) {
192                if (propertySet==null) {
193                        if (chainPropertySet) {
194                                return new LocalStringPropertySet(executorService, converter, context, classLoader);
195                        }
196                        return null;
197                }
198                
199                if (psPrefix!=null) {
200                        if (chainPropertySet) {
201                                return new LocalStringPropertySet(executorService, converter, context, classLoader, propertySet.subset(psPrefix));
202                        }
203                        return propertySet.subset(psPrefix);                        
204                }
205                if (chainPropertySet) {
206                        return new LocalStringPropertySet(executorService, converter, context, classLoader, propertySet);
207                }
208                return propertySet;                        
209        }
210 
211        /**
212         * Iterates over argument iterators
213         * @param invocation
214         * @param executorService
215         * @param args
216         * @param i Current argument index
217         */
218        private void _invoke(final C context, final Invocation<String> invocation, ExecutorService executorService, final Object[] args, int idx, Collection<R> collector) {
219                if (idx==args.length) {
220                        InvocationImpl<String> iv = new InvocationImpl<String>(invocation);
221                        iv.setArguments(args);
222                        iv.setPropertySet(preparePropertySet(executorService, invocation.getPropertySet()));
223                        
224                        collector.add(invocable.invoke(context, iv, executorService));
225                } else {
226                        if (args[idx] instanceof ArgumentIterator) {
227                                ArgumentIterator<Object> ai = (ArgumentIterator<Object>) args[idx];
228                                while (ai.hasNext()) {
229                                        args[idx] = convert(ai.next(), idx);
230                                        _invoke(context, invocation, executorService, args, idx+1, collector);
231                                }
232                        } else {
233                                if (args[idx]!=null && !parameterTypes[idx].isInstance(args[idx])) {
234                                        args[idx] = convert(args[idx], idx);
235                                }
236                                _invoke(context, invocation, executorService, args, idx+1, collector);
237                        }
238                }
239                
240        }
241        
242        private Object convert(Object arg, int idx) {
243                if (arg==null || parameterTypes[idx].isInstance(arg)) {
244                        return null;
245                }
246                Object ret = converter.convert(arg, parameterTypes[idx], context);
247                if (ret==null) {
248                        throw new ConversionException("Cannot convert "+arg+" to "+parameterTypes[idx]);
249                }
250                return ret;
251        }
252 
253        @Override
254        public Class<Future<Iterable<R>>> getReturnType() {
255                // Strange, but doesn't compile otherwise.
256                return (Class<Future<Iterable<R>>>) (Class) Future.class;
257        }
258 
259        @Override
260        public Class<?>[] getParameterTypes() {
261                return invocable.getParameterTypes();
262        }                
263 
264}

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