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

History | View | Annotate | Download (13.1 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.io.StringWriter;
4
import java.net.URI;
5
import org.gvsig.expressionevaluator.Grammar;
6
import org.gvsig.expressionevaluator.GrammarFactory;
7
import java.util.Collection;
8
import java.util.HashMap;
9
import java.util.Map;
10
import java.util.Objects;
11
import java.util.regex.Matcher;
12
import java.util.regex.Pattern;
13
import org.apache.commons.io.FilenameUtils;
14
import org.apache.commons.io.IOUtils;
15
import org.apache.commons.lang3.ArrayUtils;
16
import org.apache.commons.lang3.StringUtils;
17
import org.gvsig.expressionevaluator.Code;
18
import org.gvsig.expressionevaluator.CodeBuilder;
19
import org.gvsig.expressionevaluator.Expression;
20
import org.gvsig.expressionevaluator.ExpressionBuilder;
21
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
22
import org.gvsig.expressionevaluator.Interpreter;
23
import org.gvsig.expressionevaluator.LexicalAnalyzer;
24
import org.gvsig.expressionevaluator.MutableSymbolTable;
25
import org.gvsig.expressionevaluator.Optimizer;
26
import org.gvsig.expressionevaluator.SymbolTable;
27
import org.gvsig.expressionevaluator.SymbolTableFactory;
28
import org.gvsig.expressionevaluator.Compiler;
29
import org.gvsig.expressionevaluator.GrammarSet;
30
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
import org.gvsig.tools.resourcesstorage.ResourcesStorage;
35
import org.gvsig.tools.script.Script;
36
import org.slf4j.Logger;
37
import org.slf4j.LoggerFactory;
38

    
39

    
40
@SuppressWarnings("UseSpecificCatch")
41
public class DefaultExpressionEvaluatorManager implements ExpressionEvaluatorManager {
42

    
43
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExpressionEvaluatorManager.class);
44
    
45
    private Double accuracy;
46
    private final Map<String,SymbolTableFactory>symbolTableFactories;
47
    private final Map<String,GrammarFactory> grammarFactories;
48
    private Bookmarks<Expression> bookmarks;
49
    private History<Expression> history;
50
    private SymbolTable inmutableSymbolTable;
51

    
52
    public DefaultExpressionEvaluatorManager() {
53
        this.symbolTableFactories = new HashMap<>();
54
        this.grammarFactories = new HashMap<>();
55
    }
56

    
57
    @Override
58
    public SymbolTable getSymbolTable(String name) {
59
        if( name == null ) {
60
            return null;
61
        }
62
        SymbolTableFactory factory = this.symbolTableFactories.get(name.toUpperCase());
63
        if( factory == null ) {
64
            return null;
65
        }
66
        return factory.create();
67
    }
68

    
69
    @Override
70
    public Collection<SymbolTableFactory> getSymbolTableFactories() {
71
        return this.symbolTableFactories.values();
72
    }
73

    
74
    @Override
75
    public final void registerSymbolTable(SymbolTableFactory factory) {
76
        if( factory == null ) {
77
            throw new IllegalArgumentException("factory can't be null");
78
        }
79
        this.symbolTableFactories.put(factory.getName().toUpperCase(),factory);
80
        this.inmutableSymbolTable = null;
81
    }
82

    
83
    @Override
84
    public SymbolTable getInmutableSymbolTable() {
85
        if( this.inmutableSymbolTable==null ) {
86
            this.inmutableSymbolTable = new InmutableSymbolTable();
87
        }
88
        return this.inmutableSymbolTable;
89
    }
90
    
91
    @Override
92
    public Object evaluate(String source) {
93
        DefaultInterpreter interpreter = new DefaultInterpreter();
94
        DefaultCompiler compiler = new DefaultCompiler();
95
        Code code = compiler.compileExpression(source);
96
        return interpreter.run(code);
97
    }
98
    
99
    @Override
100
    public Object evaluate(SymbolTable symbolTable, String source) {
101
        DefaultInterpreter interpreter = new DefaultInterpreter();
102
        DefaultCompiler compiler = new DefaultCompiler();
103
        Code code = compiler.compileExpression(source);
104
        if( symbolTable!=null ) {
105
            interpreter.setSymbolTable(symbolTable);
106
        }
107
        return interpreter.run(code);
108
    }
109

    
110
    @Override
111
    public Object evaluate(SymbolTable symbolTable, Code code) {
112
        DefaultInterpreter interpreter = new DefaultInterpreter();
113
        if( symbolTable!=null ) {
114
            interpreter.setSymbolTable(symbolTable);
115
        }
116
        return interpreter.run(code);
117
    }
118

    
119
    @Override
120
    public String evaluateDynamicText(String source) {
121
        return evaluateDynamicText(null, source);
122
    }
123
    
124
    @Override
125
    public boolean isDynamicText(String source) {
126
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
127
        if( ArrayUtils.isEmpty(sources) ) {
128
            return false;
129
        }
130
        return true;
131
    }
132
    
133
    @Override
134
    public String evaluateDynamicText(SymbolTable symbolTable, String source) {
135
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
136
        if( ArrayUtils.isEmpty(sources) ) {
137
            return source;
138
        }
139
        String[] values = new String[sources.length];
140
        
141
        DefaultInterpreter interpreter = new DefaultInterpreter();
142
        if( symbolTable!=null ) {
143
            interpreter.setSymbolTable(symbolTable);
144
        }
145
        StringWriter writer = new StringWriter();
146
        interpreter.setWriter(writer);
147
        DefaultCompiler compiler = new DefaultCompiler();
148
        for (int i = 0; i < sources.length; i++) {
149
            String theSource = sources[i];
150
            if( StringUtils.startsWith(theSource, "=") ) {
151
                Code code = compiler.compileExpression(theSource.substring(1));
152
                Object value = interpreter.run(code);
153
                values[i] = Objects.toString(value, "");
154
            } else {
155
                Code code = compiler.compileExpression(theSource.substring(1));
156
                writer.getBuffer().setLength(0);
157
                interpreter.run(code);
158
                values[i] = writer.toString();
159
            }
160
            sources[i] = "<%"+sources[i]+"%>";
161
        }
162
        String output = StringUtils.replaceEach(source, sources, values);
163
        return output;
164
    }
165
    
166
    @Override
167
    public Code compile(String source) {
168
        Compiler compiler = this.createCompiler();
169
        return compiler.compileExpression(source);
170
    }
171

    
172
    @Override
173
    public Code compile(LexicalAnalyzer lex, String source) {
174
        Compiler compiler = this.createCompiler();
175
        compiler.setLexicalAnalyzer(lex);
176
        return compiler.compileExpression(source);
177
    }
178

    
179
    @Override
180
    public Code optimize(SymbolTable symbolTable, Code code) {
181
        Optimizer optimizer = this.createOptimizer();
182
        return optimizer.optimize(symbolTable, code);
183
    }
184

    
185
    @Override
186
    public MutableSymbolTable createSymbolTable() {
187
        DefaultSymbolTable theSymbolTable = new DefaultSymbolTable();
188
        return theSymbolTable;
189
    }
190
    
191
    public void populateSymbolTable(SymbolTable aSymbolTable) {
192
        for (SymbolTableFactory factory : this.getSymbolTableFactories() ) {
193
            try {
194
                if( factory.isAutoload() ) {
195
                    SymbolTable symbolTable = factory.create();
196
                    aSymbolTable.addSymbolTable(symbolTable);
197
                }
198
            } catch(Throwable th) {
199
                String factoryName = "Unknown";
200
                try {
201
                    factoryName = factory.getName();
202
                } catch(Throwable th2) {
203
                    // Do nothing
204
                }
205
                LOGGER.warn("Can't create symbol table '"+factoryName+"'.", th);
206
            }
207
        }
208
    }
209
    
210
    @Override
211
    public LexicalAnalyzer createLexicalAnalyzer() {
212
        return new SQLLexicalAnalyzer();
213
    }
214

    
215
    @Override
216
    public CodeBuilder createCodeBuilder() {
217
        return new DefaultCodeBuilder();
218
    }
219

    
220
    @Override
221
    public Compiler createCompiler() {
222
        DefaultCompiler compiler = new DefaultCompiler();
223
        this.populateGrammars(compiler);
224
        return  compiler;
225
    }
226

    
227
    @Override
228
    public Interpreter createInterpreter() {
229
        return new DefaultInterpreter();
230
    }
231

    
232
    @Override
233
    public Double getAccuracy() {
234
        return this.accuracy;
235
    }
236

    
237
    @Override
238
    public void setAccuracy(Double accuracy) {
239
        this.accuracy = accuracy;
240
    }
241

    
242
    @Override
243
    public Expression createExpression() {
244
        DefaultExpression e = new DefaultExpression();
245
        return e;
246
    }
247

    
248
    @Override
249
    public ExpressionBuilder createExpressionBuilder() {
250
        ExpressionBuilder x = new DefaultExpressionBuilder();
251
        return x;
252
    }
253

    
254
    @Override
255
    public Optimizer createOptimizer() {
256
        Optimizer x = new DefaultOptimizer();
257
        return x;
258
    }
259

    
260
    @Override
261
    public void registerGrammar(GrammarFactory factory) {
262
        if( factory==null ) {
263
            throw new IllegalArgumentException("factory can't be null");
264
        }
265
        this.grammarFactories.put(factory.getName(), factory);
266
    }
267

    
268
    @Override
269
    public Collection<GrammarFactory> getGrammarFactories() {
270
        return this.grammarFactories.values();
271
    }
272

    
273
    public void populateGrammars(Compiler compiler) {
274
        GrammarSet grammarSet = compiler.getGrammars();
275
        for (GrammarFactory factory : this.getGrammarFactories() ) {
276
            if( factory.isAutoload() ) {
277
                Grammar grammar = factory.create();
278
                grammarSet.add(grammar);
279
            }
280
        }
281
    }
282

    
283
    @Override
284
    public Grammar createGrammar(String name) {
285
        DefaultGrammar grammar = new DefaultGrammar(name);
286
        return grammar;
287
    }
288
    
289
    @Override
290
    public Bookmarks<Expression> getBookmarks() {
291
        if( this.bookmarks==null ) {
292
            this.bookmarks = new BaseBookmarks<>();
293
        }
294
        return this.bookmarks;
295
    }
296

    
297
    @Override
298
    public History<Expression> getHistory() {
299
        if( this.history==null ) {
300
            this.history = new BaseHistory<>(20);
301
        }
302
        return this.history;
303
    }
304
    
305
    @Override
306
    public Script createScript(String name, String code, String languaje) {
307
        SimpleScript sc = new SimpleScript(this.createInterpreter(), name, code);
308
        return sc;
309
    }
310

    
311
    @Override
312
    public Script locateScript(String name) {
313
        return null;
314
    }
315

    
316
    @Override
317
    public Script loadScript(final URI location) {
318
        ResourcesStorage.Resource res = null;
319
        try {
320
            if( location==null ) {
321
                return null;
322
            }
323
            res = ResourcesStorage.createResource(location);
324
            if( res == null || !res.exists() ) {
325
                return null;
326
            }
327
            Script script = loadScript(res, FilenameUtils.getBaseName(location.getPath()));
328
            return script;
329
        } catch (Exception ex) {
330
            LOGGER.warn("Can't load script from URI.", ex);
331
            return null;
332
        } finally {
333
            IOUtils.closeQuietly(res);
334
        }
335
    }
336

    
337

    
338
    @Override
339
    public Script loadScript(ResourcesStorage storage, String name) {
340
        ResourcesStorage.Resource res = null;
341
        try {
342
            if( storage==null ) {
343
                return null;
344
            }
345
            res = storage.getResource(name);
346
            if( res == null || !res.exists() ) {
347
                return null;
348
            }
349
            Script script = loadScript(res, name);
350
            return script;
351
        } catch (Exception ex) {
352
            LOGGER.warn("Can't load script from resources storage.", ex);
353
            return null;
354
        } finally {
355
            IOUtils.closeQuietly(res);
356
        }
357

    
358
    }
359

    
360
    private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)");
361
    private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)");
362
    
363
    private Script loadScript(ResourcesStorage.Resource res, String name) {
364
        try {
365
            if( res == null || !res.exists() ) {
366
                return null;
367
            }
368
            byte[] head_bytes = new byte[500];
369
            IOUtils.read(res.asInputStream(), head_bytes);
370
            IOUtils.closeQuietly(res);
371
            String head = new String(head_bytes);
372
            if( StringUtils.isEmpty(head) ) {
373
                return null;
374
            }
375
            head = StringUtils.split("\n")[0];
376
            
377
            String lang = "cosa";
378
            String encoding = null;
379
            Matcher m = RE_LANG.matcher(head);
380
            if( m.groupCount()==1 ) {
381
                String s = m.group(1);
382
                if( !StringUtils.isBlank(s) ) {
383
                    lang = s;
384
                }
385
            }
386
            m = RE_ENCODING.matcher(head);
387
            if( m.groupCount()==1 ) {
388
                String s = m.group(1);
389
                if( !StringUtils.isBlank(s) ) {
390
                    encoding = s;
391
                }
392
            }
393

    
394
            String source;
395
            if( StringUtils.isBlank(encoding) ) {
396
                source = IOUtils.toString(res.asInputStream());
397
            } else {
398
                source = IOUtils.toString(res.asInputStream(), encoding);
399
            }
400
            Script script = this.createScript(name, source, lang);
401
            return script;
402
        } catch (Exception ex) {
403
            LOGGER.warn("Can't load script from resource.", ex);
404
            return null;
405
        } finally {
406
            IOUtils.closeQuietly(res);
407
        }
408

    
409
    }
410
}
411