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 @ 44207

History | View | Annotate | Download (3.79 KB)

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

    
3
import java.util.Objects;
4
import org.gvsig.expressionevaluator.Code;
5
import org.gvsig.expressionevaluator.Code.Caller;
6
import org.gvsig.expressionevaluator.Code.Constant;
7
import org.gvsig.expressionevaluator.ExpressionBuilder;
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

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

    
21

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

    
26
    @Override
27
    public boolean allowConstantFolding() {
28
        return true;
29
    }
30
    
31
    @Override
32
    public Object call(Interpreter interpreter, Object op1, Object op2) {       
33
        int type = this.getType(op1, op2);
34
        if( (type & TYPE_DOUBLE) == TYPE_DOUBLE ) {
35
            double value = ((Number) op1).doubleValue() + ((Number) op2).doubleValue();
36
            return value;
37
        }
38
        if( (type & TYPE_FLOAT) == TYPE_FLOAT ) {
39
            double value = ((Number) op1).floatValue() + ((Number) op2).floatValue();
40
            return value;
41
        }
42
        if( (type & TYPE_LONG) == TYPE_LONG ) {
43
            long value = ((Number) op1).longValue() + ((Number) op2).longValue();
44
            return value;
45
        }
46
        if( (type & TYPE_INT) == TYPE_INT ) {
47
            int value = ((Number) op1).intValue()+ ((Number) op2).intValue();
48
            return value;
49
        }
50
        if( (type & TYPE_STRING) == TYPE_STRING ) {
51
            if( interpreter.isSQLCompatible() ) {
52
                throw new ExpressionRuntimeException(
53
                        null, 
54
                        "The '"+name()+"' operator can not be used with string operands", 
55
                        I18N.Use_the_operator_CONCAT_to_concatenate_strings()
56
                );
57
            }
58
            return Objects.toString(op1, "")+Objects.toString(op2, "");
59
        }
60
        throw new IllegalArgumentException("Types not allowed in '"+name()+"' operand.");
61
    }
62

    
63
    @Override
64
    public Code optimize(Optimizer optimizer, Caller caller) {
65
        Code op1 = optimizer.optimize(caller.parameters().get(0));
66
        Code op2 = optimizer.optimize(caller.parameters().get(1));
67
        
68
        if ( op1.code() == Code.CONSTANT && op2.code() == Code.CONSTANT) {
69
            Code newCode = optimizer.getCodeBuilder().constant(
70
                    call(
71
                            optimizer.getInterpreter(), 
72
                            ((Constant)op1).value(), 
73
                            ((Constant)op2).value()
74
                    )
75
            );
76
            return newCode;
77
            
78
        } else if ( op1.code() == Code.CONSTANT ) {
79
            Object value = ((Constant)op1).value();
80
            if( value instanceof Number ) {
81
                double n = ((Number) value).doubleValue();
82
                if( n == 0 ) {
83
                   return op2;
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 == 0 ) {
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
}