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

History | View | Annotate | Download (13.7 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
    private ResourcesStorage scriptsResourcesStorage;
52

    
53
    public DefaultExpressionEvaluatorManager() {
54
        this.symbolTableFactories = new HashMap<>();
55
        this.grammarFactories = new HashMap<>();
56
        this.scriptsResourcesStorage = ResourcesStorage.EMPTY_RESOURCESSTORAGE;
57
    }
58

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

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

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

    
85
    @Override
86
    public SymbolTable getInmutableSymbolTable() {
87
        if( this.inmutableSymbolTable==null ) {
88
            this.inmutableSymbolTable = new InmutableSymbolTable();
89
        }
90
        return this.inmutableSymbolTable;
91
    }
92
    
93
    @Override
94
    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
    
101
    @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
        if( symbolTable!=null ) {
107
            interpreter.setSymbolTable(symbolTable);
108
        }
109
        return interpreter.run(code);
110
    }
111

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

    
121
    @Override
122
    public String evaluateDynamicText(String source) {
123
        return evaluateDynamicText(null, source);
124
    }
125
    
126
    @Override
127
    public boolean isDynamicText(String source) {
128
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
129
        if( ArrayUtils.isEmpty(sources) ) {
130
            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
            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
            sources[i] = "<%"+sources[i]+"%>";
163
        }
164
        String output = StringUtils.replaceEach(source, sources, values);
165
        return output;
166
    }
167
    
168
    @Override
169
    public Code compile(String source) {
170
        Compiler compiler = this.createCompiler();
171
        return compiler.compileExpression(source);
172
    }
173

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

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

    
187
    @Override
188
    public MutableSymbolTable createSymbolTable() {
189
        DefaultSymbolTable theSymbolTable = new DefaultSymbolTable();
190
        return theSymbolTable;
191
    }
192
    
193
    public void populateSymbolTable(SymbolTable aSymbolTable) {
194
        for (SymbolTableFactory factory : this.getSymbolTableFactories() ) {
195
            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
            }
209
        }
210
    }
211
    
212
    @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
        DefaultCompiler compiler = new DefaultCompiler();
225
        this.populateGrammars(compiler);
226
        return  compiler;
227
    }
228

    
229
    @Override
230
    public Interpreter createInterpreter() {
231
        Interpreter interpreter = new DefaultInterpreter();
232
        interpreter.setResourcesStorage(this.scriptsResourcesStorage);
233
        return interpreter;
234
    }
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

    
246
    @Override
247
    public Expression createExpression() {
248
        DefaultExpression e = new DefaultExpression();
249
        return e;
250
    }
251

    
252
    @Override
253
    public ExpressionBuilder createExpressionBuilder() {
254
        ExpressionBuilder x = new DefaultExpressionBuilder();
255
        return x;
256
    }
257

    
258
    @Override
259
    public Optimizer createOptimizer() {
260
        Optimizer x = new DefaultOptimizer();
261
        return x;
262
    }
263

    
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
                Grammar grammar = factory.create();
282
                grammarSet.add(grammar);
283
            }
284
        }
285
    }
286

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

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

    
315
    @Override
316
    public Script locateScript(String name) {
317
        return loadScript(this.scriptsResourcesStorage, name);
318
    }
319

    
320
    @Override
321
    public Script loadScript(final URI location) {
322
        ResourcesStorage.Resource res = null;
323
        try {
324
            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
            return null;
336
        } finally {
337
            IOUtils.closeQuietly(res);
338
        }
339
    }
340

    
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
    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-Z_0-9]*)");
366
    
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
            head = StringUtils.split("\n")[0];
380
            
381
            String lang = "cosa";
382
            String encoding = null;
383
            Matcher m = RE_LANG.matcher(head);
384
            if( m.groupCount()==1 ) {
385
                String s = m.group(1);
386
                if( !StringUtils.isBlank(s) ) {
387
                    lang = s;
388
                }
389
            }
390
            m = RE_ENCODING.matcher(head);
391
            if( m.groupCount()==1 ) {
392
                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
    
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
}
426