001 /* Licensed to the Apache Software Foundation (ASF) under one
002 * or more contributor license agreements. See the NOTICE file
003 * distributed with this work for additional information
004 * regarding copyright ownership. The ASF licenses this file
005 * to you under the Apache License, Version 2.0 (the
006 * "License"); you may not use this file except in compliance
007 * with the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing,
012 * software distributed under the License is distributed on an
013 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
014 * KIND, either express or implied. See the License for the
015 * specific language governing permissions and limitations
016 * under the License.
017 */
018 package org.apache.qpid.filter;
019
020 import org.apache.qpid.QpidException;
021 import org.apache.qpid.client.message.AbstractJMSMessage;
022
023
024 /**
025 * An expression which performs an operation on two expression values
026 */
027 public abstract class ArithmeticExpression extends BinaryExpression
028 {
029
030 protected static final int INTEGER = 1;
031 protected static final int LONG = 2;
032 protected static final int DOUBLE = 3;
033
034
035 public ArithmeticExpression(Expression left, Expression right)
036 {
037 super(left, right);
038 }
039
040 public static Expression createPlus(Expression left, Expression right)
041 {
042 return new ArithmeticExpression(left, right)
043 {
044 protected Object evaluate(Object lvalue, Object rvalue)
045 {
046 if (lvalue instanceof String)
047 {
048 String text = (String) lvalue;
049 return text + rvalue;
050 }
051 else if (lvalue instanceof Number)
052 {
053 return plus((Number) lvalue, asNumber(rvalue));
054 }
055
056 throw new RuntimeException("Cannot call plus operation on: " + lvalue + " and: " + rvalue);
057 }
058
059 public String getExpressionSymbol()
060 {
061 return "+";
062 }
063 };
064 }
065
066 public static Expression createMinus(Expression left, Expression right)
067 {
068 return new ArithmeticExpression(left, right)
069 {
070 protected Object evaluate(Object lvalue, Object rvalue)
071 {
072 if (lvalue instanceof Number)
073 {
074 return minus((Number) lvalue, asNumber(rvalue));
075 }
076
077 throw new RuntimeException("Cannot call minus operation on: " + lvalue + " and: " + rvalue);
078 }
079
080 public String getExpressionSymbol()
081 {
082 return "-";
083 }
084 };
085 }
086
087 public static Expression createMultiply(Expression left, Expression right)
088 {
089 return new ArithmeticExpression(left, right)
090 {
091
092 protected Object evaluate(Object lvalue, Object rvalue)
093 {
094 if (lvalue instanceof Number)
095 {
096 return multiply((Number) lvalue, asNumber(rvalue));
097 }
098
099 throw new RuntimeException("Cannot call multiply operation on: " + lvalue + " and: " + rvalue);
100 }
101
102 public String getExpressionSymbol()
103 {
104 return "*";
105 }
106 };
107 }
108
109 public static Expression createDivide(Expression left, Expression right)
110 {
111 return new ArithmeticExpression(left, right)
112 {
113
114 protected Object evaluate(Object lvalue, Object rvalue)
115 {
116 if (lvalue instanceof Number)
117 {
118 return divide((Number) lvalue, asNumber(rvalue));
119 }
120
121 throw new RuntimeException("Cannot call divide operation on: " + lvalue + " and: " + rvalue);
122 }
123
124 public String getExpressionSymbol()
125 {
126 return "/";
127 }
128 };
129 }
130
131 public static Expression createMod(Expression left, Expression right)
132 {
133 return new ArithmeticExpression(left, right)
134 {
135
136 protected Object evaluate(Object lvalue, Object rvalue)
137 {
138 if (lvalue instanceof Number)
139 {
140 return mod((Number) lvalue, asNumber(rvalue));
141 }
142
143 throw new RuntimeException("Cannot call mod operation on: " + lvalue + " and: " + rvalue);
144 }
145
146 public String getExpressionSymbol()
147 {
148 return "%";
149 }
150 };
151 }
152
153 protected Number plus(Number left, Number right)
154 {
155 switch (numberType(left, right))
156 {
157
158 case ArithmeticExpression.INTEGER:
159 return new Integer(left.intValue() + right.intValue());
160
161 case ArithmeticExpression.LONG:
162 return new Long(left.longValue() + right.longValue());
163
164 default:
165 return new Double(left.doubleValue() + right.doubleValue());
166 }
167 }
168
169 protected Number minus(Number left, Number right)
170 {
171 switch (numberType(left, right))
172 {
173
174 case ArithmeticExpression.INTEGER:
175 return new Integer(left.intValue() - right.intValue());
176
177 case ArithmeticExpression.LONG:
178 return new Long(left.longValue() - right.longValue());
179
180 default:
181 return new Double(left.doubleValue() - right.doubleValue());
182 }
183 }
184
185 protected Number multiply(Number left, Number right)
186 {
187 switch (numberType(left, right))
188 {
189
190 case ArithmeticExpression.INTEGER:
191 return new Integer(left.intValue() * right.intValue());
192
193 case ArithmeticExpression.LONG:
194 return new Long(left.longValue() * right.longValue());
195
196 default:
197 return new Double(left.doubleValue() * right.doubleValue());
198 }
199 }
200
201 protected Number divide(Number left, Number right)
202 {
203 return new Double(left.doubleValue() / right.doubleValue());
204 }
205
206 protected Number mod(Number left, Number right)
207 {
208 return new Double(left.doubleValue() % right.doubleValue());
209 }
210
211 private int numberType(Number left, Number right)
212 {
213 if (isDouble(left) || isDouble(right))
214 {
215 return ArithmeticExpression.DOUBLE;
216 }
217 else if ((left instanceof Long) || (right instanceof Long))
218 {
219 return ArithmeticExpression.LONG;
220 }
221 else
222 {
223 return ArithmeticExpression.INTEGER;
224 }
225 }
226
227 private boolean isDouble(Number n)
228 {
229 return (n instanceof Float) || (n instanceof Double);
230 }
231
232 protected Number asNumber(Object value)
233 {
234 if (value instanceof Number)
235 {
236 return (Number) value;
237 }
238 else
239 {
240 throw new RuntimeException("Cannot convert value: " + value + " into a number");
241 }
242 }
243
244 public Object evaluate(AbstractJMSMessage message) throws QpidException
245 {
246 Object lvalue = left.evaluate(message);
247 if (lvalue == null)
248 {
249 return null;
250 }
251
252 Object rvalue = right.evaluate(message);
253 if (rvalue == null)
254 {
255 return null;
256 }
257
258 return evaluate(lvalue, rvalue);
259 }
260
261 /**
262 * @param lvalue
263 * @param rvalue
264 * @return
265 */
266 protected abstract Object evaluate(Object lvalue, Object rvalue);
267
268 }
|