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 / DefaultExpression.java @ 44622
History | View | Annotate | Download (14 KB)
1 |
package org.gvsig.expressionevaluator.impl; |
---|---|
2 |
|
3 |
import java.lang.ref.Reference; |
4 |
import java.lang.ref.WeakReference; |
5 |
import java.util.Objects; |
6 |
import org.apache.commons.lang3.StringUtils; |
7 |
import org.gvsig.expressionevaluator.Code; |
8 |
import org.gvsig.expressionevaluator.Compiler; |
9 |
import org.gvsig.expressionevaluator.Expression; |
10 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
11 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
12 |
import org.gvsig.expressionevaluator.ExpressionUtils; |
13 |
import org.gvsig.expressionevaluator.Interpreter; |
14 |
import org.gvsig.expressionevaluator.Optimizer; |
15 |
import org.gvsig.expressionevaluator.SymbolTable; |
16 |
import org.gvsig.tools.ToolsLocator; |
17 |
import org.gvsig.tools.dynobject.DynStruct; |
18 |
import org.gvsig.tools.persistence.PersistenceManager; |
19 |
import org.gvsig.tools.persistence.PersistentState; |
20 |
import org.gvsig.tools.persistence.exception.PersistenceException; |
21 |
import org.gvsig.tools.script.ScriptManager; |
22 |
import org.gvsig.tools.util.LabeledValue; |
23 |
import org.json.JSONObject; |
24 |
|
25 |
/**
|
26 |
*
|
27 |
* @author jjdelcerro
|
28 |
*/
|
29 |
public class DefaultExpression implements Expression, LabeledValue<Expression> { |
30 |
|
31 |
private String phrase = null; |
32 |
// private Script userScript = null;
|
33 |
// private List<Script> scripts = null;
|
34 |
// private UnmodifiableBasicList<Script> unmodifiableScripts = null;
|
35 |
|
36 |
private Code code = null; |
37 |
private Interpreter interpreter;
|
38 |
private boolean hasNotBeenOptimized = true; |
39 |
private SymbolTable mySymbolTable = null; |
40 |
private WeakReference<SymbolTable> lastSymbolTable = null; |
41 |
private boolean useBracketsForIdentifiers = false; |
42 |
|
43 |
public DefaultExpression() {
|
44 |
|
45 |
} |
46 |
|
47 |
@Override
|
48 |
public String getLabel() { |
49 |
return StringUtils.abbreviate(
|
50 |
StringUtils.normalizeSpace(this.getPhrase()),
|
51 |
35
|
52 |
); |
53 |
} |
54 |
|
55 |
@Override
|
56 |
public Expression getValue() { |
57 |
return this; |
58 |
} |
59 |
|
60 |
@Override
|
61 |
public boolean equals(Object obj) { |
62 |
if( obj == null || !(obj instanceof Expression) ) { |
63 |
return false; |
64 |
} |
65 |
String this_s = this.toJSON(); |
66 |
String other_s = ((Expression)obj).toJSON(); |
67 |
return this_s.equals(other_s);
|
68 |
} |
69 |
|
70 |
@Override
|
71 |
public int hashCode() { |
72 |
String this_s = this.toJSON(); |
73 |
return Objects.hashCode(this_s);
|
74 |
} |
75 |
|
76 |
@Override
|
77 |
public SymbolTable getSymbolTable() {
|
78 |
if( this.mySymbolTable==null ) { |
79 |
this.mySymbolTable = ExpressionUtils.createSymbolTable();
|
80 |
} |
81 |
return this.mySymbolTable; |
82 |
} |
83 |
|
84 |
@Override
|
85 |
public String getPhrase() { |
86 |
return this.phrase; |
87 |
} |
88 |
|
89 |
@Override
|
90 |
public boolean isPhraseEmpty() { |
91 |
return StringUtils.isBlank(this.phrase); |
92 |
} |
93 |
|
94 |
@Override
|
95 |
public boolean isEmpty() { |
96 |
if( !StringUtils.isBlank(this.phrase) ) { |
97 |
return false; |
98 |
} |
99 |
// if( this.scripts!=null && !this.scripts.isEmpty() ) {
|
100 |
// return false;
|
101 |
// }
|
102 |
// if( this.userScript!=null && !StringUtils.isBlank(this.userScript.getCode()) ) {
|
103 |
// return false;
|
104 |
// }
|
105 |
return true; |
106 |
} |
107 |
|
108 |
// @Override
|
109 |
// public Script getUserScript() {
|
110 |
// return this.userScript;
|
111 |
// }
|
112 |
//
|
113 |
// @Override
|
114 |
// public UnmodifiableBasicList<Script> getScripts() {
|
115 |
// if (this.unmodifiableScripts == null) {
|
116 |
// if (this.scripts == null) {
|
117 |
// return null;
|
118 |
// }
|
119 |
// this.unmodifiableScripts = new UnmodifiableBasicListAdapter<>(this.scripts);
|
120 |
// }
|
121 |
// return this.unmodifiableScripts;
|
122 |
// }
|
123 |
//
|
124 |
@Override
|
125 |
public Expression setPhrase(String phrase) { |
126 |
this.phrase = phrase;
|
127 |
this.code = null; |
128 |
this.hasNotBeenOptimized = true; |
129 |
return this; |
130 |
} |
131 |
|
132 |
// @Override
|
133 |
// public Expression setUserScript(String code, String languaje) {
|
134 |
// if (this.userScript == null) {
|
135 |
// ScriptManager scriptMananger = ToolsLocator.getScriptManager();
|
136 |
// this.userScript = scriptMananger.createScript("user", code, languaje);
|
137 |
// } else if (this.userScript.getTypeName().equalsIgnoreCase(languaje)) {
|
138 |
// this.userScript.setCode(code);
|
139 |
// } else {
|
140 |
// ScriptManager scriptMananger = ToolsLocator.getScriptManager();
|
141 |
// this.userScript = scriptMananger.createScript("user", code, languaje);
|
142 |
// }
|
143 |
// return this;
|
144 |
// }
|
145 |
//
|
146 |
// @Override
|
147 |
// public Expression setUserScript(Script script) {
|
148 |
// this.userScript = script;
|
149 |
// return this;
|
150 |
// }
|
151 |
//
|
152 |
// @Override
|
153 |
// public Expression setUserScript(String code) {
|
154 |
// this.setUserScript(code, "python");
|
155 |
// return this;
|
156 |
// }
|
157 |
//
|
158 |
// @Override
|
159 |
// public void removeAllScripts() {
|
160 |
// this.scripts = null;
|
161 |
// this.unmodifiableScripts = null;
|
162 |
// }
|
163 |
//
|
164 |
// @Override
|
165 |
// public Expression addScript(Script script) {
|
166 |
// if (this.scripts == null) {
|
167 |
// this.scripts = new ArrayList<>();
|
168 |
// }
|
169 |
// this.scripts.add(script);
|
170 |
// return this;
|
171 |
// }
|
172 |
|
173 |
@Override
|
174 |
public void clear() { |
175 |
this.phrase = null; |
176 |
// this.userScript = null;
|
177 |
// this.unmodifiableScripts = null;
|
178 |
// this.scripts = null;
|
179 |
this.code = null; |
180 |
this.interpreter = null; |
181 |
this.hasNotBeenOptimized = true; |
182 |
} |
183 |
|
184 |
@Override
|
185 |
public Code getCode() {
|
186 |
if (this.code == null) { |
187 |
ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager(); |
188 |
Compiler compiler = manager.createCompiler();
|
189 |
compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers( |
190 |
this.useBracketsForIdentifiers
|
191 |
); |
192 |
this.code = compiler.compileExpression(this.phrase); |
193 |
} |
194 |
return code;
|
195 |
} |
196 |
|
197 |
@Override
|
198 |
public void setSQLCompatible(boolean sqlCompatible) { |
199 |
this.getInterpreter().setSQLCompatible(sqlCompatible);
|
200 |
} |
201 |
|
202 |
@Override
|
203 |
public boolean isSQLCompatible() { |
204 |
return this.getInterpreter().isSQLCompatible(); |
205 |
} |
206 |
|
207 |
private Interpreter getInterpreter() {
|
208 |
if (this.interpreter == null) { |
209 |
ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager(); |
210 |
this.interpreter = manager.createInterpreter();
|
211 |
} |
212 |
return this.interpreter; |
213 |
} |
214 |
|
215 |
@Override
|
216 |
public Object execute(SymbolTable symbolTable) { |
217 |
if (this.interpreter == null) { |
218 |
ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager(); |
219 |
this.interpreter = manager.createInterpreter();
|
220 |
} |
221 |
boolean added = this.getSymbolTable().addSymbolTable(symbolTable); |
222 |
if( this.lastSymbolTable==null ) { |
223 |
this.lastSymbolTable = new WeakReference<>(symbolTable); |
224 |
} else if( this.lastSymbolTable.get()!=symbolTable ) { |
225 |
this.link(this.getSymbolTable()); |
226 |
this.lastSymbolTable = new WeakReference<>(symbolTable); |
227 |
this.hasNotBeenOptimized = true; |
228 |
} |
229 |
try {
|
230 |
this.interpreter.setSymbolTable(this.mySymbolTable); |
231 |
if( this.hasNotBeenOptimized ) { |
232 |
try {
|
233 |
Optimizer optimizer = new DefaultOptimizer(this.getSymbolTable()); |
234 |
this.code = optimizer.optimize(this.getCode()); |
235 |
} catch(Throwable th) { |
236 |
// Si no es capaz de optimizar la expresion no, peta y la
|
237 |
// ejecuta tal cual.
|
238 |
} |
239 |
this.hasNotBeenOptimized = false; |
240 |
} |
241 |
Object x = this.interpreter.run(this.getCode()); |
242 |
|
243 |
return x;
|
244 |
} finally {
|
245 |
if( added ) {
|
246 |
this.getSymbolTable().removeSymbolTable(symbolTable);
|
247 |
} |
248 |
} |
249 |
} |
250 |
|
251 |
@Override
|
252 |
public void link(SymbolTable symbolTable) { |
253 |
if (this.interpreter == null) { |
254 |
ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager(); |
255 |
this.interpreter = manager.createInterpreter();
|
256 |
} |
257 |
this.interpreter.setSymbolTable(symbolTable);
|
258 |
if( this.hasNotBeenOptimized ) { |
259 |
Optimizer optimizer = new DefaultOptimizer(symbolTable);
|
260 |
this.code = optimizer.optimize(this.getCode()); |
261 |
this.hasNotBeenOptimized = false; |
262 |
} |
263 |
this.interpreter.link(this.getCode()); |
264 |
} |
265 |
|
266 |
@Override
|
267 |
public void saveToState(PersistentState state) throws PersistenceException { |
268 |
state.set("phrase", this.phrase); |
269 |
// if (this.userScript == null) {
|
270 |
// state.setNull("userScript_code");
|
271 |
// state.setNull("userScript_language");
|
272 |
// } else {
|
273 |
// state.set("userScript_code", this.userScript.getCode());
|
274 |
// state.set("userScript_language", this.userScript.getTypeName());
|
275 |
// }
|
276 |
// if (this.scripts != null && !this.scripts.isEmpty()) {
|
277 |
// List<URL> l = new ArrayList<>();
|
278 |
// for (Script script : this.scripts) {
|
279 |
// URL location = script.getURL();
|
280 |
// if (location != null) {
|
281 |
// l.add(location);
|
282 |
// }
|
283 |
// }
|
284 |
// if (l.isEmpty()) {
|
285 |
// state.setNull("scripts");
|
286 |
// } else {
|
287 |
// state.set("scripts", l);
|
288 |
// }
|
289 |
// } else {
|
290 |
// state.setNull("scripts");
|
291 |
// }
|
292 |
} |
293 |
|
294 |
@Override
|
295 |
public void loadFromState(PersistentState state) throws PersistenceException { |
296 |
ScriptManager scriptManager = ToolsLocator.getScriptManager(); |
297 |
|
298 |
this.clear();
|
299 |
|
300 |
this.phrase = state.getString("phrase"); |
301 |
// String userScript_code = state.getString("userScript_code");
|
302 |
// String userScript_language = state.getString("userScript_language");
|
303 |
// if (StringUtils.isEmpty(userScript_code)) {
|
304 |
// this.userScript = null;
|
305 |
// } else {
|
306 |
// if (StringUtils.isEmpty(userScript_language)) {
|
307 |
// userScript_language = "python";
|
308 |
// }
|
309 |
// this.userScript = scriptManager.createScript("user", userScript_code, userScript_language);
|
310 |
// }
|
311 |
// Iterator scriptsLocations = state.getIterator("scripts");
|
312 |
// if (scriptsLocations != null) {
|
313 |
// while (scriptsLocations.hasNext()) {
|
314 |
// URI location = (URI) scriptsLocations.next();
|
315 |
// Script script = scriptManager.loadScript(location);
|
316 |
// if (script != null) {
|
317 |
// if (this.scripts == null) {
|
318 |
// this.scripts = new ArrayList<>();
|
319 |
// }
|
320 |
// this.scripts.add(script);
|
321 |
// }
|
322 |
// }
|
323 |
// }
|
324 |
} |
325 |
|
326 |
public static void registerPersistence() { |
327 |
PersistenceManager manager = ToolsLocator.getPersistenceManager(); |
328 |
if (manager.getDefinition("Expression") == null) { |
329 |
DynStruct definition = manager.addDefinition(DefaultExpression.class, |
330 |
"Expression", "Expression persistence definition", null, null); |
331 |
definition.addDynFieldString("phrase").setMandatory(false); |
332 |
// definition.addDynFieldString("userScript_code").setMandatory(false);
|
333 |
// definition.addDynFieldString("userScript_language").setMandatory(false);
|
334 |
// definition.addDynFieldList("scripts")
|
335 |
// .setClassOfItems(URL.class)
|
336 |
// .setMandatory(false);
|
337 |
} |
338 |
} |
339 |
|
340 |
@Override
|
341 |
public String toJSON() { |
342 |
JSONObject expressionJson = new JSONObject();
|
343 |
expressionJson.put("phrase", this.phrase); |
344 |
|
345 |
// if (this.userScript != null) {
|
346 |
// JSONObject userScriptJson = new JSONObject();
|
347 |
// userScriptJson.put("code", this.userScript.getCode());
|
348 |
// userScriptJson.put("language", this.userScript.getTypeName());
|
349 |
// expressionJson.put("userScript", userScriptJson);
|
350 |
// }
|
351 |
//
|
352 |
// if (this.scripts != null && !this.scripts.isEmpty()) {
|
353 |
// JSONArray scriptsJson = new JSONArray();
|
354 |
// for (Script script : this.scripts) {
|
355 |
// scriptsJson.put(script.getURL());
|
356 |
// }
|
357 |
// expressionJson.put("scripts", scriptsJson);
|
358 |
// }
|
359 |
return expressionJson.toString();
|
360 |
} |
361 |
|
362 |
@Override
|
363 |
public void fromJSON(String json) { |
364 |
this.clear();
|
365 |
ScriptManager scriptMananger = ToolsLocator.getScriptManager(); |
366 |
|
367 |
JSONObject expressionJson = new JSONObject(json);
|
368 |
if (expressionJson.has("phrase")) { |
369 |
this.phrase = expressionJson.getString("phrase"); |
370 |
} |
371 |
// if (expressionJson.has("userScript")) {
|
372 |
// String theCode = "";
|
373 |
// String theLanguage = "python";
|
374 |
// JSONObject userScriptJson = expressionJson.getJSONObject("userScript");
|
375 |
// if (userScriptJson.has("code")) {
|
376 |
// theCode = userScriptJson.getString("code");
|
377 |
// }
|
378 |
// if (userScriptJson.has("language")) {
|
379 |
// theCode = userScriptJson.getString("language");
|
380 |
// }
|
381 |
// this.userScript = scriptMananger.createScript("user", theCode, theLanguage);
|
382 |
// }
|
383 |
// if (expressionJson.has("scripts")) {
|
384 |
// this.scripts = new ArrayList<>();
|
385 |
// JSONArray scriptsJson = expressionJson.getJSONArray("scripts");
|
386 |
// for (Object object : scriptsJson) {
|
387 |
// URI location = (URI) object;
|
388 |
// Script script = scriptMananger.loadScript(location);
|
389 |
// this.scripts.add(script);
|
390 |
// }
|
391 |
// }
|
392 |
} |
393 |
|
394 |
@Override
|
395 |
public String toString() { |
396 |
return this.toJSON(); |
397 |
} |
398 |
|
399 |
@Override
|
400 |
public Expression clone() throws CloneNotSupportedException { |
401 |
Expression other = (Expression) super.clone(); |
402 |
other.fromJSON(this.toJSON());
|
403 |
return other;
|
404 |
} |
405 |
|
406 |
@Override
|
407 |
public void setUseBracketsForIdentifiers(boolean useBracketsForIdentifiers) { |
408 |
this.useBracketsForIdentifiers = useBracketsForIdentifiers;
|
409 |
} |
410 |
|
411 |
@Override
|
412 |
public boolean getUseBracketsForIdentifiers() { |
413 |
return this.useBracketsForIdentifiers; |
414 |
} |
415 |
|
416 |
} |