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 / MulOperator.java @ 46505

History | View | Annotate | Download (3.55 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_MULT;
6
import org.gvsig.expressionevaluator.Function;
7
import org.gvsig.expressionevaluator.Interpreter;
8
import org.gvsig.expressionevaluator.Optimizer;
9

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

    
15
    public MulOperator() {
16
        super(Function.GROUP_NUMERIC, OPERATOR_MULT, 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_BIGDECIMAL) == TYPE_BIGDECIMAL ) {
31
            BigDecimal value = getBigDecimal(op1,1).multiply(getBigDecimal(op2,2));
32
            return value;
33
        }
34
        if( (type & TYPE_DOUBLE) == TYPE_DOUBLE ) {
35
            double value = getDouble(op1,1) * getDouble(op2,2);
36
            checkDoubleValue(value);
37
            return value;
38
        }
39
        if( (type & TYPE_FLOAT) == TYPE_FLOAT ) {
40
            double value = getFloat(op1,1) * getFloat(op2,2);
41
            checkDoubleValue(value);
42
            return value;
43
        }
44
        if( (type & TYPE_LONG) == TYPE_LONG ) {
45
            long value = getLong(op1,1) * getLong(op2,2);
46
            return value;
47
        }
48
        if( (type & TYPE_INT) == TYPE_INT ) {
49
            int value = getInt(op1,1) * getInt(op2,2);
50
            return value;
51
        }
52
        throw new IllegalArgumentException("Types not allowed in '"+name()+"' operand.");
53
    }
54

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

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

    
99
        return caller;
100
    }
101
    
102

    
103
}