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

History | View | Annotate | Download (12.1 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.ExpressionEvaluator;
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.evaluator.Evaluator;
19
import org.gvsig.tools.persistence.PersistenceManager;
20
import org.gvsig.tools.persistence.PersistentState;
21
import org.gvsig.tools.persistence.exception.PersistenceException;
22
import org.gvsig.tools.script.ScriptManager;
23
import org.gvsig.tools.util.LabeledValue;
24
import org.json.JSONObject;
25

    
26
/**
27
 *
28
 * @author jjdelcerro
29
 */
30
public class DefaultExpression implements Expression, LabeledValue<Expression> {
31

    
32
    private String phrase = null;
33

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
353
    @Override
354
    public Evaluator toEvaluator() {
355
        ExpressionEvaluator evaluator = this.manager.createExpressionEvaluator(this);
356
        return evaluator;
357
    }
358
    
359
}