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

History | View | Annotate | Download (4.05 KB)

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

    
3
import java.math.BigDecimal;
4
import java.util.Objects;
5
import org.apache.commons.math.exception.OutOfRangeException;
6
import org.gvsig.expressionevaluator.Code;
7
import org.gvsig.expressionevaluator.Code.Constant;
8
import static org.gvsig.expressionevaluator.ExpressionBuilder.OPERATOR_ADD;
9
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
10
import org.gvsig.expressionevaluator.Function;
11
import org.gvsig.expressionevaluator.Interpreter;
12
import org.gvsig.expressionevaluator.Optimizer;
13
import org.gvsig.expressionevaluator.Optimizer.FunctionOptimizer;
14
import org.gvsig.expressionevaluator.impl.I18N;
15
import org.gvsig.expressionevaluator.Code.Callable;
16

    
17
public class AddOperator 
18
        extends AbstractBinaryOperator 
19
        implements FunctionOptimizer
20
    {
21

    
22

    
23
    public AddOperator() {
24
        super(Function.GROUP_NUMERIC, OPERATOR_ADD, true);
25
    }
26

    
27
    @Override
28
    public boolean allowConstantFolding() {
29
        return true;
30
    }
31
    
32
    @Override
33
    public Object call(Interpreter interpreter, Object op1, Object op2) {
34
        if (op1 == null || op2 == null) {
35
            return null;
36
        }
37
        int type = this.getType(op1, op2);
38
        if( (type & TYPE_BIGDECIMAL) == TYPE_BIGDECIMAL ) {
39
            BigDecimal value = getBigDecimal(op1,1).add(getBigDecimal(op2,2));
40
            return value;
41
        }
42
        if( (type & TYPE_DOUBLE) == TYPE_DOUBLE ) {
43
            double value = getDouble(op1,1) + getDouble(op2,2);
44
            checkDoubleValue(value);
45
            return value;
46
        }
47
        if( (type & TYPE_FLOAT) == TYPE_FLOAT ) {
48
            double value = getFloat(op1,1) + getFloat(op2,2);
49
            checkDoubleValue(value);
50
            return value;
51
        }
52
        if( (type & TYPE_LONG) == TYPE_LONG ) {
53
            long value = getLong(op1,1) + getLong(op2,2);
54
            return value;
55
        }
56
        if( (type & TYPE_INT) == TYPE_INT ) {
57
            int value = getInt(op1,1) + getInt(op2,2);
58
            return value;
59
        }
60
        if( (type & TYPE_STRING) == TYPE_STRING ) {
61
            if( interpreter.isSQLCompatible() ) {
62
                throw new ExpressionRuntimeException(
63
                        null, 
64
                        "The '"+name()+"' operator can not be used with string operands", 
65
                        I18N.Use_the_operator_CONCAT_to_concatenate_strings()
66
                );
67
            }
68
            return Objects.toString(op1, "")+Objects.toString(op2, "");
69
        }
70
        throw new IllegalArgumentException("Types not allowed in '"+name()+"' operand.");
71
    }
72

    
73
    @Override
74
    public Code optimize(Optimizer optimizer, Callable caller) {
75
        Code op1 = optimizer.optimize(caller.parameters().get(0));
76
        Code op2 = optimizer.optimize(caller.parameters().get(1));
77
        
78
        if ( op1.code() == Code.CONSTANT && op2.code() == Code.CONSTANT) {
79
            Code newCode = optimizer.getCodeBuilder().constant(
80
                    call(
81
                            optimizer.getInterpreter(), 
82
                            ((Constant)op1).value(), 
83
                            ((Constant)op2).value()
84
                    )
85
            );
86
            return newCode;
87
            
88
        } else if ( op1.code() == Code.CONSTANT ) {
89
            Object value = ((Constant)op1).value();
90
            if( value instanceof Number ) {
91
                double n = ((Number) value).doubleValue();
92
                if( n == 0 ) {
93
                   return op2;
94
                }
95
            }
96
            Code newCode = optimizer.getCodeBuilder().operator(caller.name(), op1, op2);
97
            return newCode;
98

    
99
        } else if ( op2.code() == Code.CONSTANT ) {
100
            Object value = ((Code.Constant)op2).value();
101
            if( value instanceof Number ) {
102
                double n = ((Number) value).doubleValue();
103
                if( n == 0 ) {
104
                    return op1;
105
                }
106
            }
107
            Code newCode = optimizer.getCodeBuilder().operator(caller.name(), op1, op2);
108
            return newCode;
109
        }
110

    
111
        return caller;
112
    }
113
    
114
}