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 / 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
}