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

COVERAGE SUMMARY FOR SOURCE FILE [JavaExtractorFactory.java]

nameclass, %method, %block, %line, %
JavaExtractorFactory.java100% (1/1)100% (5/5)72%  (816/1137)72%  (100.8/140)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class JavaExtractorFactory100% (1/1)100% (5/5)72%  (816/1137)72%  (100.8/140)
createPredicate (String, String, String [], Class [], Class, ClassLoader): Pr... 100% (1/1)9%   (6/70)17%  (2/12)
createExtractor (String, String, String [], Class [], Class, Class, ClassLoad... 100% (1/1)71%  (49/69)67%  (8/12)
createExtractor (double, TimeUnit, Java$Atom, String [], Class [], Class, Cla... 100% (1/1)76%  (748/985)77%  (85.8/111)
JavaExtractorFactory (): void 100% (1/1)100% (3/3)100% (1/1)
compose (Predicate, Collection): Extractor 100% (1/1)100% (10/10)100% (4/4)

1package com.hammurapi.extract.java;
2 
3import java.io.StringReader;
4import java.lang.reflect.InvocationTargetException;
5import java.util.ArrayList;
6import java.util.Collection;
7import java.util.concurrent.TimeUnit;
8import java.util.concurrent.atomic.AtomicReference;
9 
10import org.codehaus.commons.compiler.CompileException;
11import org.codehaus.janino.ExpressionEvaluator;
12import org.codehaus.janino.Java;
13import org.codehaus.janino.Java.Atom;
14import org.codehaus.janino.Java.BinaryOperation;
15import org.codehaus.janino.Java.Instanceof;
16import org.codehaus.janino.Java.Literal;
17import org.codehaus.janino.Java.MethodInvocation;
18import org.codehaus.janino.Java.ParenthesizedExpression;
19import org.codehaus.janino.Java.Rvalue;
20import org.codehaus.janino.Java.Type;
21import org.codehaus.janino.Java.UnaryOperation;
22import org.codehaus.janino.Parser;
23import org.codehaus.janino.Scanner;
24 
25import antlr.RecognitionException;
26import antlr.TokenStreamException;
27 
28import com.hammurapi.extract.Add;
29import com.hammurapi.extract.And;
30import com.hammurapi.extract.CommutativeAnd;
31import com.hammurapi.extract.CommutativeOr;
32import com.hammurapi.extract.CompositePredicate;
33import com.hammurapi.extract.Constant;
34import com.hammurapi.extract.Divide;
35import com.hammurapi.extract.Equal;
36import com.hammurapi.extract.Extractor;
37import com.hammurapi.extract.ExtractorException;
38import com.hammurapi.extract.ExtractorFactory;
39import com.hammurapi.extract.ExtractorUtil;
40import com.hammurapi.extract.False;
41import com.hammurapi.extract.GreaterEqual;
42import com.hammurapi.extract.GreaterThan;
43import com.hammurapi.extract.InstanceOfPredicate;
44import com.hammurapi.extract.LessEqual;
45import com.hammurapi.extract.LessThan;
46import com.hammurapi.extract.Multiply;
47import com.hammurapi.extract.Not;
48import com.hammurapi.extract.NotEqual;
49import com.hammurapi.extract.Or;
50import com.hammurapi.extract.Predicate;
51import com.hammurapi.extract.Subtract;
52import com.hammurapi.extract.True;
53 
54public class JavaExtractorFactory implements ExtractorFactory {
55 
56        private static final String LOGICAL_OR = "||";
57        private static final String LOGICAL_AND = "&&";
58        private static final String COMMUTATIVE_AND_MACRO = "AND";
59        private static final String COMMUTATIVE_OR_MACRO = "OR";
60        private static final String COST_MACRO = "COST";
61        
62        @SuppressWarnings("unchecked")
63        @Override
64        public <T, V, C> Extractor<T, V, C> createExtractor(
65                        String language,
66                        String code, 
67                        String[] parameterNames, 
68                        Class<T>[] parameterTypes,
69                        Class<V> valueType, 
70                        Class<C> contextType, 
71                        ClassLoader classLoader) {
72                
73                if ("java".equals(language)) {
74                        try {
75                                Parser jnp = new Parser(new Scanner("Expression "+code, new StringReader(code)));
76                                Atom expr = jnp.parseExpression();                                
77                                Extractor<T, V, C> ret = createExtractor(0, null, expr, parameterNames, parameterTypes, valueType,        contextType, classLoader, null, null);
78                                if (ret instanceof CompositePredicate) {
79                                        return ((CompositePredicate) ret).normalize();
80                                }
81                                return ret;
82                        } catch (ExtractorException e) {
83                                throw e;
84                        } catch (Exception e) {
85                                throw new ExtractorException("Error creating Java extractor for code '"+code+"': "+e, e);
86                        }
87                }
88                return null;
89        }
90 
91        @SuppressWarnings("unchecked")
92        @Override
93        public <T, C> Predicate<T, C> createPredicate(
94                        String language,
95                        String code, 
96                        String[] parameterNames, 
97                        Class<T>[] parameterTypes,
98                        Class<C> contextType, 
99                        ClassLoader classLoader) {
100                
101                if ("java".equals(language)) {
102                        try {
103                                Parser jnp = new Parser(new Scanner("Expression "+code, new StringReader(code)));
104                                Atom expr = jnp.parseExpression();                                
105                                Extractor<T, Boolean, C> ret = createExtractor(0, null, expr, parameterNames, parameterTypes, Boolean.class, contextType, classLoader, null, null);
106                                if (ret instanceof CompositePredicate) {
107                                        return ((CompositePredicate) ret).normalize();
108                                }
109                                return ExtractorUtil.wrap(ret);
110                        } catch (ExtractorException e) {
111                                throw e;
112                        } catch (Exception e) {
113                                throw new ExtractorException("Error creating Java extractor for code '"+code+"': "+e, e);
114                        }
115                }
116                return null;
117        }
118        
119        @SuppressWarnings("unchecked")
120        private <T, V, C> Extractor<T, V, C> createExtractor(
121                        double initialCost,
122                        TimeUnit costUnit,
123                        Atom expr, 
124                        String[] parameterNames, 
125                        Class<T>[] parameterTypes,
126                        Class<V> valueType, 
127                        Class<C> contextType, 
128                        ClassLoader classLoader,
129                        Collection<Predicate<T,C>> collector,
130                        Class<?> collectorType) throws RecognitionException, TokenStreamException, ClassNotFoundException, CompileException, InvocationTargetException {
131                
132                Params<T, C> params = new Params<T, C>(expr, parameterNames, parameterTypes, contextType);
133                
134                final Class<V> objectType = (Class<V>) Object.class;
135                final Class<V> numberType = (Class<V>) Number.class;
136 
137                
138                // Try to evaluate expression which doesn't depend on arguments.
139                if (params.topLevelNames.isEmpty()) {
140                        try {
141                                ExpressionEvaluator eval = new ExpressionEvaluator(expr.toString(), Object.class, new String[] {}, new Class[] {});
142                                Object val = eval.evaluate(new Object[] {});
143                                
144                                if (Boolean.TRUE.equals(val)) {
145                                        return compose((Predicate<T, C>) True.getInstance(), collector);
146                                }
147                                
148                                if (Boolean.FALSE.equals(val)) {
149                                        return compose((Predicate<T, C>) False.getInstance(), collector);
150                                }
151                                
152                                return new Constant<T, V, C>((V) val);                        
153                        } catch (Exception e) {
154                                // Nothing.
155                        }
156                }
157                
158                // Do parsing
159                
160                if (expr instanceof ParenthesizedExpression) {
161                        return createExtractor(initialCost, costUnit, ((ParenthesizedExpression) expr).value, parameterNames, parameterTypes, valueType, contextType, classLoader, collector, collectorType);
162                }
163                
164                if (expr instanceof BinaryOperation) {
165                        BinaryOperation bo = (BinaryOperation) expr;
166                        // *
167                        if ("*".equals(bo.op)) {                                
168                                // TODO - in the future handle multiplication chains like 2*3*10*55 in a single multiply.
169                                Extractor<T, Number, C> leftExtractor = (Extractor<T, Number, C>) createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
170                                Extractor<T, Number, C> rightExtractor = (Extractor<T, Number, C>) createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
171                                return (Extractor<T, V, C>) new Multiply<T, C>(initialCost, costUnit, leftExtractor, rightExtractor);
172                        }
173                        // /
174                        if ("/".equals(bo.op)) {                                
175                                // TODO - in the future handle multiplication chains like 2*3*10*55 in a single multiply.
176                                Extractor<T, Number, C> leftExtractor = (Extractor<T, Number, C>) createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
177                                Extractor<T, Number, C> rightExtractor = (Extractor<T, Number, C>) createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
178                                return (Extractor<T, V, C>) new Divide<T, C>(initialCost, costUnit, leftExtractor, rightExtractor);
179                        }
180                        // *
181                        if ("-".equals(bo.op)) {                                
182                                // TODO - in the future handle multiplication chains like 2*3*10*55 in a single multiply.
183                                Extractor<T, Number, C> leftExtractor = (Extractor<T, Number, C>) createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
184                                Extractor<T, Number, C> rightExtractor = (Extractor<T, Number, C>) createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
185                                return (Extractor<T, V, C>) new Subtract<T, C>(initialCost, costUnit, leftExtractor, rightExtractor);
186                        }
187                        // + 
188                        if ("+".equals(bo.op)) {
189                                // TODO - in the future handle addition chains like 2+3+10+55 in a single add.
190                                // Do only if both left and right  
191                                Extractor<T, Object, C> leftExtractor = (Extractor<T, Object, C>) createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
192                                Extractor<T, Object, C> rightExtractor = (Extractor<T, Object, C>) createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
193                                return (Extractor<T, V, C>) new Add<T, C>(initialCost, costUnit, leftExtractor, rightExtractor);                                
194                        }
195                        // <
196                        if (LOGICAL_OR.equals(bo.op)) {
197                                Collection<Predicate<T,C>> ret = Or.class.equals(collectorType) ? collector : new ArrayList<Predicate<T,C>>();  
198                                createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, valueType, contextType, classLoader, ret, Or.class);
199                                createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, valueType, contextType, classLoader, ret, Or.class);
200                                return (Extractor<T, V, C>) new Or<T,C>(initialCost, costUnit, ret);
201                        } 
202        
203                        if (LOGICAL_AND.equals(bo.op)) {
204                                Collection<Predicate<T,C>> ret = And.class.equals(collectorType) ? collector : new ArrayList<Predicate<T,C>>();  
205                                createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, valueType, contextType, classLoader, ret, And.class);
206                                createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, valueType, contextType, classLoader, ret, And.class);
207                                return (Extractor<T, V, C>) new And<T,C>(initialCost, costUnit, ret);
208                        }        
209                        
210                        if ("<".equals(bo.op)) {
211                                Extractor<T, V, C> leftExtractor = createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
212                                Extractor<T, V, C> rightExtractor = createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
213                                return compose(new LessThan(initialCost, costUnit, leftExtractor, rightExtractor), collector);
214                        }
215                        // >
216                        if (">".equals(bo.op)) {
217                                Extractor<T, V, C> leftExtractor = createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
218                                Extractor<T, V, C> rightExtractor = createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
219                                return compose(new GreaterThan(initialCost, costUnit, leftExtractor, rightExtractor), collector);
220                        }
221                        // <=
222                        if ("<=".equals(bo.op)) {
223                                Extractor<T, V, C> leftExtractor = createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
224                                Extractor<T, V, C> rightExtractor = createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
225                                return compose(new LessEqual(initialCost, costUnit, leftExtractor, rightExtractor), collector);                                
226                        }
227                        // >=
228                        if (">=".equals(bo.op)) {
229                                Extractor<T, V, C> leftExtractor = createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
230                                Extractor<T, V, C> rightExtractor = createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, numberType, contextType, classLoader, null, null);
231                                return compose(new GreaterEqual(initialCost, costUnit, leftExtractor, rightExtractor), collector);
232                        }
233                        // ==
234                        if ("==".equals(bo.op)) {
235                                Extractor<T, V, C> leftExtractor = createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
236                                Extractor<T, V, C> rightExtractor = createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
237                                return compose(new Equal(initialCost, costUnit, leftExtractor, rightExtractor, true), collector);
238                        }
239                        // !=
240                        if ("!=".equals(bo.op)) {
241                                Extractor<T, V, C> leftExtractor = createExtractor(0, null, bo.lhs, parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
242                                Extractor<T, V, C> rightExtractor = createExtractor(0, null, bo.rhs, parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
243                                return compose(new NotEqual(initialCost, costUnit, leftExtractor, rightExtractor, true), collector);
244                        }                                                
245                } else if (expr instanceof Instanceof) {
246                        ClassLoader cl = classLoader==null ? getClass().getClassLoader() : classLoader;
247                        Type rhs = ((Instanceof) expr).rhs;
248                        Rvalue lhs = ((Instanceof) expr).lhs;                        
249                        Extractor<T, V, C> extractor = createExtractor(initialCost, costUnit, lhs, parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
250                        return compose(new InstanceOfPredicate(extractor, cl.loadClass(rhs.toString())), collector);
251                } else if (expr instanceof MethodInvocation) {
252                        MethodInvocation mi = (MethodInvocation) expr;
253                        if (mi.methodName.equals("equals") && mi.optionalTarget!=null) {
254                                Extractor<T, V, C> le = createExtractor(0, null, mi.optionalTarget, parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
255                                Extractor<T, V, C> re = createExtractor(0, null, mi.arguments[0], parameterNames, parameterTypes, objectType, contextType, classLoader, null, null);
256                                return compose(new Equal<T, V, C>(initialCost, costUnit, le, re, false), collector);
257                        } else if (COMMUTATIVE_OR_MACRO.equals(mi.methodName)) {
258                                Collection<Predicate<T,C>> ret = CommutativeOr.class.equals(collectorType) ? collector : new ArrayList<Predicate<T,C>>();  
259                                for (Java.Rvalue arg: mi.arguments) {
260                                        createExtractor(0, null, arg, parameterNames, parameterTypes, valueType, contextType, classLoader, ret, CommutativeOr.class);
261                                }
262                                return (Extractor<T, V, C>) new CommutativeOr<T,C>(initialCost, costUnit, ret);
263                        } else if (COMMUTATIVE_AND_MACRO.equals(mi.methodName)) {
264                                Collection<Predicate<T,C>> ret = CommutativeAnd.class.equals(collectorType) ? collector : new ArrayList<Predicate<T,C>>();  
265                                for (Java.Rvalue arg: mi.arguments) {
266                                        createExtractor(0, null, arg, parameterNames, parameterTypes, valueType, contextType, classLoader, ret, CommutativeAnd.class);
267                                }                        
268                                return (Extractor<T, V, C>) new CommutativeAnd<T,C>(initialCost, costUnit, ret);
269                        } else if (COST_MACRO.equals(mi.methodName)) {
270                                String costValue = mi.arguments[0].toString();
271                                for (TimeUnit cu: TimeUnit.values()) {
272                                        if (cu.name().equals(costValue)) {
273                                                return createExtractor(0, cu, mi.arguments[1], parameterNames, parameterTypes, valueType, contextType, classLoader, collector, collectorType);
274                                        }
275                                }
276                                ExpressionEvaluator eval = new ExpressionEvaluator(costValue, Object.class, new String[] {}, new Class[] {});
277                                Object val = eval.evaluate(new Object[] {});
278                                return createExtractor(((Number) val).doubleValue(), null, mi.arguments[1], parameterNames, parameterTypes, valueType, contextType, classLoader, collector, collectorType);                                
279                        }
280                } else if (expr instanceof UnaryOperation) {
281                        UnaryOperation uo = (UnaryOperation) expr;
282                        if ("!".equals(uo.operator)) {
283                                Extractor<T, V, C> extractor = createExtractor(initialCost, costUnit, uo.operand, parameterNames, parameterTypes, valueType, contextType, classLoader, null, null);
284                                return compose(new Not((Predicate) extractor), collector);
285                        }                        
286                } else if (expr instanceof Literal) {
287                        Literal lit = (Literal) expr;
288                        if (Boolean.TRUE.equals(lit.value)) {
289                                return compose((Predicate<T, C>) True.getInstance(), collector);
290                        }
291                        
292                        if (Boolean.FALSE.equals(lit.value)) {
293                                return compose((Predicate<T, C>) False.getInstance(), collector);
294                        }
295                        
296                        return new Constant<T, V, C>((V) lit.value);                        
297                }
298                
299                if (Boolean.class.equals(valueType)) {
300                        return compose(new JavaPredicate<T, C>(initialCost, costUnit, params, classLoader), collector);                        
301                }
302                return new JavaExtractor<T, V, C>(initialCost, costUnit, params, valueType, classLoader);
303        }
304        
305        @SuppressWarnings("unchecked")
306        private <T, V, C> Extractor<T, V, C> compose(Predicate<T, C> ret, Collection<Predicate<T,C>> collector) {
307                if (collector==null) {
308                        return (Extractor<T, V, C>) ret;
309                }
310                collector.add(ret);
311                return null;
312        }
313 
314//        private <T, V, C> Predicate<T, C> createPredicate(
315//                        Atom expr,
316//                        String[] parameterNames, 
317//                        Class<T>[] parameterTypes,
318//                        Class<V> valueType, 
319//                        Class<C> contextType, 
320//                        ClassLoader classLoader,
321//                        Predicate<T, C> parentPredicate) throws RecognitionException, TokenStreamException, ClassNotFoundException {
322//                
323//                if (expr instanceof Instanceof) {
324//                        ClassLoader cl = classLoader==null ? getClass().getClassLoader() : classLoader;
325//                        Type rhs = ((Instanceof) expr).rhs;
326//                        Rvalue lhs = ((Instanceof) expr).lhs;                        
327//                        Extractor<T, V, C> extractor = createExtractor(lhs, parameterNames, parameterTypes, valueType, contextType, classLoader);
328//                        return new InstanceOfPredicate(extractor, cl.loadClass(rhs.toString()));
329//                } else if (expr instanceof UnaryOperation) {
330//                        UnaryOperation uo = (UnaryOperation) expr;
331//                        if ("!".equals(uo.operator)) {
332//                                return new Not(createPredicate(uo.operand, parameterNames, parameterTypes, valueType, contextType, classLoader, null));
333//                        }
334//                } else if (expr instanceof MethodInvocation) {
335//                        MethodInvocation mi = (MethodInvocation) expr;
336//                        if (mi.methodName.equals("equals") && mi.optionalTarget!=null) {
337//                                Extractor<T, V, C> le = createExtractor(mi.optionalTarget, parameterNames, parameterTypes, valueType, contextType, classLoader);
338//                                Extractor<T, V, C> re = createExtractor(mi.arguments[0], parameterNames, parameterTypes, valueType, contextType, classLoader);
339//                                return new Equal<T, V, C>(le, re, false);
340//                        } else if (COMMUTATIVE_OR_MACROS.equals(mi.methodName)) {
341//                                CommutativeOr<T, C> ret = parentPredicate instanceof CommutativeOr ? (CommutativeOr<T, C>) parentPredicate : new CommutativeOr<T, C>();  
342//                                for (Java.Rvalue arg: mi.arguments) {
343//                                        createPredicate(arg, parameterNames, parameterTypes, valueType, contextType, classLoader, ret);
344//                                }
345//                                return ret;
346//                        } else if (COMMUTATIVE_AND_MACROS.equals(mi.methodName)) {
347//                                CommutativeAnd<T, C> ret = parentPredicate instanceof CommutativeAnd ? (CommutativeAnd<T, C>) parentPredicate : new CommutativeAnd<T, C>();  
348//                                for (Java.Rvalue arg: mi.arguments) {
349//                                        createPredicate(arg, parameterNames, parameterTypes, valueType, contextType, classLoader, ret);
350//                                }                        
351//                                return ret;
352//                        }
353//                } else if (expr instanceof BinaryOperation) {
354//                        BinaryOperation bo = (BinaryOperation) expr;
355//                }
356//                
357//                // TODO parse, 
358//                Params<T, C> params = new Params<T, C>(expr, parameterNames, parameterTypes, contextType);
359//                return new JavaPredicate<T, C>(params, classLoader);
360//        }
361                
362}

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