01: package org.obe.sql;
02:
03: import java.math.BigDecimal;
04: import java.math.BigInteger;
05: import java.util.ArrayList;
06: import java.util.List;
07: import org.obe.convert.Calculator;
08: import org.obe.convert.Converter;
09: import org.obe.convert.ConverterRegistry;
10:
11: /**
12: * @author Adrian Price
13: */
14: public abstract class SQLArithmeticExpr extends SimpleNode {
15: // Represents the type promotion order.
16: protected static final Class[] _types = { Void.class, String.class,
17: Byte.class, Short.class, Integer.class, Long.class,
18: Float.class, Double.class, BigInteger.class,
19: BigDecimal.class };
20: protected List operators = new ArrayList();
21:
22: private static int getTypeIndex(Object obj) {
23: Class clazz = obj == null ? Void.class : obj.getClass();
24: for (int i = 0; i < _types.length; i++) {
25: if (_types[i] == clazz)
26: return i;
27: }
28: throw new IllegalArgumentException("Illegal argument type: "
29: + clazz);
30: }
31:
32: static Calculator prepare(Object[] args) {
33: int i0 = getTypeIndex(args[0]);
34: int i1 = getTypeIndex(args[1]);
35: Class targetClass = _types[Math.max(i0, i1)];
36: Converter converter = ConverterRegistry.getInstance()
37: .findConverter(targetClass);
38: for (int i = 0; i < args.length; i++)
39: args[i] = converter.convert(args[i]);
40: return converter instanceof Calculator ? (Calculator) converter
41: : ConverterRegistry.getInstance().findCalculator(
42: targetClass);
43: }
44:
45: protected SQLArithmeticExpr(int i) {
46: super (i);
47: }
48:
49: protected Object add(Object[] args) {
50: return prepare(args).add(args[0], args[1]);
51: }
52:
53: protected Object subtract(Object[] args) {
54: return prepare(args).subtract(args[0], args[1]);
55: }
56:
57: protected Object multiply(Object[] args) {
58: return prepare(args).multiply(args[0], args[1]);
59: }
60:
61: protected Object divide(Object[] args) {
62: return prepare(args).divide(args[0], args[1]);
63: }
64:
65: protected Object negate(Object arg) {
66: return arg == null ? null : ConverterRegistry.getInstance()
67: .findCalculator(arg.getClass()).negate(arg);
68: }
69:
70: protected int compare(Object lhs, Object rhs) {
71: Object[] args = new Object[] { lhs, rhs };
72: return prepare(args).compare(args[0], args[1]);
73: }
74: }
|