Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.lib / org.gvsig.expressionevaluator.lib.impl / src / main / java / org / gvsig / expressionevaluator / impl / function / operator / DivOperator.java @ 46901

History | View | Annotate | Download (3.57 KB)

1
package org.gvsig.expressionevaluator.impl.function.operator;
2

    
3
import java.math.BigDecimal;
4
import org.gvsig.expressionevaluator.Code;
5
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_DIV;
6
import org.gvsig.expressionevaluator.Function;
7
import org.gvsig.expressionevaluator.Interpreter;
8
import org.gvsig.expressionevaluator.Optimizer;
9

    
10
public class DivOperator 
11
        extends AbstractBinaryOperator 
12
        implements Optimizer.FunctionOptimizer
13
    {
14

    
15
    public DivOperator() {
16
        super(Function.GROUP_NUMERIC, OPERATOR_DIV, true);
17
    }
18

    
19
    @Override
20
    public boolean allowConstantFolding() {
21
        return true;
22
    }
23
    
24
    @Override
25
    public Object call(Interpreter interpreter, Object op1, Object op2) {
26
        if (op1 == null || op2 == null) {
27
            return null;
28
        }
29
        int type = this.getType(op1, op2);
30
        if( (type & TYPE_DOUBLE) == TYPE_DOUBLE ) {
31
            double value = getDouble(op1,1) / getDouble(op2,2);
32
            checkDoubleValue(value);
33
            return value;
34
        }
35
        if( (type & TYPE_FLOAT) == TYPE_FLOAT ) {
36
            double value = getFloat(op1,1) / getFloat(op2,2);
37
            checkDoubleValue(value);
38
            return value;
39
        }
40
        if( (type & TYPE_BIGDECIMAL) == TYPE_BIGDECIMAL ) {
41
            try {
42
                BigDecimal value = getBigDecimal(op1,1).divide(getBigDecimal(op2,2));
43
                return value;
44
            } catch(ArithmeticException ex) {
45
                double v1 = getDouble(op1,1) / getDouble(op2,2);
46
                BigDecimal value = BigDecimal.valueOf(v1);
47
                return value;
48
            }
49
        }
50
        if( (type & TYPE_LONG) == TYPE_LONG ) {
51
            long value = getLong(op1,1) / getLong(op2,2);
52
            return value;
53
        }
54
        if( (type & TYPE_INT) == TYPE_INT ) {
55
            int value = getInt(op1,1) / getInt(op2,2);
56
            return value;
57
        }
58
        throw new IllegalArgumentException("Types not allowed in '"+name()+"' operand.");
59
    }
60
    
61

    
62
    @Override
63
    public Code optimize(Optimizer optimizer, Code.Callable caller) {
64
        Code op1 = optimizer.optimize(caller.parameters().get(0));
65
        Code op2 = optimizer.optimize(caller.parameters().get(1));
66
        
67
        if ( op1.code() == Code.CONSTANT && op2.code() == Code.CONSTANT) {
68
            Code newCode = optimizer.getCodeBuilder().constant(
69
                    call(
70
                            optimizer.getInterpreter(), 
71
                            ((Code.Constant)op1).value(), 
72
                            ((Code.Constant)op2).value()
73
                    )
74
            );
75
            return newCode;
76
            
77
        } else if ( op1.code() == Code.CONSTANT ) {
78
            Object value = ((Code.Constant)op1).value();
79
            if( value instanceof Number ) {
80
                double n = ((Number) value).doubleValue();
81
                if( n == 0 ) {
82
                    Code newCode = optimizer.getCodeBuilder().constant(0);
83
                    return newCode;
84
                }
85
            }
86
            Code newCode = optimizer.getCodeBuilder().operator(caller.name(), op1, op2);
87
            return newCode;
88

    
89
        } else if ( op2.code() == Code.CONSTANT ) {
90
            Object value = ((Code.Constant)op2).value();
91
            if( value instanceof Number ) {
92
                double n = ((Number) value).doubleValue();
93
                if( n == 1 ) {
94
                    return op1;
95
                }
96
            }
97
            Code newCode = optimizer.getCodeBuilder().operator(caller.name(), op1, op2);
98
            return newCode;
99
        }
100

    
101
        return caller;
102
    }
103
    
104
}