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