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 / test / java / org / gvsig / expresionevaluator / impl / TestCodeFormatter.java @ 44198

History | View | Annotate | Download (19.1 KB)

1 44006 jjdelcerro
package org.gvsig.expresionevaluator.impl;
2 43128 jjdelcerro
3 44198 jjdelcerro
import java.text.MessageFormat;
4
import static junit.framework.Assert.assertEquals;
5 44006 jjdelcerro
import junit.framework.TestCase;
6 44198 jjdelcerro
import org.apache.commons.lang3.StringUtils;
7 43128 jjdelcerro
import org.cresques.cts.IProjection;
8 44198 jjdelcerro
import org.gvsig.expressionevaluator.Code;
9
import org.gvsig.expressionevaluator.Code.Caller;
10
import org.gvsig.expressionevaluator.Code.Constant;
11
import org.gvsig.expressionevaluator.Codes;
12 44006 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionBuilder;
13 44198 jjdelcerro
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
14
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
15
import org.gvsig.expressionevaluator.ExpressionUtils;
16
import org.gvsig.expressionevaluator.Formatter;
17
import org.gvsig.expressionevaluator.LexicalAnalyzer;
18 43128 jjdelcerro
import org.gvsig.fmap.crs.CRSFactory;
19
import org.gvsig.fmap.geom.Geometry;
20 44198 jjdelcerro
import org.gvsig.fmap.geom.GeometryUtils;
21 43128 jjdelcerro
import org.gvsig.fmap.geom.exception.CreateGeometryException;
22
import org.gvsig.fmap.geom.primitive.Point;
23 44006 jjdelcerro
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
24 43128 jjdelcerro
25 44198 jjdelcerro
public class TestCodeFormatter extends TestCase {
26 44006 jjdelcerro
27 44198 jjdelcerro
    private static class MyFormatter implements Formatter<Code> {
28
29
        private class Formatter_constant_bytearray implements Formatter<Code> {
30
31
            @Override
32
            public boolean canApply(Code code) {
33
                if( code instanceof Constant ) {
34
                    return ((Constant)code).value() instanceof byte[];
35
                }
36
                return false;
37
            }
38
39
            @Override
40
            public String format(Code code) {
41
                return builder.bytearray_x((byte[]) ((Constant)code).value());
42
            }
43
        }
44
45
        private class Formatter_constant_geometry implements Formatter<Code> {
46
47
            @Override
48
            public boolean canApply(Code code) {
49
                if( code instanceof Constant ) {
50
                    return ((Constant)code).value() instanceof Geometry;
51
                }
52
                return false;
53
            }
54
55
            @Override
56
            public String format(Code code) {
57
                Geometry geometry = (Geometry) ((Constant)code).value();
58
                return MessageFormat.format(
59
                        "ST_GeomFromWKB(({0}), ({1}))",
60
                        builder.bytearray_x(GeometryUtils.toWKB(geometry)),
61
                        String.valueOf(builder.srs_id(geometry.getProjection()))
62
                );
63
64
            }
65
        }
66
67
68
        private class Formatter_ST_intersects_H2Spatial implements Formatter<Code> {
69
            // Need for H2Spatial
70
            @Override
71
            public boolean canApply(Code code) {
72
                if( code instanceof Caller ) {
73
                    return StringUtils.equalsIgnoreCase("ST_intersects",((Caller)code).name());
74
                }
75
                return false;
76
            }
77
78
            @Override
79
            public String format(Code code) {
80
                Codes parameters = ((Caller)code).parameters();
81
                String p1 = parameters.get(0).toString(MyFormatter.this);
82
                String p2 = parameters.get(1).toString(MyFormatter.this);
83
                String r = MessageFormat.format(
84
                        "( (({0}) && ({1})) AND ST_Intersects(({0}),({1}) ))",
85
                        p1,
86
                        p2
87
                );
88
                return r;
89
            }
90
        }
91
92
        private class Formatter_ST_intersects_SpatiaLite implements Formatter<Code> {
93
            // Need for SpatiaLite
94
95
            private final String table;
96
            private final String geomcolumn;
97
98
            public Formatter_ST_intersects_SpatiaLite(String table, String geomcolumn) {
99
                this.table = table;
100
                this.geomcolumn = geomcolumn;
101
            }
102
103
            @Override
104
            public boolean canApply(Code code) {
105
                if( code instanceof Caller ) {
106
                    return StringUtils.equalsIgnoreCase("ST_intersects2",((Caller)code).name());
107
                }
108
                return false;
109
            }
110
111
            @Override
112
            public String format(Code code) {
113
                Codes parameters = ((Caller)code).parameters();
114
                String p1 = parameters.get(0).toString(MyFormatter.this);
115
                String p2 = parameters.get(1).toString(MyFormatter.this);
116
                String r = MessageFormat.format(
117
                    "(ST_Intersects({0},{1}) AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = ''{2}'' AND f_geometry_column = ''{3}'' AND search_frame = \"{2}\".\"{3}\"))",
118
                    p1,
119
                    p2,
120
                    table,
121
                    geomcolumn
122
                );
123
                return r;
124
            }
125
        }
126
127
        private class Formatter_DECODE implements Formatter<Code> {
128
            // Need for SpatiaLite
129
            @Override
130
            public boolean canApply(Code code) {
131
                if( code instanceof Caller ) {
132
                    if( StringUtils.equalsIgnoreCase("DECODE",((Caller)code).name()) ) {
133
                        Codes parameters = ((Caller)code).parameters();
134
                        Code code_p1 = parameters.get(0);
135
                        Code code_p2 = parameters.get(1);
136
                        if( code_p1 instanceof Constant && code_p2 instanceof Constant ) {
137
                            Object p1 = ((Constant)code_p1).value();
138
                            Object p2 = ((Constant)code_p2).value();
139
                            if( p1 instanceof String && p1 instanceof String &&
140
                                StringUtils.equalsIgnoreCase((CharSequence) p2,"hex") ) {
141
                                return true;
142
                            }
143
                        }
144
                    }
145
                }
146
                return false;
147
            }
148
149
            @Override
150
            public String format(Code code) {
151
                Codes parameters = ((Caller)code).parameters();
152
                Object p1 = ((Constant)parameters.get(0)).value();
153
                return "x'"+ (String)p1 + "'";
154
            }
155
        }
156
157
        private class Formatter_IFNULL implements Formatter<Code> {
158
            // Need for H2Spatial
159
            @Override
160
            public boolean canApply(Code code) {
161
                if( code instanceof Caller ) {
162
                    return StringUtils.equalsIgnoreCase("IFNULL",((Caller)code).name());
163
                }
164
                return false;
165
            }
166
167
            @Override
168
            public String format(Code code) {
169
                Codes parameters = ((Caller)code).parameters();
170
                String p1 = parameters.get(0).toString(MyFormatter.this);
171
                String p2 = parameters.get(1).toString(MyFormatter.this);
172
                String p3 = parameters.get(2).toString(MyFormatter.this);
173
                String r = MessageFormat.format(
174
                        "NVL2({0}, {1}, {2})",
175
                        p1,
176
                        p3,
177
                        p2
178
                );
179
                return r;
180
            }
181
        }
182
183
        private class Formatter_ILIKE implements Formatter<Code> {
184
            // Need for SpatiaLite
185
            @Override
186
            public boolean canApply(Code code) {
187
                if( code instanceof Caller ) {
188
                    return StringUtils.equalsIgnoreCase("ILIKE",((Caller)code).name());
189
                }
190
                return false;
191
            }
192
193
            @Override
194
            public String format(Code code) {
195
                Codes parameters = ((Caller)code).parameters();
196
                String p1 = parameters.get(0).toString(MyFormatter.this);
197
                String p2 = parameters.get(1).toString(MyFormatter.this);
198
                String r = MessageFormat.format(
199
                        "LOWER({0}) LIKE LOWER({1})",
200
                        p1,
201
                        p2
202
                );
203
                return r;
204
            }
205
        }
206
207
        private class Formatter_NOT_IS_NULL implements Formatter<Code> {
208
            // Need for H2Spatial
209
            @Override
210
            public boolean canApply(Code code) {
211
                if( code instanceof Caller ) {
212
                    return StringUtils.equalsIgnoreCase("NOT_IS_NULL",((Caller)code).name());
213
                }
214
                return false;
215
            }
216
217
            @Override
218
            public String format(Code code) {
219
                Codes parameters = ((Caller)code).parameters();
220
                String p1 = parameters.get(0).toString(MyFormatter.this);
221
                String r = MessageFormat.format(
222
                        "( ({0}) IS NOT NULL )",
223
                        p1
224
                );
225
                return r;
226
            }
227
        }
228
229
        private final Formatter<Code>[] formatters;
230
        private final ExpressionBuilder builder;
231
232
        public MyFormatter() {
233
            this.builder = ExpressionUtils.createExpressionBuilder();
234
            this.formatters = new Formatter[] {
235
//                new Formatter_constant_bytearray(),
236
//                new Formatter_constant_geometry(),
237
                new Formatter_IFNULL(),
238
                new Formatter_NOT_IS_NULL(),
239
                new Formatter_ST_intersects_H2Spatial(),
240
                new Formatter_ST_intersects_SpatiaLite("mytable", "the_geom"),
241
                new Formatter_ILIKE(),
242
                new Formatter_DECODE(),
243
            };
244
        }
245
246
        @Override
247
        public boolean canApply(Code code) {
248
            for (Formatter<Code> formatter : formatters) {
249
                if( formatter.canApply(code) ) {
250
                    return true;
251
                }
252
            }
253
            return false;
254
        }
255
256
        @Override
257
        public String format(Code code) {
258
            for (Formatter<Code> formatter : formatters) {
259
                if( formatter.canApply(code) ) {
260
                    return formatter.format(code);
261
                }
262
            }
263
            return code.toString(this);
264
        }
265
266
    }
267
268
    public TestCodeFormatter(String testName) {
269 44006 jjdelcerro
        super(testName);
270
    }
271
272 43128 jjdelcerro
    @Override
273 44006 jjdelcerro
    protected void setUp() throws Exception {
274
        super.setUp();
275
        new DefaultLibrariesInitializer().fullInitialize();
276
    }
277 43128 jjdelcerro
278 44006 jjdelcerro
    @Override
279
    protected void tearDown() throws Exception {
280
        super.tearDown();
281 43128 jjdelcerro
    }
282 44006 jjdelcerro
283
    // TODO add test methods here. The name must begin with 'test'. For example:
284
    // public void testHello() {}
285 43128 jjdelcerro
286 44198 jjdelcerro
    protected LexicalAnalyzer createLexicalAnalyzer() {
287
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
288
        LexicalAnalyzer lexer = manager.createLexicalAnalyzer();
289
        return lexer;
290 43128 jjdelcerro
    }
291 44198 jjdelcerro
292
    protected org.gvsig.expressionevaluator.Compiler createCompiler() {
293
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
294
        org.gvsig.expressionevaluator.Compiler compiler = manager.createCompiler();
295
        compiler.setLexicalAnalyzer(createLexicalAnalyzer());
296
        return compiler;
297
    }
298 43128 jjdelcerro
299 44198 jjdelcerro
    private Formatter<Code> formatter() {
300
        return new MyFormatter();
301 43128 jjdelcerro
    }
302 44198 jjdelcerro
303
    public Code compileExpression(String source) {
304
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
305
        Code code = compiler.compileExpression(source);
306
        return code;
307
    }
308 43128 jjdelcerro
309 44198 jjdelcerro
    public void testIdentifier1() {
310
        String source = "precio";
311
312
        Code code = compileExpression(source);
313
        assertEquals("\"precio\"", code.toString(formatter()));
314
    }
315
316
    public void testIdentifier2() {
317
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
318
        compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(true);
319
320
        String source = "[precio]";
321
322
        Code code = compiler.compileExpression(source);
323
        assertEquals("\"precio\"", code.toString(formatter()));
324
    }
325
326
    public void testIdentifier3() {
327
        String source = "\"precio\"";
328
329
        Code code = compileExpression(source);
330
        assertEquals("\"precio\"", code.toString(formatter()));
331
    }
332
333
334
    public void testTrue() {
335
        String source = "true";
336
337
        Code code = compileExpression(source);
338
        assertEquals("TRUE", code.toString(formatter()));
339
    }
340
341
    public void testFalse() {
342
        String source = "false";
343
344
        Code code = compileExpression(source);
345
        assertEquals("FALSE", code.toString(formatter()));
346
    }
347
348
    public void testNull() {
349
        String source = "null";
350
351
        Code code = compileExpression(source);
352
        assertEquals("NULL", code.toString(formatter()));
353
    }
354
355
    public void testNotTrue() {
356
        String source = "not true";
357
358
        Code code = compileExpression(source);
359
        assertEquals("NOT(TRUE)", code.toString(formatter()));
360
    }
361
362
    public void testInteger() {
363
        String source = "23";
364
365
        Code code = compileExpression(source);
366
        assertEquals("23", code.toString(formatter()));
367
    }
368
369
    public void operator(String operatorName) {
370
        String source = "precio " + operatorName + " 23";
371
372
        Code code = compileExpression(source);
373
        assertEquals("(\"precio\" "+ operatorName + " 23)", code.toString(formatter()));
374
    }
375
376
    public void testOperators() {
377
378
        operator("=");
379
        operator("<>");
380
        operator(">");
381
        operator(">=");
382
        operator("<");
383
        operator("<=");
384
        operator("LIKE");
385
//        operator("ILIKE");
386
        operator("||");
387
        operator("+");
388
        operator("-");
389
        operator("*");
390
        operator("OR");
391
        operator("AND");
392
        operator("%");
393
        operator("IS");
394
395
        operator("~");
396
    }
397
398
    public void testILike() {
399
        String source = "precio ILike 23";
400
401
        Code code = compileExpression(source);
402
        assertEquals("LOWER(\"precio\") LIKE LOWER(23)", code.toString(formatter()));
403
    }
404
405
    public void testAddMul() {
406
        String source = "precio + 10 * 2 + 20 + 30";
407
408
        Code code = compileExpression(source);
409
        assertEquals("(((\"precio\" + (10 * 2)) + 20) + 30)", code.toString(formatter()));
410
    }
411
412
    public void testAddMulPar() {
413
        String source = "(precio + 10) * 2 + 20 + 30";
414
415
        Code code = compileExpression(source);
416
        assertEquals("((((\"precio\" + 10) * 2) + 20) + 30)", code.toString(formatter()));
417
    }
418
419
    public void testAbs() {
420
        String source = "precio + abs(10)";
421
422
        Code code = compileExpression(source);
423
        assertEquals("(\"precio\" + abs(10))", code.toString(formatter()));
424
    }
425
426
    public void testAbs2() {
427
        String source = "precio + abs(-10)";
428
429
        Code code = compileExpression(source);
430
        assertEquals("(\"precio\" + abs(-(10)))", code.toString(formatter()));
431
    }
432
433
    public void testPI() {
434
        String source = "precio + PI()";
435
436
        Code code = compileExpression(source);
437
        assertEquals("(\"precio\" + PI())", code.toString(formatter()));
438
    }
439
440
    public void testCeil() {
441
        String source = "precio + CEIL(PI())";
442
443
        Code code = compileExpression(source);
444
        assertEquals("(\"precio\" + CEIL(PI()))", code.toString(formatter()));
445
    }
446
447
    public void testGetitem1() {
448
        String source = "LIST('uno','dos','tres')[1]" ;
449
450
        Code code = compileExpression(source);
451
        assertEquals("GETITEM(LIST('uno', 'dos', 'tres'), 1)", code.toString(formatter()));
452
    }
453
454
    public void testConcat() {
455
        String source = "CONCAT(precio,' euros')";
456
457
        Code code = compileExpression(source);
458
        assertEquals("CONCAT(\"precio\", ' euros')", code.toString(formatter()));
459
    }
460
461
    public void test1() {
462
        String source = "NOMBRE03 = 'Torre d''En Besora (la)'";
463
464
        Code code = compileExpression(source);
465
        assertEquals("(\"NOMBRE03\" = 'Torre d''En Besora (la)')", code.toString(formatter()));
466
    }
467
468 43128 jjdelcerro
    public void test2() {
469 44198 jjdelcerro
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
470
        compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(true);
471
472
        String source = "[1990] = 0.168873933773767";
473
474
        Code code = compiler.compileExpression(source);
475
        assertEquals("(\"1990\" = 0.168873933773767)", code.toString(formatter()));
476 43128 jjdelcerro
    }
477 44198 jjdelcerro
478
    public void test2fields() {
479
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
480
        compiler.getLexicalAnalyzer().setUseBracketsForIdentifiers(true);
481
482
        String source = "[1990] = [precio]";
483
484
        Code code = compiler.compileExpression(source);
485
        assertEquals("(\"1990\" = \"precio\")", code.toString(formatter()));
486
    }
487 43128 jjdelcerro
488 44198 jjdelcerro
489
    public void testInvokeFunction1() {
490
        String source = "ST_Area(GEOMETRY)";
491
492
        Code code = compileExpression(source);
493
        assertEquals("ST_Area(\"GEOMETRY\")", code.toString(formatter()));
494
    }
495
496 43128 jjdelcerro
    public void test3() throws CreateGeometryException {
497 44198 jjdelcerro
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
498
499 43128 jjdelcerro
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
500 44198 jjdelcerro
        Point point = GeometryUtils.createPoint(10, 20);
501
502 43128 jjdelcerro
        builder.set(
503
            builder.ST_Intersects(
504
              builder.geometry(point,proj),
505
              builder.variable("the_geom")
506
            )
507
        );
508 44198 jjdelcerro
        Code code = compileExpression(builder.toString());
509 43128 jjdelcerro
        assertEquals(
510 44198 jjdelcerro
                "ST_Intersects(ST_GeomFromWKB(DECODE('000000000140240000000000004034000000000000', 'hex'), 4326), \"the_geom\")",
511
                code.toString()
512 43128 jjdelcerro
        );
513
        assertEquals(
514 44198 jjdelcerro
                "( ((ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326)) && (\"the_geom\")) AND ST_Intersects((ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326)),(\"the_geom\") ))",
515
                code.toString(formatter())
516 43128 jjdelcerro
        );
517
    }
518
519
    public void test4() throws CreateGeometryException {
520 44198 jjdelcerro
        ExpressionBuilder builder = ExpressionUtils.createExpressionBuilder();
521
522 43128 jjdelcerro
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
523 44198 jjdelcerro
        Point point = GeometryUtils.createPoint(10, 20);
524
525
        builder.set(
526
            builder.function("ST_Intersects2",
527
                builder.geometry(point,proj),
528
                builder.variable("the_geom")
529
            )
530 43128 jjdelcerro
        );
531 44198 jjdelcerro
        Code code = compileExpression(builder.toString());
532 43128 jjdelcerro
        assertEquals(
533 44198 jjdelcerro
                "ST_Intersects2(ST_GeomFromWKB(DECODE('000000000140240000000000004034000000000000', 'hex'), 4326), \"the_geom\")",
534
                code.toString()
535 43128 jjdelcerro
        );
536
        assertEquals(
537 44198 jjdelcerro
                "(ST_Intersects(ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326),\"the_geom\") AND ROWID IN ( SELECT ROWID FROM SpatialIndex WHERE f_table_name = 'mytable' AND f_geometry_column = 'the_geom' AND search_frame = \"mytable\".\"the_geom\"))",
538
                code.toString(formatter())
539 43128 jjdelcerro
        );
540
    }
541 44198 jjdelcerro
542 43128 jjdelcerro
}