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 / HostExpressionUtils.java @ 47293

History | View | Annotate | Download (14.6 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.List;
5
import java.util.Objects;
6
import org.apache.commons.lang3.StringUtils;
7
import org.gvsig.expressionevaluator.Code;
8
import org.gvsig.expressionevaluator.CodeBuilder;
9
import org.gvsig.expressionevaluator.Codes;
10
import org.gvsig.expressionevaluator.Compiler;
11
import org.gvsig.expressionevaluator.Expression;
12
import org.gvsig.expressionevaluator.ExpressionBuilder;
13
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
14
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
15
import org.gvsig.expressionevaluator.Interpreter;
16
import org.gvsig.expressionevaluator.SymbolTable;
17
import org.gvsig.expressionevaluator.impl.function.programming.$HostExpressionFunction;
18
import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockFunction;
19
import org.gvsig.expressionevaluator.impl.function.programming.CodeBlockWithExceptFunction;
20
import org.gvsig.expressionevaluator.spi.UndefinedSymbolException;
21
import org.gvsig.tools.exception.BaseException;
22
import org.gvsig.tools.visitor.VisitCanceledException;
23

    
24
/**
25
 *
26
 * @author jjdelcerro
27
 */
28
public class HostExpressionUtils {
29

    
30
    public static boolean hasHostExpressions(Code statement) {
31
        try {
32
            statement.accept(
33
                    (Object code) -> {
34
                        if( !(code instanceof Code.Callable) ) {
35
                            return;
36
                        }
37
                        Code.Callable callable = (Code.Callable) code;
38
                        if( StringUtils.equalsIgnoreCase(callable.name(), ExpressionBuilder.FUNCTION_$HOSTEXPRESSION) ) {
39
                            throw new VisitCanceledException();
40
                        }
41
                    }, null
42
            );
43
            return false;
44
        } catch(VisitCanceledException ex) {
45
            return true;
46
        } catch(BaseException ex) {
47
            throw new RuntimeException("Can't check host expressions", ex);
48
        }
49
    }
50

    
51
    public static boolean hasHostExpressions(ExpressionBuilder.Value statement) {
52
        List<ExpressionBuilder.Function> hostExpressions = new ArrayList<>();
53
        statement.accept((ExpressionBuilder.Visitable value) -> {
54
                if( !(value instanceof ExpressionBuilder.Function) ) {
55
                    return;
56
                }
57
                ExpressionBuilder.Function function = (ExpressionBuilder.Function) value;
58
                if( StringUtils.equalsIgnoreCase(function.name(), ExpressionBuilder.FUNCTION_$HOSTEXPRESSION) ) {
59
                    hostExpressions.add(function);
60
                }
61
        }, null);
62
        return !hostExpressions.isEmpty();
63
    }
64

    
65
    public static boolean hasHostExpressions(String statement) {
66
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
67
        Code code = compiler.compileExpression(statement);
68
        return hasHostExpressions(code);
69
    }
70
    
71
    public static List<Code> getHostExpressions(Code statement) throws Exception {
72
        List<Code> hostExpressions = new ArrayList<>();
73
        statement.accept(
74
                (Object code) -> {
75
                    if( !(code instanceof Code.Callable) ) {
76
                        return;
77
                    }
78
                    Code.Callable callable = (Code.Callable) code;
79
                    if( StringUtils.equalsIgnoreCase(callable.name(), ExpressionBuilder.FUNCTION_$HOSTEXPRESSION) ) {
80
                        hostExpressions.add(callable);
81
                    }
82
                }, null 
83
        );
84
        return hostExpressions;
85
    }
86

    
87
    public static List<ExpressionBuilder.Value> getHostExpressions(ExpressionBuilder.Value statement) throws Exception {
88
        List<ExpressionBuilder.Value> hostExpressions = new ArrayList<>();
89
        ExpressionBuilder.Value newstatement = (ExpressionBuilder.Value) statement.clone();
90
        newstatement.accept((ExpressionBuilder.Visitable value) -> {
91
                if( !(value instanceof ExpressionBuilder.Function) ) {
92
                    return;
93
                }
94
                ExpressionBuilder.Function function = (ExpressionBuilder.Function) value;
95
                if( StringUtils.equalsIgnoreCase(function.name(), ExpressionBuilder.FUNCTION_$HOSTEXPRESSION) ) {
96
                    hostExpressions.add(function);
97
                }
98
        }, null);
99
        return hostExpressions;
100
    }
101

    
102
    public static ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder) {
103
        return getHostExpressionValue(hostExpression, expbuilder, null, null);        
104
    }
105
    
106
    public static ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder, SymbolTable symbolTable) {
107
        Interpreter interpreter = createInterpreter();
108
        if( symbolTable!=null ) {
109
            interpreter.setSymbolTable(symbolTable);
110
        }
111
        return getHostExpressionValue(hostExpression, expbuilder, null, interpreter);        
112
    }
113
    
114
    public static ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder, org.gvsig.expressionevaluator.Compiler compiler, Interpreter interpreter) {
115
        if( expbuilder == null ) {
116
            expbuilder = createExpressionBuilder();
117
        }
118
        if( compiler == null ) {
119
            compiler = createCompiler();
120
        }
121
        if( interpreter == null ) {
122
            interpreter = createInterpreter();
123
        }
124
        List<ExpressionBuilder.Value> params = hostExpression.parameters();
125
        String mode_specifier;
126
        ExpressionBuilder.Value exp;
127
        switch(params.size()) {
128
            case 1:
129
            default:
130
                exp = params.get(0);
131
                mode_specifier = $HostExpressionFunction.MODE_SPECIFIER_IN;
132
                break;
133
            case 2:
134
                exp = params.get(0);
135
                mode_specifier = Objects.toString(((ExpressionBuilder.Constant)params.get(1)).value(),"IN").toUpperCase();
136
                break;
137
        }
138
        Code code = compiler.compileExpression(exp.toString());
139
        Object v = interpreter.run(code);
140
        ExpressionBuilder.Value value;
141
        switch(mode_specifier) {
142
            case $HostExpressionFunction.MODE_SPECIFIER_IN:
143
            default:
144
                value = expbuilder.constant(v);
145
                break;
146
            case $HostExpressionFunction.MODE_SPECIFIER_OUT:
147
            case $HostExpressionFunction.MODE_SPECIFIER_INOUT:
148
                throw new UnsupportedOperationException("Mode OUT/INOUT not implemented");
149
            case $HostExpressionFunction.MODE_SPECIFIER_ID:
150
                value = expbuilder.variable(Objects.toString(v, null));
151
                break;
152
        }
153
        return value;
154
    }
155
    
156
    public static List<ExpressionBuilder.Value> getHostExpressionsValuesFromValues(Interpreter interpreter, List<ExpressionBuilder.Value> hostExpressions) throws Exception {
157
        ExpressionBuilder expbuilder = createExpressionBuilder();
158
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
159
        List<ExpressionBuilder.Value> values = new ArrayList<>();        
160
        for (ExpressionBuilder.Value value : hostExpressions) {            
161
            ExpressionBuilder.Function hostExpression = (ExpressionBuilder.Function)value;
162
            values.add(getHostExpressionValue(hostExpression, expbuilder, compiler, interpreter));
163
        }
164
        return values;
165
    }
166
        
167
    public static List<Code> getHostExpressionsValuesFromCodes(Interpreter interpreter, List<Code> hostExpressions) throws Exception {
168
        CodeBuilder codeBuilder = ((DefaultInterpreter)interpreter).getCodeBuilder();
169
        List<Code> values = new ArrayList<>();
170
        for (Code code : hostExpressions) {
171
            Code.Callable hostExpression = (Code.Callable)code;
172
            Codes params = hostExpression.parameters();
173
            String mode_specifier;
174
            Code exp;
175
            switch(params.size()) {
176
                case 1:
177
                default:
178
                    exp = params.get(0);
179
                    mode_specifier = $HostExpressionFunction.MODE_SPECIFIER_IN;
180
                    break;
181
                case 2:
182
                    exp = params.get(0);
183
                    mode_specifier = Objects.toString(((Code.Constant)params.get(1)).value(),"IN").toUpperCase();
184
                    break;
185
            }
186
            Code replacement;
187
            try {
188
                Object v = interpreter.run(exp);
189
                switch(mode_specifier) {
190
                    case $HostExpressionFunction.MODE_SPECIFIER_IN:
191
                    default:
192
                        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
193
                        replacement = manager.convertToCode(codeBuilder, v, null);
194
                        break;
195
                    case $HostExpressionFunction.MODE_SPECIFIER_OUT:
196
                    case $HostExpressionFunction.MODE_SPECIFIER_INOUT:
197
                        throw new UnsupportedOperationException("Mode OUT/INOUT not implemented");
198
                    case $HostExpressionFunction.MODE_SPECIFIER_ID:
199
                        replacement = codeBuilder.identifier(Objects.toString(v, null));
200
                        break;
201
                }
202
            } catch(UndefinedSymbolException ex) {
203
                replacement = null;
204
            }
205
            values.add(replacement);
206
        }
207
        return values;
208
    }
209
        
210

    
211
    public static Code resolveHostExpressions(Code statement, Interpreter interpreter) {
212
        try {
213
            if( statement.code()==Code.CALLABLE ) {
214
                // Los bloques BEGIN/END se ejecutan en local siempre, y se
215
                // encargan ellos de resolver las host-expression.
216
                if( StringUtils.equalsIgnoreCase(CodeBlockFunction.NAME, ((Code.Callable)statement).name()) ) {
217
                    return statement;
218
                }
219
                if( StringUtils.equalsIgnoreCase(CodeBlockWithExceptFunction.NAME, ((Code.Callable)statement).name()) ) {
220
                    return statement;
221
                }
222
            }
223
            if( !hasHostExpressions(statement) ) {
224
                return statement;
225
            }
226
            Code newstatement = (Code) statement.clone();
227
            List<Code> hostExpressions = getHostExpressions(newstatement);
228
            if (hostExpressions.isEmpty()) {
229
                return statement;
230
            }
231
            List<Code> replacements = getHostExpressionsValuesFromCodes(interpreter, hostExpressions);
232

    
233
            for (int i = 0; i < hostExpressions.size(); i++) {
234
                Code hostExpression = hostExpressions.get(i);
235
                Code value = replacements.get(i);
236
                if( value != null ) {
237
                    newstatement.replace(hostExpression, value);
238
                }
239
            }
240
            return newstatement;
241
        } catch (Exception ex) {
242
            throw new RuntimeException("Can't resolve host expressions", ex);
243
        }
244
    }
245
    
246
    public static ExpressionBuilder.Value resolveHostExpressions(ExpressionBuilder.Value statement, SymbolTable symbolTable) {
247
        try {
248
            if( !hasHostExpressions(statement) ) {
249
                return statement;
250
            }
251
            ExpressionBuilder.Value newstatement = (ExpressionBuilder.Value) statement.clone();
252
            List<ExpressionBuilder.Value> hostExpressions = getHostExpressions(newstatement);
253
            if (hostExpressions.isEmpty()) {
254
                return statement;
255
            }
256
            
257
            Interpreter interpreter = createInterpreter();
258
            if( symbolTable!=null ) {
259
                interpreter.setSymbolTable(symbolTable);
260
            }
261
            List<ExpressionBuilder.Value> replacements = getHostExpressionsValuesFromValues(interpreter, hostExpressions);
262

    
263
            for (int i = 0; i < hostExpressions.size(); i++) {
264
                ExpressionBuilder.Value hostExpression = hostExpressions.get(i);
265
                ExpressionBuilder.Value value = replacements.get(i);
266
                newstatement.replace(hostExpression, value);
267
            }
268
            return newstatement;
269
        } catch (Exception ex) {
270
            throw new RuntimeException("Can't resolve host expressions", ex);
271
        }
272
    }
273
    
274
    public static Code resolveHostExpressions(Code statement, SymbolTable symbolTable) {
275
        try {
276
            if( !hasHostExpressions(statement) ) {
277
                return statement;
278
            }
279
            Code newstatement = (Code) statement.clone();
280
            List<Code> hostExpressions = getHostExpressions(newstatement);
281
            if (hostExpressions.isEmpty()) {
282
                return statement;
283
            }
284
            Interpreter interpreter = createInterpreter();
285
            if( symbolTable!=null ) {
286
                interpreter.setSymbolTable(symbolTable);
287
            }
288
            List<Code> replacements = getHostExpressionsValuesFromCodes(interpreter, hostExpressions);
289

    
290
            for (int i = 0; i < hostExpressions.size(); i++) {
291
                Code hostExpression = hostExpressions.get(i);
292
                Code value = replacements.get(i);
293
                newstatement.replace(hostExpression, value);
294
            }
295
            return newstatement;
296
        } catch (Exception ex) {
297
            throw new RuntimeException("Can't resolve host expressions", ex);
298
        }
299
    }
300
    
301
    public static Expression resolveHostExpressions(Expression expression, SymbolTable symbolTable) {
302
            Code newcode = resolveHostExpressions(expression.getCode(), symbolTable);
303
            if( newcode == expression.getCode() ) {
304
                // No hay "hosts expressions", devolvemos la expresion original.
305
                return expression;
306
            }
307
            Expression exp = createExpression();
308
            exp.setPhrase(newcode.toValue().toString());
309
            return exp;
310
    }
311

    
312
    private static Compiler createCompiler() {
313
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
314
        return manager.createCompiler();
315
    }
316

    
317
    private static Interpreter createInterpreter() {
318
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
319
        return manager.createInterpreter();
320
    }
321

    
322
    private static ExpressionBuilder createExpressionBuilder() {
323
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
324
        return manager.createExpressionBuilder();
325
    }
326

    
327
    private static Expression createExpression() {
328
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
329
        return manager.createExpression();
330
    }
331
    
332
}