Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.spi / src / main / java / org / gvsig / fmap / dal / feature / spi / ExpressionEvaluatorBase.java @ 43088

History | View | Annotate | Download (16.1 KB)

1

    
2
package org.gvsig.fmap.dal.feature.spi;
3

    
4
import gnu.jel.CompilationException;
5
import gnu.jel.CompiledExpression;
6
import gnu.jel.DVMap;
7
import java.util.ArrayList;
8
import java.util.Date;
9
import java.util.List;
10
import java.util.regex.Matcher;
11
import java.util.regex.Pattern;
12
import org.cresques.cts.IProjection;
13
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.Find_SRID;
14
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_AsBinary;
15
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_AsEWKB;
16
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_AsText;
17
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Contains;
18
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Crosses;
19
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Disjoint;
20
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Envelope;
21
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Equals;
22
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_GeomFromEWKB;
23
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_GeomFromText;
24
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_GeomFromWKB;
25
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Intersects;
26
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_IsClosed;
27
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Overlaps;
28
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_SRID;
29
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Touches;
30
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ST_Within;
31
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.isNull;
32
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.lcase;
33
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.notIsNull;
34
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_AND;
35
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_EQ;
36
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_GE;
37
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_GT;
38
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_ILIKE;
39
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_LE;
40
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_LIKE;
41
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_LT;
42
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_NE;
43
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_OR;
44
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.operator_not;
45
import static org.gvsig.fmap.dal.ExpressionBuilder.Config.ucase;
46
import org.gvsig.fmap.dal.ExpressionEvaluator;
47
import org.gvsig.fmap.geom.Geometry;
48
import org.gvsig.fmap.geom.GeometryException;
49
import org.gvsig.fmap.geom.GeometryLocator;
50
import org.gvsig.fmap.geom.GeometryManager;
51
import org.gvsig.fmap.geom.operation.GeometryOperationException;
52
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
53
import org.gvsig.fmap.geom.primitive.Envelope;
54
import org.gvsig.tools.evaluator.EvaluatorData;
55
import org.gvsig.tools.evaluator.EvaluatorException;
56
import org.gvsig.tools.evaluator.EvaluatorFieldsInfo;
57

    
58

    
59
public class ExpressionEvaluatorBase extends ExpressionBuilderBase implements ExpressionEvaluator {
60

    
61
    public class JELConfig extends ConfigBase {
62
        
63
        public JELConfig() {
64
            super();
65
            
66
            this.set(has_spatial_functions,true);
67
            this.set(constant_true, "true");
68
            this.set(constant_false, "false");
69
            this.set(quote_for_identifiers, "");
70
            this.set(quote_for_strings, "\"");
71
            this.set(geometry_type_support, GeometrySupportType.WKT);
72
            this.set(group, "( {0} )");
73
            
74
            this.set(Find_SRID , "Find_SRID(({0}), ({1}), ({2}))");
75
            this.set(ST_SRID , "ST_SRID({0})");
76
            this.set(ST_AsText , "ST_AsText({0})");
77
            this.set(ST_AsBinary, "ST_AsBinary({0})");
78
            this.set(ST_AsEWKB, "ST_AsWKB({0})");
79
            this.set(ST_Contains, "ST_Contains(({0}), ({1}))");            
80
            this.set(ST_Crosses,  "ST_Crosses(({0}), ({1}))");
81
            this.set(ST_Disjoint ,  "ST_Disjoint(({0}), ({1}))");
82
            this.set(ST_Equals ,  "ST_Equals(({0}), ({1}))");
83
            this.set(ST_IsClosed,  "ST_IsClosed({0})");
84
            this.set(ST_Overlaps,  "ST_Overlaps(({0}), ({1}))");
85
            this.set(ST_Touches,  "ST_Touches(({0}), ({1}))");
86
            this.set(ST_Within, "ST_Within(({0}), ({1}))");            
87
            this.set(ST_Envelope, "ST_Envelope({0})");
88
            this.set(ST_Intersects, "ST_Intersects(({0}), ({1}))");
89
            this.set(ST_GeomFromText, "ST_GeomFromText({0}, ({1}))");
90
            this.set(ST_GeomFromWKB, "ST_GeomFromWKB(({0}), ({1}))");
91
            this.set(ST_GeomFromEWKB, "ST_GeomFromEWKB(({0}), ({1}))");
92
            this.set(lcase, "LCASE({0})");
93
            this.set(ucase, "UCASE({0})");
94
            this.set(isNull, "( ({0}) == null )");
95
            this.set(notIsNull, "( ! (({0}) == null) )");
96
            this.set(operator_not, "( ! ({0}) )");
97
            
98
            this.set(operator_AND, "{0} && {1}");
99
            this.set(operator_OR, "{0} || {1}");
100
            this.set(operator_EQ, "( ({0}) == ({1}) )");
101
            this.set(operator_NE, "( ({0}) != ({1}) )");
102
            this.set(operator_GT, "( ({0}) > ({1}) )");
103
            this.set(operator_GE, "( ({0}) >= ({1}) )");
104
            this.set(operator_LT, "( ({0}) < ({1}) )");
105
            this.set(operator_LE, "( ({0}) <= ({1}) )");
106
            this.set(operator_LIKE, "LIKE( ({0}), ({1}) )");
107
            this.set(operator_ILIKE, "ILIKE( ({0}), ({1}) )");
108

    
109
            this.set(operator_add, "{0} + {1}");
110
            this.set(operator_subst, "{0} - {1}");
111
            this.set(operator_mult, "{0} * {1}");
112
            this.set(operator_div, "{0} / {1}");
113
            this.set(operator_concat, "{0} + {1}");
114
        }
115
    }
116
    
117
    public static class JELFunctions {
118
        public static String Find_SRID(Object a, Object b, Object c) {
119
            return null;
120
        }
121
        
122
        public static String ST_SRID(Geometry geom) {
123
            return null;
124
        }
125
        
126
        public static String ST_AsText(Geometry geom) throws GeometryOperationException, GeometryOperationNotSupportedException {
127
            return geom.convertToWKT();
128
        }
129
        
130
        public static byte[] ST_AsBinary(Geometry geom) throws GeometryOperationException, GeometryOperationNotSupportedException {
131
            return geom.convertToWKB();
132
        }
133
        
134
        public static byte[] ST_AsEWKB(Geometry geom) throws GeometryOperationException, GeometryOperationNotSupportedException {
135
            return geom.convertToEWKB();
136
        }
137
        
138
        public static Envelope ST_Envelope(Geometry geom) throws GeometryOperationException, GeometryOperationNotSupportedException {
139
            return geom.getEnvelope();
140
        }            
141
        
142
        public static boolean ST_Contains(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
143
            return geom1.contains(geom2);
144
        }            
145
        
146
        public static boolean ST_Crosses(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
147
            return geom1.crosses(geom2);
148
        }            
149
        
150
        public static boolean ST_Disjoint(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
151
            return geom1.disjoint(geom2);
152
        }            
153
        
154
        public static boolean ST_Overlaps(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
155
            return geom1.overlaps(geom2);
156
        }            
157
        
158
        public static boolean ST_Touches(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
159
            return geom1.touches(geom2);
160
        }            
161
        
162
        public static boolean ST_Within(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
163
            return geom1.within(geom2);
164
        }            
165
        
166
        public static boolean ST_Intersects(Geometry geom1, Geometry geom2) throws GeometryOperationException, GeometryOperationNotSupportedException {
167
            return geom1.intersects(geom2);
168
        }            
169
        
170
        public static boolean ST_Equals(Geometry geom1, Geometry geom2) {
171
            return geom1.equals(geom2);
172
        }            
173
        
174
        public static boolean ST_IsClosed(Geometry geom1) throws GeometryOperationException, GeometryOperationNotSupportedException {
175
            return geom1.isClossed();
176
        }            
177
        
178
        public static Geometry ST_GeomFromText(String geom, IProjection srs) throws GeometryException {
179
            GeometryManager manager = GeometryLocator.getGeometryManager();
180
            return manager.createFrom(geom,srs);
181
        }            
182
        
183
        public static Geometry ST_GeomFromWKB(byte[] geom, IProjection srs) throws GeometryException {
184
            GeometryManager manager = GeometryLocator.getGeometryManager();
185
            return manager.createFrom(geom,srs);
186
        }            
187
        
188
        public static Geometry ST_GeomFromEWKB(byte[] geom, IProjection srs) throws GeometryException {
189
            GeometryManager manager = GeometryLocator.getGeometryManager();
190
            return manager.createFrom(geom,srs);
191
        }            
192
            
193
        public static String LCASE(Object x) {
194
            if( x == null ) {
195
                return null;
196
            }
197
            return x.toString().toLowerCase();
198
        }            
199
            
200
        public static String UCASE(Object x) {
201
            if( x == null ) {
202
                return null;
203
            }
204
            return x.toString().toLowerCase();
205
        }            
206
          
207
        private static final Integer ZERO_OR_MORE_CHARS = 0;
208
        private static final Integer ONE_CHAR = 1;
209

    
210
        public static boolean LIKE(Object x1, Object x2) {
211
            if (x1 == null || x2 == null) {
212
                return false;
213
            }
214
            String source = x1.toString();
215
            String match = x2.toString();
216

    
217
            List<Object> format = new ArrayList<>();
218
            StringBuilder fill = new StringBuilder();
219
            final int plen = match.length();
220
            Character lastSymbol = null;
221
            for (int i = 0; i < plen; i++) {
222
                boolean f = false;
223
                char c = match.charAt(i);
224
                if (lastSymbol == '\\') {
225
                    lastSymbol = null;
226
                    fill.append(c);
227
                } else {
228
                    if (c == '%') {
229
                        if (fill.length() > 0) {
230
                            format.add(fill.toString());
231
                            fill.setLength(0);
232
                        }
233
                        format.add(ZERO_OR_MORE_CHARS);
234
                    } else if (c == '_') {
235
                        if (fill.length() > 0) {
236
                            format.add(fill.toString());
237
                            fill.setLength(0);
238
                        }
239
                        format.add(ONE_CHAR);
240
                    } else {
241
                        fill.append(c);
242
                    }
243
                    lastSymbol = c;
244
                }
245
                if (fill.length() > 0) {
246
                    format.add(fill.toString());
247
                }
248
            }
249

    
250
            StringBuilder repattern = new StringBuilder("^");
251
            for (Object o : format) {
252
                if (o == ZERO_OR_MORE_CHARS) {
253
                    repattern.append(".*?");
254
                } else if (o == ONE_CHAR) {
255
                    repattern.append(".?");
256
                } else {
257
                    repattern.append((String) o);
258
                }
259
            }
260

    
261
            Pattern pattern = Pattern.compile(repattern.toString());
262
            Matcher m = pattern.matcher(source);
263
            return m.find();
264
        }
265
            
266
        public static boolean ILIKE(Object x1, Object x2) {
267
            if (x1 == null || x2 == null) {
268
                return false;
269
            }
270
            x1 = x1.toString().toLowerCase();
271
            x2 = x2.toString().toLowerCase();
272
            return LIKE(x1, x2);
273
        }
274
            
275
    }
276
    
277
    protected class VariableProvider extends DVMap {
278
        private EvaluatorData data;
279

    
280
        public VariableProvider() {
281
        }
282
        
283
        public void setValues(EvaluatorData data) {
284
            this.data = data;
285
        }
286
        
287
        @Override
288
        public String getTypeName(String name) {
289
            Object value = this.data.getDataValue(name);
290
            return value.getClass().getSimpleName();
291
        }
292

    
293
        public double getDoubleProperty(String name) {
294
            Object value = this.data.getDataValue(name);
295
            return (double) value;
296
        }        
297

    
298
        public float getFloatProperty(String name) {
299
            Object value = this.data.getDataValue(name);
300
            return (float) (double) value;
301
        }        
302
        
303
        public int getIntegerProperty(String name) {
304
            Object value = this.data.getDataValue(name);
305
            return (int) (double) value;
306
        }        
307
        
308
        public long getLongProperty(String name) {
309
            Object value = this.data.getDataValue(name);
310
            return (long) (double) value;
311
        }        
312
        
313
        public String getStringProperty(String name) {
314
            Object value = this.data.getDataValue(name);
315
            return (String) value;
316
        }        
317

    
318
        public Date getDateProperty(String name) {
319
            Object value = this.data.getDataValue(name);
320
            return (Date) value;
321
        }        
322
    }
323
    
324
    protected VariableProvider jel_variables = null;
325
    protected Object[] jel_context = null;
326
    protected CompiledExpression jel_expression = null;
327
    protected Config jel_config = new JELConfig();
328
    protected EvaluatorFieldsInfo fieldsInfo = null; // For compatibility 
329
    
330
    public ExpressionEvaluatorBase() {
331
        super();
332
    }
333
    
334
    public void compile() {
335
        jel_variables = new VariableProvider();
336
        gnu.jel.Library lib = new gnu.jel.Library(
337
                new Class[]{ Math.class, JELFunctions.class }, 
338
                new Class[]{ jel_variables.getClass() }, 
339
                new Class[0],
340
                jel_variables,
341
                null
342
        );
343
        jel_context = new Object[] { jel_variables };
344
        Config config = this.config;
345
        try {
346
            this.config = jel_config;
347
            String expr = this.value.toString();
348
            jel_expression = gnu.jel.Evaluator.compile(expr, lib);
349
        } catch (CompilationException ex) {
350
            throw new RuntimeException("Can't compile expression.", ex);
351
        } finally {
352
            this.config = config;
353
        }
354
    }
355
    
356
    public void clear() {
357
        this.set(null);
358
        this.jel_expression = null;
359
    }
360
    
361
    @Override
362
    public Object evaluate(EvaluatorData data) throws EvaluatorException {
363
        try {
364
            if( jel_variables == null ) {
365
                this.compile();
366
            }
367
            jel_variables.setValues(data);
368
            return jel_expression.evaluate(jel_context);
369
        } catch (Throwable th) {
370
            throw new EvaluatorException(
371
                    "Can't evaluate expression", 
372
                    th, 
373
                    "ExpressionEvaluatorBase_evaluate_error", 
374
                    0
375
                );
376
        }
377
    }
378

    
379
    @Override
380
    public String getName() {
381
        return "Generic expression evaluator";
382
    }
383

    
384
    @Override
385
    public String getDescription() {
386
        return "";
387
    }
388

    
389
    @Override
390
    public String getSQL() {
391
        return this.value.toString();
392
    }
393

    
394
    @Override
395
    public EvaluatorFieldsInfo getFieldsInfo() {
396
        if( this.fieldsInfo==null ) {
397
            this.fieldsInfo = new EvaluatorFieldsInfo();
398
            for( Variable var : this.getVariables() ) {
399
                this.fieldsInfo.addFieldValue(var.getName());
400
            }
401
        }
402
        return this.fieldsInfo;
403
    }
404

    
405
    
406
    
407
}