Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.geometry / org.gvsig.expressionevaluator.geometry.lib / org.gvsig.expressionevaluator.geometry.lib.impl / src / test / java / org / gvsig / expresionevaluator / impl / TestCodeFormatter.java @ 44644

History | View | Annotate | Download (13.5 KB)

1 44006 jjdelcerro
package org.gvsig.expresionevaluator.impl;
2 43128 jjdelcerro
3 44198 jjdelcerro
import java.text.MessageFormat;
4 44006 jjdelcerro
import junit.framework.TestCase;
5 44198 jjdelcerro
import org.apache.commons.lang3.StringUtils;
6 43128 jjdelcerro
import org.cresques.cts.IProjection;
7 44198 jjdelcerro
import org.gvsig.expressionevaluator.Code;
8
import org.gvsig.expressionevaluator.Code.Caller;
9
import org.gvsig.expressionevaluator.Code.Constant;
10
import org.gvsig.expressionevaluator.Codes;
11
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator;
12
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager;
13
import org.gvsig.expressionevaluator.Formatter;
14 44644 jjdelcerro
import org.gvsig.expressionevaluator.GeometryExpressionBuilder;
15
import org.gvsig.expressionevaluator.GeometryExpressionUtils;
16 44198 jjdelcerro
import org.gvsig.expressionevaluator.LexicalAnalyzer;
17 43128 jjdelcerro
import org.gvsig.fmap.crs.CRSFactory;
18
import org.gvsig.fmap.geom.Geometry;
19 44198 jjdelcerro
import org.gvsig.fmap.geom.GeometryUtils;
20 43128 jjdelcerro
import org.gvsig.fmap.geom.exception.CreateGeometryException;
21
import org.gvsig.fmap.geom.primitive.Point;
22 44006 jjdelcerro
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
23 43128 jjdelcerro
24 44198 jjdelcerro
public class TestCodeFormatter extends TestCase {
25 44006 jjdelcerro
26 44198 jjdelcerro
    private static class MyFormatter implements Formatter<Code> {
27
28
        private class Formatter_constant_bytearray implements Formatter<Code> {
29
30
            @Override
31
            public boolean canApply(Code code) {
32
                if( code instanceof Constant ) {
33
                    return ((Constant)code).value() instanceof byte[];
34
                }
35
                return false;
36
            }
37
38
            @Override
39
            public String format(Code code) {
40
                return builder.bytearray_x((byte[]) ((Constant)code).value());
41
            }
42
        }
43
44
        private class Formatter_constant_geometry implements Formatter<Code> {
45
46
            @Override
47
            public boolean canApply(Code code) {
48
                if( code instanceof Constant ) {
49
                    return ((Constant)code).value() instanceof Geometry;
50
                }
51
                return false;
52
            }
53
54
            @Override
55
            public String format(Code code) {
56
                Geometry geometry = (Geometry) ((Constant)code).value();
57
                return MessageFormat.format(
58
                        "ST_GeomFromWKB(({0}), ({1}))",
59
                        builder.bytearray_x(GeometryUtils.toWKB(geometry)),
60
                        String.valueOf(builder.srs_id(geometry.getProjection()))
61
                );
62
63
            }
64
        }
65
66
67
        private class Formatter_ST_intersects_H2Spatial implements Formatter<Code> {
68
            // Need for H2Spatial
69
            @Override
70
            public boolean canApply(Code code) {
71
                if( code instanceof Caller ) {
72
                    return StringUtils.equalsIgnoreCase("ST_intersects",((Caller)code).name());
73
                }
74
                return false;
75
            }
76
77
            @Override
78
            public String format(Code code) {
79
                Codes parameters = ((Caller)code).parameters();
80
                String p1 = parameters.get(0).toString(MyFormatter.this);
81
                String p2 = parameters.get(1).toString(MyFormatter.this);
82
                String r = MessageFormat.format(
83
                        "( (({0}) && ({1})) AND ST_Intersects(({0}),({1}) ))",
84
                        p1,
85
                        p2
86
                );
87
                return r;
88
            }
89
        }
90
91
        private class Formatter_ST_intersects_SpatiaLite implements Formatter<Code> {
92
            // Need for SpatiaLite
93
94
            private final String table;
95
            private final String geomcolumn;
96
97
            public Formatter_ST_intersects_SpatiaLite(String table, String geomcolumn) {
98
                this.table = table;
99
                this.geomcolumn = geomcolumn;
100
            }
101
102
            @Override
103
            public boolean canApply(Code code) {
104
                if( code instanceof Caller ) {
105
                    return StringUtils.equalsIgnoreCase("ST_intersects2",((Caller)code).name());
106
                }
107
                return false;
108
            }
109
110
            @Override
111
            public String format(Code code) {
112
                Codes parameters = ((Caller)code).parameters();
113
                String p1 = parameters.get(0).toString(MyFormatter.this);
114
                String p2 = parameters.get(1).toString(MyFormatter.this);
115
                String r = MessageFormat.format(
116
                    "(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}\"))",
117
                    p1,
118
                    p2,
119
                    table,
120
                    geomcolumn
121
                );
122
                return r;
123
            }
124
        }
125
126
        private class Formatter_DECODE implements Formatter<Code> {
127
            // Need for SpatiaLite
128
            @Override
129
            public boolean canApply(Code code) {
130
                if( code instanceof Caller ) {
131
                    if( StringUtils.equalsIgnoreCase("DECODE",((Caller)code).name()) ) {
132
                        Codes parameters = ((Caller)code).parameters();
133
                        Code code_p1 = parameters.get(0);
134
                        Code code_p2 = parameters.get(1);
135
                        if( code_p1 instanceof Constant && code_p2 instanceof Constant ) {
136
                            Object p1 = ((Constant)code_p1).value();
137
                            Object p2 = ((Constant)code_p2).value();
138
                            if( p1 instanceof String && p1 instanceof String &&
139
                                StringUtils.equalsIgnoreCase((CharSequence) p2,"hex") ) {
140
                                return true;
141
                            }
142
                        }
143
                    }
144
                }
145
                return false;
146
            }
147
148
            @Override
149
            public String format(Code code) {
150
                Codes parameters = ((Caller)code).parameters();
151
                Object p1 = ((Constant)parameters.get(0)).value();
152
                return "x'"+ (String)p1 + "'";
153
            }
154
        }
155
156
        private class Formatter_IFNULL implements Formatter<Code> {
157
            // Need for H2Spatial
158
            @Override
159
            public boolean canApply(Code code) {
160
                if( code instanceof Caller ) {
161
                    return StringUtils.equalsIgnoreCase("IFNULL",((Caller)code).name());
162
                }
163
                return false;
164
            }
165
166
            @Override
167
            public String format(Code code) {
168
                Codes parameters = ((Caller)code).parameters();
169
                String p1 = parameters.get(0).toString(MyFormatter.this);
170
                String p2 = parameters.get(1).toString(MyFormatter.this);
171
                String p3 = parameters.get(2).toString(MyFormatter.this);
172
                String r = MessageFormat.format(
173
                        "NVL2({0}, {1}, {2})",
174
                        p1,
175
                        p3,
176
                        p2
177
                );
178
                return r;
179
            }
180
        }
181
182
        private class Formatter_ILIKE implements Formatter<Code> {
183
            // Need for SpatiaLite
184
            @Override
185
            public boolean canApply(Code code) {
186
                if( code instanceof Caller ) {
187
                    return StringUtils.equalsIgnoreCase("ILIKE",((Caller)code).name());
188
                }
189
                return false;
190
            }
191
192
            @Override
193
            public String format(Code code) {
194
                Codes parameters = ((Caller)code).parameters();
195
                String p1 = parameters.get(0).toString(MyFormatter.this);
196
                String p2 = parameters.get(1).toString(MyFormatter.this);
197
                String r = MessageFormat.format(
198
                        "LOWER({0}) LIKE LOWER({1})",
199
                        p1,
200
                        p2
201
                );
202
                return r;
203
            }
204
        }
205
206
        private class Formatter_NOT_IS_NULL implements Formatter<Code> {
207
            // Need for H2Spatial
208
            @Override
209
            public boolean canApply(Code code) {
210
                if( code instanceof Caller ) {
211
                    return StringUtils.equalsIgnoreCase("NOT_IS_NULL",((Caller)code).name());
212
                }
213
                return false;
214
            }
215
216
            @Override
217
            public String format(Code code) {
218
                Codes parameters = ((Caller)code).parameters();
219
                String p1 = parameters.get(0).toString(MyFormatter.this);
220
                String r = MessageFormat.format(
221
                        "( ({0}) IS NOT NULL )",
222
                        p1
223
                );
224
                return r;
225
            }
226
        }
227
228
        private final Formatter<Code>[] formatters;
229 44644 jjdelcerro
        private final GeometryExpressionBuilder builder;
230 44198 jjdelcerro
231
        public MyFormatter() {
232 44644 jjdelcerro
            this.builder = GeometryExpressionUtils.createExpressionBuilder();
233 44198 jjdelcerro
            this.formatters = new Formatter[] {
234
//                new Formatter_constant_bytearray(),
235
//                new Formatter_constant_geometry(),
236
                new Formatter_IFNULL(),
237
                new Formatter_NOT_IS_NULL(),
238
                new Formatter_ST_intersects_H2Spatial(),
239
                new Formatter_ST_intersects_SpatiaLite("mytable", "the_geom"),
240
                new Formatter_ILIKE(),
241
                new Formatter_DECODE(),
242
            };
243
        }
244
245
        @Override
246
        public boolean canApply(Code code) {
247
            for (Formatter<Code> formatter : formatters) {
248
                if( formatter.canApply(code) ) {
249
                    return true;
250
                }
251
            }
252
            return false;
253
        }
254
255
        @Override
256
        public String format(Code code) {
257
            for (Formatter<Code> formatter : formatters) {
258
                if( formatter.canApply(code) ) {
259
                    return formatter.format(code);
260
                }
261
            }
262
            return code.toString(this);
263
        }
264
265
    }
266
267
    public TestCodeFormatter(String testName) {
268 44006 jjdelcerro
        super(testName);
269
    }
270
271 43128 jjdelcerro
    @Override
272 44006 jjdelcerro
    protected void setUp() throws Exception {
273
        super.setUp();
274
        new DefaultLibrariesInitializer().fullInitialize();
275
    }
276 43128 jjdelcerro
277 44006 jjdelcerro
    @Override
278
    protected void tearDown() throws Exception {
279
        super.tearDown();
280 43128 jjdelcerro
    }
281 44006 jjdelcerro
282
    // TODO add test methods here. The name must begin with 'test'. For example:
283
    // public void testHello() {}
284 43128 jjdelcerro
285 44198 jjdelcerro
    protected LexicalAnalyzer createLexicalAnalyzer() {
286
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
287
        LexicalAnalyzer lexer = manager.createLexicalAnalyzer();
288
        return lexer;
289 43128 jjdelcerro
    }
290 44198 jjdelcerro
291
    protected org.gvsig.expressionevaluator.Compiler createCompiler() {
292
        ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager();
293
        org.gvsig.expressionevaluator.Compiler compiler = manager.createCompiler();
294
        compiler.setLexicalAnalyzer(createLexicalAnalyzer());
295
        return compiler;
296
    }
297 43128 jjdelcerro
298 44198 jjdelcerro
    private Formatter<Code> formatter() {
299
        return new MyFormatter();
300 43128 jjdelcerro
    }
301 44198 jjdelcerro
302
    public Code compileExpression(String source) {
303
        org.gvsig.expressionevaluator.Compiler compiler = createCompiler();
304
        Code code = compiler.compileExpression(source);
305
        return code;
306
    }
307
308 43128 jjdelcerro
    public void test3() throws CreateGeometryException {
309 44644 jjdelcerro
        GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder();
310 44198 jjdelcerro
311 43128 jjdelcerro
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
312 44198 jjdelcerro
        Point point = GeometryUtils.createPoint(10, 20);
313
314 43128 jjdelcerro
        builder.set(
315
            builder.ST_Intersects(
316
              builder.geometry(point,proj),
317
              builder.variable("the_geom")
318
            )
319
        );
320 44198 jjdelcerro
        Code code = compileExpression(builder.toString());
321 43128 jjdelcerro
        assertEquals(
322 44198 jjdelcerro
                "ST_Intersects(ST_GeomFromWKB(DECODE('000000000140240000000000004034000000000000', 'hex'), 4326), \"the_geom\")",
323
                code.toString()
324 43128 jjdelcerro
        );
325
        assertEquals(
326 44198 jjdelcerro
                "( ((ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326)) && (\"the_geom\")) AND ST_Intersects((ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326)),(\"the_geom\") ))",
327
                code.toString(formatter())
328 43128 jjdelcerro
        );
329
    }
330
331
    public void test4() throws CreateGeometryException {
332 44644 jjdelcerro
        GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder();
333 44198 jjdelcerro
334 43128 jjdelcerro
        IProjection proj = CRSFactory.getCRS("EPSG:4326");
335 44198 jjdelcerro
        Point point = GeometryUtils.createPoint(10, 20);
336
337
        builder.set(
338
            builder.function("ST_Intersects2",
339
                builder.geometry(point,proj),
340
                builder.variable("the_geom")
341
            )
342 43128 jjdelcerro
        );
343 44198 jjdelcerro
        Code code = compileExpression(builder.toString());
344 43128 jjdelcerro
        assertEquals(
345 44198 jjdelcerro
                "ST_Intersects2(ST_GeomFromWKB(DECODE('000000000140240000000000004034000000000000', 'hex'), 4326), \"the_geom\")",
346
                code.toString()
347 43128 jjdelcerro
        );
348
        assertEquals(
349 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\"))",
350
                code.toString(formatter())
351 43128 jjdelcerro
        );
352
    }
353 44198 jjdelcerro
354 43128 jjdelcerro
}