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 / programming / ForEachFunction.java @ 47734

History | View | Annotate | Download (4.47 KB)

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

    
3
import java.util.Objects;
4
import org.apache.commons.lang3.Range;
5
import org.gvsig.expressionevaluator.Code;
6
import org.gvsig.expressionevaluator.Codes;
7
import org.gvsig.expressionevaluator.Function;
8
import org.gvsig.expressionevaluator.Interpreter;
9
import org.gvsig.expressionevaluator.spi.AbstractFunction;
10
import org.gvsig.expressionevaluator.ExpressionRuntimeException;
11
import org.gvsig.expressionevaluator.Formatter;
12
import org.gvsig.expressionevaluator.MutableSymbolTable;
13
import org.gvsig.expressionevaluator.PrettyFormatter;
14
import org.gvsig.expressionevaluator.impl.function.programming.BreakFunction.BreakException;
15
import org.gvsig.expressionevaluator.impl.function.programming.ReturnFunction.ReturnException;
16

    
17
public class ForEachFunction extends AbstractFunction {
18
    
19
    public static final String NAME = "FOREACH";
20

    
21
    public ForEachFunction() {
22
        super(Function.GROUP_PROGRAMMING, 
23
                NAME, 
24
                Range.is(3),
25
                "The foreach() function evaluate body for every element of the iterable.",
26
                "FOR n IN {{expression}}\n  BEGIN\n  PASS;\nEND FOR\n",
27
                null,
28
                "Object",
29
                false
30
        );
31
    }
32

    
33
    @Override
34
    public boolean isHidden() {
35
      return true;
36
    }
37
    
38
    @Override
39
    public boolean useArgumentsInsteadObjects() {
40
        return true;
41
    }
42

    
43
    @Override
44
    public boolean allowConstantFolding() {
45
        return false;
46
    }
47
    
48
    @Override
49
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
50
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
51
    }
52
    
53
    @Override
54
    public Object call(Interpreter interpreter, Codes args) throws Exception {
55
        if ( getObject(interpreter, args, 1)==null) {
56
            return null;
57
        }
58
        if( !(interpreter.getSymbolTable() instanceof MutableSymbolTable) ) {
59
            throw new ExpressionRuntimeException("The use of forech loops require a mutable symbol table.");
60
        }
61
        MutableSymbolTable symbolTable = (MutableSymbolTable) interpreter.getSymbolTable();
62
        
63
        Object body = null;
64
        String varname = getObject(interpreter, args, 0).toString();
65
        int argn = 1;
66
        Iterable iterable = (Iterable) getObject(interpreter, args, 1);
67
        for (Object value : iterable) {
68
            symbolTable.setVar(varname, value);
69
            try {
70
                Object x = getObject(interpreter, args, 2);
71
                body = x;
72
            } catch(BreakException ex) {
73
                break;
74
            } catch(ReturnException ex) {
75
                throw ex;
76
            } catch(Exception ex) {
77
                String stmt = "unknown";
78
                try {
79
                    stmt = Objects.toString(args);
80
                } catch(Exception ex2) {
81
                    
82
                }
83
                LOGGER.warn("Error in foreach function calling arg "+ argn + ", "+ stmt, ex);
84
                throw ex;
85
            }
86
            argn++;
87
        }
88
        return body;
89
    }
90

    
91
    @Override
92
    public String toString(Codes args, Formatter<Code> formatter) {
93
        Code codeVarname = args.get(0);
94
        Code codeList = args.get(1);
95
        Code codeLoopBody = args.get(2);
96
        
97
        PrettyFormatter builder = PrettyFormatter.get(formatter);
98
        try {
99
            builder.push();
100

    
101
            builder.append("FOR \"");
102
            builder.append(Objects.toString(((Code.Constant)codeVarname).value()));        
103
            builder.append("\" IN ");
104
            builder.append(codeList.toString(formatter));
105
            builder.append(" LOOP ");
106
            builder.indent();
107
            builder.nl();
108
            if( Code.isFunction(codeLoopBody,"BLOCK") ) {
109
                Code.Callable block = (Code.Callable)codeLoopBody;
110
                for (Code parameter : block.parameters()) {
111
                    builder.nl();
112
                    builder.append(parameter.toString(formatter));
113
                    builder.append("; ");
114
                }
115
            } else {
116
                builder.nl();
117
                builder.append(codeLoopBody.toString(formatter));
118
                builder.append(" ");
119
            }            
120
            builder.unindent();
121
            builder.nl();
122
            builder.append("END LOOP");
123
            
124
            return builder.build();
125
        } finally {
126
            builder.pop();
127
        }
128
    }
129
    
130
}