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 @ 44752
History | View | Annotate | Download (13.5 KB)
1 |
package org.gvsig.expresionevaluator.impl; |
---|---|
2 |
|
3 |
import java.text.MessageFormat; |
4 |
import junit.framework.TestCase; |
5 |
import org.apache.commons.lang3.StringUtils; |
6 |
import org.cresques.cts.IProjection; |
7 |
import org.gvsig.expressionevaluator.Code; |
8 |
import org.gvsig.expressionevaluator.Code.Constant; |
9 |
import org.gvsig.expressionevaluator.Codes; |
10 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorLocator; |
11 |
import org.gvsig.expressionevaluator.ExpressionEvaluatorManager; |
12 |
import org.gvsig.expressionevaluator.Formatter; |
13 |
import org.gvsig.expressionevaluator.GeometryExpressionBuilder; |
14 |
import org.gvsig.expressionevaluator.GeometryExpressionUtils; |
15 |
import org.gvsig.expressionevaluator.LexicalAnalyzer; |
16 |
import org.gvsig.fmap.crs.CRSFactory; |
17 |
import org.gvsig.fmap.geom.Geometry; |
18 |
import org.gvsig.fmap.geom.GeometryUtils; |
19 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
20 |
import org.gvsig.fmap.geom.primitive.Point; |
21 |
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer; |
22 |
import org.gvsig.expressionevaluator.Code.Callable; |
23 |
|
24 |
public class TestCodeFormatter extends TestCase { |
25 |
|
26 |
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 Callable ) { |
72 |
return StringUtils.equalsIgnoreCase("ST_intersects",((Callable)code).name()); |
73 |
} |
74 |
return false; |
75 |
} |
76 |
|
77 |
@Override
|
78 |
public String format(Code code) { |
79 |
Codes parameters = ((Callable)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 Callable ) { |
105 |
return StringUtils.equalsIgnoreCase("ST_intersects2",((Callable)code).name()); |
106 |
} |
107 |
return false; |
108 |
} |
109 |
|
110 |
@Override
|
111 |
public String format(Code code) { |
112 |
Codes parameters = ((Callable)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 Callable ) { |
131 |
if( StringUtils.equalsIgnoreCase("DECODE",((Callable)code).name()) ) { |
132 |
Codes parameters = ((Callable)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 = ((Callable)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 Callable ) { |
161 |
return StringUtils.equalsIgnoreCase("IFNULL",((Callable)code).name()); |
162 |
} |
163 |
return false; |
164 |
} |
165 |
|
166 |
@Override
|
167 |
public String format(Code code) { |
168 |
Codes parameters = ((Callable)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 Callable ) { |
187 |
return StringUtils.equalsIgnoreCase("ILIKE",((Callable)code).name()); |
188 |
} |
189 |
return false; |
190 |
} |
191 |
|
192 |
@Override
|
193 |
public String format(Code code) { |
194 |
Codes parameters = ((Callable)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 Callable ) { |
211 |
return StringUtils.equalsIgnoreCase("NOT_IS_NULL",((Callable)code).name()); |
212 |
} |
213 |
return false; |
214 |
} |
215 |
|
216 |
@Override
|
217 |
public String format(Code code) { |
218 |
Codes parameters = ((Callable)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 |
private final GeometryExpressionBuilder builder; |
230 |
|
231 |
public MyFormatter() {
|
232 |
this.builder = GeometryExpressionUtils.createExpressionBuilder();
|
233 |
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 |
super(testName);
|
269 |
} |
270 |
|
271 |
@Override
|
272 |
protected void setUp() throws Exception { |
273 |
super.setUp();
|
274 |
new DefaultLibrariesInitializer().fullInitialize();
|
275 |
} |
276 |
|
277 |
@Override
|
278 |
protected void tearDown() throws Exception { |
279 |
super.tearDown();
|
280 |
} |
281 |
|
282 |
// TODO add test methods here. The name must begin with 'test'. For example:
|
283 |
// public void testHello() {}
|
284 |
|
285 |
protected LexicalAnalyzer createLexicalAnalyzer() {
|
286 |
ExpressionEvaluatorManager manager = ExpressionEvaluatorLocator.getManager(); |
287 |
LexicalAnalyzer lexer = manager.createLexicalAnalyzer(); |
288 |
return lexer;
|
289 |
} |
290 |
|
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 |
|
298 |
private Formatter<Code> formatter() { |
299 |
return new MyFormatter(); |
300 |
} |
301 |
|
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 |
public void test3() throws CreateGeometryException { |
309 |
GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder(); |
310 |
|
311 |
IProjection proj = CRSFactory.getCRS("EPSG:4326");
|
312 |
Point point = GeometryUtils.createPoint(10, 20); |
313 |
|
314 |
builder.set( |
315 |
builder.ST_Intersects( |
316 |
builder.geometry(point,proj), |
317 |
builder.variable("the_geom")
|
318 |
) |
319 |
); |
320 |
Code code = compileExpression(builder.toString()); |
321 |
assertEquals( |
322 |
"ST_Intersects(ST_GeomFromWKB(DECODE('000000000140240000000000004034000000000000', 'hex'), 4326), \"the_geom\")",
|
323 |
code.toString() |
324 |
); |
325 |
assertEquals( |
326 |
"( ((ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326)) && (\"the_geom\")) AND ST_Intersects((ST_GeomFromWKB(x'000000000140240000000000004034000000000000', 4326)),(\"the_geom\") ))",
|
327 |
code.toString(formatter()) |
328 |
); |
329 |
} |
330 |
|
331 |
public void test4() throws CreateGeometryException { |
332 |
GeometryExpressionBuilder builder = GeometryExpressionUtils.createExpressionBuilder(); |
333 |
|
334 |
IProjection proj = CRSFactory.getCRS("EPSG:4326");
|
335 |
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 |
); |
343 |
Code code = compileExpression(builder.toString()); |
344 |
assertEquals( |
345 |
"ST_Intersects2(ST_GeomFromWKB(DECODE('000000000140240000000000004034000000000000', 'hex'), 4326), \"the_geom\")",
|
346 |
code.toString() |
347 |
); |
348 |
assertEquals( |
349 |
"(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 |
); |
352 |
} |
353 |
|
354 |
} |