svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.expressionevaluator / org.gvsig.expressionevaluator.lib / org.gvsig.expressionevaluator.lib.impl / src / main / java / org / gvsig / expressionevaluator / impl / DefaultCodeBuilder.java @ 44052
History | View | Annotate | Download (10.8 KB)
1 | 43512 | jjdelcerro | package org.gvsig.expressionevaluator.impl; |
---|---|---|---|
2 | |||
3 | import java.util.ArrayList; |
||
4 | import java.util.Iterator; |
||
5 | import java.util.List; |
||
6 | 43519 | jjdelcerro | import org.apache.commons.lang3.StringUtils; |
7 | 43512 | jjdelcerro | import org.gvsig.expressionevaluator.Code; |
8 | import static org.gvsig.expressionevaluator.Code.CALLER; |
||
9 | import static org.gvsig.expressionevaluator.Code.CONSTANT; |
||
10 | 44006 | jjdelcerro | import static org.gvsig.expressionevaluator.Code.IDENTIFIER; |
11 | import static org.gvsig.expressionevaluator.Code.UNDEFINED; |
||
12 | 43512 | jjdelcerro | import org.gvsig.expressionevaluator.Code.Caller; |
13 | import org.gvsig.expressionevaluator.Code.Caller.Arguments; |
||
14 | import org.gvsig.expressionevaluator.Code.Constant; |
||
15 | import org.gvsig.expressionevaluator.Code.Identifier; |
||
16 | 43939 | jjdelcerro | import org.gvsig.expressionevaluator.Code.Method; |
17 | 43512 | jjdelcerro | import org.gvsig.expressionevaluator.CodeBuilder; |
18 | import org.gvsig.expressionevaluator.Function; |
||
19 | 43521 | jjdelcerro | import org.gvsig.expressionevaluator.Interpreter; |
20 | 44009 | jjdelcerro | import org.gvsig.fmap.geom.Geometry; |
21 | 43512 | jjdelcerro | import org.gvsig.tools.exception.BaseException; |
22 | import org.gvsig.tools.visitor.Visitor; |
||
23 | |||
24 | 44009 | jjdelcerro | @SuppressWarnings("UseSpecificCatch") |
25 | public class DefaultCodeBuilder implements CodeBuilder { |
||
26 | 43512 | jjdelcerro | |
27 | public class BaseCode implements Code { |
||
28 | |||
29 | @Override
|
||
30 | public int code() { |
||
31 | return UNDEFINED;
|
||
32 | } |
||
33 | |||
34 | @Override
|
||
35 | public void accept(Visitor visitor) throws BaseException { |
||
36 | visitor.visit(this);
|
||
37 | } |
||
38 | |||
39 | } |
||
40 | |||
41 | class BaseConstant extends BaseCode implements Constant { |
||
42 | |||
43 | private final Object value; |
||
44 | |||
45 | public BaseConstant(Object value) { |
||
46 | this.value = value;
|
||
47 | } |
||
48 | |||
49 | @Override
|
||
50 | public int code() { |
||
51 | return CONSTANT;
|
||
52 | } |
||
53 | |||
54 | @Override
|
||
55 | public Object value() { |
||
56 | return this.value; |
||
57 | } |
||
58 | |||
59 | 43521 | jjdelcerro | @Override
|
60 | public String toString() { |
||
61 | StringBuilder builder = new StringBuilder(); |
||
62 | Object v = this.value(); |
||
63 | if( v instanceof CharSequence ) { |
||
64 | v = StringUtils.wrap(v.toString(), "'");
|
||
65 | 44009 | jjdelcerro | builder.append(v); |
66 | |||
67 | } else if( v instanceof Geometry ) { |
||
68 | try {
|
||
69 | builder.append("'");
|
||
70 | builder.append(((Geometry) v).convertToWKT()); |
||
71 | builder.append("'::geometry");
|
||
72 | } catch (Exception ex) { |
||
73 | builder.append("'UNKNOW'::geometry");
|
||
74 | } |
||
75 | |||
76 | } else {
|
||
77 | builder.append(v); |
||
78 | 43521 | jjdelcerro | } |
79 | return builder.toString();
|
||
80 | } |
||
81 | |||
82 | 43512 | jjdelcerro | } |
83 | |||
84 | public class BaseIdentifier extends BaseCode implements Identifier { |
||
85 | |||
86 | String name;
|
||
87 | |||
88 | public BaseIdentifier(String name) { |
||
89 | this.name = name;
|
||
90 | } |
||
91 | |||
92 | @Override
|
||
93 | public int code() { |
||
94 | return IDENTIFIER;
|
||
95 | } |
||
96 | |||
97 | @Override
|
||
98 | public String name() { |
||
99 | return this.name; |
||
100 | } |
||
101 | |||
102 | 43521 | jjdelcerro | @Override
|
103 | public String toString() { |
||
104 | StringBuilder builder = new StringBuilder(); |
||
105 | 44006 | jjdelcerro | builder.append("\"");
|
106 | 43521 | jjdelcerro | builder.append(this.name());
|
107 | 44006 | jjdelcerro | builder.append("\"");
|
108 | 43521 | jjdelcerro | return builder.toString();
|
109 | } |
||
110 | |||
111 | 43512 | jjdelcerro | } |
112 | |||
113 | public class BaseArguments implements Arguments { |
||
114 | |||
115 | private final List<Code> args; |
||
116 | |||
117 | public BaseArguments() {
|
||
118 | this.args = new ArrayList<>(); |
||
119 | } |
||
120 | |||
121 | @Override
|
||
122 | public int count() { |
||
123 | if( args == null ) { |
||
124 | return 0; |
||
125 | } |
||
126 | return this.args.size(); |
||
127 | } |
||
128 | |||
129 | public void add(Code arg) { |
||
130 | this.args.add(arg);
|
||
131 | } |
||
132 | |||
133 | @Override
|
||
134 | public Iterator<Code> iterator() { |
||
135 | return this.args.iterator(); |
||
136 | } |
||
137 | |||
138 | @Override
|
||
139 | public Code get(int n) { |
||
140 | return this.args.get(n); |
||
141 | } |
||
142 | |||
143 | @Override
|
||
144 | public void accept(Visitor visitor) throws BaseException { |
||
145 | 43521 | jjdelcerro | for( Code arg : this.args ) { |
146 | 43512 | jjdelcerro | visitor.visit(arg); |
147 | } |
||
148 | } |
||
149 | |||
150 | 43521 | jjdelcerro | @Override
|
151 | public String toString() { |
||
152 | if( args != null ) { |
||
153 | StringBuilder builder = new StringBuilder(); |
||
154 | boolean skipcoma = true; |
||
155 | for( Code arg : args ) {
|
||
156 | if( skipcoma ) {
|
||
157 | skipcoma = false;
|
||
158 | } else {
|
||
159 | builder.append(", ");
|
||
160 | } |
||
161 | builder.append(arg.toString()); |
||
162 | } |
||
163 | return builder.toString();
|
||
164 | } |
||
165 | return ""; |
||
166 | } |
||
167 | |||
168 | 43512 | jjdelcerro | } |
169 | |||
170 | public class BaseCaller extends BaseCode implements Caller { |
||
171 | |||
172 | private final String name; |
||
173 | private final Arguments args; |
||
174 | private Function function;
|
||
175 | private final int type; |
||
176 | |||
177 | public BaseCaller(String name, int type, Arguments args) { |
||
178 | this.name = name;
|
||
179 | this.args = args;
|
||
180 | this.type = type;
|
||
181 | this.function = null; |
||
182 | } |
||
183 | |||
184 | @Override
|
||
185 | public int code() { |
||
186 | return CALLER;
|
||
187 | } |
||
188 | |||
189 | @Override
|
||
190 | 43521 | jjdelcerro | public Object call(Interpreter interpreter, Object[] args) throws Exception { |
191 | return this.function.call(interpreter, args); |
||
192 | 43512 | jjdelcerro | } |
193 | |||
194 | @Override
|
||
195 | public String name() { |
||
196 | return this.name; |
||
197 | } |
||
198 | |||
199 | @Override
|
||
200 | public Function function() {
|
||
201 | return this.function; |
||
202 | } |
||
203 | |||
204 | @Override
|
||
205 | public Function function(Function function) {
|
||
206 | this.function = function;
|
||
207 | return this.function; |
||
208 | } |
||
209 | |||
210 | @Override
|
||
211 | public Code.Caller.Arguments args() {
|
||
212 | return this.args; |
||
213 | } |
||
214 | |||
215 | @Override
|
||
216 | public int type() { |
||
217 | return this.type; |
||
218 | } |
||
219 | |||
220 | @Override
|
||
221 | public void accept(Visitor visitor) throws BaseException { |
||
222 | visitor.visit(this);
|
||
223 | 44052 | omartinez | if(this.args!=null) { |
224 | this.args.accept(visitor);
|
||
225 | } |
||
226 | 43512 | jjdelcerro | } |
227 | |||
228 | 43521 | jjdelcerro | @Override
|
229 | public String toString() { |
||
230 | StringBuilder builder = new StringBuilder(); |
||
231 | builder.append(this.name());
|
||
232 | builder.append("(");
|
||
233 | if( this.args()!=null ) { |
||
234 | builder.append(this.args().toString());
|
||
235 | } |
||
236 | builder.append(")");
|
||
237 | return builder.toString();
|
||
238 | } |
||
239 | |||
240 | 43512 | jjdelcerro | } |
241 | |||
242 | 43939 | jjdelcerro | public class BaseMethod extends BaseCaller implements Method { |
243 | |||
244 | private final Code obj; |
||
245 | private final String methodname; |
||
246 | |||
247 | public BaseMethod(Code obj, String methodname, Arguments args) { |
||
248 | super(methodname, FUNCTION, args);
|
||
249 | this.obj = obj;
|
||
250 | this.methodname = methodname;
|
||
251 | } |
||
252 | |||
253 | @Override
|
||
254 | public int code() { |
||
255 | return METHOD;
|
||
256 | } |
||
257 | |||
258 | @Override
|
||
259 | public String methodname() { |
||
260 | return this.methodname; |
||
261 | } |
||
262 | |||
263 | @Override
|
||
264 | public Code obj() {
|
||
265 | return this.obj; |
||
266 | } |
||
267 | |||
268 | @Override
|
||
269 | public String toString() { |
||
270 | StringBuilder builder = new StringBuilder(); |
||
271 | builder.append(this.obj.toString());
|
||
272 | builder.append("->");
|
||
273 | builder.append(this.methodname());
|
||
274 | builder.append("(");
|
||
275 | if( this.args()!=null ) { |
||
276 | builder.append(this.args().toString());
|
||
277 | } |
||
278 | builder.append(")");
|
||
279 | return builder.toString();
|
||
280 | } |
||
281 | } |
||
282 | |||
283 | 43512 | jjdelcerro | @Override
|
284 | 43809 | jjdelcerro | public CodeBuilder clone() throws CloneNotSupportedException { |
285 | // This implementation of CodeBuilder does not maintain state, so
|
||
286 | // we only call the super class.
|
||
287 | DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
|
||
288 | return other;
|
||
289 | } |
||
290 | |||
291 | @Override
|
||
292 | 43512 | jjdelcerro | public Constant constant(Object value) { |
293 | return new BaseConstant(value); |
||
294 | } |
||
295 | |||
296 | @Override
|
||
297 | public Identifier identifier(String name) { |
||
298 | return new BaseIdentifier(name); |
||
299 | } |
||
300 | |||
301 | @Override
|
||
302 | public Caller.Arguments args() {
|
||
303 | return new BaseArguments(); |
||
304 | } |
||
305 | |||
306 | @Override
|
||
307 | public Caller function(String name, int type, Arguments args) { |
||
308 | return new BaseCaller(name, type, args); |
||
309 | } |
||
310 | |||
311 | @Override
|
||
312 | public Caller function(String name, Arguments args) { |
||
313 | return function(name, Caller.FUNCTION, args);
|
||
314 | } |
||
315 | 43939 | jjdelcerro | |
316 | 43512 | jjdelcerro | @Override
|
317 | 43939 | jjdelcerro | public Code method(Code obj, String methodname, Arguments methodargs) { |
318 | Method m = new BaseMethod(obj, methodname, methodargs); |
||
319 | return m;
|
||
320 | } |
||
321 | |||
322 | @Override
|
||
323 | 43512 | jjdelcerro | public Caller operator(String name, Code arg1) { |
324 | Arguments args = args(); |
||
325 | 43809 | jjdelcerro | ((BaseArguments)args).add(arg1); |
326 | 43512 | jjdelcerro | return function(name, Caller.UNARY_OPERATOR, args);
|
327 | } |
||
328 | |||
329 | @Override
|
||
330 | public Caller operator(String name, Code arg1, Code arg2) { |
||
331 | Arguments args = args(); |
||
332 | 43809 | jjdelcerro | ((BaseArguments)args).add(arg1); |
333 | ((BaseArguments)args).add(arg2); |
||
334 | 43512 | jjdelcerro | return function(name, Caller.BINARY_OPERATOR, args);
|
335 | } |
||
336 | |||
337 | @Override
|
||
338 | public Code not(Code op1) {
|
||
339 | return operator("not", op1); |
||
340 | } |
||
341 | |||
342 | @Override
|
||
343 | public Code add(Code op1, Code op2) {
|
||
344 | return operator("+", op1, op2); |
||
345 | } |
||
346 | |||
347 | @Override
|
||
348 | public Code subst(Code op1, Code op2) {
|
||
349 | return operator("-", op1, op2); |
||
350 | } |
||
351 | |||
352 | @Override
|
||
353 | public Code mult(Code op1, Code op2) {
|
||
354 | return operator("*", op1, op2); |
||
355 | } |
||
356 | |||
357 | @Override
|
||
358 | public Code div(Code op1, Code op2) {
|
||
359 | return operator("/", op1, op2); |
||
360 | } |
||
361 | |||
362 | @Override
|
||
363 | public Code mod(Code op1, Code op2) {
|
||
364 | return operator("%", op1, op2); |
||
365 | } |
||
366 | |||
367 | @Override
|
||
368 | public Code or(Code op1, Code op2) {
|
||
369 | return operator("or", op1, op2); |
||
370 | } |
||
371 | |||
372 | @Override
|
||
373 | public Code and(Code op1, Code op2) {
|
||
374 | return operator("and", op1, op2); |
||
375 | } |
||
376 | |||
377 | @Override
|
||
378 | public Code like(Code op1, Code op2) {
|
||
379 | return operator("like", op1, op2); |
||
380 | } |
||
381 | |||
382 | @Override
|
||
383 | public Code ilike(Code op1, Code op2) {
|
||
384 | return operator("ilike", op1, op2); |
||
385 | } |
||
386 | |||
387 | @Override
|
||
388 | 43532 | jjdelcerro | public Code regexp(Code op1, Code op2) {
|
389 | return operator("~", op1, op2); |
||
390 | } |
||
391 | |||
392 | @Override
|
||
393 | 43512 | jjdelcerro | public Code lt(Code op1, Code op2) {
|
394 | return operator("<", op1, op2); |
||
395 | } |
||
396 | |||
397 | @Override
|
||
398 | public Code gt(Code op1, Code op2) {
|
||
399 | return operator(">", op1, op2); |
||
400 | } |
||
401 | |||
402 | @Override
|
||
403 | public Code le(Code op1, Code op2) {
|
||
404 | return operator("<=", op1, op2); |
||
405 | } |
||
406 | |||
407 | @Override
|
||
408 | public Code ge(Code op1, Code op2) {
|
||
409 | return operator(">=", op1, op2); |
||
410 | } |
||
411 | |||
412 | @Override
|
||
413 | public Code eq(Code op1, Code op2) {
|
||
414 | return operator("=", op1, op2); |
||
415 | } |
||
416 | |||
417 | @Override
|
||
418 | public Code ne(Code op1, Code op2) {
|
||
419 | return operator("<>", op1, op2); |
||
420 | } |
||
421 | |||
422 | @Override
|
||
423 | public Code is(Code op1, Code op2) {
|
||
424 | return operator("is", op1, op2); |
||
425 | } |
||
426 | |||
427 | 43939 | jjdelcerro | @Override
|
428 | public Code getattr(Code obj, String attrname) { |
||
429 | Arguments args = args(); |
||
430 | ((BaseArguments)args).add(obj); |
||
431 | ((BaseArguments)args).add(constant(attrname)); |
||
432 | return function("getattr", args); |
||
433 | } |
||
434 | |||
435 | 43512 | jjdelcerro | } |