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
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Iterator;
6
import java.util.List;
7
import org.apache.commons.lang3.StringUtils;
8
import org.gvsig.expressionevaluator.Code;
9
import static org.gvsig.expressionevaluator.Code.CALLER;
10
import static org.gvsig.expressionevaluator.Code.CONSTANT;
11
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
12
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
13
import org.gvsig.expressionevaluator.Code.Caller;
14
import org.gvsig.expressionevaluator.Code.Constant;
15
import org.gvsig.expressionevaluator.Code.Identifier;
16
import org.gvsig.expressionevaluator.Code.Method;
17
import org.gvsig.expressionevaluator.CodeBuilder;
18
import org.gvsig.expressionevaluator.Codes;
19
import org.gvsig.expressionevaluator.Function;
20
import org.gvsig.expressionevaluator.Interpreter;
21
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
import org.gvsig.fmap.geom.Geometry;
44
import org.gvsig.tools.exception.BaseException;
45
import org.gvsig.tools.visitor.Visitor;
46

    
47
@SuppressWarnings("UseSpecificCatch")
48
    public class DefaultCodeBuilder implements CodeBuilder {
49

    
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
        @Override
83
        public String toString() {
84
            StringBuilder builder = new StringBuilder();
85
            Object v = this.value();
86
            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
                
96
            } else if( v instanceof Boolean ) {
97
                builder.append(((Boolean)v).toString().toUpperCase());
98
                
99
            } 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
            }
111
            return builder.toString();
112
        }
113

    
114
    }
115

    
116
    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

    
133
        @Override
134
        public boolean enterCode(int max) {
135
            this.counter += 1;
136
            return this.counter < max;
137
        }
138

    
139
        @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
        public BaseIdentifier(String name) {
157
            this.name = name;
158
            this.recursionSupport = new RecursionSupport();
159
        }
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
        @Override
172
        public String toString() {
173
            StringBuilder builder = new StringBuilder();
174
            builder.append("\"");
175
            builder.append(this.name());
176
            builder.append("\"");
177
            return builder.toString();
178
        }
179

    
180
        @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
    }
196

    
197
    public class BaseCodes implements Codes {
198

    
199
        private final List<Code> codes;
200

    
201
        public BaseCodes() {
202
            this.codes = new ArrayList<>();
203
        }
204

    
205
        @Override
206
        public int size() {
207
            if( codes == null ) {
208
                return 0;
209
            }
210
            return this.codes.size();
211
        }
212

    
213
        public void add(Code arg) {
214
            this.codes.add(arg);
215
        }
216

    
217
        @Override
218
        public Iterator<Code> iterator() {
219
            return this.codes.iterator();
220
        }
221

    
222
        @Override
223
        public Code get(int n) {
224
            return this.codes.get(n);
225
        }
226

    
227
        @Override
228
        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
        public void accept(Visitor visitor) throws BaseException {
239
            for( Code arg : this.codes ) {
240
                visitor.visit(arg);
241
            }
242
        }
243

    
244
        @Override
245
        public String toString() {
246
            if( codes != null ) {
247
                StringBuilder builder = new StringBuilder();
248
                boolean skipcoma = true;
249
                for( Code code : codes ) {
250
                    if( code == null ) {
251
                        continue;
252
                    }
253
                    if( skipcoma ) {
254
                        skipcoma = false;
255
                    } else {
256
                        builder.append(", ");
257
                    }
258
                    builder.append(code.toString());
259
                }
260
                return builder.toString();
261
            }
262
            return "";
263
        }
264

    
265
    }
266

    
267
    public class BaseCaller extends BaseCode implements Caller, RecursionControlSupport {
268

    
269
        private final String name;
270
        private final Codes args;
271
        private Function function;
272
        private final int type;
273
        private RecursionSupport recursionSupport;
274

    
275
        public BaseCaller(String name, int type, Codes args) {
276
            this.name = name;
277
            this.args = args;
278
            this.type = type;
279
            this.function = null;
280
            this.recursionSupport = new RecursionSupport();
281
        }
282

    
283
        @Override
284
        public int code() {
285
            return CALLER;
286
        }
287

    
288
        @Override
289
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
290
            return this.function.call(interpreter, args);
291
        }
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
        public Codes args() {
311
            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
            if(this.args!=null) {
323
                this.args.accept(visitor);
324
            }
325
        }
326

    
327
        @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
        @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
    }
354

    
355
    public class BaseMethod extends BaseCaller implements Method {
356

    
357
        private final Code obj;
358
        private final String methodname;
359
        
360
        public BaseMethod(Code obj, String methodname, Codes args) {
361
            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
    @Override
397
    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
    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
    public BaseCodes args() {
416
        return new BaseCodes();
417
    }
418

    
419
    @Override
420
    public Caller function(String name, int type, Codes args) {
421
        return new BaseCaller(name, type, args);
422
    }
423

    
424
    @Override
425
    public Caller function(String name, Codes args) {
426
        return function(name, Caller.FUNCTION, args);
427
    }
428
    
429
    @Override
430
    public Code method(Code obj, String methodname, Codes methodargs) {
431
        Method m = new BaseMethod(obj, methodname, methodargs);
432
        return m;
433
    }
434
    
435
    @Override
436
    public Caller operator(String name, Code arg1) {
437
        BaseCodes args = args();
438
        args.add(arg1);
439
        return function(name, Caller.UNARY_OPERATOR, args);
440
    }
441

    
442
    @Override
443
    public Caller operator(String name, Code arg1, Code arg2) {
444
        BaseCodes args = args();
445
        args.add(arg1);
446
        args.add(arg2);
447
        return function(name, Caller.BINARY_OPERATOR, args);
448
    }
449

    
450
    @Override
451
    public Code not(Code op1) {
452
        return operator(NotOperator.NAME, op1);
453
    }
454

    
455
    @Override
456
    public Code negate(Code op1) {
457
        return operator(NegOperator.NAME, op1);
458
    }
459

    
460
    @Override
461
    public Code concat(Code op1, Code op2) {
462
        return operator(ConcatOperator.NAME, op1, op2);
463
    }
464

    
465
    @Override
466
    public Code add(Code op1, Code op2) {
467
        return operator(AddOperator.NAME, op1, op2);
468
    }
469

    
470
    @Override
471
    public Code subst(Code op1, Code op2) {
472
        return operator(SubstOperator.NAME, op1, op2);
473
    }
474

    
475
    @Override
476
    public Code mult(Code op1, Code op2) {
477
        return operator(MulOperator.NAME, op1, op2);
478
    }
479

    
480
    @Override
481
    public Code div(Code op1, Code op2) {
482
        return operator(DivOperator.NAME, op1, op2);
483
    }
484

    
485
    @Override
486
    public Code mod(Code op1, Code op2) {
487
        return operator(ModOperator.NAME, op1, op2);
488
    }
489

    
490
    @Override
491
    public Code or(Code op1, Code op2) {
492
        return operator(OrOperator.NAME, op1, op2);
493
    }
494

    
495
    @Override
496
    public Code and(Code op1, Code op2) {
497
        return operator(AndOperator.NAME, op1, op2);
498
    }
499

    
500
    @Override
501
    public Code like(Code op1, Code op2) {
502
        return operator(LikeOperator.NAME, op1, op2);
503
    }
504

    
505
    @Override
506
    public Code ilike(Code op1, Code op2) {
507
        return operator(IlikeOperator.NAME, op1, op2);
508
    }
509

    
510
    @Override
511
    public Code regexp(Code op1, Code op2) {
512
        return operator(RegExpOperator.NAME, op1, op2);
513
    }
514

    
515
    @Override
516
    public Code lt(Code op1, Code op2) {
517
        return operator(LtOperator.NAME, op1, op2);
518
    }
519

    
520
    @Override
521
    public Code gt(Code op1, Code op2) {
522
        return operator(GtOperator.NAME, op1, op2);
523
    }
524

    
525
    @Override
526
    public Code le(Code op1, Code op2) {
527
        return operator(LeOperator.NAME, op1, op2);
528
    }
529

    
530
    @Override
531
    public Code ge(Code op1, Code op2) {
532
        return operator(GeOperator.NAME, op1, op2);
533
    }
534

    
535
    @Override
536
    public Code eq(Code op1, Code op2) {
537
        return operator(EqOperator.NAME, op1, op2);
538
    }
539

    
540
    @Override
541
    public Code ne(Code op1, Code op2) {
542
        return operator(NeOperator.NAME, op1, op2);
543
    }
544

    
545
    @Override
546
    public Code is(Code op1, Code op2) {
547
        return operator(IsOperator.NAME, op1, op2);
548
    }
549

    
550
    @Override
551
    public Code getattr(Code obj, String attrname) {
552
        BaseCodes args = args();
553
        args.add(obj);
554
        args.add(constant(attrname));
555
        return function(GetattrFunction.NAME, args);
556
    }    
557

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