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

History | View | Annotate | Download (7.66 KB)

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

    
3
import java.util.ArrayList;
4
import java.util.Collection;
5
import java.util.Collections;
6
import java.util.List;
7
import java.util.Objects;
8
import org.apache.commons.lang3.Range;
9
import org.apache.commons.lang3.StringUtils;
10
import org.gvsig.expressionevaluator.Code;
11
import org.gvsig.expressionevaluator.Codes;
12
import org.gvsig.expressionevaluator.Formatter;
13
import org.gvsig.expressionevaluator.Function;
14
import org.gvsig.expressionevaluator.Interpreter;
15
import org.gvsig.expressionevaluator.MutableSymbolTable;
16
import org.gvsig.expressionevaluator.SymbolTable;
17
import org.gvsig.expressionevaluator.impl.DefaultInterpreter;
18
import org.gvsig.expressionevaluator.impl.HostExpressionUtils;
19
import org.gvsig.expressionevaluator.impl.function.programming.BreakFunction.BreakException;
20
import org.gvsig.expressionevaluator.impl.function.programming.ReturnFunction.ReturnException;
21
import org.gvsig.expressionevaluator.spi.AbstractFunction;
22
import org.gvsig.expressionevaluator.PrettyFormatter;
23

    
24
public class CodeBlockWithExceptFunction extends AbstractFunction {
25

    
26
    public static final String NAME = "BLOCK_EXCEPT";
27
    
28
    public CodeBlockWithExceptFunction() {
29
        super(Function.GROUP_PROGRAMMING, 
30
                NAME, 
31
                Range.between(1,Integer.MAX_VALUE),
32
                "Evaluate each of the arguments sequentially.",
33
                NAME+"( {{arguments...}} )",
34
                null,
35
                "Object",
36
                false
37
        );
38
    }
39

    
40
    @Override
41
    public boolean isHidden() {
42
      return true;
43
    }
44
    
45
    @Override
46
    public boolean useArgumentsInsteadObjects() {
47
        return true;
48
    }
49

    
50
    @Override
51
    public boolean allowConstantFolding() {
52
        return false;
53
    }
54
    
55
    @Override
56
    public Object call(Interpreter interpreter, Object[] args) throws Exception {
57
        throw new UnsupportedOperationException("Not supported yet.");
58
    }
59
    
60
    @Override
61
    public Object call(Interpreter interpreter, Codes args) throws Exception {
62
        Object value = null;
63
        Code exceptionCode = args.get(args.size()-2);
64
        Code declareCode = args.get(args.size()-1);
65
        if( declareCode != null ) {
66
            try {
67
                value = ((DefaultInterpreter)interpreter).runCode(declareCode);
68
//            } catch(BreakException|ReturnException ex) {
69
//                throw ex;
70
            } catch(Exception ex) {
71
                if( exceptionCode==null ) {
72
                    LOGGER.warn("Error in DECLARE calling "+ code2string(declareCode), ex);
73
                    throw ex;
74
                } else {                    
75
                    value = ((DefaultInterpreter)interpreter).runCode(exceptionCode);
76
                }
77
            }
78
        }
79
        for (int argn = 0; argn < args.size()-2; argn++) {
80
            Code statement = args.get(argn);
81
            // LLamamos a runCode para que no atrape los returns.
82
            try {
83
                statement = HostExpressionUtils.resolveHostExpressions(statement, interpreter);
84
                value = ((DefaultInterpreter)interpreter).runCode(statement);
85
            } catch(BreakException|ReturnException ex) {
86
                throw ex;
87
            } catch(Exception ex) {
88
                if( exceptionCode==null ) {
89
                    LOGGER.warn("Error in BEGIN/END calling line "+ argn + ", "+ code2string(statement), ex);
90
                    throw ex;
91
                } else {     
92
                    SymbolTable symbolTable = interpreter.getSymbolTable();
93
                    if( symbolTable instanceof MutableSymbolTable ) {
94
                        ((MutableSymbolTable) symbolTable).setVar("@ErrorMessage", ex.getMessage());
95
                        ((MutableSymbolTable) symbolTable).setVar("@ErrorStatement", getErrorStatement(statement));
96
                        ((MutableSymbolTable) symbolTable).setVar("@ErrorContext", this.getErrorContext(symbolTable));
97
                    }
98
                    value = ((DefaultInterpreter)interpreter).runCode(exceptionCode);
99
                }
100
            }
101
        }
102
        return value;
103
    }
104
    
105
    private String getErrorContext(SymbolTable symbolTable) {
106
        try {
107
            StringBuilder builder = new StringBuilder();
108
            List<String> names = new ArrayList<>(symbolTable.variables());
109
            Collections.sort(names);
110
            for (String name : names) {
111
                if( StringUtils.equalsIgnoreCase("@ErrorContext", name) ) {
112
                    continue;
113
                }
114
                String value = "##ERROR##";
115
                try {
116
                    value = Objects.toString(symbolTable.value(name));
117
                } catch(Throwable t) {
118
                    LOGGER.debug("Can't retrieve value for '"+name+"'.",t);
119
                }
120
                builder.append(name);
121
                builder.append("=");
122
                builder.append(value);
123
                builder.append(";\n");
124
            }
125
            return builder.toString();
126
        } catch(Throwable t) {
127
            return "##ERROR##";
128
        }
129
    }
130
    
131
    private String getErrorStatement(Code statement) {
132
        try { 
133
            return statement.toString(); 
134
        } catch(Throwable t) { 
135
            return "Unknown";
136
        }
137
    }
138

    
139
    private String code2string(Code code) {
140
        try {
141
            return Objects.toString(code,"");
142
        } catch(Exception ex2) {
143
            return "unknown";
144
        }
145
    }
146
    
147
    @Override
148
    public String toString(Codes args, Formatter<Code> formatter) {
149
        Code exceptionCode = args.get(args.size()-2);
150
        Code declareCode = args.get(args.size()-1);
151

    
152
        PrettyFormatter builder = PrettyFormatter.get(formatter);
153
        try {
154
            builder.push();
155
            if( declareCode != null ) {
156
                builder.append("DECLARE ");
157
                builder.indent();
158
                if( Code.isFunction(exceptionCode,"BLOCK") ) {
159
                    Code.Callable block = (Code.Callable)declareCode;
160
                    for (Code parameter : block.parameters()) {
161
                        builder.nl();                
162
                        builder.append(parameter.toString(formatter));
163
                        builder.append("; ");
164
                    }
165
                } else {
166
                    builder.nl();
167
                    builder.append(declareCode.toString(formatter));
168
                }
169
                builder.unindent();
170
                builder.nl();
171
            }
172
            builder.append("BEGIN ");
173
            builder.indent();
174
            for (int argn = 0; argn < args.size()-2; argn++) {
175
                Code statement = args.get(argn);
176
                builder.nl();
177
                builder.append(statement.toString(formatter));
178
                builder.append("; ");
179
            }
180
            if( exceptionCode != null ) {
181
                builder.unindent();
182
                builder.nl();
183
                builder.append("EXCEPT ");
184
                builder.indent();
185
                if( Code.isFunction(exceptionCode,"BLOCK") ) {
186
                    Code.Callable block = (Code.Callable)exceptionCode;
187
                    for (Code parameter : block.parameters()) {
188
                        builder.nl();
189
                        builder.append(parameter.toString(formatter));
190
                        builder.append("; ");
191
                    }
192
                } else {
193
                    builder.nl();
194
                    builder.append(exceptionCode.toString(formatter));
195
                    builder.append(" ");
196
                }
197
            }
198
            builder.unindent();
199
            builder.nl();
200
            builder.append("END ");
201
            builder.nl();
202
            return builder.build();
203
        } finally {
204
            builder.pop();
205
        }
206
    }
207
}