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

History | View | Annotate | Download (12.4 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 evaluatePage(String source) {
107
        return evaluatePage(null, source);
108
    }
109
    
110
    @Override
111
    public String evaluatePage(SymbolTable symbolTable, String source) {
112
        String[] sources = StringUtils.substringsBetween(source, "<%", "%>");
113
        if( ArrayUtils.isEmpty(sources) ) {
114
            return source;
115
        }
116
        String[] values = new String[sources.length];
117
        
118
        DefaultInterpreter interpreter = new DefaultInterpreter();
119
        if( symbolTable!=null ) {
120
            interpreter.setSymbolTable(symbolTable);
121
        }
122
        StringWriter writer = new StringWriter();
123
        interpreter.setWriter(writer);
124
        DefaultCompiler compiler = new DefaultCompiler();
125
        for (int i = 0; i < sources.length; i++) {
126
            String theSource = sources[i];
127
            if( StringUtils.startsWith(theSource, "=") ) {
128
                Code code = compiler.compileExpression(theSource.substring(1));
129
                Object value = interpreter.run(code);
130
                values[i] = Objects.toString(value, "");
131
            } else {
132
                Code code = compiler.compileExpression(theSource.substring(1));
133
                writer.getBuffer().setLength(0);
134
                interpreter.run(code);
135
                values[i] = writer.toString();
136
            }
137
            sources[i] = "<%"+sources[i]+"%>";
138
        }
139
        String output = StringUtils.replaceEach(source, sources, values);
140
        return output;
141
    }
142
    
143
    @Override
144
    public Code compile(String source) {
145
        Compiler compiler = this.createCompiler();
146
        return compiler.compileExpression(source);
147
    }
148

    
149
    @Override
150
    public Code compile(LexicalAnalyzer lex, String source) {
151
        Compiler compiler = this.createCompiler();
152
        compiler.setLexicalAnalyzer(lex);
153
        return compiler.compileExpression(source);
154
    }
155

    
156
    @Override
157
    public Code optimize(SymbolTable symbolTable, Code code) {
158
        Optimizer optimizer = this.createOptimizer();
159
        return optimizer.optimize(symbolTable, code);
160
    }
161

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

    
192
    @Override
193
    public CodeBuilder createCodeBuilder() {
194
        return new DefaultCodeBuilder();
195
    }
196

    
197
    @Override
198
    public Compiler createCompiler() {
199
        DefaultCompiler compiler = new DefaultCompiler();
200
        this.populateGrammars(compiler);
201
        return  compiler;
202
    }
203

    
204
    @Override
205
    public Interpreter createInterpreter() {
206
        return new DefaultInterpreter();
207
    }
208

    
209
    @Override
210
    public Double getAccuracy() {
211
        return this.accuracy;
212
    }
213

    
214
    @Override
215
    public void setAccuracy(Double accuracy) {
216
        this.accuracy = accuracy;
217
    }
218

    
219
    @Override
220
    public Expression createExpression() {
221
        DefaultExpression e = new DefaultExpression();
222
        return e;
223
    }
224

    
225
    @Override
226
    public ExpressionBuilder createExpressionBuilder() {
227
        ExpressionBuilder x = new DefaultExpressionBuilder();
228
        return x;
229
    }
230

    
231
    @Override
232
    public Optimizer createOptimizer() {
233
        Optimizer x = new DefaultOptimizer();
234
        return x;
235
    }
236

    
237
    @Override
238
    public void registerGrammar(GrammarFactory factory) {
239
        if( factory==null ) {
240
            throw new IllegalArgumentException("factory can't be null");
241
        }
242
        this.grammarFactories.put(factory.getName(), factory);
243
    }
244

    
245
    @Override
246
    public Collection<GrammarFactory> getGrammarFactories() {
247
        return this.grammarFactories.values();
248
    }
249

    
250
    public void populateGrammars(Compiler compiler) {
251
        GrammarSet grammarSet = compiler.getGrammars();
252
        for (GrammarFactory factory : this.getGrammarFactories() ) {
253
            if( factory.isAutoload() ) {
254
                Grammar grammar = factory.create();
255
                grammarSet.add(grammar);
256
            }
257
        }
258
    }
259

    
260
    @Override
261
    public Grammar createGrammar(String name) {
262
        DefaultGrammar grammar = new DefaultGrammar(name);
263
        return grammar;
264
    }
265
    
266
    @Override
267
    public Bookmarks<Expression> getBookmarks() {
268
        if( this.bookmarks==null ) {
269
            this.bookmarks = new BaseBookmarks<>();
270
        }
271
        return this.bookmarks;
272
    }
273

    
274
    @Override
275
    public History<Expression> getHistory() {
276
        if( this.history==null ) {
277
            this.history = new BaseHistory<>(20);
278
        }
279
        return this.history;
280
    }
281
    
282
    @Override
283
    public Script createScript(String name, String code, String languaje) {
284
        SimpleScript sc = new SimpleScript(this.createInterpreter(), name, code);
285
        return sc;
286
    }
287

    
288
    @Override
289
    public Script locateScript(String name) {
290
        return null;
291
    }
292

    
293
    @Override
294
    public Script loadScript(final URI location) {
295
        ResourcesStorage.Resource res = null;
296
        try {
297
            if( location==null ) {
298
                return null;
299
            }
300
            res = ResourcesStorage.createResource(location);
301
            if( res == null || !res.exists() ) {
302
                return null;
303
            }
304
            Script script = loadScript(res, FilenameUtils.getBaseName(location.getPath()));
305
            return script;
306
        } catch (Exception ex) {
307
            LOGGER.warn("Can't load script from URI.", ex);
308
            return null;
309
        } finally {
310
            IOUtils.closeQuietly(res);
311
        }
312
    }
313

    
314

    
315
    @Override
316
    public Script loadScript(ResourcesStorage storage, String name) {
317
        ResourcesStorage.Resource res = null;
318
        try {
319
            if( storage==null ) {
320
                return null;
321
            }
322
            res = storage.getResource(name);
323
            if( res == null || !res.exists() ) {
324
                return null;
325
            }
326
            Script script = loadScript(res, name);
327
            return script;
328
        } catch (Exception ex) {
329
            LOGGER.warn("Can't load script from resources storage.", ex);
330
            return null;
331
        } finally {
332
            IOUtils.closeQuietly(res);
333
        }
334

    
335
    }
336

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

    
371
            String source;
372
            if( StringUtils.isBlank(encoding) ) {
373
                source = IOUtils.toString(res.asInputStream());
374
            } else {
375
                source = IOUtils.toString(res.asInputStream(), encoding);
376
            }
377
            Script script = this.createScript(name, source, lang);
378
            return script;
379
        } catch (Exception ex) {
380
            LOGGER.warn("Can't load script from resource.", ex);
381
            return null;
382
        } finally {
383
            IOUtils.closeQuietly(res);
384
        }
385

    
386
    }
387
}
388