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

History | View | Annotate | Download (11.5 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.ExpressionEvaluatorManager;
10
import org.gvsig.expressionevaluator.ExpressionUtils;
11
import org.gvsig.expressionevaluator.Interpreter;
12
import org.gvsig.expressionevaluator.Optimizer;
13
import org.gvsig.expressionevaluator.SymbolTable;
14
import org.gvsig.tools.ToolsLocator;
15
import org.gvsig.tools.dynobject.DynStruct;
16
import org.gvsig.tools.persistence.PersistenceManager;
17
import org.gvsig.tools.persistence.PersistentState;
18
import org.gvsig.tools.persistence.exception.PersistenceException;
19
import org.gvsig.tools.script.ScriptManager;
20
import org.gvsig.tools.util.LabeledValue;
21
import org.json.JSONObject;
22

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

    
29
    private String phrase = null;
30

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

    
39
    public DefaultExpression(ExpressionEvaluatorManager manager) {
40
        this.manager = manager;
41
    }
42

    
43
    @Override
44
    public String getLabel() {
45
        return StringUtils.abbreviate(
46
                StringUtils.normalizeSpace(this.getPhrase()),
47
                35
48
        );
49
    }
50

    
51
    @Override
52
    public Expression getValue() {
53
        return this;
54
    }
55

    
56
    @Override
57
    public boolean equals(Object obj) {
58
        if( obj == null || !(obj instanceof Expression) ) {
59
            return false;
60
        }
61
        String this_s = this.toJSON();
62
        String other_s = ((Expression)obj).toJSON();
63
        return this_s.equals(other_s);
64
    }
65

    
66
    @Override
67
    public int hashCode() {
68
        String this_s = this.toJSON();
69
        return Objects.hashCode(this_s);
70
    }
71
    
72
    @Override
73
    public SymbolTable getSymbolTable() {
74
        if( this.mySymbolTable==null ) {
75
            this.mySymbolTable = ExpressionUtils.createSymbolTable();
76
        }
77
        return this.mySymbolTable;
78
    }
79

    
80
    @Override
81
    public String getPhrase() {
82
        return this.phrase;
83
    }
84

    
85
    @Override
86
    public boolean isPhraseEmpty() {
87
        return StringUtils.isBlank(this.phrase);
88
    }
89

    
90
    @Override
91
    public boolean isEmpty() {
92
        if( !StringUtils.isBlank(this.phrase) ) {
93
            return false;
94
        }
95
        return true;
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 void clear() {
108
        this.phrase = null;
109
        this.code = null;
110
        this.interpreter = null;
111
        this.hasNotBeenOptimized = true;
112
    }
113

    
114
    @Override
115
    public Code getCode() {
116
        if (this.code == null) {
117
            Compiler compiler = this.manager.createCompiler();
118
            compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(
119
                    this.useBracketsForIdentifiers
120
            );
121
            this.code = compiler.compileExpression(this.phrase);
122
        }
123
        return code;
124
    }
125

    
126
    @Override
127
    public void setSQLCompatible(boolean sqlCompatible) {
128
        this.getInterpreter().setSQLCompatible(sqlCompatible);
129
    }
130

    
131
    @Override
132
    public boolean isSQLCompatible() {
133
        return this.getInterpreter().isSQLCompatible();
134
    }
135

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

    
170
            return x;
171
        } finally {
172
            if( added ) {
173
                this.getSymbolTable().removeSymbolTable(symbolTable);
174
            }
175
        }
176
    }
177

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

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

    
221
    @Override
222
    public void loadFromState(PersistentState state) throws PersistenceException {
223
        ScriptManager scriptManager = ToolsLocator.getScriptManager();
224

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

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

    
267
    @Override
268
    public String toJSON() {
269
        JSONObject expressionJson = new JSONObject();
270
        expressionJson.put("phrase", this.phrase);
271

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

    
289
    @Override
290
    public void fromJSON(String json) {
291
        this.clear();
292
        ScriptManager scriptMananger = ToolsLocator.getScriptManager();
293

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

    
321
    @Override
322
    public String toString() {
323
        return this.toJSON();
324
    }
325

    
326
    @Override
327
    public Expression clone() throws CloneNotSupportedException {
328
        Expression other = (Expression) super.clone();
329
        other.fromJSON(this.toJSON());
330
        return other;
331
    }
332

    
333
    @Override
334
    public void setUseBracketsForIdentifiers(boolean useBracketsForIdentifiers) {
335
        this.useBracketsForIdentifiers = useBracketsForIdentifiers;
336
    }
337
    
338
    @Override
339
    public boolean getUseBracketsForIdentifiers() {
340
        return this.useBracketsForIdentifiers;
341
    }
342
    
343
}