##### Coverage Report - org.webmacro.engine.Expression

Classes in this File | Line Coverage | Branch Coverage | Complexity
Expression |
88% | 15/17
80% | 8/10
| 2.504854368932039;2.505
Expression$AddBuilder |
0% | 0/7
0% | 0/8
| 2.504854368932039;2.505
Expression$AddOperation |
0% | 0/6
0% | 0/4
| 2.504854368932039;2.505
Expression$AndBuilder |
55% | 5/9
14% | 2/14
| 2.504854368932039;2.505
Expression$AndOperation |
84% | 11/13
75% | 6/8
| 2.504854368932039;2.505
Expression$BinaryOperation |
77% | 7/9
75% | 3/4
| 2.504854368932039;2.505
Expression$BinaryOperationBuilder |
100% | 7/7
75% | 3/4
| 2.504854368932039;2.505
Expression$Compare |
79% | 19/24
86% | 19/22
| 2.504854368932039;2.505
Expression$CompareEq |
85% | 6/7
87% | 7/8
| 2.504854368932039;2.505
Expression$CompareEqBuilder |
62% | 5/8
25% | 1/4
| 2.504854368932039;2.505
Expression$CompareGe |
0% | 0/5
0% | 0/4
| 2.504854368932039;2.505
Expression$CompareGeBuilder |
0% | 0/8
0% | 0/4
| 2.504854368932039;2.505
Expression$CompareGt |
60% | 3/5
50% | 2/4
| 2.504854368932039;2.505
Expression$CompareGtBuilder |
62% | 5/8
25% | 1/4
| 2.504854368932039;2.505
Expression$CompareLe |
0% | 0/5
0% | 0/4
| 2.504854368932039;2.505
Expression$CompareLeBuilder |
0% | 0/8
0% | 0/4
| 2.504854368932039;2.505
Expression$CompareLt |
60% | 3/5
25% | 1/4
| 2.504854368932039;2.505
Expression$CompareLtBuilder |
62% | 5/8
25% | 1/4
| 2.504854368932039;2.505
Expression$CompareNe |
71% | 5/7
75% | 6/8
| 2.504854368932039;2.505
Expression$CompareNeBuilder |
62% | 5/8
25% | 1/4
| 2.504854368932039;2.505
Expression$DivideBuilder |
0% | 0/10
0% | 0/10
| 2.504854368932039;2.505
Expression$DivideOperation |
0% | 0/9
0% | 0/6
| 2.504854368932039;2.505
Expression$ExpressionBase |
50% | 2/4
N/A | N/A
| 2.504854368932039;2.505
Expression$MultiplyBuilder |
0% | 0/7
0% | 0/8
| 2.504854368932039;2.505
Expression$MultiplyOperation |
0% | 0/6
0% | 0/4
| 2.504854368932039;2.505
Expression$NotBuilder |
80% | 4/5
25% | 1/4
| 2.504854368932039;2.505
Expression$NotOperation |
75% | 3/4
100% | 2/2
| 2.504854368932039;2.505
Expression$OrBuilder |
55% | 5/9
14% | 2/14
| 2.504854368932039;2.505
Expression$OrOperation |
84% | 11/13
75% | 6/8
| 2.504854368932039;2.505
Expression$SubtractBuilder |
57% | 4/7
12% | 1/8
| 2.504854368932039;2.505
Expression$SubtractOperation |
66% | 4/6
50% | 2/4
| 2.504854368932039;2.505
Expression$UnaryOperation |
71% | 5/7
50% | 1/2
| 2.504854368932039;2.505
Expression$UnaryOperationBuilder |
100% | 5/5
50% | 1/2
| 2.504854368932039;2.505

1 |  |
     /*
2 |  |
      * Copyright (C) 1998-2000 Semiotek Inc.  All Rights Reserved.
3 |  |
      *
4 |  |
      * Redistribution and use in source and binary forms, with or without
5 |  |
      * modification, are permitted under the terms of either of the following
6 |  |
      * Open Source licenses:
7 |  |
      *
8 |  |
      * The GNU General Public License, version 2, or any later version, as
9 |  |
      * published by the Free Software Foundation
10 |  |
      * (http://www.fsf.org/copyleft/gpl.html);
11 |  |
      *
12 |  |
      *  or
13 |  |
      *
14 |  |
      * The Semiotek Public License (http://webmacro.org/LICENSE.)
15 |  |
      *
16 |  |
      * This software is provided "as is", with NO WARRANTY, not even the
17 |  |
      * implied warranties of fitness to purpose, or merchantability. You
18 |  |
      * assume all risks and liabilities associated with its use.
19 |  |
      *
20 |  |
      * See www.webmacro.org for more information on the WebMacro project.
21 |  |
      */
22 |  |
23 |  |
     package org.webmacro.engine;
24 |  |
25 |  |
     import java.io.IOException;
26 |  |
27 |  |
     import org.webmacro.Context;
28 |  |
     import org.webmacro.FastWriter;
29 |  |
     import org.webmacro.Macro;
30 |  |
     import org.webmacro.PropertyException;
31 |  |
     import org.webmacro.TemplateVisitor;
32 |  |
     import org.webmacro.Visitable;
33 |  |
34 |  |
     /**
35 |  |
      * All WM expressions derive from this base class.
36 |  |
      * All expression and expression builder classes are contained
37 |  |
      * in this file.
38 |  |
      */
39 | 13802 |
     public abstract class Expression
40 |  |
     {
41 |  |
42 | 2 |
         final private static org.webmacro.engine.UndefinedMacro UNDEF
43 |  |
                 = org.webmacro.engine.UndefinedMacro.getInstance();
44 |  |
45 |  |
         public abstract static class ExpressionBase implements Macro, Visitable
46 |  |
         {
47 |  |
48 |  |
             protected ExpressionBase ()
49 | 232 |
             {
50 | 232 |
             }
51 |  |
52 |  |
             // Macro methods
53 |  |
             final public void write (FastWriter out, Context context)
54 |  |
                     throws PropertyException, IOException
55 |  |
             {
56 | 0 |
                 out.write(evaluate(context).toString());
57 | 0 |
             }
58 |  |
         }
59 |  |
60 | 2 |
         final private static Boolean TRUE = Boolean.TRUE;
61 | 2 |
         final private static Boolean FALSE = Boolean.FALSE;
62 |  |
63 |  |
         public static boolean isTrue (Object o)
64 |  |
         {
65 | 45150 |
             if (o == null)
66 | 916 |
                 return false;
67 | 44234 |
             else if (o instanceof Boolean)
68 | 31776 |
                 return ((Boolean) o).booleanValue();
69 |  |
             //  added by Keats 30-Nov-01
70 | 12458 |
             else if (o == UNDEF)
71 | 11038 |
                 return false;
72 |  |
             else
73 | 1420 |
                 return true;
74 |  |
         }
75 |  |
76 |  |
         public static boolean isNumber (Object o)
77 |  |
         {
78 | 18860 |
             return (o instanceof Number);
79 |  |
         }
80 |  |
81 |  |
         public static Object numberObject (long result, Object op1, Object op2)
82 |  |
         {
83 | 118 |
             if (op1.getClass() == Long.class || op2.getClass() == Long.class)
84 | 0 |
                 return new Long(result);
85 |  |
             else
86 | 118 |
                 return new Integer((int) result);
87 |  |
         }
88 |  |
89 |  |
         public static long numberValue (Object o)
90 |  |
         {
91 | 1096 |
             return ((Number) o).longValue();
92 |  |
         }
93 |  |
94 |  |
         public abstract static class BinaryOperation extends ExpressionBase
95 |  |
         {
96 |  |
97 |  |
             private Object _l, _r;
98 |  |
99 |  |
             BinaryOperation (Object l, Object r)
100 | 118 |
             {
101 | 118 |
                 _l = l;
102 | 118 |
                 _r = r;
103 | 118 |
             }
104 |  |
105 |  |
             public abstract Object operate (Object l, Object r) throws PropertyException;
106 |  |
107 |  |
             public Object evaluate (Context context)
108 |  |
                     throws PropertyException
109 |  |
             {
110 |  |
                 Object l, r;
111 |  |
112 | 9430 |
                 l = (_l instanceof Macro) ? ((Macro) _l).evaluate(context) : _l;
113 | 9430 |
                 r = (_r instanceof Macro) ? ((Macro) _r).evaluate(context) : _r;
114 |  |
115 | 9430 |
                 return operate(l, r);
116 |  |
             }
117 |  |
118 |  |
             public abstract String getName ();
119 |  |
120 |  |
             public void accept (TemplateVisitor v)
121 |  |
             {
122 | 0 |
                 v.visitBinaryOperation(getName(), _l, _r);
123 | 0 |
             }
124 |  |
         }
125 |  |
126 |  |
         public abstract static class UnaryOperation extends ExpressionBase
127 |  |
         {
128 |  |
129 |  |
             private Object _o;
130 |  |
131 |  |
             UnaryOperation (Object o)
132 | 42 |
             {
133 | 42 |
                 _o = o;
134 | 42 |
             }
135 |  |
136 |  |
             public abstract Object operate (Object o);
137 |  |
138 |  |
             public Object evaluate (Context context)
139 |  |
                     throws PropertyException
140 |  |
             {
141 | 2384 |
                 Object o = (_o instanceof Macro) ? ((Macro) _o).evaluate(context) : _o;
142 |  |
143 | 2384 |
                 return operate(o);
144 |  |
             }
145 |  |
146 |  |
             public abstract String getName ();
147 |  |
148 |  |
             public void accept (TemplateVisitor v)
149 |  |
             {
150 | 0 |
                 v.visitUnaryOperation(getName(), _o);
151 | 0 |
             }
152 |  |
         }
153 |  |
154 |  |
         public static class AndOperation extends ExpressionBase
155 |  |
         {
156 |  |
157 |  |
             private Object _l, _r;
158 |  |
159 |  |
             public AndOperation (Object l, Object r)
160 | 54 |
             {
161 | 54 |
                 _l = l;
162 | 54 |
                 _r = r;
163 | 54 |
             }
164 |  |
165 |  |
             public Object evaluate (Context context)
166 |  |
                     throws PropertyException
167 |  |
             {
168 |  |
                 Object l, r;
169 |  |
170 | 1846 |
                 l = (_l instanceof Macro) ? ((Macro) _l).evaluate(context) : _l;
171 | 1846 |
                 if (!isTrue(l))
172 | 1624 |
                     return FALSE;
173 |  |
174 | 222 |
                 r = (_r instanceof Macro) ? ((Macro) _r).evaluate(context) : _r;
175 | 222 |
                 if (!isTrue(r))
176 | 150 |
                     return FALSE;
177 |  |
178 | 72 |
                 return TRUE;
179 |  |
             }
180 |  |
181 |  |
             public void accept (TemplateVisitor v)
182 |  |
             {
183 | 0 |
                 v.visitBinaryOperation("And", _l, _r);
184 | 0 |
             }
185 |  |
         }
186 |  |
187 |  |
         public static class OrOperation extends ExpressionBase
188 |  |
         {
189 |  |
190 |  |
             private Object _l, _r;
191 |  |
192 |  |
             public OrOperation (Object l, Object r)
193 | 18 |
             {
194 | 18 |
                 _l = l;
195 | 18 |
                 _r = r;
196 | 18 |
             }
197 |  |
198 |  |
             public Object evaluate (Context context)
199 |  |
                     throws PropertyException
200 |  |
             {
201 |  |
                 Object l, r;
202 |  |
203 | 260 |
                 l = (_l instanceof Macro) ? ((Macro) _l).evaluate(context) : _l;
204 | 260 |
                 if (isTrue(l))
205 | 74 |
                     return TRUE;
206 |  |
207 | 186 |
                 r = (_r instanceof Macro) ? ((Macro) _r).evaluate(context) : _r;
208 | 186 |
                 if (isTrue(r))
209 | 12 |
                     return TRUE;
210 |  |
211 | 174 |
                 return FALSE;
212 |  |
             }
213 |  |
214 |  |
             public void accept (TemplateVisitor v)
215 |  |
             {
216 | 0 |
                 v.visitBinaryOperation("Or", _l, _r);
217 | 0 |
             }
218 |  |
         }
219 |  |
220 |  |
         public static class NotOperation extends UnaryOperation
221 |  |
         {
222 |  |
223 |  |
             public NotOperation (Object o)
224 |  |
             {
225 | 42 |
                 super(o);
226 | 42 |
             }
227 |  |
228 |  |
             public String getName ()
229 |  |
             {
230 | 0 |
                 return "Not";
231 |  |
             }
232 |  |
233 |  |
             public Object operate (Object o)
234 |  |
             {
235 | 2384 |
                 return (!Expression.isTrue(o)) ? TRUE : FALSE;
236 |  |
             }
237 |  |
         }
238 |  |
239 |  |
240 |  |
         public static class AddOperation extends BinaryOperation
241 |  |
         {
242 |  |
243 |  |
             public AddOperation (Object l, Object r)
244 |  |
             {
245 | 0 |
                 super(l, r);
246 | 0 |
             }
247 |  |
248 |  |
             public String getName ()
249 |  |
             {
250 | 0 |
                 return "Add";
251 |  |
             }
252 |  |
253 |  |
             public Object operate (Object l, Object r) throws PropertyException
254 |  |
             {
255 | 0 |
                 if (!isNumber(l) || !isNumber(r))
256 | 0 |
                     throw new PropertyException("Add requires numeric operands");
257 |  |
                 else
258 | 0 |
                     return numberObject(numberValue(l) + numberValue(r), l, r);
259 |  |
             }
260 |  |
         }
261 |  |
262 |  |
         public static class SubtractOperation extends BinaryOperation
263 |  |
         {
264 |  |
265 |  |
             public SubtractOperation (Object l, Object r)
266 |  |
             {
267 | 6 |
                 super(l, r);
268 | 6 |
             }
269 |  |
270 |  |
             public String getName ()
271 |  |
             {
272 | 0 |
                 return "Subtract";
273 |  |
             }
274 |  |
275 |  |
             public Object operate (Object l, Object r) throws PropertyException
276 |  |
             {
277 | 118 |
                 if (!isNumber(l) || !isNumber(r))
278 | 0 |
                     throw new PropertyException("Subtract requires numeric operands");
279 |  |
                 else
280 | 118 |
                     return numberObject(numberValue(l) - numberValue(r), l, r);
281 |  |
             }
282 |  |
         }
283 |  |
284 |  |
         public static class MultiplyOperation extends BinaryOperation
285 |  |
         {
286 |  |
287 |  |
             public MultiplyOperation (Object l, Object r)
288 |  |
             {
289 | 0 |
                 super(l, r);
290 | 0 |
             }
291 |  |
292 |  |
             public String getName ()
293 |  |
             {
294 | 0 |
                 return "Multiply";
295 |  |
             }
296 |  |
297 |  |
             public Object operate (Object l, Object r) throws PropertyException
298 |  |
             {
299 | 0 |
                 if (!isNumber(l) || !isNumber(r))
300 | 0 |
                     throw new PropertyException("Multiply requires numeric operands");
301 |  |
                 else
302 | 0 |
                     return numberObject(numberValue(l) * numberValue(r), l, r);
303 |  |
             }
304 |  |
         }
305 |  |
306 |  |
         public static class DivideOperation extends BinaryOperation
307 |  |
         {
308 |  |
309 |  |
             public DivideOperation (Object l, Object r)
310 |  |
             {
311 | 0 |
                 super(l, r);
312 | 0 |
             }
313 |  |
314 |  |
             public String getName ()
315 |  |
             {
316 | 0 |
                 return "Divide";
317 |  |
             }
318 |  |
319 |  |
             public Object operate (Object l, Object r) throws PropertyException
320 |  |
             {
321 | 0 |
                 if (!isNumber(l) || !isNumber(r))
322 | 0 |
                     throw new PropertyException("Divide requires numeric operands");
323 |  |
                 else
324 |  |
                 {
325 | 0 |
                     long denom = numberValue(r);
326 | 0 |
                     if (denom == 0)
327 | 0 |
                         throw new PropertyException("Divide by zero");
328 |  |
                     else
329 | 0 |
                         return numberObject(numberValue(l) / denom, l, r);
330 |  |
                 }
331 |  |
             }
332 |  |
         }
333 |  |
334 |  |
335 |  |
         public abstract static class Compare extends BinaryOperation
336 |  |
         {
337 |  |
338 |  |
             public Compare (Object l, Object r)
339 |  |
             {
340 | 112 |
                 super(l, r);
341 | 112 |
             }
342 |  |
343 |  |
             public abstract Boolean compare (String l, String r);
344 |  |
345 |  |
             public abstract Boolean compare (long l, long r);
346 |  |
347 |  |
             public Boolean compare (Object l, Object r)
348 |  |
             {
349 | 0 |
                 return null;
350 |  |
             }
351 |  |
352 |  |
             public Boolean compareNull (Object o)
353 |  |
             {
354 | 0 |
                 return null;
355 |  |
             }
356 |  |
357 |  |
             public Object operate (Object l, Object r) throws PropertyException
358 |  |
             {
359 | 9312 |
                 Boolean b = null;
360 | 9312 |
                 boolean lIsNumber = isNumber(l), rIsNumber = isNumber(r);
361 |  |
362 | 9312 |
                 if (lIsNumber && rIsNumber)
363 | 430 |
                     b = compare(numberValue(l), numberValue(r));
364 |  |
                 else
365 |  |
                 {
366 | 8882 |
                     boolean lIsString = (l instanceof String),
367 | 8882 |
                             rIsString = (r instanceof String);
368 |  |
369 | 8882 |
                     if (lIsString && rIsString)
370 | 4194 |
                         b = compare((String) l, (String) r);
371 | 4688 |
                     else if (lIsString && rIsNumber)
372 | 0 |
                         b = compare((String) l, Long.toString(numberValue(r)));
373 | 4688 |
                     else if (lIsNumber && rIsString)
374 | 0 |
                         b = compare(Long.toString(numberValue(l)), (String) r);
375 | 4688 |
                     else if (l == null)
376 | 1298 |
                         b = compareNull(r);
377 | 3390 |
                     else if (r == null)
378 | 3386 |
                         b = compareNull(l);
379 |  |
                     else
380 | 4 |
                         b = compare(l, r);
381 |  |
                 }
382 |  |
383 | 9312 |
                 if (b == null)
384 | 0 |
                     throw new PropertyException("Objects not comparable");
385 |  |
                 else
386 | 9312 |
                     return b;
387 |  |
             }
388 |  |
         }
389 |  |
390 |  |
         public static class CompareEq extends Compare
391 |  |
         {
392 |  |
393 |  |
             public CompareEq (Object l, Object r)
394 |  |
             {
395 | 44 |
                 super(l, r);
396 | 44 |
             }
397 |  |
398 |  |
             public String getName ()
399 |  |
             {
400 | 0 |
                 return "CompareEq";
401 |  |
             }
402 |  |
403 |  |
             public Boolean compare (Object l, Object r)
404 |  |
             {
405 | 4 |
                 return (l.equals(r)) ? TRUE : FALSE;
406 |  |
             }
407 |  |
408 |  |
             public Boolean compare (String l, String r)
409 |  |
             {
410 | 3594 |
                 return (l.equals(r)) ? TRUE : FALSE;
411 |  |
             }
412 |  |
413 |  |
             public Boolean compare (long l, long r)
414 |  |
             {
415 | 112 |
                 return (l == r) ? TRUE : FALSE;
416 |  |
             }
417 |  |
418 |  |
             public Boolean compareNull (Object o)
419 |  |
             {
420 | 3658 |
                 return (o == null) ? TRUE : FALSE;
421 |  |
             }
422 |  |
         }
423 |  |
424 |  |
         public static class CompareNe extends Compare
425 |  |
         {
426 |  |
427 |  |
             public CompareNe (Object l, Object r)
428 |  |
             {
429 | 58 |
                 super(l, r);
430 | 58 |
             }
431 |  |
432 |  |
             public String getName ()
433 |  |
             {
434 | 0 |
                 return "CompareNe";
435 |  |
             }
436 |  |
437 |  |
             public Boolean compare (Object l, Object r)
438 |  |
             {
439 | 0 |
                 return (!l.equals(r)) ? TRUE : FALSE;
440 |  |
             }
441 |  |
442 |  |
             public Boolean compare (String l, String r)
443 |  |
             {
444 | 600 |
                 return (!l.equals(r)) ? TRUE : FALSE;
445 |  |
             }
446 |  |
447 |  |
             public Boolean compare (long l, long r)
448 |  |
             {
449 | 242 |
                 return (l != r) ? TRUE : FALSE;
450 |  |
             }
451 |  |
452 |  |
             public Boolean compareNull (Object o)
453 |  |
             {
454 | 1026 |
                 return (o != null) ? TRUE : FALSE;
455 |  |
             }
456 |  |
         }
457 |  |
458 |  |
         public static class CompareLe extends Compare
459 |  |
         {
460 |  |
461 |  |
             public CompareLe (Object l, Object r)
462 |  |
             {
463 | 0 |
                 super(l, r);
464 | 0 |
             }
465 |  |
466 |  |
             public String getName ()
467 |  |
             {
468 | 0 |
                 return "CompareLe";
469 |  |
             }
470 |  |
471 |  |
             public Boolean compare (String l, String r)
472 |  |
             {
473 | 0 |
                 return (l.compareTo(r) <= 0) ? TRUE : FALSE;
474 |  |
             }
475 |  |
476 |  |
             public Boolean compare (long l, long r)
477 |  |
             {
478 | 0 |
                 return (l <= r) ? TRUE : FALSE;
479 |  |
             }
480 |  |
         }
481 |  |
482 |  |
         public static class CompareLt extends Compare
483 |  |
         {
484 |  |
485 |  |
             public CompareLt (Object l, Object r)
486 |  |
             {
487 | 2 |
                 super(l, r);
488 | 2 |
             }
489 |  |
490 |  |
             public String getName ()
491 |  |
             {
492 | 0 |
                 return "CompareLt";
493 |  |
             }
494 |  |
495 |  |
             public Boolean compare (String l, String r)
496 |  |
             {
497 | 0 |
                 return (l.compareTo(r) < 0) ? TRUE : FALSE;
498 |  |
             }
499 |  |
500 |  |
             public Boolean compare (long l, long r)
501 |  |
             {
502 | 6 |
                 return (l < r) ? TRUE : FALSE;
503 |  |
             }
504 |  |
         }
505 |  |
506 |  |
         public static class CompareGe extends Compare
507 |  |
         {
508 |  |
509 |  |
             public CompareGe (Object l, Object r)
510 |  |
             {
511 | 0 |
                 super(l, r);
512 | 0 |
             }
513 |  |
514 |  |
             public String getName ()
515 |  |
             {
516 | 0 |
                 return "CompareGe";
517 |  |
             }
518 |  |
519 |  |
             public Boolean compare (String l, String r)
520 |  |
             {
521 | 0 |
                 return (l.compareTo(r) >= 0) ? TRUE : FALSE;
522 |  |
             }
523 |  |
524 |  |
             public Boolean compare (long l, long r)
525 |  |
             {
526 | 0 |
                 return (l >= r) ? TRUE : FALSE;
527 |  |
             }
528 |  |
         }
529 |  |
530 |  |
         public static class CompareGt extends Compare
531 |  |
         {
532 |  |
533 |  |
             public CompareGt (Object l, Object r)
534 |  |
             {
535 | 8 |
                 super(l, r);
536 | 8 |
             }
537 |  |
538 |  |
             public String getName ()
539 |  |
             {
540 | 0 |
                 return "CompareGt";
541 |  |
             }
542 |  |
543 |  |
             public Boolean compare (String l, String r)
544 |  |
             {
545 | 0 |
                 return (l.compareTo(r) > 0) ? TRUE : FALSE;
546 |  |
             }
547 |  |
548 |  |
             public Boolean compare (long l, long r)
549 |  |
             {
550 | 70 |
                 return (l > r) ? TRUE : FALSE;
551 |  |
             }
552 |  |
         }
553 |  |
554 |  |
555 |  |
         public abstract static class BinaryOperationBuilder implements Builder
556 |  |
         {
557 |  |
558 |  |
             private Object _l, _r;
559 |  |
560 |  |
             public BinaryOperationBuilder (Object l, Object r)
561 | 190 |
             {
562 | 190 |
                 _l = l;
563 | 190 |
                 _r = r;
564 | 190 |
             }
565 |  |
566 |  |
             public abstract Object build (Object l, Object r) throws BuildException;
567 |  |
568 |  |
             public Object build (BuildContext pc)
569 |  |
                     throws BuildException
570 |  |
             {
571 |  |
                 Object l, r;
572 | 190 |
                 l = (_l instanceof Builder) ? ((Builder) _l).build(pc) : _l;
573 | 190 |
                 r = (_r instanceof Builder) ? ((Builder) _r).build(pc) : _r;
574 |  |
575 | 190 |
                 return build(l, r);
576 |  |
             }
577 |  |
         }
578 |  |
579 |  |
         public abstract static class UnaryOperationBuilder implements Builder
580 |  |
         {
581 |  |
582 |  |
             private Object _o;
583 |  |
584 |  |
             public UnaryOperationBuilder (Object o)
585 | 42 |
             {
586 | 42 |
                 _o = o;
587 | 42 |
             }
588 |  |
589 |  |
             public abstract Object build (Object o) throws BuildException;
590 |  |
591 |  |
             public Object build (BuildContext pc)
592 |  |
                     throws BuildException
593 |  |
             {
594 |  |
                 Object o;
595 | 42 |
                 o = (_o instanceof Builder) ? ((Builder) _o).build(pc) : _o;
596 |  |
597 | 42 |
                 return build(o);
598 |  |
             }
599 |  |
         }
600 |  |
601 |  |
602 |  |
         public static class AndBuilder extends BinaryOperationBuilder
603 |  |
         {
604 |  |
605 |  |
             public AndBuilder (Object l, Object r)
606 |  |
             {
607 | 54 |
                 super(l, r);
608 | 54 |
             }
609 |  |
610 |  |
             public Object build (Object l, Object r)
611 |  |
             {
612 | 54 |
                 if (l instanceof Macro)
613 |  |
                 {
614 | 54 |
                     if (r instanceof Macro)
615 | 54 |
                         return new AndOperation(l, r);
616 |  |
                     else
617 | 0 |
                         return isTrue(r) ? l : FALSE;
618 |  |
                 }
619 |  |
                 else
620 |  |
                 {
621 | 0 |
                     if (r instanceof Macro)
622 | 0 |
                         return isTrue(l) ? r : FALSE;
623 |  |
                     else
624 | 0 |
                         return (isTrue(l) && isTrue(r)) ? TRUE : FALSE;
625 |  |
                 }
626 |  |
             }
627 |  |
         }
628 |  |
629 |  |
         public static class OrBuilder extends BinaryOperationBuilder
630 |  |
         {
631 |  |
632 |  |
             public OrBuilder (Object l, Object r)
633 |  |
             {
634 | 18 |
                 super(l, r);
635 | 18 |
             }
636 |  |
637 |  |
             public Object build (Object l, Object r)
638 |  |
             {
639 | 18 |
                 if (l instanceof Macro)
640 |  |
                 {
641 | 18 |
                     if (r instanceof Macro)
642 | 18 |
                         return new OrOperation(l, r);
643 |  |
                     else
644 | 0 |
                         return isTrue(r) ? TRUE : l;
645 |  |
                 }
646 |  |
                 else
647 |  |
                 {
648 | 0 |
                     if (r instanceof Macro)
649 | 0 |
                         return isTrue(l) ? TRUE : r;
650 |  |
                     else
651 | 0 |
                         return (isTrue(l) || isTrue(r)) ? TRUE : FALSE;
652 |  |
                 }
653 |  |
             }
654 |  |
         }
655 |  |
656 |  |
         public static class NotBuilder extends UnaryOperationBuilder
657 |  |
         {
658 |  |
659 |  |
             public NotBuilder (Object o)
660 |  |
             {
661 | 42 |
                 super(o);
662 | 42 |
             }
663 |  |
664 |  |
             public Object build (Object o)
665 |  |
             {
666 | 42 |
                 if (o instanceof Macro)
667 | 42 |
                     return new NotOperation(o);
668 |  |
                 else
669 | 0 |
                     return !isTrue(o) ? TRUE : FALSE;
670 |  |
             }
671 |  |
         }
672 |  |
673 |  |
674 |  |
         public static class AddBuilder extends BinaryOperationBuilder
675 |  |
         {
676 |  |
677 |  |
             public AddBuilder (Object l, Object r)
678 |  |
             {
679 | 0 |
                 super(l, r);
680 | 0 |
             }
681 |  |
682 |  |
             public Object build (Object l, Object r) throws BuildException
683 |  |
             {
684 | 0 |
                 if (!(l instanceof Macro) && !(r instanceof Macro))
685 |  |
                 {
686 | 0 |
                     if (isNumber(l) && isNumber(r))
687 | 0 |
                         return numberObject(numberValue(l) + numberValue(r), l, r);
688 |  |
                     else
689 | 0 |
                         throw new BuildException("Add requires numeric operands");
690 |  |
                 }
691 |  |
                 else
692 | 0 |
                     return new AddOperation(l, r);
693 |  |
             }
694 |  |
         }
695 |  |
696 |  |
         public static class SubtractBuilder extends BinaryOperationBuilder
697 |  |
         {
698 |  |
699 |  |
             public SubtractBuilder (Object l, Object r)
700 |  |
             {
701 | 6 |
                 super(l, r);
702 | 6 |
             }
703 |  |
704 |  |
             public Object build (Object l, Object r) throws BuildException
705 |  |
             {
706 | 6 |
                 if (!(l instanceof Macro) && !(r instanceof Macro))
707 |  |
                 {
708 | 0 |
                     if (isNumber(l) && isNumber(r))
709 | 0 |
                         return numberObject(numberValue(l) - numberValue(r), l, r);
710 |  |
                     else
711 | 0 |
                         throw new BuildException("Subtract requires numeric operands");
712 |  |
                 }
713 |  |
                 else
714 | 6 |
                     return new SubtractOperation(l, r);
715 |  |
             }
716 |  |
         }
717 |  |
718 |  |
         public static class MultiplyBuilder extends BinaryOperationBuilder
719 |  |
         {
720 |  |
721 |  |
             public MultiplyBuilder (Object l, Object r)
722 |  |
             {
723 | 0 |
                 super(l, r);
724 | 0 |
             }
725 |  |
726 |  |
             public Object build (Object l, Object r) throws BuildException
727 |  |
             {
728 | 0 |
                 if (!(l instanceof Macro) && !(r instanceof Macro))
729 |  |
                 {
730 | 0 |
                     if (isNumber(l) && isNumber(r))
731 | 0 |
                         return numberObject(numberValue(l) * numberValue(r), l, r);
732 |  |
                     else
733 | 0 |
                         throw new BuildException("Multiply requires numeric operands");
734 |  |
                 }
735 |  |
                 else
736 | 0 |
                     return new MultiplyOperation(l, r);
737 |  |
             }
738 |  |
         }
739 |  |
740 |  |
         public static class DivideBuilder extends BinaryOperationBuilder
741 |  |
         {
742 |  |
743 |  |
             public DivideBuilder (Object l, Object r)
744 |  |
             {
745 | 0 |
                 super(l, r);
746 | 0 |
             }
747 |  |
748 |  |
             public Object build (Object l, Object r) throws BuildException
749 |  |
             {
750 | 0 |
                 if (!(l instanceof Macro) && !(r instanceof Macro))
751 |  |
                 {
752 | 0 |
                     if (isNumber(l) && isNumber(r))
753 |  |
                     {
754 | 0 |
                         long denom = numberValue(r);
755 | 0 |
                         if (denom == 0)
756 | 0 |
                             throw new BuildException("Divide by zero");
757 |  |
                         else
758 | 0 |
                             return numberObject(numberValue(l) / denom, l, r);
759 |  |
                     }
760 |  |
                     else
761 | 0 |
                         throw new BuildException("Divide requires numeric operands");
762 |  |
                 }
763 |  |
                 else
764 | 0 |
                     return new DivideOperation(l, r);
765 |  |
             }
766 |  |
         }
767 |  |
768 |  |
         public static class CompareEqBuilder extends BinaryOperationBuilder
769 |  |
         {
770 |  |
771 |  |
             public CompareEqBuilder (Object l, Object r)
772 |  |
             {
773 | 44 |
                 super(l, r);
774 | 44 |
             }
775 |  |
776 |  |
             public Object build (Object l, Object r) throws BuildException
777 |  |
             {
778 | 44 |
                 CompareEq c = new CompareEq(l, r);
779 |  |
780 | 44 |
                 if ((l instanceof Macro) || (r instanceof Macro))
781 | 44 |
                     return c;
782 |  |
                 else
783 |  |
                     try
784 |  |
                     {
785 | 0 |
                         return c.operate(l, r);
786 |  |
                     }
787 | 0 |
                     catch (PropertyException e)
788 |  |
                     {
789 | 0 |
                         throw new BuildException(e.toString());
790 |  |
                     }
791 |  |
             }
792 |  |
         }
793 |  |
794 |  |
         public static class CompareNeBuilder extends BinaryOperationBuilder
795 |  |
         {
796 |  |
797 |  |
             public CompareNeBuilder (Object l, Object r)
798 |  |
             {
799 | 58 |
                 super(l, r);
800 | 58 |
             }
801 |  |
802 |  |
             public Object build (Object l, Object r) throws BuildException
803 |  |
             {
804 | 58 |
                 CompareNe c = new CompareNe(l, r);
805 |  |
806 | 58 |
                 if ((l instanceof Macro) || (r instanceof Macro))
807 | 58 |
                     return c;
808 |  |
                 else
809 |  |
                     try
810 |  |
                     {
811 | 0 |
                         return c.operate(l, r);
812 |  |
                     }
813 | 0 |
                     catch (PropertyException e)
814 |  |
                     {
815 | 0 |
                         throw new BuildException(e.toString());
816 |  |
                     }
817 |  |
             }
818 |  |
         }
819 |  |
820 |  |
         public static class CompareLeBuilder extends BinaryOperationBuilder
821 |  |
         {
822 |  |
823 |  |
             public CompareLeBuilder (Object l, Object r)
824 |  |
             {
825 | 0 |
                 super(l, r);
826 | 0 |
             }
827 |  |
828 |  |
             public Object build (Object l, Object r) throws BuildException
829 |  |
             {
830 | 0 |
                 CompareLe c = new CompareLe(l, r);
831 |  |
832 | 0 |
                 if ((l instanceof Macro) || (r instanceof Macro))
833 | 0 |
                     return c;
834 |  |
                 else
835 |  |
                     try
836 |  |
                     {
837 | 0 |
                         return c.operate(l, r);
838 |  |
                     }
839 | 0 |
                     catch (PropertyException e)
840 |  |
                     {
841 | 0 |
                         throw new BuildException(e.toString());
842 |  |
                     }
843 |  |
             }
844 |  |
         }
845 |  |
846 |  |
         public static class CompareLtBuilder extends BinaryOperationBuilder
847 |  |
         {
848 |  |
849 |  |
             public CompareLtBuilder (Object l, Object r)
850 |  |
             {
851 | 2 |
                 super(l, r);
852 | 2 |
             }
853 |  |
854 |  |
             public Object build (Object l, Object r) throws BuildException
855 |  |
             {
856 | 2 |
                 CompareLt c = new CompareLt(l, r);
857 |  |
858 | 2 |
                 if ((l instanceof Macro) || (r instanceof Macro))
859 | 2 |
                     return c;
860 |  |
                 else
861 |  |
                     try
862 |  |
                     {
863 | 0 |
                         return c.operate(l, r);
864 |  |
                     }
865 | 0 |
                     catch (PropertyException e)
866 |  |
                     {
867 | 0 |
                         throw new BuildException(e.toString());
868 |  |
                     }
869 |  |
             }
870 |  |
         }
871 |  |
872 |  |
         public static class CompareGeBuilder extends BinaryOperationBuilder
873 |  |
         {
874 |  |
875 |  |
             public CompareGeBuilder (Object l, Object r)
876 |  |
             {
877 | 0 |
                 super(l, r);
878 | 0 |
             }
879 |  |
880 |  |
             public Object build (Object l, Object r) throws BuildException
881 |  |
             {
882 | 0 |
                 CompareGe c = new CompareGe(l, r);
883 |  |
884 | 0 |
                 if ((l instanceof Macro) || (r instanceof Macro))
885 | 0 |
                     return c;
886 |  |
                 else
887 |  |
                     try
888 |  |
                     {
889 | 0 |
                         return c.operate(l, r);
890 |  |
                     }
891 | 0 |
                     catch (PropertyException e)
892 |  |
                     {
893 | 0 |
                         throw new BuildException(e.toString());
894 |  |
                     }
895 |  |
             }
896 |  |
         }
897 |  |
898 | 0 |
         public static class CompareGtBuilder extends BinaryOperationBuilder
899 |  |
         {
900 |  |
901 |  |
             public CompareGtBuilder (Object l, Object r)
902 |  |
             {
903 | 8 |
                 super(l, r);
904 | 8 |
             }
905 |  |
906 |  |
             public Object build (Object l, Object r) throws BuildException
907 |  |
             {
908 | 8 |
                 CompareGt c = new CompareGt(l, r);
909 |  |
910 | 8 |
                 if ((l instanceof Macro) || (r instanceof Macro))
911 | 8 |
                     return c;
912 |  |
                 else
913 |  |
                     try
914 |  |
                     {
915 | 0 |
                         return c.operate(l, r);
916 |  |
                     }
917 | 0 |
                     catch (PropertyException e)
918 |  |
                     {
919 | 0 |
                         throw new BuildException(e.toString());
920 |  |
                     }
921 |  |
             }
922 |  |
         }
923 |  |
     }