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

History | View | Annotate | Download (12.1 KB)

1 43983 jjdelcerro
package org.gvsig.expressionevaluator.impl;
2
3 44622 jjdelcerro
import java.lang.ref.WeakReference;
4 44390 jjdelcerro
import java.util.Objects;
5 45425 jjdelcerro
import javax.json.JsonObject;
6 43983 jjdelcerro
import org.apache.commons.lang3.StringUtils;
7 47192 jjdelcerro
import org.apache.commons.lang3.builder.ToStringBuilder;
8 43983 jjdelcerro
import org.gvsig.expressionevaluator.Code;
9 44215 jjdelcerro
import org.gvsig.expressionevaluator.Compiler;
10 43983 jjdelcerro
import org.gvsig.expressionevaluator.Expression;
11 45366 omartinez
import org.gvsig.expressionevaluator.ExpressionEvaluator;
12 44665 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
13 43983 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
14 44215 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionUtils;
15 43983 jjdelcerro
import org.gvsig.expressionevaluator.Interpreter;
16 44009 jjdelcerro
import org.gvsig.expressionevaluator.Optimizer;
17 43983 jjdelcerro
import org.gvsig.expressionevaluator.SymbolTable;
18 45425 jjdelcerro
import org.gvsig.json.Json;
19 45789 fdiaz
import org.gvsig.json.JsonManager;
20 45425 jjdelcerro
import org.gvsig.json.JsonObjectBuilder;
21 45789 fdiaz
import org.gvsig.json.SupportToJson;
22 43983 jjdelcerro
import org.gvsig.tools.ToolsLocator;
23
import org.gvsig.tools.dynobject.DynStruct;
24 45308 fdiaz
import org.gvsig.tools.evaluator.Evaluator;
25 47141 fdiaz
import org.gvsig.tools.packageutils.Version;
26
import org.gvsig.tools.packageutils.impl.DefaultVersion;
27 43983 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
28
import org.gvsig.tools.persistence.PersistentState;
29
import org.gvsig.tools.persistence.exception.PersistenceException;
30
import org.gvsig.tools.script.ScriptManager;
31 44390 jjdelcerro
import org.gvsig.tools.util.LabeledValue;
32 47141 fdiaz
import org.slf4j.Logger;
33
import org.slf4j.LoggerFactory;
34 43983 jjdelcerro
35
/**
36
 *
37
 * @author jjdelcerro
38
 */
39 44390 jjdelcerro
public class DefaultExpression implements Expression, LabeledValue<Expression> {
40 47141 fdiaz
41
    private static final Logger LOGGER = LoggerFactory.getLogger(DefaultExpression.class);
42
43
    private static final Version VERSION_2_6_0_1 = ToolsLocator.getPackageManager().createVersion("2.6.0-1");
44 43983 jjdelcerro
45 47141 fdiaz
    //?Ojo!, esto est? copiado de DataAccessGrammarFactory por cuestiones de dependencias. Si lo tocamos hay que tocarlo en los dos lados
46
    public static final String COMPATIBILITY_SELECT_ID = "SELECT";
47
    public static final String COMPATIBILITY_SELECT_OPTIONAL_SEMICOLON_AT_END = "OPTIONAL_SEMICOLON_AT_END";
48
49 43983 jjdelcerro
    private String phrase = null;
50
51
    private Code code = null;
52
    private Interpreter interpreter;
53 44009 jjdelcerro
    private boolean hasNotBeenOptimized = true;
54 44215 jjdelcerro
    private SymbolTable mySymbolTable = null;
55 44622 jjdelcerro
    private WeakReference<SymbolTable> lastSymbolTable = null;
56 44215 jjdelcerro
    private boolean useBracketsForIdentifiers = false;
57 44644 jjdelcerro
    protected ExpressionEvaluatorManager manager;
58 43983 jjdelcerro
59 44665 jjdelcerro
    public DefaultExpression() {
60
        this(ExpressionEvaluatorLocator.getExpressionEvaluatorManager());
61
    }
62
63 44644 jjdelcerro
    public DefaultExpression(ExpressionEvaluatorManager manager) {
64
        this.manager = manager;
65 43983 jjdelcerro
    }
66 44665 jjdelcerro
67 44390 jjdelcerro
    @Override
68
    public String getLabel() {
69
        return StringUtils.abbreviate(
70
                StringUtils.normalizeSpace(this.getPhrase()),
71
                35
72
        );
73
    }
74
75
    @Override
76
    public Expression getValue() {
77
        return this;
78
    }
79
80
    @Override
81
    public boolean equals(Object obj) {
82
        if( obj == null || !(obj instanceof Expression) ) {
83
            return false;
84
        }
85
        String this_s = this.toJSON();
86
        String other_s = ((Expression)obj).toJSON();
87
        return this_s.equals(other_s);
88
    }
89
90
    @Override
91
    public int hashCode() {
92
        String this_s = this.toJSON();
93
        return Objects.hashCode(this_s);
94
    }
95 44215 jjdelcerro
96
    @Override
97
    public SymbolTable getSymbolTable() {
98
        if( this.mySymbolTable==null ) {
99
            this.mySymbolTable = ExpressionUtils.createSymbolTable();
100
        }
101
        return this.mySymbolTable;
102
    }
103 43983 jjdelcerro
104
    @Override
105
    public String getPhrase() {
106
        return this.phrase;
107
    }
108
109
    @Override
110 44126 jjdelcerro
    public boolean isPhraseEmpty() {
111
        return StringUtils.isBlank(this.phrase);
112
    }
113
114
    @Override
115 44163 jjdelcerro
    public boolean isEmpty() {
116
        if( !StringUtils.isBlank(this.phrase) ) {
117
            return false;
118
        }
119
        return true;
120
    }
121
122
    @Override
123
    public Expression setPhrase(String phrase) {
124 43983 jjdelcerro
        this.phrase = phrase;
125
        this.code = null;
126 44009 jjdelcerro
        this.hasNotBeenOptimized = true;
127 44163 jjdelcerro
        return this;
128 43983 jjdelcerro
    }
129
130
    @Override
131 43984 jjdelcerro
    public void clear() {
132
        this.phrase = null;
133
        this.code = null;
134
        this.interpreter = null;
135 44009 jjdelcerro
        this.hasNotBeenOptimized = true;
136 43984 jjdelcerro
    }
137
138
    @Override
139 43989 jjdelcerro
    public Code getCode() {
140 43983 jjdelcerro
        if (this.code == null) {
141 44644 jjdelcerro
            Compiler compiler = this.manager.createCompiler();
142 44215 jjdelcerro
            compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(
143
                    this.useBracketsForIdentifiers
144
            );
145
            this.code = compiler.compileExpression(this.phrase);
146 43983 jjdelcerro
        }
147 43989 jjdelcerro
        return code;
148
    }
149
150
    @Override
151 44191 jjdelcerro
    public void setSQLCompatible(boolean sqlCompatible) {
152
        this.getInterpreter().setSQLCompatible(sqlCompatible);
153
    }
154
155
    @Override
156
    public boolean isSQLCompatible() {
157
        return this.getInterpreter().isSQLCompatible();
158
    }
159
160
    private Interpreter getInterpreter() {
161
        if (this.interpreter == null) {
162 44644 jjdelcerro
            this.interpreter = this.manager.createInterpreter();
163 44191 jjdelcerro
        }
164
        return this.interpreter;
165
    }
166
167
    @Override
168 43989 jjdelcerro
    public Object execute(SymbolTable symbolTable) {
169 43983 jjdelcerro
        if (this.interpreter == null) {
170 44644 jjdelcerro
            this.interpreter = this.manager.createInterpreter();
171 46711 jjdelcerro
        }
172 45067 jjdelcerro
        boolean added = false;
173
        if( symbolTable!=null ) {
174
            added = this.getSymbolTable().addSymbolTable(symbolTable);
175
            if( this.lastSymbolTable==null ) {
176
                this.lastSymbolTable = new WeakReference<>(symbolTable);
177
            } else if( this.lastSymbolTable.get()!=symbolTable ) {
178
                this.link(this.getSymbolTable());
179
                this.hasNotBeenOptimized = true;
180
            }
181 44622 jjdelcerro
        }
182 44215 jjdelcerro
        try {
183 45067 jjdelcerro
            this.interpreter.setSymbolTable(this.getSymbolTable());
184 44215 jjdelcerro
            if( this.hasNotBeenOptimized  ) {
185 44622 jjdelcerro
                try {
186 44644 jjdelcerro
                    Optimizer optimizer = this.manager.createOptimizer();
187
                    optimizer.setSymbolTable(this.getSymbolTable());
188 44622 jjdelcerro
                    this.code = optimizer.optimize(this.getCode());
189
                } catch(Throwable th) {
190
                    // Si no es capaz de optimizar la expresion no, peta y la
191
                    // ejecuta tal cual.
192
                }
193 44215 jjdelcerro
                this.hasNotBeenOptimized = false;
194
            }
195 46711 jjdelcerro
            Code code_exp = this.getCode();
196
            if( this.manager.hasHostExpressions(code_exp) ) {
197
                code_exp = this.manager.resolveHostExpressions(code_exp, interpreter);
198
            }
199
            Object x = this.interpreter.run(code_exp);
200 44215 jjdelcerro
201
            return x;
202
        } finally {
203
            if( added ) {
204
                this.getSymbolTable().removeSymbolTable(symbolTable);
205
            }
206 44009 jjdelcerro
        }
207 43983 jjdelcerro
    }
208
209
    @Override
210 44191 jjdelcerro
    public void link(SymbolTable symbolTable) {
211
        if (this.interpreter == null) {
212 44644 jjdelcerro
            this.interpreter = this.manager.createInterpreter();
213 44191 jjdelcerro
        }
214 44623 jjdelcerro
        this.lastSymbolTable = new WeakReference<>(symbolTable);
215 44191 jjdelcerro
        this.interpreter.setSymbolTable(symbolTable);
216
        if( this.hasNotBeenOptimized  ) {
217 44644 jjdelcerro
            Optimizer optimizer = new DefaultOptimizer(this.manager, symbolTable);
218 44191 jjdelcerro
            this.code = optimizer.optimize(this.getCode());
219
            this.hasNotBeenOptimized = false;
220
        }
221
        this.interpreter.link(this.getCode());
222
    }
223
224
    @Override
225 43983 jjdelcerro
    public void saveToState(PersistentState state) throws PersistenceException {
226 47141 fdiaz
        state.set("version", VERSION_2_6_0_1);
227 43983 jjdelcerro
        state.set("phrase", this.phrase);
228
    }
229
230
    @Override
231
    public void loadFromState(PersistentState state) throws PersistenceException {
232
        ScriptManager scriptManager = ToolsLocator.getScriptManager();
233
234 44009 jjdelcerro
        this.clear();
235 47141 fdiaz
236
        Version version = (Version) state.get("version");
237 43983 jjdelcerro
        this.phrase = state.getString("phrase");
238 47141 fdiaz
        this.fixCompatibility(version);
239
240 43983 jjdelcerro
    }
241
242
    public static void registerPersistence() {
243
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
244
        if (manager.getDefinition("Expression") == null) {
245
            DynStruct definition = manager.addDefinition(DefaultExpression.class,
246
                    "Expression", "Expression persistence definition", null, null);
247
            definition.addDynFieldString("phrase").setMandatory(false);
248 47141 fdiaz
249
            definition.addDynFieldObject("version")
250
                    .setClassOfValue(DefaultVersion.class)
251
                    .setMandatory(false);
252
253 43983 jjdelcerro
        }
254
    }
255
256
    @Override
257 45425 jjdelcerro
    public JsonObject toJson() {
258
        return this.toJsonBuilder().build();
259 43984 jjdelcerro
    }
260
261
    @Override
262 45425 jjdelcerro
    public JsonObjectBuilder toJsonBuilder() {
263
        JsonObjectBuilder builder = Json.createObjectBuilder();
264
        builder.add_class(this);
265
        builder.add("phrase", this.phrase);
266 47141 fdiaz
        builder.add("version", VERSION_2_6_0_1.toString());
267 45425 jjdelcerro
        return builder;
268
    }
269
270
    @Override
271
    public void fromJson(JsonObject values) {
272 43984 jjdelcerro
        this.clear();
273 45425 jjdelcerro
        if( values.containsKey("phrase") ) {
274
            this.phrase = values.getString("phrase");
275 43984 jjdelcerro
        }
276 47141 fdiaz
        String version_s = values.getString("version", null);
277
        Version version = ToolsLocator.getPackageManager().createVersion(version_s);
278
        this.fixCompatibility(version);
279
280 43983 jjdelcerro
    }
281 45425 jjdelcerro
282
    @Deprecated
283
    @Override
284
    public String toJSON() {
285
        return toJson().toString();
286
    }
287 43983 jjdelcerro
288 45425 jjdelcerro
    @Deprecated
289 43984 jjdelcerro
    @Override
290 45425 jjdelcerro
    public void fromJSON(String json) {
291
        this.fromJson(Json.createObject(json));
292
    }
293
294
    @Override
295 43984 jjdelcerro
    public Expression clone() throws CloneNotSupportedException {
296
        Expression other = (Expression) super.clone();
297
        other.fromJSON(this.toJSON());
298
        return other;
299
    }
300
301 44215 jjdelcerro
    @Override
302 47192 jjdelcerro
    public String toString() {
303
        try {
304
            ToStringBuilder builder = new ToStringBuilder(this);
305
            builder.append("phrase", this.phrase);
306
            return builder.toString();
307
        } catch (Exception e) {
308
            return super.toString();
309
        }
310
    }
311
312
    @Override
313 44215 jjdelcerro
    public void setUseBracketsForIdentifiers(boolean useBracketsForIdentifiers) {
314
        this.useBracketsForIdentifiers = useBracketsForIdentifiers;
315
    }
316
317
    @Override
318
    public boolean getUseBracketsForIdentifiers() {
319
        return this.useBracketsForIdentifiers;
320
    }
321 45308 fdiaz
322
    @Override
323
    public Evaluator toEvaluator() {
324 45366 omartinez
        ExpressionEvaluator evaluator = this.manager.createExpressionEvaluator(this);
325 45308 fdiaz
        return evaluator;
326
    }
327 45789 fdiaz
328
    public static void selfRegister() {
329
        Json.registerSerializer(new TheJsonSerializer());
330
    }
331 47141 fdiaz
332
    private void fixCompatibility(Version version) {
333
        if (version == null || version.compareTo(VERSION_2_6_0_1) < 0) {
334
            try {
335
                if (StringUtils.isNotBlank(this.phrase)) {
336
                    ExpressionEvaluatorManager expressionManager = ExpressionEvaluatorLocator.getExpressionEvaluatorManager();
337
                    org.gvsig.expressionevaluator.Compiler compiler = expressionManager.createCompiler();
338
                    compiler.addCompatibility(
339
                            COMPATIBILITY_SELECT_ID,
340
                            COMPATIBILITY_SELECT_OPTIONAL_SEMICOLON_AT_END
341
                    );
342
                    Code code = compiler.compileExpressionQuietly(this.phrase);
343
                    if (code != null) {
344
                        code.link();
345
                        this.phrase = code.toString();
346
                    }
347
                }
348
            } catch (Throwable t) {
349 47164 fdiaz
                LOGGER.warn("Can't check select compatibility in select ("+this.phrase+")", t);
350 47141 fdiaz
            }
351
        }
352
    }
353 45789 fdiaz
354
    private static class TheJsonSerializer implements JsonManager.JsonSerializer {
355
356
        public TheJsonSerializer() {
357
        }
358
359
        @Override
360
        public Class getObjectClass() {
361
            return DefaultExpression.class;
362
        }
363
364
        @Override
365
        public Object toObject(JsonObject json) {
366
            DefaultExpression o = new DefaultExpression();
367
            o.fromJson(json);
368
            return o;
369
        }
370
371
        @Override
372
        public JsonObjectBuilder toJsonBuilder(Object value) {
373
            return ((SupportToJson)value).toJsonBuilder();
374
        }
375
376
    }
377
378
379
380 43983 jjdelcerro
}