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

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

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

    
30
    private String phrase = null;
31

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
175
            return x;
176
        } finally {
177
            if( added ) {
178
                this.getSymbolTable().removeSymbolTable(symbolTable);
179
            }
180
        }
181
    }
182

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

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

    
226
    @Override
227
    public void loadFromState(PersistentState state) throws PersistenceException {
228
        ScriptManager scriptManager = ToolsLocator.getScriptManager();
229

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

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

    
272
    @Override
273
    public String toJSON() {
274
        JSONObject expressionJson = new JSONObject();
275
        expressionJson.put("phrase", this.phrase);
276

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

    
294
    @Override
295
    public void fromJSON(String json) {
296
        this.clear();
297
        ScriptManager scriptMananger = ToolsLocator.getScriptManager();
298

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

    
326
    @Override
327
    public String toString() {
328
        return this.toJSON();
329
    }
330

    
331
    @Override
332
    public Expression clone() throws CloneNotSupportedException {
333
        Expression other = (Expression) super.clone();
334
        other.fromJSON(this.toJSON());
335
        return other;
336
    }
337

    
338
    @Override
339
    public void setUseBracketsForIdentifiers(boolean useBracketsForIdentifiers) {
340
        this.useBracketsForIdentifiers = useBracketsForIdentifiers;
341
    }
342
    
343
    @Override
344
    public boolean getUseBracketsForIdentifiers() {
345
        return this.useBracketsForIdentifiers;
346
    }
347
    
348
}