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

History | View | Annotate | Download (12.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

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

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

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

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

    
81
    @Override
82
    public Object evaluate(String source) {
83
        DefaultInterpreter interpreter = new DefaultInterpreter();
84
        DefaultCompiler compiler = new DefaultCompiler();
85
        Code code = compiler.compileExpression(source);
86
        return interpreter.run(code);
87
    }
88
    
89
    @Override
90
    public Object evaluate(SymbolTable symbolTable, String source) {
91
        DefaultInterpreter interpreter = new DefaultInterpreter();
92
        DefaultCompiler compiler = new DefaultCompiler();
93
        Code code = compiler.compileExpression(source);
94
        interpreter.setSymbolTable(symbolTable);
95
        return interpreter.run(code);
96
    }
97

    
98
    @Override
99
    public Object evaluate(SymbolTable symbolTable, Code code) {
100
        DefaultInterpreter interpreter = new DefaultInterpreter();
101
        interpreter.setSymbolTable(symbolTable);
102
        return interpreter.run(code);
103
    }
104

    
105
    @Override
106
    public String evaluateDynamicText(String source) {
107
        return evaluateDynamicText(null, source);
108
    }
109
    
110
    @Override
111
    public boolean isDynamicText(String source) {
112
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
113
        if( ArrayUtils.isEmpty(sources) ) {
114
            return false;
115
        }
116
        return true;
117
    }
118
    
119
    @Override
120
    public String evaluateDynamicText(SymbolTable symbolTable, String source) {
121
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
122
        if( ArrayUtils.isEmpty(sources) ) {
123
            return source;
124
        }
125
        String[] values = new String[sources.length];
126
        
127
        DefaultInterpreter interpreter = new DefaultInterpreter();
128
        if( symbolTable!=null ) {
129
            interpreter.setSymbolTable(symbolTable);
130
        }
131
        StringWriter writer = new StringWriter();
132
        interpreter.setWriter(writer);
133
        DefaultCompiler compiler = new DefaultCompiler();
134
        for (int i = 0; i < sources.length; i++) {
135
            String theSource = sources[i];
136
            if( StringUtils.startsWith(theSource, "=") ) {
137
                Code code = compiler.compileExpression(theSource.substring(1));
138
                Object value = interpreter.run(code);
139
                values[i] = Objects.toString(value, "");
140
            } else {
141
                Code code = compiler.compileExpression(theSource.substring(1));
142
                writer.getBuffer().setLength(0);
143
                interpreter.run(code);
144
                values[i] = writer.toString();
145
            }
146
            sources[i] = "<%"+sources[i]+"%>";
147
        }
148
        String output = StringUtils.replaceEach(source, sources, values);
149
        return output;
150
    }
151
    
152
    @Override
153
    public Code compile(String source) {
154
        Compiler compiler = this.createCompiler();
155
        return compiler.compileExpression(source);
156
    }
157

    
158
    @Override
159
    public Code compile(LexicalAnalyzer lex, String source) {
160
        Compiler compiler = this.createCompiler();
161
        compiler.setLexicalAnalyzer(lex);
162
        return compiler.compileExpression(source);
163
    }
164

    
165
    @Override
166
    public Code optimize(SymbolTable symbolTable, Code code) {
167
        Optimizer optimizer = this.createOptimizer();
168
        return optimizer.optimize(symbolTable, code);
169
    }
170

    
171
    @Override
172
    public MutableSymbolTable createSymbolTable() {
173
        DefaultSymbolTable theSymbolTable = new DefaultSymbolTable();
174
        return theSymbolTable;
175
    }
176
    
177
    public void populateSymbolTable(SymbolTable aSymbolTable) {
178
        for (SymbolTableFactory factory : this.getSymbolTableFactories() ) {
179
            try {
180
                if( factory.isAutoload() ) {
181
                    SymbolTable symbolTable = factory.create();
182
                    aSymbolTable.addSymbolTable(symbolTable);
183
                }
184
            } catch(Throwable th) {
185
                String factoryName = "Unknown";
186
                try {
187
                    factoryName = factory.getName();
188
                } catch(Throwable th2) {
189
                    // Do nothing
190
                }
191
                LOGGER.warn("Can't create symbol table '"+factoryName+"'.", th);
192
            }
193
        }
194
    }
195
    
196
    @Override
197
    public LexicalAnalyzer createLexicalAnalyzer() {
198
        return new SQLLexicalAnalyzer();
199
    }
200

    
201
    @Override
202
    public CodeBuilder createCodeBuilder() {
203
        return new DefaultCodeBuilder();
204
    }
205

    
206
    @Override
207
    public Compiler createCompiler() {
208
        DefaultCompiler compiler = new DefaultCompiler();
209
        this.populateGrammars(compiler);
210
        return  compiler;
211
    }
212

    
213
    @Override
214
    public Interpreter createInterpreter() {
215
        return new DefaultInterpreter();
216
    }
217

    
218
    @Override
219
    public Double getAccuracy() {
220
        return this.accuracy;
221
    }
222

    
223
    @Override
224
    public void setAccuracy(Double accuracy) {
225
        this.accuracy = accuracy;
226
    }
227

    
228
    @Override
229
    public Expression createExpression() {
230
        DefaultExpression e = new DefaultExpression();
231
        return e;
232
    }
233

    
234
    @Override
235
    public ExpressionBuilder createExpressionBuilder() {
236
        ExpressionBuilder x = new DefaultExpressionBuilder();
237
        return x;
238
    }
239

    
240
    @Override
241
    public Optimizer createOptimizer() {
242
        Optimizer x = new DefaultOptimizer();
243
        return x;
244
    }
245

    
246
    @Override
247
    public void registerGrammar(GrammarFactory factory) {
248
        if( factory==null ) {
249
            throw new IllegalArgumentException("factory can't be null");
250
        }
251
        this.grammarFactories.put(factory.getName(), factory);
252
    }
253

    
254
    @Override
255
    public Collection<GrammarFactory> getGrammarFactories() {
256
        return this.grammarFactories.values();
257
    }
258

    
259
    public void populateGrammars(Compiler compiler) {
260
        GrammarSet grammarSet = compiler.getGrammars();
261
        for (GrammarFactory factory : this.getGrammarFactories() ) {
262
            if( factory.isAutoload() ) {
263
                Grammar grammar = factory.create();
264
                grammarSet.add(grammar);
265
            }
266
        }
267
    }
268

    
269
    @Override
270
    public Grammar createGrammar(String name) {
271
        DefaultGrammar grammar = new DefaultGrammar(name);
272
        return grammar;
273
    }
274
    
275
    @Override
276
    public Bookmarks<Expression> getBookmarks() {
277
        if( this.bookmarks==null ) {
278
            this.bookmarks = new BaseBookmarks<>();
279
        }
280
        return this.bookmarks;
281
    }
282

    
283
    @Override
284
    public History<Expression> getHistory() {
285
        if( this.history==null ) {
286
            this.history = new BaseHistory<>(20);
287
        }
288
        return this.history;
289
    }
290
    
291
    @Override
292
    public Script createScript(String name, String code, String languaje) {
293
        SimpleScript sc = new SimpleScript(this.createInterpreter(), name, code);
294
        return sc;
295
    }
296

    
297
    @Override
298
    public Script locateScript(String name) {
299
        return null;
300
    }
301

    
302
    @Override
303
    public Script loadScript(final URI location) {
304
        ResourcesStorage.Resource res = null;
305
        try {
306
            if( location==null ) {
307
                return null;
308
            }
309
            res = ResourcesStorage.createResource(location);
310
            if( res == null || !res.exists() ) {
311
                return null;
312
            }
313
            Script script = loadScript(res, FilenameUtils.getBaseName(location.getPath()));
314
            return script;
315
        } catch (Exception ex) {
316
            LOGGER.warn("Can't load script from URI.", ex);
317
            return null;
318
        } finally {
319
            IOUtils.closeQuietly(res);
320
        }
321
    }
322

    
323

    
324
    @Override
325
    public Script loadScript(ResourcesStorage storage, String name) {
326
        ResourcesStorage.Resource res = null;
327
        try {
328
            if( storage==null ) {
329
                return null;
330
            }
331
            res = storage.getResource(name);
332
            if( res == null || !res.exists() ) {
333
                return null;
334
            }
335
            Script script = loadScript(res, name);
336
            return script;
337
        } catch (Exception ex) {
338
            LOGGER.warn("Can't load script from resources storage.", ex);
339
            return null;
340
        } finally {
341
            IOUtils.closeQuietly(res);
342
        }
343

    
344
    }
345

    
346
    private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)");
347
    private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z_0-9]*)");
348
    
349
    private Script loadScript(ResourcesStorage.Resource res, String name) {
350
        try {
351
            if( res == null || !res.exists() ) {
352
                return null;
353
            }
354
            byte[] head_bytes = new byte[500];
355
            IOUtils.read(res.asInputStream(), head_bytes);
356
            IOUtils.closeQuietly(res);
357
            String head = new String(head_bytes);
358
            if( StringUtils.isEmpty(head) ) {
359
                return null;
360
            }
361
            head = StringUtils.split("\n")[0];
362
            
363
            String lang = "cosa";
364
            String encoding = null;
365
            Matcher m = RE_LANG.matcher(head);
366
            if( m.groupCount()==1 ) {
367
                String s = m.group(1);
368
                if( !StringUtils.isBlank(s) ) {
369
                    lang = s;
370
                }
371
            }
372
            m = RE_ENCODING.matcher(head);
373
            if( m.groupCount()==1 ) {
374
                String s = m.group(1);
375
                if( !StringUtils.isBlank(s) ) {
376
                    encoding = s;
377
                }
378
            }
379

    
380
            String source;
381
            if( StringUtils.isBlank(encoding) ) {
382
                source = IOUtils.toString(res.asInputStream());
383
            } else {
384
                source = IOUtils.toString(res.asInputStream(), encoding);
385
            }
386
            Script script = this.createScript(name, source, lang);
387
            return script;
388
        } catch (Exception ex) {
389
            LOGGER.warn("Can't load script from resource.", ex);
390
            return null;
391
        } finally {
392
            IOUtils.closeQuietly(res);
393
        }
394

    
395
    }
396
}
397