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 / DefaultExpressionEvaluatorManager.java @ 47248

History | View | Annotate | Download (28.8 KB)

1 43521 jjdelcerro
package org.gvsig.expressionevaluator.impl;
2
3 46932 jjdelcerro
import java.io.IOException;
4
import java.io.PushbackReader;
5
import java.io.StringReader;
6 45366 omartinez
import org.gvsig.expressionevaluator.spi.BaseExpressionEvaluator;
7 44389 jjdelcerro
import java.io.StringWriter;
8 46958 jjdelcerro
import java.io.Writer;
9 44339 jjdelcerro
import java.net.URI;
10 44644 jjdelcerro
import java.util.ArrayList;
11 44139 jjdelcerro
import org.gvsig.expressionevaluator.Grammar;
12
import org.gvsig.expressionevaluator.GrammarFactory;
13 43983 jjdelcerro
import java.util.Collection;
14 44750 jjdelcerro
import java.util.Collections;
15 43939 jjdelcerro
import java.util.HashMap;
16 47175 jjdelcerro
import java.util.LinkedHashMap;
17 44644 jjdelcerro
import java.util.List;
18 43939 jjdelcerro
import java.util.Map;
19 44389 jjdelcerro
import java.util.Objects;
20 44392 jjdelcerro
import java.util.regex.Matcher;
21
import java.util.regex.Pattern;
22 44339 jjdelcerro
import org.apache.commons.io.FilenameUtils;
23
import org.apache.commons.io.IOUtils;
24 46958 jjdelcerro
import org.apache.commons.io.output.ProxyWriter;
25 44389 jjdelcerro
import org.apache.commons.lang3.ArrayUtils;
26
import org.apache.commons.lang3.StringUtils;
27 43521 jjdelcerro
import org.gvsig.expressionevaluator.Code;
28
import org.gvsig.expressionevaluator.CodeBuilder;
29 43983 jjdelcerro
import org.gvsig.expressionevaluator.Expression;
30 44006 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
31 43521 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
32
import org.gvsig.expressionevaluator.Interpreter;
33
import org.gvsig.expressionevaluator.LexicalAnalyzer;
34
import org.gvsig.expressionevaluator.MutableSymbolTable;
35 44009 jjdelcerro
import org.gvsig.expressionevaluator.Optimizer;
36 43521 jjdelcerro
import org.gvsig.expressionevaluator.SymbolTable;
37 44126 jjdelcerro
import org.gvsig.expressionevaluator.SymbolTableFactory;
38 44139 jjdelcerro
import org.gvsig.expressionevaluator.Compiler;
39 47175 jjdelcerro
import org.gvsig.expressionevaluator.ConverterToCode;
40 45366 omartinez
import org.gvsig.expressionevaluator.ExpressionEvaluator;
41 44769 jjdelcerro
import org.gvsig.expressionevaluator.Formatter;
42 44139 jjdelcerro
import org.gvsig.expressionevaluator.GrammarSet;
43 44644 jjdelcerro
import org.gvsig.expressionevaluator.ReprMethod;
44 47175 jjdelcerro
import org.gvsig.expressionevaluator.impl.converterstocode.ArrayToCode;
45
import org.gvsig.expressionevaluator.impl.converterstocode.BooleanToCode;
46
import org.gvsig.expressionevaluator.impl.converterstocode.CharsequenceToCode;
47
import org.gvsig.expressionevaluator.impl.converterstocode.IterableToCode;
48
import org.gvsig.expressionevaluator.impl.converterstocode.IteratorToCode;
49
import org.gvsig.expressionevaluator.impl.converterstocode.ListToCode;
50
import org.gvsig.expressionevaluator.impl.converterstocode.NullToCode;
51
import org.gvsig.expressionevaluator.impl.converterstocode.NumberToCode;
52
import org.gvsig.expressionevaluator.impl.converterstocode.ObjectToCode;
53 44644 jjdelcerro
import org.gvsig.expressionevaluator.impl.repr.ReprNull;
54
import org.gvsig.expressionevaluator.impl.repr.ReprObject;
55 44769 jjdelcerro
import org.gvsig.expressionevaluator.spi.formatter.value.BaseFormatter;
56 45282 omartinez
import org.gvsig.tools.ToolsLocator;
57 44390 jjdelcerro
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
58
import org.gvsig.tools.bookmarksandhistory.History;
59 46828 fdiaz
import org.gvsig.tools.dispose.DisposeUtils;
60 46711 jjdelcerro
import org.gvsig.tools.exception.BaseException;
61 44392 jjdelcerro
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
62 44339 jjdelcerro
import org.gvsig.tools.script.Script;
63 44006 jjdelcerro
import org.slf4j.Logger;
64
import org.slf4j.LoggerFactory;
65 43521 jjdelcerro
66
67 44339 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
68 43521 jjdelcerro
public class DefaultExpressionEvaluatorManager implements ExpressionEvaluatorManager {
69
70 44006 jjdelcerro
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExpressionEvaluatorManager.class);
71
72 43521 jjdelcerro
    private Double accuracy;
73 44126 jjdelcerro
    private final Map<String,SymbolTableFactory>symbolTableFactories;
74 44139 jjdelcerro
    private final Map<String,GrammarFactory> grammarFactories;
75 45703 jjdelcerro
    private Bookmarks<Expression> bookmarks;
76 45282 omartinez
    private static final String BOOKMARKSANDHISTORY_NAME = "ExpressionManager";
77 45703 jjdelcerro
    private History<Expression> history;
78 44446 jjdelcerro
    private SymbolTable inmutableSymbolTable;
79 44533 jjdelcerro
    private ResourcesStorage scriptsResourcesStorage;
80 45932 jjdelcerro
    private final List<ClassLoader> loaders;
81 44769 jjdelcerro
    private Formatter<ExpressionBuilder.Value> expressionBuilderFormatter;
82 43521 jjdelcerro
83 47175 jjdelcerro
    private Map<String,ConverterToCode> convertersToCode;
84
    private Map<String,ConverterToCode> convertersToCode0;
85
86 43521 jjdelcerro
    public DefaultExpressionEvaluatorManager() {
87 44126 jjdelcerro
        this.symbolTableFactories = new HashMap<>();
88 44139 jjdelcerro
        this.grammarFactories = new HashMap<>();
89 44750 jjdelcerro
        this.loaders = new ArrayList<>();
90 44533 jjdelcerro
        this.scriptsResourcesStorage = ResourcesStorage.EMPTY_RESOURCESSTORAGE;
91 44750 jjdelcerro
        this.loaders.add(this.getClass().getClassLoader());
92 44769 jjdelcerro
        this.expressionBuilderFormatter = new BaseFormatter();
93 43939 jjdelcerro
    }
94
95 43521 jjdelcerro
    @Override
96 43983 jjdelcerro
    public SymbolTable getSymbolTable(String name) {
97 44126 jjdelcerro
        if( name == null ) {
98
            return null;
99
        }
100
        SymbolTableFactory factory = this.symbolTableFactories.get(name.toUpperCase());
101
        if( factory == null ) {
102
            return null;
103
        }
104 44389 jjdelcerro
        return factory.create();
105 43939 jjdelcerro
    }
106
107
    @Override
108 44126 jjdelcerro
    public Collection<SymbolTableFactory> getSymbolTableFactories() {
109
        return this.symbolTableFactories.values();
110 43939 jjdelcerro
    }
111
112
    @Override
113 44126 jjdelcerro
    public final void registerSymbolTable(SymbolTableFactory factory) {
114
        if( factory == null ) {
115
            throw new IllegalArgumentException("factory can't be null");
116 44006 jjdelcerro
        }
117 44126 jjdelcerro
        this.symbolTableFactories.put(factory.getName().toUpperCase(),factory);
118 44446 jjdelcerro
        this.inmutableSymbolTable = null;
119 43939 jjdelcerro
    }
120 43987 jjdelcerro
121 43939 jjdelcerro
    @Override
122 44446 jjdelcerro
    public SymbolTable getInmutableSymbolTable() {
123
        if( this.inmutableSymbolTable==null ) {
124
            this.inmutableSymbolTable = new InmutableSymbolTable();
125
        }
126
        return this.inmutableSymbolTable;
127
    }
128
129
    @Override
130 43521 jjdelcerro
    public Object evaluate(String source) {
131 46932 jjdelcerro
        Compiler compiler = this.createCompiler();
132
        Code code = compiler.compileExpression(source);
133 43521 jjdelcerro
        DefaultInterpreter interpreter = new DefaultInterpreter();
134
        return interpreter.run(code);
135
    }
136 44389 jjdelcerro
137 43521 jjdelcerro
    @Override
138
    public Object evaluate(SymbolTable symbolTable, String source) {
139 46932 jjdelcerro
        Compiler compiler = this.createCompiler();
140 43521 jjdelcerro
        Code code = compiler.compileExpression(source);
141 46932 jjdelcerro
        return this.evaluate(symbolTable, code);
142 43521 jjdelcerro
    }
143
144
    @Override
145
    public Object evaluate(SymbolTable symbolTable, Code code) {
146
        DefaultInterpreter interpreter = new DefaultInterpreter();
147 44446 jjdelcerro
        if( symbolTable!=null ) {
148
            interpreter.setSymbolTable(symbolTable);
149
        }
150 43521 jjdelcerro
        return interpreter.run(code);
151
    }
152
153
    @Override
154 44397 jjdelcerro
    public String evaluateDynamicText(String source) {
155
        return evaluateDynamicText(null, source);
156 44389 jjdelcerro
    }
157
158
    @Override
159 44397 jjdelcerro
    public boolean isDynamicText(String source) {
160 44818 jjdelcerro
        String[] sources = StringUtils.substringsBetween(source, DYNAMICTEXT_STARTTAG, DYNAMICTEXT_ENDTAG);
161 44389 jjdelcerro
        if( ArrayUtils.isEmpty(sources) ) {
162 44397 jjdelcerro
            return false;
163
        }
164
        return true;
165
    }
166 46932 jjdelcerro
167
168
    private static final int MODE_EXPRESSION = 0;
169
    private static final int MODE_STATEMENT = 1;
170 44397 jjdelcerro
171 46932 jjdelcerro
    public static String dynamicTextToScript(String s, String contentsName) {
172
        PushbackReader reader = new PushbackReader(new StringReader(s),100);
173
        StringBuilder script = new StringBuilder();
174
        StringBuilder buffer = new StringBuilder();
175
        try {
176
            script.append("begin\n");
177 46958 jjdelcerro
//            script.append(contentsName);
178
//            script.append(" := StringWriter();\n");
179 46932 jjdelcerro
            int mode;
180
            int ch;
181
            int ch2;
182
            while(true) {
183
                ch = reader.read();
184
                if( ch == -1 ) {
185
                    break;
186
                }
187
                switch(ch) {
188
                    case '<':
189
                        ch2 = reader.read();
190
                        if( ch2 != '%') {
191
                            buffer.append((char)ch);
192
                            buffer.append((char)ch2);
193
                            break;
194
                        }
195
                        ch2 = reader.read();
196
                        if( ch2 == '=' ) {
197
                            mode = MODE_EXPRESSION;
198
                        } else {
199
                            mode = MODE_STATEMENT;
200
                            reader.unread(ch2);
201
                        }
202
                        if( buffer.length()>0 ) {
203
                            script.append(contentsName);
204
                            script.append(".append('");
205
                            script.append(buffer.toString());
206
                            script.append("');");
207
                        }
208
                        buffer.setLength(0);
209
                        while(true) {
210
                            ch = reader.read();
211
                            if( ch==-1) {
212
                                break;
213
                            }
214
                            if( ch == '%' ) {
215
                                ch2 = reader.read();
216
                                if( ch2 == '>') {
217
                                    if( mode == MODE_EXPRESSION ) {
218
                                        if( buffer.length()>0 ) {
219
                                            script.append(contentsName);
220
                                            script.append(".append(");
221
                                            script.append(buffer.toString());
222
                                            script.append(");");
223
                                        }
224
                                    } else {
225
                                        script.append(buffer.toString());
226
                                    }
227
                                    buffer.setLength(0);
228
                                    break;
229
                                } else {
230
                                    buffer.append((char)ch);
231
                                    buffer.append((char)ch2);
232
                                }
233
                            } else {
234
                                buffer.append((char)ch);
235
                            }
236
                        }
237
                        break;
238
                    case '\'':
239
                        buffer.append('\'');
240
                        buffer.append('\'');
241
                        break;
242
                    default:
243
                        buffer.append((char)ch);
244
                        break;
245
                }
246
            }
247
        } catch (IOException ex) {
248
249
        }
250
        if( buffer.length()>0 ) {
251
            script.append(contentsName);
252
            script.append(".append('");
253
            script.append(buffer.toString());
254
            script.append("');");
255
            script.append("\n");
256
        }
257 46958 jjdelcerro
//        script.append(contentsName);
258
//        script.append(".toString();\n");
259 46932 jjdelcerro
        script.append("end\n");
260 46958 jjdelcerro
261 46932 jjdelcerro
        return script.toString();
262
    }
263
264 44397 jjdelcerro
    @Override
265
    public String evaluateDynamicText(SymbolTable symbolTable, String source) {
266 46958 jjdelcerro
        return evaluateDynamicText(symbolTable, source, null);
267
    }
268 47063 jjdelcerro
269 46958 jjdelcerro
    public static class AppendExWriter extends ProxyWriter {
270
        public AppendExWriter(Writer writer) {
271
            super(writer);
272 46932 jjdelcerro
        }
273 46958 jjdelcerro
274
        public Writer append(Object x) throws IOException {
275
            if( x!=null ) {
276
                this.append(x.toString());
277
            }
278
            return this;
279 46939 jjdelcerro
        }
280 46958 jjdelcerro
281
        public Writer getWriter() {
282
            return this.out;
283
        }
284 46932 jjdelcerro
    }
285
286 47077 jjdelcerro
    @Override
287
    public String evaluateDynamicText(SymbolTable symbolTable, String source, Writer output) {
288
        return this.evaluateDynamicText(symbolTable, source, output, scriptsResourcesStorage);
289
    }
290 46958 jjdelcerro
291
    @Override
292 47077 jjdelcerro
    public String evaluateDynamicText(SymbolTable symbolTable, String source, Writer output, ResourcesStorage resources) {
293 46958 jjdelcerro
        try {
294
            if (!StringUtils.contains(source, DYNAMICTEXT_STARTTAG)) {
295
                if (output == null) {
296
                    return source;
297
                }
298
                output.append(source);
299
                return null;
300
            }
301
            AppendExWriter writer;
302
            if (output == null) {
303
                writer = new AppendExWriter(new StringWriter());
304
            } else {
305
                writer = new AppendExWriter(output);
306
            }
307
            String script = dynamicTextToScript(source, "contents");
308
            MutableSymbolTable st = this.createSymbolTable();
309
            if (symbolTable != null) {
310
                st.addSymbolTable(symbolTable);
311
            }
312
            st.setVar("contents", writer);
313 47077 jjdelcerro
314
            Compiler compiler = this.createCompiler();
315
            DefaultInterpreter interpreter = new DefaultInterpreter();
316
            interpreter.setSymbolTable(st);
317
            if( resources!=null ) {
318
                interpreter.setResourcesStorage(resources);
319
            }
320
321
            Code code = compiler.compileExpression(script);
322
            interpreter.run(code);
323
324 46958 jjdelcerro
            if (output == null) {
325
                return ((StringWriter) writer.getWriter()).toString();
326
            }
327
            return null;
328
        } catch (IOException ex) {
329
            throw new RuntimeException("Can't evaluate dynamic-text.", ex);
330
        }
331
    }
332
333 46932 jjdelcerro
    public String evaluateDynamicText_old(SymbolTable symbolTable, String source) {
334 44818 jjdelcerro
        String[] sources = StringUtils.substringsBetween(source, DYNAMICTEXT_STARTTAG, DYNAMICTEXT_ENDTAG);
335 44397 jjdelcerro
        if( ArrayUtils.isEmpty(sources) ) {
336 44389 jjdelcerro
            return source;
337
        }
338
        String[] values = new String[sources.length];
339
340
        DefaultInterpreter interpreter = new DefaultInterpreter();
341
        if( symbolTable!=null ) {
342
            interpreter.setSymbolTable(symbolTable);
343
        }
344
        StringWriter writer = new StringWriter();
345
        interpreter.setWriter(writer);
346 44644 jjdelcerro
        DefaultCompiler compiler = new DefaultCompiler(this);
347 44389 jjdelcerro
        for (int i = 0; i < sources.length; i++) {
348
            String theSource = sources[i];
349
            if( StringUtils.startsWith(theSource, "=") ) {
350
                Code code = compiler.compileExpression(theSource.substring(1));
351
                Object value = interpreter.run(code);
352
                values[i] = Objects.toString(value, "");
353
            } else {
354 45778 fdiaz
                Code code = compiler.compileExpression(theSource.substring(0));
355 44389 jjdelcerro
                writer.getBuffer().setLength(0);
356
                interpreter.run(code);
357
                values[i] = writer.toString();
358
            }
359 44818 jjdelcerro
            sources[i] = DYNAMICTEXT_STARTTAG+sources[i]+DYNAMICTEXT_ENDTAG;
360 44389 jjdelcerro
        }
361
        String output = StringUtils.replaceEach(source, sources, values);
362
        return output;
363
    }
364
365
    @Override
366 43521 jjdelcerro
    public Code compile(String source) {
367 44139 jjdelcerro
        Compiler compiler = this.createCompiler();
368 43521 jjdelcerro
        return compiler.compileExpression(source);
369
    }
370
371
    @Override
372
    public Code compile(LexicalAnalyzer lex, String source) {
373 44139 jjdelcerro
        Compiler compiler = this.createCompiler();
374 43521 jjdelcerro
        compiler.setLexicalAnalyzer(lex);
375
        return compiler.compileExpression(source);
376
    }
377
378
    @Override
379 44019 jjdelcerro
    public Code optimize(SymbolTable symbolTable, Code code) {
380
        Optimizer optimizer = this.createOptimizer();
381
        return optimizer.optimize(symbolTable, code);
382
    }
383
384
    @Override
385 43521 jjdelcerro
    public MutableSymbolTable createSymbolTable() {
386 43987 jjdelcerro
        DefaultSymbolTable theSymbolTable = new DefaultSymbolTable();
387
        return theSymbolTable;
388 43521 jjdelcerro
    }
389 43939 jjdelcerro
390 45932 jjdelcerro
    @Override
391 43987 jjdelcerro
    public void populateSymbolTable(SymbolTable aSymbolTable) {
392 44126 jjdelcerro
        for (SymbolTableFactory factory : this.getSymbolTableFactories() ) {
393 44394 jjdelcerro
            try {
394
                if( factory.isAutoload() ) {
395
                    SymbolTable symbolTable = factory.create();
396
                    aSymbolTable.addSymbolTable(symbolTable);
397
                }
398
            } catch(Throwable th) {
399
                String factoryName = "Unknown";
400
                try {
401
                    factoryName = factory.getName();
402
                } catch(Throwable th2) {
403
                    // Do nothing
404
                }
405 44965 jjdelcerro
                LOGGER.warn("Can't create symbol table '"+factoryName+"', ignore this symbol table.");
406
                LOGGER.debug("Error creating symbol table.",th);
407 43987 jjdelcerro
            }
408
        }
409
    }
410
411 43521 jjdelcerro
    @Override
412
    public LexicalAnalyzer createLexicalAnalyzer() {
413
        return new SQLLexicalAnalyzer();
414
    }
415
416
    @Override
417
    public CodeBuilder createCodeBuilder() {
418 44644 jjdelcerro
        return new DefaultCodeBuilder(this);
419 43521 jjdelcerro
    }
420
421
    @Override
422
    public Compiler createCompiler() {
423 44644 jjdelcerro
        DefaultCompiler compiler = new DefaultCompiler(this);
424 44139 jjdelcerro
        this.populateGrammars(compiler);
425
        return  compiler;
426 43521 jjdelcerro
    }
427
428
    @Override
429
    public Interpreter createInterpreter() {
430 44533 jjdelcerro
        Interpreter interpreter = new DefaultInterpreter();
431
        interpreter.setResourcesStorage(this.scriptsResourcesStorage);
432
        return interpreter;
433 43521 jjdelcerro
    }
434
435
    @Override
436
    public Double getAccuracy() {
437
        return this.accuracy;
438
    }
439
440
    @Override
441
    public void setAccuracy(Double accuracy) {
442
        this.accuracy = accuracy;
443
    }
444 43983 jjdelcerro
445
    @Override
446
    public Expression createExpression() {
447 44644 jjdelcerro
        DefaultExpression e = new DefaultExpression(this);
448 43983 jjdelcerro
        return e;
449
    }
450 44006 jjdelcerro
451
    @Override
452
    public ExpressionBuilder createExpressionBuilder() {
453 44644 jjdelcerro
        ExpressionBuilder x = new DefaultExpressionBuilder(this);
454 44006 jjdelcerro
        return x;
455
    }
456 44009 jjdelcerro
457
    @Override
458
    public Optimizer createOptimizer() {
459 44644 jjdelcerro
        Optimizer x = new DefaultOptimizer(this);
460 44009 jjdelcerro
        return x;
461
    }
462 44139 jjdelcerro
463
    @Override
464
    public void registerGrammar(GrammarFactory factory) {
465
        if( factory==null ) {
466
            throw new IllegalArgumentException("factory can't be null");
467
        }
468
        this.grammarFactories.put(factory.getName(), factory);
469
    }
470
471
    @Override
472
    public Collection<GrammarFactory> getGrammarFactories() {
473
        return this.grammarFactories.values();
474
    }
475
476
    public void populateGrammars(Compiler compiler) {
477
        GrammarSet grammarSet = compiler.getGrammars();
478
        for (GrammarFactory factory : this.getGrammarFactories() ) {
479
            if( factory.isAutoload() ) {
480 44389 jjdelcerro
                Grammar grammar = factory.create();
481 44139 jjdelcerro
                grammarSet.add(grammar);
482
            }
483
        }
484
    }
485
486 44263 jjdelcerro
    @Override
487 44139 jjdelcerro
    public Grammar createGrammar(String name) {
488
        DefaultGrammar grammar = new DefaultGrammar(name);
489
        return grammar;
490
    }
491 44263 jjdelcerro
492
    @Override
493 45703 jjdelcerro
    public Bookmarks<Expression> getBookmarks() {
494 44263 jjdelcerro
        if( this.bookmarks==null ) {
495 45703 jjdelcerro
             this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
496 45282 omartinez
497 44263 jjdelcerro
        }
498
        return this.bookmarks;
499
    }
500
501
    @Override
502 45703 jjdelcerro
    public History<Expression> getHistory() {
503 44263 jjdelcerro
        if( this.history==null ) {
504 45703 jjdelcerro
            this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
505 44263 jjdelcerro
        }
506
        return this.history;
507
    }
508 44339 jjdelcerro
509
    @Override
510
    public Script createScript(String name, String code, String languaje) {
511 44389 jjdelcerro
        SimpleScript sc = new SimpleScript(this.createInterpreter(), name, code);
512 44339 jjdelcerro
        return sc;
513
    }
514
515
    @Override
516
    public Script locateScript(String name) {
517 44533 jjdelcerro
        return loadScript(this.scriptsResourcesStorage, name);
518 44339 jjdelcerro
    }
519
520
    @Override
521 44392 jjdelcerro
    public Script loadScript(final URI location) {
522
        ResourcesStorage.Resource res = null;
523 44339 jjdelcerro
        try {
524 44392 jjdelcerro
            if( location==null ) {
525
                return null;
526
            }
527 44710 jjdelcerro
            String resourceName = FilenameUtils.getBaseName(location.getPath());
528
            res = ResourcesStorage.createResource(resourceName, location);
529 44392 jjdelcerro
            if( res == null || !res.exists() ) {
530
                return null;
531
            }
532 44710 jjdelcerro
            Script script = loadScript(res, resourceName);
533 44392 jjdelcerro
            return script;
534
        } catch (Exception ex) {
535
            LOGGER.warn("Can't load script from URI.", ex);
536 44339 jjdelcerro
            return null;
537
        } finally {
538 44392 jjdelcerro
            IOUtils.closeQuietly(res);
539 44339 jjdelcerro
        }
540
    }
541 44392 jjdelcerro
542
543
    @Override
544
    public Script loadScript(ResourcesStorage storage, String name) {
545
        ResourcesStorage.Resource res = null;
546
        try {
547
            if( storage==null ) {
548
                return null;
549
            }
550
            res = storage.getResource(name);
551
            if( res == null || !res.exists() ) {
552
                return null;
553
            }
554
            Script script = loadScript(res, name);
555
            return script;
556
        } catch (Exception ex) {
557
            LOGGER.warn("Can't load script from resources storage.", ex);
558
            return null;
559
        } finally {
560
            IOUtils.closeQuietly(res);
561
        }
562
563
    }
564
565 44592 jjdelcerro
    private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9_]*).*");
566
    private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z0-9_-]*).*");
567 44392 jjdelcerro
568
    private Script loadScript(ResourcesStorage.Resource res, String name) {
569
        try {
570
            if( res == null || !res.exists() ) {
571
                return null;
572
            }
573 44851 jjdelcerro
            String head = EncodingUtils.getFirstLine(res.asInputStream());
574
            IOUtils.closeQuietly(res); // Eliminar con org.gvsig.tools > 3.0.230
575 44392 jjdelcerro
            if( StringUtils.isEmpty(head) ) {
576
                return null;
577
            }
578 44339 jjdelcerro
579 44851 jjdelcerro
            String encoding = EncodingUtils.getEncoding(head);
580
581 44392 jjdelcerro
            String lang = "cosa";
582
            Matcher m = RE_LANG.matcher(head);
583 44592 jjdelcerro
            if( m!=null && m.matches() && m.groupCount()==1 ) {
584 44392 jjdelcerro
                String s = m.group(1);
585
                if( !StringUtils.isBlank(s) ) {
586
                    lang = s;
587
                }
588
            }
589
            String source;
590
            if( StringUtils.isBlank(encoding) ) {
591
                source = IOUtils.toString(res.asInputStream());
592
            } else {
593
                source = IOUtils.toString(res.asInputStream(), encoding);
594
            }
595
            Script script = this.createScript(name, source, lang);
596
            return script;
597
        } catch (Exception ex) {
598
            LOGGER.warn("Can't load script from resource.", ex);
599
            return null;
600
        } finally {
601
            IOUtils.closeQuietly(res);
602
        }
603
604
    }
605 44533 jjdelcerro
606
    @Override
607
    public ResourcesStorage getScriptsResourcesStorage() {
608
        return this.scriptsResourcesStorage;
609
    }
610
611
    @Override
612
    public void setScriptsResourcesStorage(ResourcesStorage scriptsResourcesStorage) {
613 46828 fdiaz
        if(this.scriptsResourcesStorage != null){
614
            DisposeUtils.disposeQuietly(this.scriptsResourcesStorage);
615
        }
616
        DisposeUtils.bind(scriptsResourcesStorage);
617 44533 jjdelcerro
        this.scriptsResourcesStorage = scriptsResourcesStorage;
618
    }
619 44644 jjdelcerro
620 44533 jjdelcerro
621 44644 jjdelcerro
    private final List<ReprMethod> reprMethods = new ArrayList<>();
622
    private final Map<Class,ReprMethod> reprMethodsCache = new HashMap<>();
623
    private final ReprMethod reprNull = new ReprNull();
624
    private final ReprMethod reprObject = new ReprObject();
625
626
    @Override
627
    public void addReprMethod(ReprMethod method) {
628
        this.reprMethods.add(method);
629
        this.reprMethodsCache.clear();
630
    }
631
632
    @Override
633
    public ReprMethod getReprMethod(Object value) {
634
        if( value == null ) {
635
            return this.reprNull;
636
        }
637
        ReprMethod method = this.reprMethodsCache.get(value.getClass());
638
        if( method!=null ) {
639
            return method;
640
        }
641
        for (ReprMethod theMethod : reprMethods) {
642
            if( theMethod.isApplicable(value) ) {
643
                this.reprMethodsCache.put(value.getClass(), theMethod);
644
                return theMethod;
645
            }
646
        }
647
        return this.reprObject;
648
    }
649 44750 jjdelcerro
650
    @Override
651
    public void registerClassLoader(ClassLoader loader) {
652
      this.loaders.add(loader);
653
    }
654
655
    @Override
656
    public List<ClassLoader> getClassLoaders() {
657
      return Collections.unmodifiableList(loaders);
658
    }
659 44769 jjdelcerro
660
    @Override
661
    public Formatter<ExpressionBuilder.Value> getExpressionBuilderFormatter() {
662
      return expressionBuilderFormatter;
663
    }
664
665
    @Override
666
    public void registerExpressionBuilderFormatter(Formatter<ExpressionBuilder.Value> formatter) {
667
      this.expressionBuilderFormatter = formatter;
668
    }
669 45366 omartinez
670
    @Override
671
    public ExpressionEvaluator createExpressionEvaluator(Expression expression) {
672
        return new BaseExpressionEvaluator(expression);
673
    }
674 44769 jjdelcerro
675 45899 jjdelcerro
    @Override
676
    public ExpressionEvaluator createEvaluator(String expression) {
677
        Expression exp = this.createExpression();
678
        exp.setPhrase(expression);
679
        return new BaseExpressionEvaluator(exp);
680
    }
681 46695 jjdelcerro
682 46711 jjdelcerro
    @Override
683
    public boolean hasHostExpressions(Code statement) {
684
        try {
685
            List<Code> hostExpressions = new ArrayList<>();
686
            statement.accept(
687
                    (Object code) -> {
688
                        if( !(code instanceof Code.Callable) ) {
689
                            return;
690
                        }
691
                        Code.Callable callable = (Code.Callable) code;
692
                        if( StringUtils.equalsIgnoreCase(callable.name(), ExpressionBuilder.FUNCTION_$HOSTEXPRESSION) ) {
693
                            hostExpressions.add(callable);
694
                        }
695
                    }, null
696
            );
697
            return !hostExpressions.isEmpty();
698
        } catch (BaseException ex) {
699
            throw new RuntimeException("Can't check host expressions", ex);
700
        }
701
    }
702
703
    @Override
704
    public boolean hasHostExpressions(ExpressionBuilder.Value statement) {
705 47063 jjdelcerro
        return HostExpressionUtils.hasHostExpressions(statement);
706 46711 jjdelcerro
    }
707
708
    @Override
709
    public Code resolveHostExpressions(Code statement, Interpreter interpreter) {
710 47063 jjdelcerro
        return HostExpressionUtils.resolveHostExpressions(statement, interpreter);
711 46695 jjdelcerro
    }
712
713 46711 jjdelcerro
    @Override
714
    public ExpressionBuilder.Value resolveHostExpressions(ExpressionBuilder.Value statement, SymbolTable symbolTable) {
715 47063 jjdelcerro
        return HostExpressionUtils.resolveHostExpressions(statement, symbolTable);
716 46695 jjdelcerro
    }
717
718 46711 jjdelcerro
    @Override
719
    public Code resolveHostExpressions(Code statement, SymbolTable symbolTable) {
720 47063 jjdelcerro
        return HostExpressionUtils.resolveHostExpressions(statement, symbolTable);
721 46711 jjdelcerro
    }
722
723
    @Override
724
    public Expression resolveHostExpressions(Expression expression, SymbolTable symbolTable) {
725 47063 jjdelcerro
        return HostExpressionUtils.resolveHostExpressions(expression, symbolTable);
726 46695 jjdelcerro
    }
727
728 47063 jjdelcerro
    @Override
729
    public boolean hasHostExpressions(String statement) {
730
        return HostExpressionUtils.hasHostExpressions(statement);
731
    }
732
733
    @Override
734
    public ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder) {
735
        return HostExpressionUtils.getHostExpressionValue(hostExpression, expbuilder);
736
    }
737
738
    @Override
739
    public ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder, SymbolTable symbolTable) {
740
        return HostExpressionUtils.getHostExpressionValue(hostExpression, expbuilder, symbolTable);
741
    }
742 47175 jjdelcerro
743
    public void initConvertersToCode() {
744
        this.convertersToCode0 = new LinkedHashMap<>();
745
        ConverterToCode[] converters = new ConverterToCode[] {
746
            new NullToCode(),
747
            new CharsequenceToCode(),
748
            new NumberToCode(),
749
            new BooleanToCode(),
750
            new IteratorToCode(),
751
            new IterableToCode(),
752
            new ListToCode(),
753
            new ArrayToCode(),
754
            new ObjectToCode()
755
        };
756
        for (ConverterToCode converter : converters) {
757
            this.convertersToCode0.put(converter.getName(),converter);
758
        }
759
        this.convertersToCode = new LinkedHashMap<>();
760
    }
761 47063 jjdelcerro
762 47175 jjdelcerro
    @Override
763
    public void registerCodeConverter(ConverterToCode converter) {
764
        if( this.convertersToCode == null ) {
765
            this.initConvertersToCode();
766
        }
767
        this.convertersToCode.put(converter.getName(), converter);
768
    }
769
770
    @Override
771
    public ConverterToCode getConverterToCode(Object ob) {
772
        if( this.convertersToCode == null ) {
773
            this.initConvertersToCode();
774
        }
775
        for (ConverterToCode converter : this.convertersToCode.values()) {
776
            if( converter.isApplicable(ob) ) {
777
                return converter;
778
            }
779
        }
780
        for (ConverterToCode converter : this.convertersToCode0.values()) {
781
            if( converter.isApplicable(ob) ) {
782
                return converter;
783
            }
784
        }
785
        return null;
786
    }
787
788
    @Override
789 47184 jjdelcerro
    public ExpressionBuilder.Value convertToValue(Object obj) {
790
        Code code = this.convertToCode(obj);
791
        ExpressionBuilder.Value value = code.toValue();
792
        return value;
793
    }
794
795
    @Override
796
    public Code convertToCode(Object obj) {
797
        return convertToCode(null, obj, null);
798
    }
799
800
    @Override
801
    public Code convertToCode(CodeBuilder builder, Object obj, Map<String,Object> props) {
802 47175 jjdelcerro
        if( this.convertersToCode == null ) {
803
            this.initConvertersToCode();
804
        }
805 47184 jjdelcerro
        if( builder == null ) {
806
            builder = this.createCodeBuilder();
807
        }
808 47175 jjdelcerro
        for (ConverterToCode converter : this.convertersToCode.values()) {
809 47184 jjdelcerro
            if( converter.isApplicable(obj) ) {
810
                return converter.toCode(builder, obj, props);
811 47175 jjdelcerro
            }
812
        }
813
        for (ConverterToCode converter : this.convertersToCode0.values()) {
814 47184 jjdelcerro
            if( converter.isApplicable(obj) ) {
815
                return converter.toCode(builder, obj, props);
816 47175 jjdelcerro
            }
817
        }
818
        return null;
819
    }
820
821
    public ConverterToCode getConverterToCodeByName(String name) {
822
        ConverterToCode converter = this.convertersToCode.get(name);
823
        if( converter!=null ) {
824
            return converter;
825
        }
826
        converter = this.convertersToCode0.get(name);
827
        return converter;
828
    }
829
830 43521 jjdelcerro
}