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

History | View | Annotate | Download (12.5 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.net.URI;
4
import java.util.ArrayList;
5
import java.util.Iterator;
6
import java.util.List;
7
import org.apache.commons.lang3.StringUtils;
8
import org.gvsig.expressionevaluator.Code;
9
import org.gvsig.expressionevaluator.Compiler;
10
import org.gvsig.expressionevaluator.Expression;
11
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
13
import org.gvsig.expressionevaluator.ExpressionUtils;
14
import org.gvsig.expressionevaluator.Interpreter;
15
import org.gvsig.expressionevaluator.Optimizer;
16
import org.gvsig.expressionevaluator.SymbolTable;
17
import org.gvsig.tools.ToolsLocator;
18
import org.gvsig.tools.dynobject.DynStruct;
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.Script;
23
import org.gvsig.tools.script.ScriptManager;
24
import org.gvsig.tools.util.UnmodifiableBasicList;
25
import org.gvsig.tools.util.UnmodifiableBasicListAdapter;
26
import org.json.JSONArray;
27
import org.json.JSONObject;
28

    
29
/**
30
 *
31
 * @author jjdelcerro
32
 */
33
public class DefaultExpression implements Expression {
34

    
35
    private String phrase = null;
36
    private Script userScript = null;
37
    private List<Script> scripts = null;
38
    private UnmodifiableBasicList<Script> unmodifiableScripts = null;
39

    
40
    private Code code = null;
41
    private Interpreter interpreter;
42
    private boolean hasNotBeenOptimized = true;
43
    private SymbolTable mySymbolTable = null;
44
    private boolean useBracketsForIdentifiers = false;
45

    
46
    public DefaultExpression() {
47

    
48
    }
49
    
50
    @Override
51
    public SymbolTable getSymbolTable() {
52
        if( this.mySymbolTable==null ) {
53
            this.mySymbolTable = ExpressionUtils.createSymbolTable();
54
        }
55
        return this.mySymbolTable;
56
    }
57

    
58
    @Override
59
    public String getPhrase() {
60
        return this.phrase;
61
    }
62

    
63
    @Override
64
    public boolean isPhraseEmpty() {
65
        return StringUtils.isBlank(this.phrase);
66
    }
67

    
68
    @Override
69
    public boolean isEmpty() {
70
        if( !StringUtils.isBlank(this.phrase) ) {
71
            return false;
72
        }
73
        if( this.scripts!=null && !this.scripts.isEmpty() ) {
74
            return false;
75
        }
76
        if( this.userScript!=null && !StringUtils.isBlank(this.userScript.getCode()) ) {
77
            return false;
78
        }
79
        return true;
80
    }
81

    
82
    @Override
83
    public Script getUserScript() {
84
        return this.userScript;
85
    }
86

    
87
    @Override
88
    public UnmodifiableBasicList<Script> getScripts() {
89
        if (this.unmodifiableScripts == null) {
90
            if (this.scripts == null) {
91
                return null;
92
            }
93
            this.unmodifiableScripts = new UnmodifiableBasicListAdapter<>(this.scripts);
94
        }
95
        return this.unmodifiableScripts;
96
    }
97

    
98
    @Override
99
    public Expression setPhrase(String phrase) {
100
        this.phrase = phrase;
101
        this.code = null;
102
        this.hasNotBeenOptimized = true;
103
        return this;
104
    }
105

    
106
    @Override
107
    public Expression setUserScript(String code, String languaje) {
108
        if (this.userScript == null) {
109
            ScriptManager scriptMananger = ToolsLocator.getScriptManager();
110
            this.userScript = scriptMananger.createScript("user", code, languaje);
111
        } else if (this.userScript.getTypeName().equalsIgnoreCase(languaje)) {
112
            this.userScript.setCode(code);
113
        } else {
114
            ScriptManager scriptMananger = ToolsLocator.getScriptManager();
115
            this.userScript = scriptMananger.createScript("user", code, languaje);
116
        }
117
        return this;
118
    }
119

    
120
    @Override
121
    public Expression setUserScript(Script script) {
122
        this.userScript = script;
123
        return this;
124
    }
125

    
126
    @Override
127
    public Expression setUserScript(String code) {
128
        this.setUserScript(code, "python");
129
        return this;
130
    }
131

    
132
    @Override
133
    public void removeAllScripts() {
134
        this.scripts = null;
135
        this.unmodifiableScripts = null;
136
    }
137

    
138
    @Override
139
    public Expression addScript(Script script) {
140
        if (this.scripts == null) {
141
            this.scripts = new ArrayList<>();
142
        }
143
        this.scripts.add(script);
144
        return this;
145
    }
146

    
147
    @Override
148
    public void clear() {
149
        this.phrase = null;
150
        this.userScript = null;
151
        this.unmodifiableScripts = null;
152
        this.scripts = null;
153
        this.code = null;
154
        this.interpreter = null;
155
        this.hasNotBeenOptimized = true;
156
    }
157

    
158
    @Override
159
    public Code getCode() {
160
        if (this.code == null) {
161
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
162
            Compiler compiler = manager.createCompiler();
163
            compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(
164
                    this.useBracketsForIdentifiers
165
            );
166
            this.code = compiler.compileExpression(this.phrase);
167
        }
168
        return code;
169
    }
170

    
171
    @Override
172
    public void setSQLCompatible(boolean sqlCompatible) {
173
        this.getInterpreter().setSQLCompatible(sqlCompatible);
174
    }
175

    
176
    @Override
177
    public boolean isSQLCompatible() {
178
        return this.getInterpreter().isSQLCompatible();
179
    }
180

    
181
    private Interpreter getInterpreter() {
182
        if (this.interpreter == null) {
183
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
184
            this.interpreter = manager.createInterpreter();
185
        }
186
        return this.interpreter;
187
    }
188
    
189
    @Override
190
    public Object execute(SymbolTable symbolTable) {
191
        if (this.interpreter == null) {
192
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
193
            this.interpreter = manager.createInterpreter();
194
        }
195
        boolean added = this.getSymbolTable().addSymbolTable(symbolTable);
196
        try {
197
            this.interpreter.setSymbolTable(this.mySymbolTable);
198
            if( this.hasNotBeenOptimized  ) {
199
                Optimizer optimizer = new DefaultOptimizer(symbolTable);
200
                this.code = optimizer.optimize(this.getCode());
201
                this.hasNotBeenOptimized = false;
202
            }
203
            Object x = this.interpreter.run(this.getCode());
204

    
205
            return x;
206
        } finally {
207
            if( added ) {
208
                this.getSymbolTable().removeSymbolTable(symbolTable);
209
            }
210
        }
211
    }
212

    
213
    @Override
214
    public void link(SymbolTable symbolTable) {
215
        if (this.interpreter == null) {
216
            ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
217
            this.interpreter = manager.createInterpreter();
218
        }
219
        this.interpreter.setSymbolTable(symbolTable);
220
        if( this.hasNotBeenOptimized  ) {
221
            Optimizer optimizer = new DefaultOptimizer(symbolTable);
222
            this.code = optimizer.optimize(this.getCode());
223
            this.hasNotBeenOptimized = false;
224
        }
225
        this.interpreter.link(this.getCode());
226
    }
227

    
228
    @Override
229
    public void saveToState(PersistentState state) throws PersistenceException {
230
        state.set("phrase", this.phrase);
231
        if (this.userScript == null) {
232
            state.setNull("userScript_code");
233
            state.setNull("userScript_language");
234
        } else {
235
            state.set("userScript_code", this.userScript.getCode());
236
            state.set("userScript_language", this.userScript.getTypeName());
237
        }
238
        if (this.scripts != null && !this.scripts.isEmpty()) {
239
            List<URI> l = new ArrayList<>();
240
            for (Script script : this.scripts) {
241
                URI location = script.getURI();
242
                if (location != null) {
243
                    l.add(location);
244
                }
245
            }
246
            if (l.isEmpty()) {
247
                state.setNull("scripts");
248
            } else {
249
                state.set("scripts", l);
250
            }
251
        } else {
252
            state.setNull("scripts");
253
        }
254
    }
255

    
256
    @Override
257
    public void loadFromState(PersistentState state) throws PersistenceException {
258
        ScriptManager scriptManager = ToolsLocator.getScriptManager();
259

    
260
        this.clear();
261
        
262
        this.phrase = state.getString("phrase");
263
        String userScript_code = state.getString("userScript_code");
264
        String userScript_language = state.getString("userScript_language");
265
        if (StringUtils.isEmpty(userScript_code)) {
266
            this.userScript = null;
267
        } else {
268
            if (StringUtils.isEmpty(userScript_language)) {
269
                userScript_language = "python";
270
            }
271
            this.userScript = scriptManager.createScript("user", userScript_code, userScript_language);
272
        }
273
        Iterator scriptsLocations = state.getIterator("scripts");
274
        if (scriptsLocations != null) {
275
            while (scriptsLocations.hasNext()) {
276
                URI location = (URI) scriptsLocations.next();
277
                Script script = scriptManager.loadScript(location);
278
                if (script != null) {
279
                    if (this.scripts == null) {
280
                        this.scripts = new ArrayList<>();
281
                    }
282
                    this.scripts.add(script);
283
                }
284
            }
285
        }
286
    }
287

    
288
    public static void registerPersistence() {
289
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
290
        if (manager.getDefinition("Expression") == null) {
291
            DynStruct definition = manager.addDefinition(DefaultExpression.class,
292
                    "Expression", "Expression persistence definition", null, null);
293
            definition.addDynFieldString("phrase").setMandatory(false);
294
            definition.addDynFieldString("userScript_code").setMandatory(false);
295
            definition.addDynFieldString("userScript_language").setMandatory(false);
296
            definition.addDynFieldList("scripts")
297
                    .setClassOfItems(URI.class)
298
                    .setMandatory(false);
299
        }
300
    }
301

    
302
    @Override
303
    public String toJSON() {
304
        JSONObject expressionJson = new JSONObject();
305
        expressionJson.put("phrase", this.phrase);
306

    
307
        if (this.userScript != null) {
308
            JSONObject userScriptJson = new JSONObject();
309
            userScriptJson.put("code", this.userScript.getCode());
310
            userScriptJson.put("language", this.userScript.getTypeName());
311
            expressionJson.put("userScript", userScriptJson);
312
        }
313

    
314
        if (this.scripts != null && !this.scripts.isEmpty()) {
315
            JSONArray scriptsJson = new JSONArray();
316
            for (Script script : this.scripts) {
317
                scriptsJson.put(script.getURI());
318
            }
319
            expressionJson.put("scripts", scriptsJson);
320
        }
321
        return expressionJson.toString();
322
    }
323

    
324
    @Override
325
    public void fromJSON(String json) {
326
        this.clear();
327
        ScriptManager scriptMananger = ToolsLocator.getScriptManager();
328

    
329
        JSONObject expressionJson = new JSONObject(json);
330
        if (expressionJson.has("phrase")) {
331
            this.phrase = expressionJson.getString("phrase");
332
        }
333
        if (expressionJson.has("userScript")) {
334
            String theCode = "";
335
            String theLanguage = "python";
336
            JSONObject userScriptJson = expressionJson.getJSONObject("userScript");
337
            if (userScriptJson.has("code")) {
338
                theCode = userScriptJson.getString("code");
339
            }
340
            if (userScriptJson.has("language")) {
341
                theCode = userScriptJson.getString("language");
342
            }
343
            this.userScript = scriptMananger.createScript("user", theCode, theLanguage);
344
        }
345
        if (expressionJson.has("scripts")) {
346
            this.scripts = new ArrayList<>();
347
            JSONArray scriptsJson = expressionJson.getJSONArray("scripts");
348
            for (Object object : scriptsJson) {
349
                URI location = (URI) object;
350
                Script script = scriptMananger.loadScript(location);
351
                this.scripts.add(script);
352
            }
353
        }
354
    }
355

    
356
    @Override
357
    public String toString() {
358
        return this.toJSON();
359
    }
360

    
361
    @Override
362
    public Expression clone() throws CloneNotSupportedException {
363
        Expression other = (Expression) super.clone();
364
        other.fromJSON(this.toJSON());
365
        return other;
366
    }
367

    
368
    @Override
369
    public void setUseBracketsForIdentifiers(boolean useBracketsForIdentifiers) {
370
        this.useBracketsForIdentifiers = useBracketsForIdentifiers;
371
    }
372
    
373
    @Override
374
    public boolean getUseBracketsForIdentifiers() {
375
        return this.useBracketsForIdentifiers;
376
    }
377
    
378
}