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 / main / java / org / gvsig / expressionevaluator / impl / DefaultCodeBuilder.java @ 44154

History | View | Annotate | Download (15.4 KB)

1 43512 jjdelcerro
package org.gvsig.expressionevaluator.impl;
2
3
import java.util.ArrayList;
4 44139 jjdelcerro
import java.util.Collections;
5 43512 jjdelcerro
import java.util.Iterator;
6
import java.util.List;
7 43519 jjdelcerro
import org.apache.commons.lang3.StringUtils;
8 43512 jjdelcerro
import org.gvsig.expressionevaluator.Code;
9
import static org.gvsig.expressionevaluator.Code.CALLER;
10
import static org.gvsig.expressionevaluator.Code.CONSTANT;
11 44006 jjdelcerro
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
12
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
13 43512 jjdelcerro
import org.gvsig.expressionevaluator.Code.Caller;
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 44139 jjdelcerro
import org.gvsig.expressionevaluator.Codes;
19 43512 jjdelcerro
import org.gvsig.expressionevaluator.Function;
20 43521 jjdelcerro
import org.gvsig.expressionevaluator.Interpreter;
21 44139 jjdelcerro
import org.gvsig.expressionevaluator.impl.function.operator.AddOperator;
22
import org.gvsig.expressionevaluator.impl.function.operator.AndOperator;
23
import org.gvsig.expressionevaluator.impl.function.operator.ConcatOperator;
24
import org.gvsig.expressionevaluator.impl.function.operator.DivOperator;
25
import org.gvsig.expressionevaluator.impl.function.operator.EqOperator;
26
import org.gvsig.expressionevaluator.impl.function.operator.GeOperator;
27
import org.gvsig.expressionevaluator.impl.function.operator.GtOperator;
28
import org.gvsig.expressionevaluator.impl.function.operator.IsOperator;
29
import org.gvsig.expressionevaluator.impl.function.operator.LeOperator;
30
import org.gvsig.expressionevaluator.impl.function.operator.LtOperator;
31
import org.gvsig.expressionevaluator.impl.function.operator.ModOperator;
32
import org.gvsig.expressionevaluator.impl.function.operator.MulOperator;
33
import org.gvsig.expressionevaluator.impl.function.operator.NeOperator;
34
import org.gvsig.expressionevaluator.impl.function.operator.NegOperator;
35
import org.gvsig.expressionevaluator.impl.function.operator.NotOperator;
36
import org.gvsig.expressionevaluator.impl.function.operator.OrOperator;
37
import org.gvsig.expressionevaluator.impl.function.operator.RegExpOperator;
38
import org.gvsig.expressionevaluator.impl.function.operator.SubstOperator;
39
import org.gvsig.expressionevaluator.impl.function.predicate.IlikeOperator;
40
import org.gvsig.expressionevaluator.impl.function.predicate.LikeOperator;
41
import org.gvsig.expressionevaluator.impl.function.programming.GetattrFunction;
42
import org.gvsig.expressionevaluator.impl.function.programming.GetitemFunction;
43 44009 jjdelcerro
import org.gvsig.fmap.geom.Geometry;
44 43512 jjdelcerro
import org.gvsig.tools.exception.BaseException;
45
import org.gvsig.tools.visitor.Visitor;
46
47 44009 jjdelcerro
@SuppressWarnings("UseSpecificCatch")
48
    public class DefaultCodeBuilder implements CodeBuilder {
49 43512 jjdelcerro
50
    public class BaseCode implements Code {
51
52
        @Override
53
        public int code() {
54
            return UNDEFINED;
55
        }
56
57
        @Override
58
        public void accept(Visitor visitor) throws BaseException {
59
            visitor.visit(this);
60
        }
61
62
    }
63
64
    class BaseConstant extends BaseCode implements Constant {
65
66
        private final Object value;
67
68
        public BaseConstant(Object value) {
69
            this.value = value;
70
        }
71
72
        @Override
73
        public int code() {
74
            return CONSTANT;
75
        }
76
77
        @Override
78
        public Object value() {
79
            return this.value;
80
        }
81
82 43521 jjdelcerro
        @Override
83
        public String toString() {
84
            StringBuilder builder = new StringBuilder();
85
            Object v = this.value();
86 44139 jjdelcerro
            if( v == null ) {
87
                builder.append("NULL");
88
            } else if( v instanceof CharSequence ) {
89
                if( StringUtils.isEmpty((CharSequence)v) ) {
90
                    builder.append("''");
91
                } else {
92
                    v = StringUtils.wrap(v.toString(), "'");
93
                    builder.append(v);
94
                }
95 44009 jjdelcerro
96 44139 jjdelcerro
            } else if( v instanceof Boolean ) {
97
                builder.append(((Boolean)v).toString().toUpperCase());
98
99 44009 jjdelcerro
            } else if( v instanceof Geometry ) {
100
                try {
101
                    builder.append("'");
102
                    builder.append(((Geometry) v).convertToWKT());
103
                    builder.append("'::geometry");
104
                } catch (Exception ex) {
105
                    builder.append("'UNKNOW'::geometry");
106
                }
107
108
            } else {
109
                builder.append(v);
110 43521 jjdelcerro
            }
111
            return builder.toString();
112
        }
113
114 43512 jjdelcerro
    }
115
116 44154 jjdelcerro
    public interface RecursionControlSupport {
117
118
        public boolean enterCode(int max);
119
120
        public void exitCode();
121
122
        public void resetRecursionState();
123
    }
124
125
    private class RecursionSupport implements RecursionControlSupport {
126
127
        private int counter;
128
129
        public RecursionSupport() {
130
            this.counter = 0;
131
        }
132 43512 jjdelcerro
133 44154 jjdelcerro
        @Override
134
        public boolean enterCode(int max) {
135
            this.counter += 1;
136
            return this.counter < max;
137
        }
138 43512 jjdelcerro
139 44154 jjdelcerro
        @Override
140
        public void exitCode() {
141
            this.counter -= 1;
142
        }
143
144
        @Override
145
        public void resetRecursionState() {
146
            this.counter = 0;
147
        }
148
149
    }
150
151
    public class BaseIdentifier extends BaseCode implements Identifier, RecursionControlSupport {
152
153
        private String name;
154
        private RecursionSupport recursionSupport;
155
156 43512 jjdelcerro
        public BaseIdentifier(String name) {
157
            this.name = name;
158 44154 jjdelcerro
            this.recursionSupport = new RecursionSupport();
159 43512 jjdelcerro
        }
160
161
        @Override
162
        public int code() {
163
            return IDENTIFIER;
164
        }
165
166
        @Override
167
        public String name() {
168
            return this.name;
169
        }
170
171 43521 jjdelcerro
        @Override
172
        public String toString() {
173
            StringBuilder builder = new StringBuilder();
174 44006 jjdelcerro
            builder.append("\"");
175 43521 jjdelcerro
            builder.append(this.name());
176 44006 jjdelcerro
            builder.append("\"");
177 43521 jjdelcerro
            return builder.toString();
178
        }
179
180 44154 jjdelcerro
        @Override
181
        public boolean enterCode(int max) {
182
            return this.recursionSupport.enterCode(max);
183
        }
184
185
        @Override
186
        public void exitCode() {
187
            this.recursionSupport.exitCode();
188
        }
189
190
        @Override
191
        public void resetRecursionState() {
192
            this.recursionSupport.resetRecursionState();
193
        }
194
195 43512 jjdelcerro
    }
196
197 44139 jjdelcerro
    public class BaseCodes implements Codes {
198 43512 jjdelcerro
199 44139 jjdelcerro
        private final List<Code> codes;
200 43512 jjdelcerro
201 44139 jjdelcerro
        public BaseCodes() {
202
            this.codes = new ArrayList<>();
203 43512 jjdelcerro
        }
204
205
        @Override
206 44139 jjdelcerro
        public int size() {
207
            if( codes == null ) {
208 43512 jjdelcerro
                return 0;
209
            }
210 44139 jjdelcerro
            return this.codes.size();
211 43512 jjdelcerro
        }
212
213
        public void add(Code arg) {
214 44139 jjdelcerro
            this.codes.add(arg);
215 43512 jjdelcerro
        }
216
217
        @Override
218
        public Iterator<Code> iterator() {
219 44139 jjdelcerro
            return this.codes.iterator();
220 43512 jjdelcerro
        }
221
222
        @Override
223
        public Code get(int n) {
224 44139 jjdelcerro
            return this.codes.get(n);
225 43512 jjdelcerro
        }
226
227
        @Override
228 44139 jjdelcerro
        public boolean isEmpty() {
229
            return this.codes.isEmpty();
230
        }
231
232
        @Override
233
        public List<Code> toList() {
234
            return Collections.unmodifiableList(this.codes);
235
        }
236
237
        @Override
238 43512 jjdelcerro
        public void accept(Visitor visitor) throws BaseException {
239 44139 jjdelcerro
            for( Code arg : this.codes ) {
240 43512 jjdelcerro
                visitor.visit(arg);
241
            }
242
        }
243
244 43521 jjdelcerro
        @Override
245
        public String toString() {
246 44139 jjdelcerro
            if( codes != null ) {
247 43521 jjdelcerro
                StringBuilder builder = new StringBuilder();
248
                boolean skipcoma = true;
249 44139 jjdelcerro
                for( Code code : codes ) {
250
                    if( code == null ) {
251
                        continue;
252
                    }
253 43521 jjdelcerro
                    if( skipcoma ) {
254
                        skipcoma = false;
255
                    } else {
256
                        builder.append(", ");
257
                    }
258 44139 jjdelcerro
                    builder.append(code.toString());
259 43521 jjdelcerro
                }
260
                return builder.toString();
261
            }
262
            return "";
263
        }
264
265 43512 jjdelcerro
    }
266
267 44154 jjdelcerro
    public class BaseCaller extends BaseCode implements Caller, RecursionControlSupport {
268 43512 jjdelcerro
269
        private final String name;
270 44139 jjdelcerro
        private final Codes args;
271 43512 jjdelcerro
        private Function function;
272
        private final int type;
273 44154 jjdelcerro
        private RecursionSupport recursionSupport;
274 43512 jjdelcerro
275 44139 jjdelcerro
        public BaseCaller(String name, int type, Codes args) {
276 43512 jjdelcerro
            this.name = name;
277
            this.args = args;
278
            this.type = type;
279
            this.function = null;
280 44154 jjdelcerro
            this.recursionSupport = new RecursionSupport();
281 43512 jjdelcerro
        }
282
283
        @Override
284
        public int code() {
285
            return CALLER;
286
        }
287
288
        @Override
289 43521 jjdelcerro
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
290
            return this.function.call(interpreter, args);
291 43512 jjdelcerro
        }
292
293
        @Override
294
        public String name() {
295
            return this.name;
296
        }
297
298
        @Override
299
        public Function function() {
300
            return this.function;
301
        }
302
303
        @Override
304
        public Function function(Function function) {
305
            this.function = function;
306
            return this.function;
307
        }
308
309
        @Override
310 44139 jjdelcerro
        public Codes args() {
311 43512 jjdelcerro
            return this.args;
312
        }
313
314
        @Override
315
        public int type() {
316
            return this.type;
317
        }
318
319
        @Override
320
        public void accept(Visitor visitor) throws BaseException {
321
            visitor.visit(this);
322 44052 omartinez
            if(this.args!=null) {
323
                this.args.accept(visitor);
324
            }
325 43512 jjdelcerro
        }
326
327 43521 jjdelcerro
        @Override
328
        public String toString() {
329
            StringBuilder builder = new StringBuilder();
330
            builder.append(this.name());
331
            builder.append("(");
332
            if( this.args()!=null ) {
333
                builder.append(this.args().toString());
334
            }
335
            builder.append(")");
336
            return builder.toString();
337
        }
338
339 44154 jjdelcerro
        @Override
340
        public boolean enterCode(int max) {
341
            return this.recursionSupport.enterCode(max);
342
        }
343
344
        @Override
345
        public void exitCode() {
346
            this.recursionSupport.exitCode();
347
        }
348
349
        @Override
350
        public void resetRecursionState() {
351
            this.recursionSupport.resetRecursionState();
352
        }
353 43512 jjdelcerro
    }
354
355 43939 jjdelcerro
    public class BaseMethod extends BaseCaller implements Method {
356
357
        private final Code obj;
358
        private final String methodname;
359
360 44139 jjdelcerro
        public BaseMethod(Code obj, String methodname, Codes args) {
361 43939 jjdelcerro
            super(methodname, FUNCTION, args);
362
            this.obj = obj;
363
            this.methodname = methodname;
364
        }
365
366
        @Override
367
        public int code() {
368
            return METHOD;
369
        }
370
371
        @Override
372
        public String methodname() {
373
            return this.methodname;
374
        }
375
376
        @Override
377
        public Code obj() {
378
            return this.obj;
379
        }
380
381
        @Override
382
        public String toString() {
383
            StringBuilder builder = new StringBuilder();
384
            builder.append(this.obj.toString());
385
            builder.append("->");
386
            builder.append(this.methodname());
387
            builder.append("(");
388
            if( this.args()!=null ) {
389
                builder.append(this.args().toString());
390
            }
391
            builder.append(")");
392
            return builder.toString();
393
        }
394
    }
395
396 43512 jjdelcerro
    @Override
397 43809 jjdelcerro
    public CodeBuilder clone() throws CloneNotSupportedException {
398
        // This implementation of CodeBuilder does not maintain state, so
399
        // we only call the super class.
400
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
401
        return other;
402
    }
403
404
    @Override
405 43512 jjdelcerro
    public Constant constant(Object value) {
406
        return new BaseConstant(value);
407
    }
408
409
    @Override
410
    public Identifier identifier(String name) {
411
        return new BaseIdentifier(name);
412
    }
413
414
    @Override
415 44139 jjdelcerro
    public BaseCodes args() {
416
        return new BaseCodes();
417 43512 jjdelcerro
    }
418
419
    @Override
420 44139 jjdelcerro
    public Caller function(String name, int type, Codes args) {
421 43512 jjdelcerro
        return new BaseCaller(name, type, args);
422
    }
423
424
    @Override
425 44139 jjdelcerro
    public Caller function(String name, Codes args) {
426 43512 jjdelcerro
        return function(name, Caller.FUNCTION, args);
427
    }
428 43939 jjdelcerro
429 43512 jjdelcerro
    @Override
430 44139 jjdelcerro
    public Code method(Code obj, String methodname, Codes methodargs) {
431 43939 jjdelcerro
        Method m = new BaseMethod(obj, methodname, methodargs);
432
        return m;
433
    }
434
435
    @Override
436 43512 jjdelcerro
    public Caller operator(String name, Code arg1) {
437 44139 jjdelcerro
        BaseCodes args = args();
438
        args.add(arg1);
439 43512 jjdelcerro
        return function(name, Caller.UNARY_OPERATOR, args);
440
    }
441
442
    @Override
443
    public Caller operator(String name, Code arg1, Code arg2) {
444 44139 jjdelcerro
        BaseCodes args = args();
445
        args.add(arg1);
446
        args.add(arg2);
447 43512 jjdelcerro
        return function(name, Caller.BINARY_OPERATOR, args);
448
    }
449
450
    @Override
451
    public Code not(Code op1) {
452 44139 jjdelcerro
        return operator(NotOperator.NAME, op1);
453 43512 jjdelcerro
    }
454
455
    @Override
456 44098 jjdelcerro
    public Code negate(Code op1) {
457 44139 jjdelcerro
        return operator(NegOperator.NAME, op1);
458 44098 jjdelcerro
    }
459
460
    @Override
461 44139 jjdelcerro
    public Code concat(Code op1, Code op2) {
462
        return operator(ConcatOperator.NAME, op1, op2);
463
    }
464
465
    @Override
466 43512 jjdelcerro
    public Code add(Code op1, Code op2) {
467 44139 jjdelcerro
        return operator(AddOperator.NAME, op1, op2);
468 43512 jjdelcerro
    }
469
470
    @Override
471
    public Code subst(Code op1, Code op2) {
472 44139 jjdelcerro
        return operator(SubstOperator.NAME, op1, op2);
473 43512 jjdelcerro
    }
474
475
    @Override
476
    public Code mult(Code op1, Code op2) {
477 44139 jjdelcerro
        return operator(MulOperator.NAME, op1, op2);
478 43512 jjdelcerro
    }
479
480
    @Override
481
    public Code div(Code op1, Code op2) {
482 44139 jjdelcerro
        return operator(DivOperator.NAME, op1, op2);
483 43512 jjdelcerro
    }
484
485
    @Override
486
    public Code mod(Code op1, Code op2) {
487 44139 jjdelcerro
        return operator(ModOperator.NAME, op1, op2);
488 43512 jjdelcerro
    }
489
490
    @Override
491
    public Code or(Code op1, Code op2) {
492 44139 jjdelcerro
        return operator(OrOperator.NAME, op1, op2);
493 43512 jjdelcerro
    }
494
495
    @Override
496
    public Code and(Code op1, Code op2) {
497 44139 jjdelcerro
        return operator(AndOperator.NAME, op1, op2);
498 43512 jjdelcerro
    }
499
500
    @Override
501
    public Code like(Code op1, Code op2) {
502 44139 jjdelcerro
        return operator(LikeOperator.NAME, op1, op2);
503 43512 jjdelcerro
    }
504
505
    @Override
506
    public Code ilike(Code op1, Code op2) {
507 44139 jjdelcerro
        return operator(IlikeOperator.NAME, op1, op2);
508 43512 jjdelcerro
    }
509
510
    @Override
511 43532 jjdelcerro
    public Code regexp(Code op1, Code op2) {
512 44139 jjdelcerro
        return operator(RegExpOperator.NAME, op1, op2);
513 43532 jjdelcerro
    }
514
515
    @Override
516 43512 jjdelcerro
    public Code lt(Code op1, Code op2) {
517 44139 jjdelcerro
        return operator(LtOperator.NAME, op1, op2);
518 43512 jjdelcerro
    }
519
520
    @Override
521
    public Code gt(Code op1, Code op2) {
522 44139 jjdelcerro
        return operator(GtOperator.NAME, op1, op2);
523 43512 jjdelcerro
    }
524
525
    @Override
526
    public Code le(Code op1, Code op2) {
527 44139 jjdelcerro
        return operator(LeOperator.NAME, op1, op2);
528 43512 jjdelcerro
    }
529
530
    @Override
531
    public Code ge(Code op1, Code op2) {
532 44139 jjdelcerro
        return operator(GeOperator.NAME, op1, op2);
533 43512 jjdelcerro
    }
534
535
    @Override
536
    public Code eq(Code op1, Code op2) {
537 44139 jjdelcerro
        return operator(EqOperator.NAME, op1, op2);
538 43512 jjdelcerro
    }
539
540
    @Override
541
    public Code ne(Code op1, Code op2) {
542 44139 jjdelcerro
        return operator(NeOperator.NAME, op1, op2);
543 43512 jjdelcerro
    }
544
545
    @Override
546
    public Code is(Code op1, Code op2) {
547 44139 jjdelcerro
        return operator(IsOperator.NAME, op1, op2);
548 43512 jjdelcerro
    }
549
550 43939 jjdelcerro
    @Override
551
    public Code getattr(Code obj, String attrname) {
552 44139 jjdelcerro
        BaseCodes args = args();
553
        args.add(obj);
554
        args.add(constant(attrname));
555
        return function(GetattrFunction.NAME, args);
556 43939 jjdelcerro
    }
557
558 44139 jjdelcerro
    @Override
559
    public Code getitem(Code obj, Code index) {
560
        BaseCodes args = args();
561
        args.add(obj);
562
        args.add(index);
563
        return function(GetitemFunction.NAME, args);
564
    }
565
566
567 43512 jjdelcerro
}