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

History | View | Annotate | Download (12 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.lang.ref.WeakReference;
4
import java.util.Objects;
5
import org.apache.commons.lang3.StringUtils;
6
import org.gvsig.expressionevaluator.Code;
7
import org.gvsig.expressionevaluator.Compiler;
8
import org.gvsig.expressionevaluator.Expression;
9
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
10
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
11
import org.gvsig.expressionevaluator.ExpressionUtils;
12
import org.gvsig.expressionevaluator.Interpreter;
13
import org.gvsig.expressionevaluator.Optimizer;
14
import org.gvsig.expressionevaluator.SymbolTable;
15
import org.gvsig.tools.ToolsLocator;
16
import org.gvsig.tools.dynobject.DynStruct;
17
import org.gvsig.tools.evaluator.Evaluator;
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

    
33
    private Code code = null;
34
    private Interpreter interpreter;
35
    private boolean hasNotBeenOptimized = true;
36
    private SymbolTable mySymbolTable = null;
37
    private WeakReference<SymbolTable> lastSymbolTable = null;    
38
    private boolean useBracketsForIdentifiers = false;
39
    protected ExpressionEvaluatorManager manager;
40

    
41
    public DefaultExpression() {
42
        this(ExpressionEvaluatorLocator.getExpressionEvaluatorManager());
43
    }
44

    
45
    public DefaultExpression(ExpressionEvaluatorManager manager) {
46
        this.manager = manager;
47
    }
48
    
49
    @Override
50
    public String getLabel() {
51
        return StringUtils.abbreviate(
52
                StringUtils.normalizeSpace(this.getPhrase()),
53
                35
54
        );
55
    }
56

    
57
    @Override
58
    public Expression getValue() {
59
        return this;
60
    }
61

    
62
    @Override
63
    public boolean equals(Object obj) {
64
        if( obj == null || !(obj instanceof Expression) ) {
65
            return false;
66
        }
67
        String this_s = this.toJSON();
68
        String other_s = ((Expression)obj).toJSON();
69
        return this_s.equals(other_s);
70
    }
71

    
72
    @Override
73
    public int hashCode() {
74
        String this_s = this.toJSON();
75
        return Objects.hashCode(this_s);
76
    }
77
    
78
    @Override
79
    public SymbolTable getSymbolTable() {
80
        if( this.mySymbolTable==null ) {
81
            this.mySymbolTable = ExpressionUtils.createSymbolTable();
82
        }
83
        return this.mySymbolTable;
84
    }
85

    
86
    @Override
87
    public String getPhrase() {
88
        return this.phrase;
89
    }
90

    
91
    @Override
92
    public boolean isPhraseEmpty() {
93
        return StringUtils.isBlank(this.phrase);
94
    }
95

    
96
    @Override
97
    public boolean isEmpty() {
98
        if( !StringUtils.isBlank(this.phrase) ) {
99
            return false;
100
        }
101
        return true;
102
    }
103

    
104
    @Override
105
    public Expression setPhrase(String phrase) {
106
        this.phrase = phrase;
107
        this.code = null;
108
        this.hasNotBeenOptimized = true;
109
        return this;
110
    }
111

    
112
    @Override
113
    public void clear() {
114
        this.phrase = null;
115
        this.code = null;
116
        this.interpreter = null;
117
        this.hasNotBeenOptimized = true;
118
    }
119

    
120
    @Override
121
    public Code getCode() {
122
        if (this.code == null) {
123
            Compiler compiler = this.manager.createCompiler();
124
            compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(
125
                    this.useBracketsForIdentifiers
126
            );
127
            this.code = compiler.compileExpression(this.phrase);
128
        }
129
        return code;
130
    }
131

    
132
    @Override
133
    public void setSQLCompatible(boolean sqlCompatible) {
134
        this.getInterpreter().setSQLCompatible(sqlCompatible);
135
    }
136

    
137
    @Override
138
    public boolean isSQLCompatible() {
139
        return this.getInterpreter().isSQLCompatible();
140
    }
141

    
142
    private Interpreter getInterpreter() {
143
        if (this.interpreter == null) {
144
            this.interpreter = this.manager.createInterpreter();
145
        }
146
        return this.interpreter;
147
    }
148
    
149
    @Override
150
    public Object execute(SymbolTable symbolTable) {
151
        if (this.interpreter == null) {
152
            this.interpreter = this.manager.createInterpreter();
153
        }
154
        boolean added = false;
155
        if( symbolTable!=null ) {
156
            added = this.getSymbolTable().addSymbolTable(symbolTable);
157
            if( this.lastSymbolTable==null ) {
158
                this.lastSymbolTable = new WeakReference<>(symbolTable);            
159
            } else if( this.lastSymbolTable.get()!=symbolTable ) {
160
                this.link(this.getSymbolTable());
161
                this.hasNotBeenOptimized = true;            
162
            }
163
        }
164
        try {
165
            this.interpreter.setSymbolTable(this.getSymbolTable());
166
            if( this.hasNotBeenOptimized  ) {
167
                try {
168
                    Optimizer optimizer = this.manager.createOptimizer();
169
                    optimizer.setSymbolTable(this.getSymbolTable());
170
                    this.code = optimizer.optimize(this.getCode());
171
                } catch(Throwable th) {
172
                    // Si no es capaz de optimizar la expresion no, peta y la
173
                    // ejecuta tal cual.
174
                }
175
                this.hasNotBeenOptimized = false;
176
            }
177
            Object x = this.interpreter.run(this.getCode());
178

    
179
            return x;
180
        } finally {
181
            if( added ) {
182
                this.getSymbolTable().removeSymbolTable(symbolTable);
183
            }
184
        }
185
    }
186

    
187
    @Override
188
    public void link(SymbolTable symbolTable) {
189
        if (this.interpreter == null) {
190
            this.interpreter = this.manager.createInterpreter();
191
        }
192
        this.lastSymbolTable = new WeakReference<>(symbolTable);            
193
        this.interpreter.setSymbolTable(symbolTable);
194
        if( this.hasNotBeenOptimized  ) {
195
            Optimizer optimizer = new DefaultOptimizer(this.manager, symbolTable);
196
            this.code = optimizer.optimize(this.getCode());
197
            this.hasNotBeenOptimized = false;
198
        }
199
        this.interpreter.link(this.getCode());
200
    }
201

    
202
    @Override
203
    public void saveToState(PersistentState state) throws PersistenceException {
204
        state.set("phrase", this.phrase);
205
//        if (this.userScript == null) {
206
//            state.setNull("userScript_code");
207
//            state.setNull("userScript_language");
208
//        } else {
209
//            state.set("userScript_code", this.userScript.getCode());
210
//            state.set("userScript_language", this.userScript.getTypeName());
211
//        }
212
//        if (this.scripts != null && !this.scripts.isEmpty()) {
213
//            List<URL> l = new ArrayList<>();
214
//            for (Script script : this.scripts) {
215
//                URL location = script.getURL();
216
//                if (location != null) {
217
//                    l.add(location);
218
//                }
219
//            }
220
//            if (l.isEmpty()) {
221
//                state.setNull("scripts");
222
//            } else {
223
//                state.set("scripts", l);
224
//            }
225
//        } else {
226
//            state.setNull("scripts");
227
//        }
228
    }
229

    
230
    @Override
231
    public void loadFromState(PersistentState state) throws PersistenceException {
232
        ScriptManager scriptManager = ToolsLocator.getScriptManager();
233

    
234
        this.clear();
235
        
236
        this.phrase = state.getString("phrase");
237
//        String userScript_code = state.getString("userScript_code");
238
//        String userScript_language = state.getString("userScript_language");
239
//        if (StringUtils.isEmpty(userScript_code)) {
240
//            this.userScript = null;
241
//        } else {
242
//            if (StringUtils.isEmpty(userScript_language)) {
243
//                userScript_language = "python";
244
//            }
245
//            this.userScript = scriptManager.createScript("user", userScript_code, userScript_language);
246
//        }
247
//        Iterator scriptsLocations = state.getIterator("scripts");
248
//        if (scriptsLocations != null) {
249
//            while (scriptsLocations.hasNext()) {
250
//                URI location = (URI) scriptsLocations.next();
251
//                Script script = scriptManager.loadScript(location);
252
//                if (script != null) {
253
//                    if (this.scripts == null) {
254
//                        this.scripts = new ArrayList<>();
255
//                    }
256
//                    this.scripts.add(script);
257
//                }
258
//            }
259
//        }
260
    }
261

    
262
    public static void registerPersistence() {
263
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
264
        if (manager.getDefinition("Expression") == null) {
265
            DynStruct definition = manager.addDefinition(DefaultExpression.class,
266
                    "Expression", "Expression persistence definition", null, null);
267
            definition.addDynFieldString("phrase").setMandatory(false);
268
//            definition.addDynFieldString("userScript_code").setMandatory(false);
269
//            definition.addDynFieldString("userScript_language").setMandatory(false);
270
//            definition.addDynFieldList("scripts")
271
//                    .setClassOfItems(URL.class)
272
//                    .setMandatory(false);
273
        }
274
    }
275

    
276
    @Override
277
    public String toJSON() {
278
        JSONObject expressionJson = new JSONObject();
279
        expressionJson.put("phrase", this.phrase);
280

    
281
//        if (this.userScript != null) {
282
//            JSONObject userScriptJson = new JSONObject();
283
//            userScriptJson.put("code", this.userScript.getCode());
284
//            userScriptJson.put("language", this.userScript.getTypeName());
285
//            expressionJson.put("userScript", userScriptJson);
286
//        }
287
//
288
//        if (this.scripts != null && !this.scripts.isEmpty()) {
289
//            JSONArray scriptsJson = new JSONArray();
290
//            for (Script script : this.scripts) {
291
//                scriptsJson.put(script.getURL());
292
//            }
293
//            expressionJson.put("scripts", scriptsJson);
294
//        }
295
        return expressionJson.toString();
296
    }
297

    
298
    @Override
299
    public void fromJSON(String json) {
300
        this.clear();
301
        ScriptManager scriptMananger = ToolsLocator.getScriptManager();
302

    
303
        JSONObject expressionJson = new JSONObject(json);
304
        if (expressionJson.has("phrase")) {
305
            this.phrase = expressionJson.getString("phrase");
306
        }
307
//        if (expressionJson.has("userScript")) {
308
//            String theCode = "";
309
//            String theLanguage = "python";
310
//            JSONObject userScriptJson = expressionJson.getJSONObject("userScript");
311
//            if (userScriptJson.has("code")) {
312
//                theCode = userScriptJson.getString("code");
313
//            }
314
//            if (userScriptJson.has("language")) {
315
//                theCode = userScriptJson.getString("language");
316
//            }
317
//            this.userScript = scriptMananger.createScript("user", theCode, theLanguage);
318
//        }
319
//        if (expressionJson.has("scripts")) {
320
//            this.scripts = new ArrayList<>();
321
//            JSONArray scriptsJson = expressionJson.getJSONArray("scripts");
322
//            for (Object object : scriptsJson) {
323
//                URI location = (URI) object;
324
//                Script script = scriptMananger.loadScript(location);
325
//                this.scripts.add(script);
326
//            }
327
//        }
328
    }
329

    
330
    @Override
331
    public String toString() {
332
        return this.toJSON();
333
    }
334

    
335
    @Override
336
    public Expression clone() throws CloneNotSupportedException {
337
        Expression other = (Expression) super.clone();
338
        other.fromJSON(this.toJSON());
339
        return other;
340
    }
341

    
342
    @Override
343
    public void setUseBracketsForIdentifiers(boolean useBracketsForIdentifiers) {
344
        this.useBracketsForIdentifiers = useBracketsForIdentifiers;
345
    }
346
    
347
    @Override
348
    public boolean getUseBracketsForIdentifiers() {
349
        return this.useBracketsForIdentifiers;
350
    }
351

    
352
    @Override
353
    public Evaluator toEvaluator() {
354
        DefaultExpressionEvaluator evaluator = new DefaultExpressionEvaluator(this);
355
        return evaluator;
356
    }
357
    
358
}