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 | } |