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 @ 44139

History | View | Annotate | Download (13.6 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 class BaseIdentifier extends BaseCode implements Identifier {
117

    
118
        String name;
119

    
120
        public BaseIdentifier(String name) {
121
            this.name = name;
122
        }
123

    
124
        @Override
125
        public int code() {
126
            return IDENTIFIER;
127
        }
128

    
129
        @Override
130
        public String name() {
131
            return this.name;
132
        }
133

    
134
        @Override
135
        public String toString() {
136
            StringBuilder builder = new StringBuilder();
137
            builder.append("\"");
138
            builder.append(this.name());
139
            builder.append("\"");
140
            return builder.toString();
141
        }
142

    
143
    }
144

    
145
    public class BaseCodes implements Codes {
146

    
147
        private final List<Code> codes;
148

    
149
        public BaseCodes() {
150
            this.codes = new ArrayList<>();
151
        }
152

    
153
        @Override
154
        public int size() {
155
            if( codes == null ) {
156
                return 0;
157
            }
158
            return this.codes.size();
159
        }
160

    
161
        public void add(Code arg) {
162
            this.codes.add(arg);
163
        }
164

    
165
        @Override
166
        public Iterator<Code> iterator() {
167
            return this.codes.iterator();
168
        }
169

    
170
        @Override
171
        public Code get(int n) {
172
            return this.codes.get(n);
173
        }
174

    
175
        @Override
176
        public boolean isEmpty() {
177
            return this.codes.isEmpty();
178
        }
179

    
180
        @Override
181
        public List<Code> toList() {
182
            return Collections.unmodifiableList(this.codes);
183
        }
184

    
185
        @Override
186
        public void accept(Visitor visitor) throws BaseException {
187
            for( Code arg : this.codes ) {
188
                visitor.visit(arg);
189
            }
190
        }
191

    
192
        @Override
193
        public String toString() {
194
            if( codes != null ) {
195
                StringBuilder builder = new StringBuilder();
196
                boolean skipcoma = true;
197
                for( Code code : codes ) {
198
                    if( code == null ) {
199
                        continue;
200
                    }
201
                    if( skipcoma ) {
202
                        skipcoma = false;
203
                    } else {
204
                        builder.append(", ");
205
                    }
206
                    builder.append(code.toString());
207
                }
208
                return builder.toString();
209
            }
210
            return "";
211
        }
212

    
213
    }
214

    
215
    public class BaseCaller extends BaseCode implements Caller {
216

    
217
        private final String name;
218
        private final Codes args;
219
        private Function function;
220
        private final int type;
221

    
222
        public BaseCaller(String name, int type, Codes args) {
223
            this.name = name;
224
            this.args = args;
225
            this.type = type;
226
            this.function = null;
227
        }
228

    
229
        @Override
230
        public int code() {
231
            return CALLER;
232
        }
233

    
234
        @Override
235
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
236
            return this.function.call(interpreter, args);
237
        }
238

    
239
        @Override
240
        public String name() {
241
            return this.name;
242
        }
243

    
244
        @Override
245
        public Function function() {
246
            return this.function;
247
        }
248

    
249
        @Override
250
        public Function function(Function function) {
251
            this.function = function;
252
            return this.function;
253
        }
254

    
255
        @Override
256
        public Codes args() {
257
            return this.args;
258
        }
259

    
260
        @Override
261
        public int type() {
262
            return this.type;
263
        }
264

    
265
        @Override
266
        public void accept(Visitor visitor) throws BaseException {
267
            visitor.visit(this);
268
            if(this.args!=null) {
269
                this.args.accept(visitor);
270
            }
271
        }
272

    
273
        @Override
274
        public String toString() {
275
            StringBuilder builder = new StringBuilder();
276
            builder.append(this.name());
277
            builder.append("(");
278
            if( this.args()!=null ) {
279
                builder.append(this.args().toString());
280
            }
281
            builder.append(")");
282
            return builder.toString();
283
        }
284

    
285
    }
286

    
287
    public class BaseMethod extends BaseCaller implements Method {
288

    
289
        private final Code obj;
290
        private final String methodname;
291
        
292
        public BaseMethod(Code obj, String methodname, Codes args) {
293
            super(methodname, FUNCTION, args);
294
            this.obj = obj;
295
            this.methodname = methodname;
296
        }
297

    
298
        @Override
299
        public int code() {
300
            return METHOD;
301
        }
302
        
303
        @Override
304
        public String methodname() {
305
            return this.methodname;
306
        }
307

    
308
        @Override
309
        public Code obj() {
310
            return this.obj;
311
        }
312

    
313
        @Override
314
        public String toString() {
315
            StringBuilder builder = new StringBuilder();
316
            builder.append(this.obj.toString());
317
            builder.append("->");
318
            builder.append(this.methodname());
319
            builder.append("(");
320
            if( this.args()!=null ) {
321
                builder.append(this.args().toString());
322
            }
323
            builder.append(")");
324
            return builder.toString();
325
        }
326
    }    
327
    
328
    @Override
329
    public CodeBuilder clone() throws CloneNotSupportedException {
330
        // This implementation of CodeBuilder does not maintain state, so 
331
        // we only call the super class.
332
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
333
        return other;
334
    }
335

    
336
    @Override
337
    public Constant constant(Object value) {
338
        return new BaseConstant(value);
339
    }
340

    
341
    @Override
342
    public Identifier identifier(String name) {
343
        return new BaseIdentifier(name);
344
    }
345

    
346
    @Override
347
    public BaseCodes args() {
348
        return new BaseCodes();
349
    }
350

    
351
    @Override
352
    public Caller function(String name, int type, Codes args) {
353
        return new BaseCaller(name, type, args);
354
    }
355

    
356
    @Override
357
    public Caller function(String name, Codes args) {
358
        return function(name, Caller.FUNCTION, args);
359
    }
360
    
361
    @Override
362
    public Code method(Code obj, String methodname, Codes methodargs) {
363
        Method m = new BaseMethod(obj, methodname, methodargs);
364
        return m;
365
    }
366
    
367
    @Override
368
    public Caller operator(String name, Code arg1) {
369
        BaseCodes args = args();
370
        args.add(arg1);
371
        return function(name, Caller.UNARY_OPERATOR, args);
372
    }
373

    
374
    @Override
375
    public Caller operator(String name, Code arg1, Code arg2) {
376
        BaseCodes args = args();
377
        args.add(arg1);
378
        args.add(arg2);
379
        return function(name, Caller.BINARY_OPERATOR, args);
380
    }
381

    
382
    @Override
383
    public Code not(Code op1) {
384
        return operator(NotOperator.NAME, op1);
385
    }
386

    
387
    @Override
388
    public Code negate(Code op1) {
389
        return operator(NegOperator.NAME, op1);
390
    }
391

    
392
    @Override
393
    public Code concat(Code op1, Code op2) {
394
        return operator(ConcatOperator.NAME, op1, op2);
395
    }
396

    
397
    @Override
398
    public Code add(Code op1, Code op2) {
399
        return operator(AddOperator.NAME, op1, op2);
400
    }
401

    
402
    @Override
403
    public Code subst(Code op1, Code op2) {
404
        return operator(SubstOperator.NAME, op1, op2);
405
    }
406

    
407
    @Override
408
    public Code mult(Code op1, Code op2) {
409
        return operator(MulOperator.NAME, op1, op2);
410
    }
411

    
412
    @Override
413
    public Code div(Code op1, Code op2) {
414
        return operator(DivOperator.NAME, op1, op2);
415
    }
416

    
417
    @Override
418
    public Code mod(Code op1, Code op2) {
419
        return operator(ModOperator.NAME, op1, op2);
420
    }
421

    
422
    @Override
423
    public Code or(Code op1, Code op2) {
424
        return operator(OrOperator.NAME, op1, op2);
425
    }
426

    
427
    @Override
428
    public Code and(Code op1, Code op2) {
429
        return operator(AndOperator.NAME, op1, op2);
430
    }
431

    
432
    @Override
433
    public Code like(Code op1, Code op2) {
434
        return operator(LikeOperator.NAME, op1, op2);
435
    }
436

    
437
    @Override
438
    public Code ilike(Code op1, Code op2) {
439
        return operator(IlikeOperator.NAME, op1, op2);
440
    }
441

    
442
    @Override
443
    public Code regexp(Code op1, Code op2) {
444
        return operator(RegExpOperator.NAME, op1, op2);
445
    }
446

    
447
    @Override
448
    public Code lt(Code op1, Code op2) {
449
        return operator(LtOperator.NAME, op1, op2);
450
    }
451

    
452
    @Override
453
    public Code gt(Code op1, Code op2) {
454
        return operator(GtOperator.NAME, op1, op2);
455
    }
456

    
457
    @Override
458
    public Code le(Code op1, Code op2) {
459
        return operator(LeOperator.NAME, op1, op2);
460
    }
461

    
462
    @Override
463
    public Code ge(Code op1, Code op2) {
464
        return operator(GeOperator.NAME, op1, op2);
465
    }
466

    
467
    @Override
468
    public Code eq(Code op1, Code op2) {
469
        return operator(EqOperator.NAME, op1, op2);
470
    }
471

    
472
    @Override
473
    public Code ne(Code op1, Code op2) {
474
        return operator(NeOperator.NAME, op1, op2);
475
    }
476

    
477
    @Override
478
    public Code is(Code op1, Code op2) {
479
        return operator(IsOperator.NAME, op1, op2);
480
    }
481

    
482
    @Override
483
    public Code getattr(Code obj, String attrname) {
484
        BaseCodes args = args();
485
        args.add(obj);
486
        args.add(constant(attrname));
487
        return function(GetattrFunction.NAME, args);
488
    }    
489

    
490
    @Override
491
    public Code getitem(Code obj, Code index) {
492
        BaseCodes args = args();
493
        args.add(obj);
494
        args.add(index);
495
        return function(GetitemFunction.NAME, args);
496
    }
497

    
498
    
499
}