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 @ 47248
History | View | Annotate | Download (28.8 KB)
1 | 43521 | jjdelcerro | package org.gvsig.expressionevaluator.impl; |
---|---|---|---|
2 | |||
3 | 46932 | jjdelcerro | import java.io.IOException; |
4 | import java.io.PushbackReader; |
||
5 | import java.io.StringReader; |
||
6 | 45366 | omartinez | import org.gvsig.expressionevaluator.spi.BaseExpressionEvaluator; |
7 | 44389 | jjdelcerro | import java.io.StringWriter; |
8 | 46958 | jjdelcerro | import java.io.Writer; |
9 | 44339 | jjdelcerro | import java.net.URI; |
10 | 44644 | jjdelcerro | import java.util.ArrayList; |
11 | 44139 | jjdelcerro | import org.gvsig.expressionevaluator.Grammar; |
12 | import org.gvsig.expressionevaluator.GrammarFactory; |
||
13 | 43983 | jjdelcerro | import java.util.Collection; |
14 | 44750 | jjdelcerro | import java.util.Collections; |
15 | 43939 | jjdelcerro | import java.util.HashMap; |
16 | 47175 | jjdelcerro | import java.util.LinkedHashMap; |
17 | 44644 | jjdelcerro | import java.util.List; |
18 | 43939 | jjdelcerro | import java.util.Map; |
19 | 44389 | jjdelcerro | import java.util.Objects; |
20 | 44392 | jjdelcerro | import java.util.regex.Matcher; |
21 | import java.util.regex.Pattern; |
||
22 | 44339 | jjdelcerro | import org.apache.commons.io.FilenameUtils; |
23 | import org.apache.commons.io.IOUtils; |
||
24 | 46958 | jjdelcerro | import org.apache.commons.io.output.ProxyWriter; |
25 | 44389 | jjdelcerro | import org.apache.commons.lang3.ArrayUtils; |
26 | import org.apache.commons.lang3.StringUtils; |
||
27 | 43521 | jjdelcerro | import org.gvsig.expressionevaluator.Code; |
28 | import org.gvsig.expressionevaluator.CodeBuilder; |
||
29 | 43983 | jjdelcerro | import org.gvsig.expressionevaluator.Expression; |
30 | 44006 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionBuilder; |
31 | 43521 | jjdelcerro | import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
32 | import org.gvsig.expressionevaluator.Interpreter; |
||
33 | import org.gvsig.expressionevaluator.LexicalAnalyzer; |
||
34 | import org.gvsig.expressionevaluator.MutableSymbolTable; |
||
35 | 44009 | jjdelcerro | import org.gvsig.expressionevaluator.Optimizer; |
36 | 43521 | jjdelcerro | import org.gvsig.expressionevaluator.SymbolTable; |
37 | 44126 | jjdelcerro | import org.gvsig.expressionevaluator.SymbolTableFactory; |
38 | 44139 | jjdelcerro | import org.gvsig.expressionevaluator.Compiler; |
39 | 47175 | jjdelcerro | import org.gvsig.expressionevaluator.ConverterToCode; |
40 | 45366 | omartinez | import org.gvsig.expressionevaluator.ExpressionEvaluator; |
41 | 44769 | jjdelcerro | import org.gvsig.expressionevaluator.Formatter; |
42 | 44139 | jjdelcerro | import org.gvsig.expressionevaluator.GrammarSet; |
43 | 44644 | jjdelcerro | import org.gvsig.expressionevaluator.ReprMethod; |
44 | 47175 | jjdelcerro | import org.gvsig.expressionevaluator.impl.converterstocode.ArrayToCode; |
45 | import org.gvsig.expressionevaluator.impl.converterstocode.BooleanToCode; |
||
46 | import org.gvsig.expressionevaluator.impl.converterstocode.CharsequenceToCode; |
||
47 | import org.gvsig.expressionevaluator.impl.converterstocode.IterableToCode; |
||
48 | import org.gvsig.expressionevaluator.impl.converterstocode.IteratorToCode; |
||
49 | import org.gvsig.expressionevaluator.impl.converterstocode.ListToCode; |
||
50 | import org.gvsig.expressionevaluator.impl.converterstocode.NullToCode; |
||
51 | import org.gvsig.expressionevaluator.impl.converterstocode.NumberToCode; |
||
52 | import org.gvsig.expressionevaluator.impl.converterstocode.ObjectToCode; |
||
53 | 44644 | jjdelcerro | import org.gvsig.expressionevaluator.impl.repr.ReprNull; |
54 | import org.gvsig.expressionevaluator.impl.repr.ReprObject; |
||
55 | 44769 | jjdelcerro | import org.gvsig.expressionevaluator.spi.formatter.value.BaseFormatter; |
56 | 45282 | omartinez | import org.gvsig.tools.ToolsLocator; |
57 | 44390 | jjdelcerro | import org.gvsig.tools.bookmarksandhistory.Bookmarks; |
58 | import org.gvsig.tools.bookmarksandhistory.History; |
||
59 | 46828 | fdiaz | import org.gvsig.tools.dispose.DisposeUtils; |
60 | 46711 | jjdelcerro | import org.gvsig.tools.exception.BaseException; |
61 | 44392 | jjdelcerro | import org.gvsig.tools.resourcesstorage.ResourcesStorage; |
62 | 44339 | jjdelcerro | import org.gvsig.tools.script.Script; |
63 | 44006 | jjdelcerro | import org.slf4j.Logger; |
64 | import org.slf4j.LoggerFactory; |
||
65 | 43521 | jjdelcerro | |
66 | |||
67 | 44339 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
68 | 43521 | jjdelcerro | public class DefaultExpressionEvaluatorManager implements ExpressionEvaluatorManager { |
69 | |||
70 | 44006 | jjdelcerro | private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExpressionEvaluatorManager.class); |
71 | |||
72 | 43521 | jjdelcerro | private Double accuracy; |
73 | 44126 | jjdelcerro | private final Map<String,SymbolTableFactory>symbolTableFactories; |
74 | 44139 | jjdelcerro | private final Map<String,GrammarFactory> grammarFactories; |
75 | 45703 | jjdelcerro | private Bookmarks<Expression> bookmarks; |
76 | 45282 | omartinez | private static final String BOOKMARKSANDHISTORY_NAME = "ExpressionManager"; |
77 | 45703 | jjdelcerro | private History<Expression> history; |
78 | 44446 | jjdelcerro | private SymbolTable inmutableSymbolTable;
|
79 | 44533 | jjdelcerro | private ResourcesStorage scriptsResourcesStorage;
|
80 | 45932 | jjdelcerro | private final List<ClassLoader> loaders; |
81 | 44769 | jjdelcerro | private Formatter<ExpressionBuilder.Value> expressionBuilderFormatter; |
82 | 43521 | jjdelcerro | |
83 | 47175 | jjdelcerro | private Map<String,ConverterToCode> convertersToCode; |
84 | private Map<String,ConverterToCode> convertersToCode0; |
||
85 | |||
86 | 43521 | jjdelcerro | public DefaultExpressionEvaluatorManager() {
|
87 | 44126 | jjdelcerro | this.symbolTableFactories = new HashMap<>(); |
88 | 44139 | jjdelcerro | this.grammarFactories = new HashMap<>(); |
89 | 44750 | jjdelcerro | this.loaders = new ArrayList<>(); |
90 | 44533 | jjdelcerro | this.scriptsResourcesStorage = ResourcesStorage.EMPTY_RESOURCESSTORAGE;
|
91 | 44750 | jjdelcerro | this.loaders.add(this.getClass().getClassLoader()); |
92 | 44769 | jjdelcerro | this.expressionBuilderFormatter = new BaseFormatter(); |
93 | 43939 | jjdelcerro | } |
94 | |||
95 | 43521 | jjdelcerro | @Override
|
96 | 43983 | jjdelcerro | public SymbolTable getSymbolTable(String name) { |
97 | 44126 | jjdelcerro | if( name == null ) { |
98 | return null; |
||
99 | } |
||
100 | SymbolTableFactory factory = this.symbolTableFactories.get(name.toUpperCase());
|
||
101 | if( factory == null ) { |
||
102 | return null; |
||
103 | } |
||
104 | 44389 | jjdelcerro | return factory.create();
|
105 | 43939 | jjdelcerro | } |
106 | |||
107 | @Override
|
||
108 | 44126 | jjdelcerro | public Collection<SymbolTableFactory> getSymbolTableFactories() { |
109 | return this.symbolTableFactories.values(); |
||
110 | 43939 | jjdelcerro | } |
111 | |||
112 | @Override
|
||
113 | 44126 | jjdelcerro | public final void registerSymbolTable(SymbolTableFactory factory) { |
114 | if( factory == null ) { |
||
115 | throw new IllegalArgumentException("factory can't be null"); |
||
116 | 44006 | jjdelcerro | } |
117 | 44126 | jjdelcerro | this.symbolTableFactories.put(factory.getName().toUpperCase(),factory);
|
118 | 44446 | jjdelcerro | this.inmutableSymbolTable = null; |
119 | 43939 | jjdelcerro | } |
120 | 43987 | jjdelcerro | |
121 | 43939 | jjdelcerro | @Override
|
122 | 44446 | jjdelcerro | public SymbolTable getInmutableSymbolTable() {
|
123 | if( this.inmutableSymbolTable==null ) { |
||
124 | this.inmutableSymbolTable = new InmutableSymbolTable(); |
||
125 | } |
||
126 | return this.inmutableSymbolTable; |
||
127 | } |
||
128 | |||
129 | @Override
|
||
130 | 43521 | jjdelcerro | public Object evaluate(String source) { |
131 | 46932 | jjdelcerro | Compiler compiler = this.createCompiler(); |
132 | Code code = compiler.compileExpression(source); |
||
133 | 43521 | jjdelcerro | DefaultInterpreter interpreter = new DefaultInterpreter();
|
134 | return interpreter.run(code);
|
||
135 | } |
||
136 | 44389 | jjdelcerro | |
137 | 43521 | jjdelcerro | @Override
|
138 | public Object evaluate(SymbolTable symbolTable, String source) { |
||
139 | 46932 | jjdelcerro | Compiler compiler = this.createCompiler(); |
140 | 43521 | jjdelcerro | Code code = compiler.compileExpression(source); |
141 | 46932 | jjdelcerro | return this.evaluate(symbolTable, code); |
142 | 43521 | jjdelcerro | } |
143 | |||
144 | @Override
|
||
145 | public Object evaluate(SymbolTable symbolTable, Code code) { |
||
146 | DefaultInterpreter interpreter = new DefaultInterpreter();
|
||
147 | 44446 | jjdelcerro | if( symbolTable!=null ) { |
148 | interpreter.setSymbolTable(symbolTable); |
||
149 | } |
||
150 | 43521 | jjdelcerro | return interpreter.run(code);
|
151 | } |
||
152 | |||
153 | @Override
|
||
154 | 44397 | jjdelcerro | public String evaluateDynamicText(String source) { |
155 | return evaluateDynamicText(null, source); |
||
156 | 44389 | jjdelcerro | } |
157 | |||
158 | @Override
|
||
159 | 44397 | jjdelcerro | public boolean isDynamicText(String source) { |
160 | 44818 | jjdelcerro | String[] sources = StringUtils.substringsBetween(source, DYNAMICTEXT_STARTTAG, DYNAMICTEXT_ENDTAG); |
161 | 44389 | jjdelcerro | if( ArrayUtils.isEmpty(sources) ) {
|
162 | 44397 | jjdelcerro | return false; |
163 | } |
||
164 | return true; |
||
165 | } |
||
166 | 46932 | jjdelcerro | |
167 | |||
168 | private static final int MODE_EXPRESSION = 0; |
||
169 | private static final int MODE_STATEMENT = 1; |
||
170 | 44397 | jjdelcerro | |
171 | 46932 | jjdelcerro | public static String dynamicTextToScript(String s, String contentsName) { |
172 | PushbackReader reader = new PushbackReader(new StringReader(s),100); |
||
173 | StringBuilder script = new StringBuilder(); |
||
174 | StringBuilder buffer = new StringBuilder(); |
||
175 | try {
|
||
176 | script.append("begin\n");
|
||
177 | 46958 | jjdelcerro | // script.append(contentsName);
|
178 | // script.append(" := StringWriter();\n");
|
||
179 | 46932 | jjdelcerro | int mode;
|
180 | int ch;
|
||
181 | int ch2;
|
||
182 | while(true) { |
||
183 | ch = reader.read(); |
||
184 | if( ch == -1 ) { |
||
185 | break;
|
||
186 | } |
||
187 | switch(ch) {
|
||
188 | case '<': |
||
189 | ch2 = reader.read(); |
||
190 | if( ch2 != '%') { |
||
191 | buffer.append((char)ch);
|
||
192 | buffer.append((char)ch2);
|
||
193 | break;
|
||
194 | } |
||
195 | ch2 = reader.read(); |
||
196 | if( ch2 == '=' ) { |
||
197 | mode = MODE_EXPRESSION; |
||
198 | } else {
|
||
199 | mode = MODE_STATEMENT; |
||
200 | reader.unread(ch2); |
||
201 | } |
||
202 | if( buffer.length()>0 ) { |
||
203 | script.append(contentsName); |
||
204 | script.append(".append('");
|
||
205 | script.append(buffer.toString()); |
||
206 | script.append("');");
|
||
207 | } |
||
208 | buffer.setLength(0);
|
||
209 | while(true) { |
||
210 | ch = reader.read(); |
||
211 | if( ch==-1) { |
||
212 | break;
|
||
213 | } |
||
214 | if( ch == '%' ) { |
||
215 | ch2 = reader.read(); |
||
216 | if( ch2 == '>') { |
||
217 | if( mode == MODE_EXPRESSION ) {
|
||
218 | if( buffer.length()>0 ) { |
||
219 | script.append(contentsName); |
||
220 | script.append(".append(");
|
||
221 | script.append(buffer.toString()); |
||
222 | script.append(");");
|
||
223 | } |
||
224 | } else {
|
||
225 | script.append(buffer.toString()); |
||
226 | } |
||
227 | buffer.setLength(0);
|
||
228 | break;
|
||
229 | } else {
|
||
230 | buffer.append((char)ch);
|
||
231 | buffer.append((char)ch2);
|
||
232 | } |
||
233 | } else {
|
||
234 | buffer.append((char)ch);
|
||
235 | } |
||
236 | } |
||
237 | break;
|
||
238 | case '\'': |
||
239 | buffer.append('\'');
|
||
240 | buffer.append('\'');
|
||
241 | break;
|
||
242 | default:
|
||
243 | buffer.append((char)ch);
|
||
244 | break;
|
||
245 | } |
||
246 | } |
||
247 | } catch (IOException ex) { |
||
248 | |||
249 | } |
||
250 | if( buffer.length()>0 ) { |
||
251 | script.append(contentsName); |
||
252 | script.append(".append('");
|
||
253 | script.append(buffer.toString()); |
||
254 | script.append("');");
|
||
255 | script.append("\n");
|
||
256 | } |
||
257 | 46958 | jjdelcerro | // script.append(contentsName);
|
258 | // script.append(".toString();\n");
|
||
259 | 46932 | jjdelcerro | script.append("end\n");
|
260 | 46958 | jjdelcerro | |
261 | 46932 | jjdelcerro | return script.toString();
|
262 | } |
||
263 | |||
264 | 44397 | jjdelcerro | @Override
|
265 | public String evaluateDynamicText(SymbolTable symbolTable, String source) { |
||
266 | 46958 | jjdelcerro | return evaluateDynamicText(symbolTable, source, null); |
267 | } |
||
268 | 47063 | jjdelcerro | |
269 | 46958 | jjdelcerro | public static class AppendExWriter extends ProxyWriter { |
270 | public AppendExWriter(Writer writer) { |
||
271 | super(writer);
|
||
272 | 46932 | jjdelcerro | } |
273 | 46958 | jjdelcerro | |
274 | public Writer append(Object x) throws IOException { |
||
275 | if( x!=null ) { |
||
276 | this.append(x.toString());
|
||
277 | } |
||
278 | return this; |
||
279 | 46939 | jjdelcerro | } |
280 | 46958 | jjdelcerro | |
281 | public Writer getWriter() { |
||
282 | return this.out; |
||
283 | } |
||
284 | 46932 | jjdelcerro | } |
285 | |||
286 | 47077 | jjdelcerro | @Override
|
287 | public String evaluateDynamicText(SymbolTable symbolTable, String source, Writer output) { |
||
288 | return this.evaluateDynamicText(symbolTable, source, output, scriptsResourcesStorage); |
||
289 | } |
||
290 | 46958 | jjdelcerro | |
291 | @Override
|
||
292 | 47077 | jjdelcerro | public String evaluateDynamicText(SymbolTable symbolTable, String source, Writer output, ResourcesStorage resources) { |
293 | 46958 | jjdelcerro | try {
|
294 | if (!StringUtils.contains(source, DYNAMICTEXT_STARTTAG)) {
|
||
295 | if (output == null) { |
||
296 | return source;
|
||
297 | } |
||
298 | output.append(source); |
||
299 | return null; |
||
300 | } |
||
301 | AppendExWriter writer; |
||
302 | if (output == null) { |
||
303 | writer = new AppendExWriter(new StringWriter()); |
||
304 | } else {
|
||
305 | writer = new AppendExWriter(output);
|
||
306 | } |
||
307 | String script = dynamicTextToScript(source, "contents"); |
||
308 | MutableSymbolTable st = this.createSymbolTable();
|
||
309 | if (symbolTable != null) { |
||
310 | st.addSymbolTable(symbolTable); |
||
311 | } |
||
312 | st.setVar("contents", writer);
|
||
313 | 47077 | jjdelcerro | |
314 | Compiler compiler = this.createCompiler(); |
||
315 | DefaultInterpreter interpreter = new DefaultInterpreter();
|
||
316 | interpreter.setSymbolTable(st); |
||
317 | if( resources!=null ) { |
||
318 | interpreter.setResourcesStorage(resources); |
||
319 | } |
||
320 | |||
321 | Code code = compiler.compileExpression(script); |
||
322 | interpreter.run(code); |
||
323 | |||
324 | 46958 | jjdelcerro | if (output == null) { |
325 | return ((StringWriter) writer.getWriter()).toString(); |
||
326 | } |
||
327 | return null; |
||
328 | } catch (IOException ex) { |
||
329 | throw new RuntimeException("Can't evaluate dynamic-text.", ex); |
||
330 | } |
||
331 | } |
||
332 | |||
333 | 46932 | jjdelcerro | public String evaluateDynamicText_old(SymbolTable symbolTable, String source) { |
334 | 44818 | jjdelcerro | String[] sources = StringUtils.substringsBetween(source, DYNAMICTEXT_STARTTAG, DYNAMICTEXT_ENDTAG); |
335 | 44397 | jjdelcerro | if( ArrayUtils.isEmpty(sources) ) {
|
336 | 44389 | jjdelcerro | return source;
|
337 | } |
||
338 | String[] values = new String[sources.length]; |
||
339 | |||
340 | DefaultInterpreter interpreter = new DefaultInterpreter();
|
||
341 | if( symbolTable!=null ) { |
||
342 | interpreter.setSymbolTable(symbolTable); |
||
343 | } |
||
344 | StringWriter writer = new StringWriter(); |
||
345 | interpreter.setWriter(writer); |
||
346 | 44644 | jjdelcerro | DefaultCompiler compiler = new DefaultCompiler(this); |
347 | 44389 | jjdelcerro | for (int i = 0; i < sources.length; i++) { |
348 | String theSource = sources[i];
|
||
349 | if( StringUtils.startsWith(theSource, "=") ) { |
||
350 | Code code = compiler.compileExpression(theSource.substring(1));
|
||
351 | Object value = interpreter.run(code);
|
||
352 | values[i] = Objects.toString(value, "");
|
||
353 | } else {
|
||
354 | 45778 | fdiaz | Code code = compiler.compileExpression(theSource.substring(0));
|
355 | 44389 | jjdelcerro | writer.getBuffer().setLength(0);
|
356 | interpreter.run(code); |
||
357 | values[i] = writer.toString(); |
||
358 | } |
||
359 | 44818 | jjdelcerro | sources[i] = DYNAMICTEXT_STARTTAG+sources[i]+DYNAMICTEXT_ENDTAG; |
360 | 44389 | jjdelcerro | } |
361 | String output = StringUtils.replaceEach(source, sources, values);
|
||
362 | return output;
|
||
363 | } |
||
364 | |||
365 | @Override
|
||
366 | 43521 | jjdelcerro | public Code compile(String source) { |
367 | 44139 | jjdelcerro | Compiler compiler = this.createCompiler(); |
368 | 43521 | jjdelcerro | return compiler.compileExpression(source);
|
369 | } |
||
370 | |||
371 | @Override
|
||
372 | public Code compile(LexicalAnalyzer lex, String source) { |
||
373 | 44139 | jjdelcerro | Compiler compiler = this.createCompiler(); |
374 | 43521 | jjdelcerro | compiler.setLexicalAnalyzer(lex); |
375 | return compiler.compileExpression(source);
|
||
376 | } |
||
377 | |||
378 | @Override
|
||
379 | 44019 | jjdelcerro | public Code optimize(SymbolTable symbolTable, Code code) {
|
380 | Optimizer optimizer = this.createOptimizer();
|
||
381 | return optimizer.optimize(symbolTable, code);
|
||
382 | } |
||
383 | |||
384 | @Override
|
||
385 | 43521 | jjdelcerro | public MutableSymbolTable createSymbolTable() {
|
386 | 43987 | jjdelcerro | DefaultSymbolTable theSymbolTable = new DefaultSymbolTable();
|
387 | return theSymbolTable;
|
||
388 | 43521 | jjdelcerro | } |
389 | 43939 | jjdelcerro | |
390 | 45932 | jjdelcerro | @Override
|
391 | 43987 | jjdelcerro | public void populateSymbolTable(SymbolTable aSymbolTable) { |
392 | 44126 | jjdelcerro | for (SymbolTableFactory factory : this.getSymbolTableFactories() ) { |
393 | 44394 | jjdelcerro | try {
|
394 | if( factory.isAutoload() ) {
|
||
395 | SymbolTable symbolTable = factory.create(); |
||
396 | aSymbolTable.addSymbolTable(symbolTable); |
||
397 | } |
||
398 | } catch(Throwable th) { |
||
399 | String factoryName = "Unknown"; |
||
400 | try {
|
||
401 | factoryName = factory.getName(); |
||
402 | } catch(Throwable th2) { |
||
403 | // Do nothing
|
||
404 | } |
||
405 | 44965 | jjdelcerro | LOGGER.warn("Can't create symbol table '"+factoryName+"', ignore this symbol table."); |
406 | LOGGER.debug("Error creating symbol table.",th);
|
||
407 | 43987 | jjdelcerro | } |
408 | } |
||
409 | } |
||
410 | |||
411 | 43521 | jjdelcerro | @Override
|
412 | public LexicalAnalyzer createLexicalAnalyzer() {
|
||
413 | return new SQLLexicalAnalyzer(); |
||
414 | } |
||
415 | |||
416 | @Override
|
||
417 | public CodeBuilder createCodeBuilder() {
|
||
418 | 44644 | jjdelcerro | return new DefaultCodeBuilder(this); |
419 | 43521 | jjdelcerro | } |
420 | |||
421 | @Override
|
||
422 | public Compiler createCompiler() { |
||
423 | 44644 | jjdelcerro | DefaultCompiler compiler = new DefaultCompiler(this); |
424 | 44139 | jjdelcerro | this.populateGrammars(compiler);
|
425 | return compiler;
|
||
426 | 43521 | jjdelcerro | } |
427 | |||
428 | @Override
|
||
429 | public Interpreter createInterpreter() {
|
||
430 | 44533 | jjdelcerro | Interpreter interpreter = new DefaultInterpreter();
|
431 | interpreter.setResourcesStorage(this.scriptsResourcesStorage);
|
||
432 | return interpreter;
|
||
433 | 43521 | jjdelcerro | } |
434 | |||
435 | @Override
|
||
436 | public Double getAccuracy() { |
||
437 | return this.accuracy; |
||
438 | } |
||
439 | |||
440 | @Override
|
||
441 | public void setAccuracy(Double accuracy) { |
||
442 | this.accuracy = accuracy;
|
||
443 | } |
||
444 | 43983 | jjdelcerro | |
445 | @Override
|
||
446 | public Expression createExpression() { |
||
447 | 44644 | jjdelcerro | DefaultExpression e = new DefaultExpression(this); |
448 | 43983 | jjdelcerro | return e;
|
449 | } |
||
450 | 44006 | jjdelcerro | |
451 | @Override
|
||
452 | public ExpressionBuilder createExpressionBuilder() {
|
||
453 | 44644 | jjdelcerro | ExpressionBuilder x = new DefaultExpressionBuilder(this); |
454 | 44006 | jjdelcerro | return x;
|
455 | } |
||
456 | 44009 | jjdelcerro | |
457 | @Override
|
||
458 | public Optimizer createOptimizer() {
|
||
459 | 44644 | jjdelcerro | Optimizer x = new DefaultOptimizer(this); |
460 | 44009 | jjdelcerro | return x;
|
461 | } |
||
462 | 44139 | jjdelcerro | |
463 | @Override
|
||
464 | public void registerGrammar(GrammarFactory factory) { |
||
465 | if( factory==null ) { |
||
466 | throw new IllegalArgumentException("factory can't be null"); |
||
467 | } |
||
468 | this.grammarFactories.put(factory.getName(), factory);
|
||
469 | } |
||
470 | |||
471 | @Override
|
||
472 | public Collection<GrammarFactory> getGrammarFactories() { |
||
473 | return this.grammarFactories.values(); |
||
474 | } |
||
475 | |||
476 | public void populateGrammars(Compiler compiler) { |
||
477 | GrammarSet grammarSet = compiler.getGrammars(); |
||
478 | for (GrammarFactory factory : this.getGrammarFactories() ) { |
||
479 | if( factory.isAutoload() ) {
|
||
480 | 44389 | jjdelcerro | Grammar grammar = factory.create(); |
481 | 44139 | jjdelcerro | grammarSet.add(grammar); |
482 | } |
||
483 | } |
||
484 | } |
||
485 | |||
486 | 44263 | jjdelcerro | @Override
|
487 | 44139 | jjdelcerro | public Grammar createGrammar(String name) { |
488 | DefaultGrammar grammar = new DefaultGrammar(name);
|
||
489 | return grammar;
|
||
490 | } |
||
491 | 44263 | jjdelcerro | |
492 | @Override
|
||
493 | 45703 | jjdelcerro | public Bookmarks<Expression> getBookmarks() { |
494 | 44263 | jjdelcerro | if( this.bookmarks==null ) { |
495 | 45703 | jjdelcerro | this.bookmarks = ToolsLocator.getBookmarksAndHistoryManager().getBookmarksGroup(BOOKMARKSANDHISTORY_NAME);
|
496 | 45282 | omartinez | |
497 | 44263 | jjdelcerro | } |
498 | return this.bookmarks; |
||
499 | } |
||
500 | |||
501 | @Override
|
||
502 | 45703 | jjdelcerro | public History<Expression> getHistory() { |
503 | 44263 | jjdelcerro | if( this.history==null ) { |
504 | 45703 | jjdelcerro | this.history = ToolsLocator.getBookmarksAndHistoryManager().getHistoryGroup(BOOKMARKSANDHISTORY_NAME);
|
505 | 44263 | jjdelcerro | } |
506 | return this.history; |
||
507 | } |
||
508 | 44339 | jjdelcerro | |
509 | @Override
|
||
510 | public Script createScript(String name, String code, String languaje) { |
||
511 | 44389 | jjdelcerro | SimpleScript sc = new SimpleScript(this.createInterpreter(), name, code); |
512 | 44339 | jjdelcerro | return sc;
|
513 | } |
||
514 | |||
515 | @Override
|
||
516 | public Script locateScript(String name) { |
||
517 | 44533 | jjdelcerro | return loadScript(this.scriptsResourcesStorage, name); |
518 | 44339 | jjdelcerro | } |
519 | |||
520 | @Override
|
||
521 | 44392 | jjdelcerro | public Script loadScript(final URI location) { |
522 | ResourcesStorage.Resource res = null;
|
||
523 | 44339 | jjdelcerro | try {
|
524 | 44392 | jjdelcerro | if( location==null ) { |
525 | return null; |
||
526 | } |
||
527 | 44710 | jjdelcerro | String resourceName = FilenameUtils.getBaseName(location.getPath());
|
528 | res = ResourcesStorage.createResource(resourceName, location); |
||
529 | 44392 | jjdelcerro | if( res == null || !res.exists() ) { |
530 | return null; |
||
531 | } |
||
532 | 44710 | jjdelcerro | Script script = loadScript(res, resourceName); |
533 | 44392 | jjdelcerro | return script;
|
534 | } catch (Exception ex) { |
||
535 | LOGGER.warn("Can't load script from URI.", ex);
|
||
536 | 44339 | jjdelcerro | return null; |
537 | } finally {
|
||
538 | 44392 | jjdelcerro | IOUtils.closeQuietly(res); |
539 | 44339 | jjdelcerro | } |
540 | } |
||
541 | 44392 | jjdelcerro | |
542 | |||
543 | @Override
|
||
544 | public Script loadScript(ResourcesStorage storage, String name) { |
||
545 | ResourcesStorage.Resource res = null;
|
||
546 | try {
|
||
547 | if( storage==null ) { |
||
548 | return null; |
||
549 | } |
||
550 | res = storage.getResource(name); |
||
551 | if( res == null || !res.exists() ) { |
||
552 | return null; |
||
553 | } |
||
554 | Script script = loadScript(res, name); |
||
555 | return script;
|
||
556 | } catch (Exception ex) { |
||
557 | LOGGER.warn("Can't load script from resources storage.", ex);
|
||
558 | return null; |
||
559 | } finally {
|
||
560 | IOUtils.closeQuietly(res); |
||
561 | } |
||
562 | |||
563 | } |
||
564 | |||
565 | 44592 | jjdelcerro | private static final Pattern RE_LANG = Pattern.compile(".*lang[:]\\s*([a-zA-Z_][a-zA-Z_0-9_]*).*"); |
566 | private static final Pattern RE_ENCODING = Pattern.compile(".*encoding[:]\\s*([a-zA-Z_][a-zA-Z0-9_-]*).*"); |
||
567 | 44392 | jjdelcerro | |
568 | private Script loadScript(ResourcesStorage.Resource res, String name) { |
||
569 | try {
|
||
570 | if( res == null || !res.exists() ) { |
||
571 | return null; |
||
572 | } |
||
573 | 44851 | jjdelcerro | String head = EncodingUtils.getFirstLine(res.asInputStream());
|
574 | IOUtils.closeQuietly(res); // Eliminar con org.gvsig.tools > 3.0.230
|
||
575 | 44392 | jjdelcerro | if( StringUtils.isEmpty(head) ) {
|
576 | return null; |
||
577 | } |
||
578 | 44339 | jjdelcerro | |
579 | 44851 | jjdelcerro | String encoding = EncodingUtils.getEncoding(head);
|
580 | |||
581 | 44392 | jjdelcerro | String lang = "cosa"; |
582 | Matcher m = RE_LANG.matcher(head);
|
||
583 | 44592 | jjdelcerro | if( m!=null && m.matches() && m.groupCount()==1 ) { |
584 | 44392 | jjdelcerro | String s = m.group(1); |
585 | if( !StringUtils.isBlank(s) ) {
|
||
586 | lang = s; |
||
587 | } |
||
588 | } |
||
589 | String source;
|
||
590 | if( StringUtils.isBlank(encoding) ) {
|
||
591 | source = IOUtils.toString(res.asInputStream()); |
||
592 | } else {
|
||
593 | source = IOUtils.toString(res.asInputStream(), encoding); |
||
594 | } |
||
595 | Script script = this.createScript(name, source, lang);
|
||
596 | return script;
|
||
597 | } catch (Exception ex) { |
||
598 | LOGGER.warn("Can't load script from resource.", ex);
|
||
599 | return null; |
||
600 | } finally {
|
||
601 | IOUtils.closeQuietly(res); |
||
602 | } |
||
603 | |||
604 | } |
||
605 | 44533 | jjdelcerro | |
606 | @Override
|
||
607 | public ResourcesStorage getScriptsResourcesStorage() {
|
||
608 | return this.scriptsResourcesStorage; |
||
609 | } |
||
610 | |||
611 | @Override
|
||
612 | public void setScriptsResourcesStorage(ResourcesStorage scriptsResourcesStorage) { |
||
613 | 46828 | fdiaz | if(this.scriptsResourcesStorage != null){ |
614 | DisposeUtils.disposeQuietly(this.scriptsResourcesStorage);
|
||
615 | } |
||
616 | DisposeUtils.bind(scriptsResourcesStorage); |
||
617 | 44533 | jjdelcerro | this.scriptsResourcesStorage = scriptsResourcesStorage;
|
618 | } |
||
619 | 44644 | jjdelcerro | |
620 | 44533 | jjdelcerro | |
621 | 44644 | jjdelcerro | private final List<ReprMethod> reprMethods = new ArrayList<>(); |
622 | private final Map<Class,ReprMethod> reprMethodsCache = new HashMap<>(); |
||
623 | private final ReprMethod reprNull = new ReprNull(); |
||
624 | private final ReprMethod reprObject = new ReprObject(); |
||
625 | |||
626 | @Override
|
||
627 | public void addReprMethod(ReprMethod method) { |
||
628 | this.reprMethods.add(method);
|
||
629 | this.reprMethodsCache.clear();
|
||
630 | } |
||
631 | |||
632 | @Override
|
||
633 | public ReprMethod getReprMethod(Object value) { |
||
634 | if( value == null ) { |
||
635 | return this.reprNull; |
||
636 | } |
||
637 | ReprMethod method = this.reprMethodsCache.get(value.getClass());
|
||
638 | if( method!=null ) { |
||
639 | return method;
|
||
640 | } |
||
641 | for (ReprMethod theMethod : reprMethods) {
|
||
642 | if( theMethod.isApplicable(value) ) {
|
||
643 | this.reprMethodsCache.put(value.getClass(), theMethod);
|
||
644 | return theMethod;
|
||
645 | } |
||
646 | } |
||
647 | return this.reprObject; |
||
648 | } |
||
649 | 44750 | jjdelcerro | |
650 | @Override
|
||
651 | public void registerClassLoader(ClassLoader loader) { |
||
652 | this.loaders.add(loader);
|
||
653 | } |
||
654 | |||
655 | @Override
|
||
656 | public List<ClassLoader> getClassLoaders() { |
||
657 | return Collections.unmodifiableList(loaders); |
||
658 | } |
||
659 | 44769 | jjdelcerro | |
660 | @Override
|
||
661 | public Formatter<ExpressionBuilder.Value> getExpressionBuilderFormatter() { |
||
662 | return expressionBuilderFormatter;
|
||
663 | } |
||
664 | |||
665 | @Override
|
||
666 | public void registerExpressionBuilderFormatter(Formatter<ExpressionBuilder.Value> formatter) { |
||
667 | this.expressionBuilderFormatter = formatter;
|
||
668 | } |
||
669 | 45366 | omartinez | |
670 | @Override
|
||
671 | public ExpressionEvaluator createExpressionEvaluator(Expression expression) { |
||
672 | return new BaseExpressionEvaluator(expression); |
||
673 | } |
||
674 | 44769 | jjdelcerro | |
675 | 45899 | jjdelcerro | @Override
|
676 | public ExpressionEvaluator createEvaluator(String expression) { |
||
677 | Expression exp = this.createExpression(); |
||
678 | exp.setPhrase(expression); |
||
679 | return new BaseExpressionEvaluator(exp); |
||
680 | } |
||
681 | 46695 | jjdelcerro | |
682 | 46711 | jjdelcerro | @Override
|
683 | public boolean hasHostExpressions(Code statement) { |
||
684 | try {
|
||
685 | List<Code> hostExpressions = new ArrayList<>(); |
||
686 | statement.accept( |
||
687 | (Object code) -> {
|
||
688 | if( !(code instanceof Code.Callable) ) { |
||
689 | return;
|
||
690 | } |
||
691 | Code.Callable callable = (Code.Callable) code; |
||
692 | if( StringUtils.equalsIgnoreCase(callable.name(), ExpressionBuilder.FUNCTION_$HOSTEXPRESSION) ) { |
||
693 | hostExpressions.add(callable); |
||
694 | } |
||
695 | }, null
|
||
696 | ); |
||
697 | return !hostExpressions.isEmpty();
|
||
698 | } catch (BaseException ex) {
|
||
699 | throw new RuntimeException("Can't check host expressions", ex); |
||
700 | } |
||
701 | } |
||
702 | |||
703 | @Override
|
||
704 | public boolean hasHostExpressions(ExpressionBuilder.Value statement) { |
||
705 | 47063 | jjdelcerro | return HostExpressionUtils.hasHostExpressions(statement);
|
706 | 46711 | jjdelcerro | } |
707 | |||
708 | @Override
|
||
709 | public Code resolveHostExpressions(Code statement, Interpreter interpreter) {
|
||
710 | 47063 | jjdelcerro | return HostExpressionUtils.resolveHostExpressions(statement, interpreter);
|
711 | 46695 | jjdelcerro | } |
712 | |||
713 | 46711 | jjdelcerro | @Override
|
714 | public ExpressionBuilder.Value resolveHostExpressions(ExpressionBuilder.Value statement, SymbolTable symbolTable) {
|
||
715 | 47063 | jjdelcerro | return HostExpressionUtils.resolveHostExpressions(statement, symbolTable);
|
716 | 46695 | jjdelcerro | } |
717 | |||
718 | 46711 | jjdelcerro | @Override
|
719 | public Code resolveHostExpressions(Code statement, SymbolTable symbolTable) {
|
||
720 | 47063 | jjdelcerro | return HostExpressionUtils.resolveHostExpressions(statement, symbolTable);
|
721 | 46711 | jjdelcerro | } |
722 | |||
723 | @Override
|
||
724 | public Expression resolveHostExpressions(Expression expression, SymbolTable symbolTable) { |
||
725 | 47063 | jjdelcerro | return HostExpressionUtils.resolveHostExpressions(expression, symbolTable);
|
726 | 46695 | jjdelcerro | } |
727 | |||
728 | 47063 | jjdelcerro | @Override
|
729 | public boolean hasHostExpressions(String statement) { |
||
730 | return HostExpressionUtils.hasHostExpressions(statement);
|
||
731 | } |
||
732 | |||
733 | @Override
|
||
734 | public ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder) {
|
||
735 | return HostExpressionUtils.getHostExpressionValue(hostExpression, expbuilder);
|
||
736 | } |
||
737 | |||
738 | @Override
|
||
739 | public ExpressionBuilder.Value getHostExpressionValue(ExpressionBuilder.Function hostExpression, ExpressionBuilder expbuilder, SymbolTable symbolTable) {
|
||
740 | return HostExpressionUtils.getHostExpressionValue(hostExpression, expbuilder, symbolTable);
|
||
741 | } |
||
742 | 47175 | jjdelcerro | |
743 | public void initConvertersToCode() { |
||
744 | this.convertersToCode0 = new LinkedHashMap<>(); |
||
745 | ConverterToCode[] converters = new ConverterToCode[] { |
||
746 | new NullToCode(),
|
||
747 | new CharsequenceToCode(),
|
||
748 | new NumberToCode(),
|
||
749 | new BooleanToCode(),
|
||
750 | new IteratorToCode(),
|
||
751 | new IterableToCode(),
|
||
752 | new ListToCode(),
|
||
753 | new ArrayToCode(),
|
||
754 | new ObjectToCode()
|
||
755 | }; |
||
756 | for (ConverterToCode converter : converters) {
|
||
757 | this.convertersToCode0.put(converter.getName(),converter);
|
||
758 | } |
||
759 | this.convertersToCode = new LinkedHashMap<>(); |
||
760 | } |
||
761 | 47063 | jjdelcerro | |
762 | 47175 | jjdelcerro | @Override
|
763 | public void registerCodeConverter(ConverterToCode converter) { |
||
764 | if( this.convertersToCode == null ) { |
||
765 | this.initConvertersToCode();
|
||
766 | } |
||
767 | this.convertersToCode.put(converter.getName(), converter);
|
||
768 | } |
||
769 | |||
770 | @Override
|
||
771 | public ConverterToCode getConverterToCode(Object ob) { |
||
772 | if( this.convertersToCode == null ) { |
||
773 | this.initConvertersToCode();
|
||
774 | } |
||
775 | for (ConverterToCode converter : this.convertersToCode.values()) { |
||
776 | if( converter.isApplicable(ob) ) {
|
||
777 | return converter;
|
||
778 | } |
||
779 | } |
||
780 | for (ConverterToCode converter : this.convertersToCode0.values()) { |
||
781 | if( converter.isApplicable(ob) ) {
|
||
782 | return converter;
|
||
783 | } |
||
784 | } |
||
785 | return null; |
||
786 | } |
||
787 | |||
788 | @Override
|
||
789 | 47184 | jjdelcerro | public ExpressionBuilder.Value convertToValue(Object obj) { |
790 | Code code = this.convertToCode(obj);
|
||
791 | ExpressionBuilder.Value value = code.toValue(); |
||
792 | return value;
|
||
793 | } |
||
794 | |||
795 | @Override
|
||
796 | public Code convertToCode(Object obj) { |
||
797 | return convertToCode(null, obj, null); |
||
798 | } |
||
799 | |||
800 | @Override
|
||
801 | public Code convertToCode(CodeBuilder builder, Object obj, Map<String,Object> props) { |
||
802 | 47175 | jjdelcerro | if( this.convertersToCode == null ) { |
803 | this.initConvertersToCode();
|
||
804 | } |
||
805 | 47184 | jjdelcerro | if( builder == null ) { |
806 | builder = this.createCodeBuilder();
|
||
807 | } |
||
808 | 47175 | jjdelcerro | for (ConverterToCode converter : this.convertersToCode.values()) { |
809 | 47184 | jjdelcerro | if( converter.isApplicable(obj) ) {
|
810 | return converter.toCode(builder, obj, props);
|
||
811 | 47175 | jjdelcerro | } |
812 | } |
||
813 | for (ConverterToCode converter : this.convertersToCode0.values()) { |
||
814 | 47184 | jjdelcerro | if( converter.isApplicable(obj) ) {
|
815 | return converter.toCode(builder, obj, props);
|
||
816 | 47175 | jjdelcerro | } |
817 | } |
||
818 | return null; |
||
819 | } |
||
820 | |||
821 | public ConverterToCode getConverterToCodeByName(String name) { |
||
822 | ConverterToCode converter = this.convertersToCode.get(name);
|
||
823 | if( converter!=null ) { |
||
824 | return converter;
|
||
825 | } |
||
826 | converter = this.convertersToCode0.get(name);
|
||
827 | return converter;
|
||
828 | } |
||
829 | |||
830 | 43521 | jjdelcerro | } |