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

History | View | Annotate | Download (13.7 KB)

1 43521 jjdelcerro
package org.gvsig.expressionevaluator.impl;
2
3 44389 jjdelcerro
import java.io.StringWriter;
4 44339 jjdelcerro
import java.net.URI;
5 44139 jjdelcerro
import org.gvsig.expressionevaluator.Grammar;
6
import org.gvsig.expressionevaluator.GrammarFactory;
7 43983 jjdelcerro
import java.util.Collection;
8 43939 jjdelcerro
import java.util.HashMap;
9
import java.util.Map;
10 44389 jjdelcerro
import java.util.Objects;
11 44392 jjdelcerro
import java.util.regex.Matcher;
12
import java.util.regex.Pattern;
13 44339 jjdelcerro
import org.apache.commons.io.FilenameUtils;
14
import org.apache.commons.io.IOUtils;
15 44389 jjdelcerro
import org.apache.commons.lang3.ArrayUtils;
16
import org.apache.commons.lang3.StringUtils;
17 43521 jjdelcerro
import org.gvsig.expressionevaluator.Code;
18
import org.gvsig.expressionevaluator.CodeBuilder;
19 43983 jjdelcerro
import org.gvsig.expressionevaluator.Expression;
20 44006 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
21 43521 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
22
import org.gvsig.expressionevaluator.Interpreter;
23
import org.gvsig.expressionevaluator.LexicalAnalyzer;
24
import org.gvsig.expressionevaluator.MutableSymbolTable;
25 44009 jjdelcerro
import org.gvsig.expressionevaluator.Optimizer;
26 43521 jjdelcerro
import org.gvsig.expressionevaluator.SymbolTable;
27 44126 jjdelcerro
import org.gvsig.expressionevaluator.SymbolTableFactory;
28 44139 jjdelcerro
import org.gvsig.expressionevaluator.Compiler;
29
import org.gvsig.expressionevaluator.GrammarSet;
30 44390 jjdelcerro
import org.gvsig.tools.bookmarksandhistory.Bookmarks;
31
import org.gvsig.tools.bookmarksandhistory.History;
32
import org.gvsig.tools.bookmarksandhistory.impl.BaseBookmarks;
33
import org.gvsig.tools.bookmarksandhistory.impl.BaseHistory;
34 44392 jjdelcerro
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
35 44339 jjdelcerro
import org.gvsig.tools.script.Script;
36 44006 jjdelcerro
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38 43521 jjdelcerro
39
40 44339 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
41 43521 jjdelcerro
public class DefaultExpressionEvaluatorManager implements ExpressionEvaluatorManager {
42
43 44006 jjdelcerro
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExpressionEvaluatorManager.class);
44
45 43521 jjdelcerro
    private Double accuracy;
46 44126 jjdelcerro
    private final Map<String,SymbolTableFactory>symbolTableFactories;
47 44139 jjdelcerro
    private final Map<String,GrammarFactory> grammarFactories;
48 44390 jjdelcerro
    private Bookmarks<Expression> bookmarks;
49
    private History<Expression> history;
50 44446 jjdelcerro
    private SymbolTable inmutableSymbolTable;
51 44533 jjdelcerro
    private ResourcesStorage scriptsResourcesStorage;
52 43521 jjdelcerro
53
    public DefaultExpressionEvaluatorManager() {
54 44126 jjdelcerro
        this.symbolTableFactories = new HashMap<>();
55 44139 jjdelcerro
        this.grammarFactories = new HashMap<>();
56 44533 jjdelcerro
        this.scriptsResourcesStorage = ResourcesStorage.EMPTY_RESOURCESSTORAGE;
57 43939 jjdelcerro
    }
58
59 43521 jjdelcerro
    @Override
60 43983 jjdelcerro
    public SymbolTable getSymbolTable(String name) {
61 44126 jjdelcerro
        if( name == null ) {
62
            return null;
63
        }
64
        SymbolTableFactory factory = this.symbolTableFactories.get(name.toUpperCase());
65
        if( factory == null ) {
66
            return null;
67
        }
68 44389 jjdelcerro
        return factory.create();
69 43939 jjdelcerro
    }
70
71
    @Override
72 44126 jjdelcerro
    public Collection<SymbolTableFactory> getSymbolTableFactories() {
73
        return this.symbolTableFactories.values();
74 43939 jjdelcerro
    }
75
76
    @Override
77 44126 jjdelcerro
    public final void registerSymbolTable(SymbolTableFactory factory) {
78
        if( factory == null ) {
79
            throw new IllegalArgumentException("factory can't be null");
80 44006 jjdelcerro
        }
81 44126 jjdelcerro
        this.symbolTableFactories.put(factory.getName().toUpperCase(),factory);
82 44446 jjdelcerro
        this.inmutableSymbolTable = null;
83 43939 jjdelcerro
    }
84 43987 jjdelcerro
85 43939 jjdelcerro
    @Override
86 44446 jjdelcerro
    public SymbolTable getInmutableSymbolTable() {
87
        if( this.inmutableSymbolTable==null ) {
88
            this.inmutableSymbolTable = new InmutableSymbolTable();
89
        }
90
        return this.inmutableSymbolTable;
91
    }
92
93
    @Override
94 43521 jjdelcerro
    public Object evaluate(String source) {
95
        DefaultInterpreter interpreter = new DefaultInterpreter();
96
        DefaultCompiler compiler = new DefaultCompiler();
97
        Code code = compiler.compileExpression(source);
98
        return interpreter.run(code);
99
    }
100 44389 jjdelcerro
101 43521 jjdelcerro
    @Override
102
    public Object evaluate(SymbolTable symbolTable, String source) {
103
        DefaultInterpreter interpreter = new DefaultInterpreter();
104
        DefaultCompiler compiler = new DefaultCompiler();
105
        Code code = compiler.compileExpression(source);
106 44446 jjdelcerro
        if( symbolTable!=null ) {
107
            interpreter.setSymbolTable(symbolTable);
108
        }
109 43521 jjdelcerro
        return interpreter.run(code);
110
    }
111
112
    @Override
113
    public Object evaluate(SymbolTable symbolTable, Code code) {
114
        DefaultInterpreter interpreter = new DefaultInterpreter();
115 44446 jjdelcerro
        if( symbolTable!=null ) {
116
            interpreter.setSymbolTable(symbolTable);
117
        }
118 43521 jjdelcerro
        return interpreter.run(code);
119
    }
120
121
    @Override
122 44397 jjdelcerro
    public String evaluateDynamicText(String source) {
123
        return evaluateDynamicText(null, source);
124 44389 jjdelcerro
    }
125
126
    @Override
127 44397 jjdelcerro
    public boolean isDynamicText(String source) {
128 44389 jjdelcerro
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
129
        if( ArrayUtils.isEmpty(sources) ) {
130 44397 jjdelcerro
            return false;
131
        }
132
        return true;
133
    }
134
135
    @Override
136
    public String evaluateDynamicText(SymbolTable symbolTable, String source) {
137
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
138
        if( ArrayUtils.isEmpty(sources) ) {
139 44389 jjdelcerro
            return source;
140
        }
141
        String[] values = new String[sources.length];
142
143
        DefaultInterpreter interpreter = new DefaultInterpreter();
144
        if( symbolTable!=null ) {
145
            interpreter.setSymbolTable(symbolTable);
146
        }
147
        StringWriter writer = new StringWriter();
148
        interpreter.setWriter(writer);
149
        DefaultCompiler compiler = new DefaultCompiler();
150
        for (int i = 0; i < sources.length; i++) {
151
            String theSource = sources[i];
152
            if( StringUtils.startsWith(theSource, "=") ) {
153
                Code code = compiler.compileExpression(theSource.substring(1));
154
                Object value = interpreter.run(code);
155
                values[i] = Objects.toString(value, "");
156
            } else {
157
                Code code = compiler.compileExpression(theSource.substring(1));
158
                writer.getBuffer().setLength(0);
159
                interpreter.run(code);
160
                values[i] = writer.toString();
161
            }
162 44390 jjdelcerro
            sources[i] = "<%"+sources[i]+"%>";
163 44389 jjdelcerro
        }
164
        String output = StringUtils.replaceEach(source, sources, values);
165
        return output;
166
    }
167
168
    @Override
169 43521 jjdelcerro
    public Code compile(String source) {
170 44139 jjdelcerro
        Compiler compiler = this.createCompiler();
171 43521 jjdelcerro
        return compiler.compileExpression(source);
172
    }
173
174
    @Override
175
    public Code compile(LexicalAnalyzer lex, String source) {
176 44139 jjdelcerro
        Compiler compiler = this.createCompiler();
177 43521 jjdelcerro
        compiler.setLexicalAnalyzer(lex);
178
        return compiler.compileExpression(source);
179
    }
180
181
    @Override
182 44019 jjdelcerro
    public Code optimize(SymbolTable symbolTable, Code code) {
183
        Optimizer optimizer = this.createOptimizer();
184
        return optimizer.optimize(symbolTable, code);
185
    }
186
187
    @Override
188 43521 jjdelcerro
    public MutableSymbolTable createSymbolTable() {
189 43987 jjdelcerro
        DefaultSymbolTable theSymbolTable = new DefaultSymbolTable();
190
        return theSymbolTable;
191 43521 jjdelcerro
    }
192 43939 jjdelcerro
193 43987 jjdelcerro
    public void populateSymbolTable(SymbolTable aSymbolTable) {
194 44126 jjdelcerro
        for (SymbolTableFactory factory : this.getSymbolTableFactories() ) {
195 44394 jjdelcerro
            try {
196
                if( factory.isAutoload() ) {
197
                    SymbolTable symbolTable = factory.create();
198
                    aSymbolTable.addSymbolTable(symbolTable);
199
                }
200
            } catch(Throwable th) {
201
                String factoryName = "Unknown";
202
                try {
203
                    factoryName = factory.getName();
204
                } catch(Throwable th2) {
205
                    // Do nothing
206
                }
207
                LOGGER.warn("Can't create symbol table '"+factoryName+"'.", th);
208 43987 jjdelcerro
            }
209
        }
210
    }
211
212 43521 jjdelcerro
    @Override
213
    public LexicalAnalyzer createLexicalAnalyzer() {
214
        return new SQLLexicalAnalyzer();
215
    }
216
217
    @Override
218
    public CodeBuilder createCodeBuilder() {
219
        return new DefaultCodeBuilder();
220
    }
221
222
    @Override
223
    public Compiler createCompiler() {
224 44139 jjdelcerro
        DefaultCompiler compiler = new DefaultCompiler();
225
        this.populateGrammars(compiler);
226
        return  compiler;
227 43521 jjdelcerro
    }
228
229
    @Override
230
    public Interpreter createInterpreter() {
231 44533 jjdelcerro
        Interpreter interpreter = new DefaultInterpreter();
232
        interpreter.setResourcesStorage(this.scriptsResourcesStorage);
233
        return interpreter;
234 43521 jjdelcerro
    }
235
236
    @Override
237
    public Double getAccuracy() {
238
        return this.accuracy;
239
    }
240
241
    @Override
242
    public void setAccuracy(Double accuracy) {
243
        this.accuracy = accuracy;
244
    }
245 43983 jjdelcerro
246
    @Override
247
    public Expression createExpression() {
248
        DefaultExpression e = new DefaultExpression();
249
        return e;
250
    }
251 44006 jjdelcerro
252
    @Override
253
    public ExpressionBuilder createExpressionBuilder() {
254
        ExpressionBuilder x = new DefaultExpressionBuilder();
255
        return x;
256
    }
257 44009 jjdelcerro
258
    @Override
259
    public Optimizer createOptimizer() {
260
        Optimizer x = new DefaultOptimizer();
261
        return x;
262
    }
263 44139 jjdelcerro
264
    @Override
265
    public void registerGrammar(GrammarFactory factory) {
266
        if( factory==null ) {
267
            throw new IllegalArgumentException("factory can't be null");
268
        }
269
        this.grammarFactories.put(factory.getName(), factory);
270
    }
271
272
    @Override
273
    public Collection<GrammarFactory> getGrammarFactories() {
274
        return this.grammarFactories.values();
275
    }
276
277
    public void populateGrammars(Compiler compiler) {
278
        GrammarSet grammarSet = compiler.getGrammars();
279
        for (GrammarFactory factory : this.getGrammarFactories() ) {
280
            if( factory.isAutoload() ) {
281 44389 jjdelcerro
                Grammar grammar = factory.create();
282 44139 jjdelcerro
                grammarSet.add(grammar);
283
            }
284
        }
285
    }
286
287 44263 jjdelcerro
    @Override
288 44139 jjdelcerro
    public Grammar createGrammar(String name) {
289
        DefaultGrammar grammar = new DefaultGrammar(name);
290
        return grammar;
291
    }
292 44263 jjdelcerro
293
    @Override
294 44390 jjdelcerro
    public Bookmarks<Expression> getBookmarks() {
295 44263 jjdelcerro
        if( this.bookmarks==null ) {
296 44392 jjdelcerro
            this.bookmarks = new BaseBookmarks<>();
297 44263 jjdelcerro
        }
298
        return this.bookmarks;
299
    }
300
301
    @Override
302 44390 jjdelcerro
    public History<Expression> getHistory() {
303 44263 jjdelcerro
        if( this.history==null ) {
304 44392 jjdelcerro
            this.history = new BaseHistory<>(20);
305 44263 jjdelcerro
        }
306
        return this.history;
307
    }
308 44339 jjdelcerro
309
    @Override
310
    public Script createScript(String name, String code, String languaje) {
311 44389 jjdelcerro
        SimpleScript sc = new SimpleScript(this.createInterpreter(), name, code);
312 44339 jjdelcerro
        return sc;
313
    }
314
315
    @Override
316
    public Script locateScript(String name) {
317 44533 jjdelcerro
        return loadScript(this.scriptsResourcesStorage, name);
318 44339 jjdelcerro
    }
319
320
    @Override
321 44392 jjdelcerro
    public Script loadScript(final URI location) {
322
        ResourcesStorage.Resource res = null;
323 44339 jjdelcerro
        try {
324 44392 jjdelcerro
            if( location==null ) {
325
                return null;
326
            }
327
            res = ResourcesStorage.createResource(location);
328
            if( res == null || !res.exists() ) {
329
                return null;
330
            }
331
            Script script = loadScript(res, FilenameUtils.getBaseName(location.getPath()));
332
            return script;
333
        } catch (Exception ex) {
334
            LOGGER.warn("Can't load script from URI.", ex);
335 44339 jjdelcerro
            return null;
336
        } finally {
337 44392 jjdelcerro
            IOUtils.closeQuietly(res);
338 44339 jjdelcerro
        }
339
    }
340 44392 jjdelcerro
341
342
    @Override
343
    public Script loadScript(ResourcesStorage storage, String name) {
344
        ResourcesStorage.Resource res = null;
345
        try {
346
            if( storage==null ) {
347
                return null;
348
            }
349
            res = storage.getResource(name);
350
            if( res == null || !res.exists() ) {
351
                return null;
352
            }
353
            Script script = loadScript(res, name);
354
            return script;
355
        } catch (Exception ex) {
356
            LOGGER.warn("Can't load script from resources storage.", ex);
357
            return null;
358
        } finally {
359
            IOUtils.closeQuietly(res);
360
        }
361
362
    }
363
364 44592 jjdelcerro
    private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9_]*).*");
365
    private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z0-9_-]*).*");
366 44392 jjdelcerro
367
    private Script loadScript(ResourcesStorage.Resource res, String name) {
368
        try {
369
            if( res == null || !res.exists() ) {
370
                return null;
371
            }
372
            byte[] head_bytes = new byte[500];
373
            IOUtils.read(res.asInputStream(), head_bytes);
374
            IOUtils.closeQuietly(res);
375
            String head = new String(head_bytes);
376
            if( StringUtils.isEmpty(head) ) {
377
                return null;
378
            }
379 44592 jjdelcerro
            head = StringUtils.split(head, "\n")[0];
380 44339 jjdelcerro
381 44392 jjdelcerro
            String lang = "cosa";
382
            String encoding = null;
383
            Matcher m = RE_LANG.matcher(head);
384 44592 jjdelcerro
            if( m!=null && m.matches() && m.groupCount()==1 ) {
385 44392 jjdelcerro
                String s = m.group(1);
386
                if( !StringUtils.isBlank(s) ) {
387
                    lang = s;
388
                }
389
            }
390
            m = RE_ENCODING.matcher(head);
391 44592 jjdelcerro
            if( m!=null && m.matches() && m.groupCount()==1 ) {
392 44392 jjdelcerro
                String s = m.group(1);
393
                if( !StringUtils.isBlank(s) ) {
394
                    encoding = s;
395
                }
396
            }
397
398
            String source;
399
            if( StringUtils.isBlank(encoding) ) {
400
                source = IOUtils.toString(res.asInputStream());
401
            } else {
402
                source = IOUtils.toString(res.asInputStream(), encoding);
403
            }
404
            Script script = this.createScript(name, source, lang);
405
            return script;
406
        } catch (Exception ex) {
407
            LOGGER.warn("Can't load script from resource.", ex);
408
            return null;
409
        } finally {
410
            IOUtils.closeQuietly(res);
411
        }
412
413
    }
414 44533 jjdelcerro
415
    @Override
416
    public ResourcesStorage getScriptsResourcesStorage() {
417
        return this.scriptsResourcesStorage;
418
    }
419
420
    @Override
421
    public void setScriptsResourcesStorage(ResourcesStorage scriptsResourcesStorage) {
422
        this.scriptsResourcesStorage = scriptsResourcesStorage;
423
    }
424
425 43521 jjdelcerro
}