View Javadoc

    1   /***
    2    *
    3    * Copyright 2004 Protique Ltd
    4    * Copyright 2004 Hiram Chirino
    5    *
    6    * Licensed under the Apache License, Version 2.0 (the "License");
    7    * you may not use this file except in compliance with the License.
    8    * You may obtain a copy of the License at
    9    *
    10   * http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   *
    18   **/
    19  package org.codehaus.activemq.filter;
    20
    21  import javax.jms.JMSException;
    22  import javax.jms.Message;
    23
    24  /***
    25   * An expression which performs an operation on two expression values
    26   *
    27   * @version $Revision: 1.1 $
    28   */
    29  public abstract class ArithmeticExpression extends BinaryExpression {
    30
    31      protected static final int INTEGER = 1;
    32      protected static final int LONG = 2;
    33      protected static final int DOUBLE = 3;
    34
    35      /***
    36       * @param left
    37       * @param right
    38       */
    39      public ArithmeticExpression(Expression left, Expression right) {
    40          super(left, right);
    41      }
    42
    43      public static Expression createPlus(Expression left, Expression right) {
    44          return new ArithmeticExpression(left, right) {
    45              protected Object evaluate(Object lvalue, Object rvalue) {
    46                  if (lvalue instanceof String) {
    47                      String text = (String) lvalue;
    48                      String answer = text + rvalue;
    49                      System.out.println("lvalue: " + lvalue + " rvalue: " + rvalue + " result: " + answer);
    50                      return answer;
    51                  }
    52                  else if (lvalue instanceof Number) {
    53                      return plus((Number) lvalue, asNumber(rvalue));
    54                  }
    55                  throw new RuntimeException("Cannot call plus operation on: " + lvalue + " and: " + rvalue);
    56              }
    57
    58              public String getExpressionSymbol() {
    59                  return "+";
    60              }
    61          };
    62      }
    63
    64      public static Expression createMinus(Expression left, Expression right) {
    65          return new ArithmeticExpression(left, right) {
    66              protected Object evaluate(Object lvalue, Object rvalue) {
    67                  if (lvalue instanceof Number) {
    68                      return minus((Number) lvalue, asNumber(rvalue));
    69                  }
    70                  throw new RuntimeException("Cannot call minus operation on: " + lvalue + " and: " + rvalue);
    71              }
    72
    73              public String getExpressionSymbol() {
    74                  return "-";
    75              }
    76          };
    77      }
    78
    79      public static Expression createMultiply(Expression left, Expression right) {
    80          return new ArithmeticExpression(left, right) {
    81
    82              protected Object evaluate(Object lvalue, Object rvalue) {
    83                  if (lvalue instanceof Number) {
    84                      return multiply((Number) lvalue, asNumber(rvalue));
    85                  }
    86                  throw new RuntimeException("Cannot call multiply operation on: " + lvalue + " and: " + rvalue);
    87              }
    88
    89              public String getExpressionSymbol() {
    90                  return "*";
    91              }
    92          };
    93      }
    94
    95      public static Expression createDivide(Expression left, Expression right) {
    96          return new ArithmeticExpression(left, right) {
    97
    98              protected Object evaluate(Object lvalue, Object rvalue) {
    99                  if (lvalue instanceof Number) {
    100                     return divide((Number) lvalue, asNumber(rvalue));
    101                 }
    102                 throw new RuntimeException("Cannot call divide operation on: " + lvalue + " and: " + rvalue);
    103             }
    104
    105             public String getExpressionSymbol() {
    106                 return "/";
    107             }
    108         };
    109     }
    110
    111     public static Expression createMod(Expression left, Expression right) {
    112         return new ArithmeticExpression(left, right) {
    113
    114             protected Object evaluate(Object lvalue, Object rvalue) {
    115                 if (lvalue instanceof Number) {
    116                     return mod((Number) lvalue, asNumber(rvalue));
    117                 }
    118                 throw new RuntimeException("Cannot call mod operation on: " + lvalue + " and: " + rvalue);
    119             }
    120
    121             public String getExpressionSymbol() {
    122                 return "%";
    123             }
    124         };
    125     }
    126
    127     protected Number plus(Number left, Number right) {
    128         switch (numberType(left, right)) {
    129             case INTEGER:
    130                 return new Integer(left.intValue() + right.intValue());
    131             case LONG:
    132                 return new Long(left.longValue() + right.longValue());
    133             default:
    134                 return new Double(left.doubleValue() + right.doubleValue());
    135         }
    136     }
    137
    138     protected Number minus(Number left, Number right) {
    139         switch (numberType(left, right)) {
    140             case INTEGER:
    141                 return new Integer(left.intValue() - right.intValue());
    142             case LONG:
    143                 return new Long(left.longValue() - right.longValue());
    144             default:
    145                 return new Double(left.doubleValue() - right.doubleValue());
    146         }
    147     }
    148
    149     protected Number multiply(Number left, Number right) {
    150         switch (numberType(left, right)) {
    151             case INTEGER:
    152                 return new Integer(left.intValue() * right.intValue());
    153             case LONG:
    154                 return new Long(left.longValue() * right.longValue());
    155             default:
    156                 return new Double(left.doubleValue() * right.doubleValue());
    157         }
    158     }
    159
    160     protected Number divide(Number left, Number right) {
    161         return new Double(left.doubleValue() / right.doubleValue());
    162     }
    163
    164     protected Number mod(Number left, Number right) {
    165         return new Double(left.doubleValue() % right.doubleValue());
    166     }
    167
    168     private int numberType(Number left, Number right) {
    169         if (isDouble(left) || isDouble(right)) {
    170             return DOUBLE;
    171         }
    172         else if (left instanceof Long || right instanceof Long) {
    173             return LONG;
    174         }
    175         else {
    176             return INTEGER;
    177         }
    178     }
    179
    180     private boolean isDouble(Number n) {
    181         return n instanceof Float || n instanceof Double;
    182     }
    183
    184     protected Number asNumber(Object value) {
    185         if (value instanceof Number) {
    186             return (Number) value;
    187         }
    188         else {
    189             throw new RuntimeException("Cannot convert value: " + value + " into a number");
    190         }
    191     }
    192
    193     public Object evaluate(Message message) throws JMSException {
    194         Object lvalue = left.evaluate(message);
    195         if (lvalue == null) {
    196             return null;
    197         }
    198         Object rvalue = right.evaluate(message);
    199         if (rvalue == null) {
    200             return null;
    201         }
    202         return evaluate(lvalue, rvalue);
    203     }
    204
    205
    206     /***
    207      * @param lvalue
    208      * @param rvalue
    209      * @return
    210      */
    211     abstract protected Object evaluate(Object lvalue, Object rvalue);
    212
    213 }