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

History | View | Annotate | Download (11.7 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
import java.util.List;
6
import org.apache.commons.lang3.StringUtils;
7
import org.gvsig.expressionevaluator.Code;
8
import static org.gvsig.expressionevaluator.Code.CALLER;
9
import static org.gvsig.expressionevaluator.Code.CONSTANT;
10
import static org.gvsig.expressionevaluator.Code.IDENTIFIER;
11
import static org.gvsig.expressionevaluator.Code.UNDEFINED;
12
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
import org.gvsig.expressionevaluator.Code.Method;
17
import org.gvsig.expressionevaluator.CodeBuilder;
18
import org.gvsig.expressionevaluator.Function;
19
import org.gvsig.expressionevaluator.Interpreter;
20
import org.gvsig.tools.exception.BaseException;
21
import org.gvsig.tools.visitor.Visitor;
22

    
23
public class DefaultCodeBuilder implements CodeBuilder {
24

    
25
    public class BaseCode implements Code {
26

    
27
        @Override
28
        public int code() {
29
            return UNDEFINED;
30
        }
31

    
32
//        @Override
33
//        public String toString() {
34
//            return this.toString(this);
35
//        }
36
//
37
//        private String toString(Code code) {
38
//            StringBuilder builder = new StringBuilder();
39
//            switch( code.code() ) {
40
//            case CONSTANT: {
41
//                Object value = ((Constant) code).value();
42
//                if( value instanceof CharSequence ) {
43
//                    value = StringUtils.wrap(value.toString(), "'");
44
//                }
45
//                builder.append(value);
46
//            }
47
//            break;
48
//
49
//            case IDENTIFIER:
50
//                builder.append(((Identifier) code).name());
51
//                break;
52
//
53
//            case CALLER:
54
//                Caller caller = (Caller) code;
55
//                builder.append(caller.name());
56
//                builder.append("(");
57
//                if( caller.args() != null ) {
58
//                    boolean skipcoma = true;
59
//                    for( Code arg : caller.args() ) {
60
//                        if( skipcoma ) {
61
//                            skipcoma = false;
62
//                        } else {
63
//                            builder.append(", ");
64
//                        }
65
//                        builder.append(toString(arg));
66
//                    }
67
//                }
68
//                builder.append(")");
69
//                break;
70
//            }
71
//            return builder.toString();
72
//        }
73

    
74
        @Override
75
        public void accept(Visitor visitor) throws BaseException {
76
            visitor.visit(this);
77
        }
78

    
79
    }
80

    
81
    class BaseConstant extends BaseCode implements Constant {
82

    
83
        private final Object value;
84

    
85
        public BaseConstant(Object value) {
86
            this.value = value;
87
        }
88

    
89
        @Override
90
        public int code() {
91
            return CONSTANT;
92
        }
93

    
94
        @Override
95
        public Object value() {
96
            return this.value;
97
        }
98

    
99
        @Override
100
        public String toString() {
101
            StringBuilder builder = new StringBuilder();
102
            Object v = this.value();
103
            if( v instanceof CharSequence ) {
104
                v = StringUtils.wrap(v.toString(), "'");
105
            }
106
            builder.append(v);
107
            return builder.toString();
108
        }
109

    
110
    }
111

    
112
    public class BaseIdentifier extends BaseCode implements Identifier {
113

    
114
        String name;
115

    
116
        public BaseIdentifier(String name) {
117
            this.name = name;
118
        }
119

    
120
        @Override
121
        public int code() {
122
            return IDENTIFIER;
123
        }
124

    
125
        @Override
126
        public String name() {
127
            return this.name;
128
        }
129

    
130
        @Override
131
        public String toString() {
132
            StringBuilder builder = new StringBuilder();
133
            builder.append("\"");
134
            builder.append(this.name());
135
            builder.append("\"");
136
            return builder.toString();
137
        }
138

    
139
    }
140

    
141
    public class BaseArguments implements Arguments {
142

    
143
        private final List<Code> args;
144

    
145
        public BaseArguments() {
146
            this.args = new ArrayList<>();
147
        }
148

    
149
        @Override
150
        public int count() {
151
            if( args == null ) {
152
                return 0;
153
            }
154
            return this.args.size();
155
        }
156

    
157
        public void add(Code arg) {
158
            this.args.add(arg);
159
        }
160

    
161
        @Override
162
        public Iterator<Code> iterator() {
163
            return this.args.iterator();
164
        }
165

    
166
        @Override
167
        public Code get(int n) {
168
            return this.args.get(n);
169
        }
170

    
171
        @Override
172
        public void accept(Visitor visitor) throws BaseException {
173
            for( Code arg : this.args ) {
174
                visitor.visit(arg);
175
            }
176
        }
177

    
178
        @Override
179
        public String toString() {
180
            if( args != null ) {
181
                StringBuilder builder = new StringBuilder();
182
                boolean skipcoma = true;
183
                for( Code arg : args ) {
184
                    if( skipcoma ) {
185
                        skipcoma = false;
186
                    } else {
187
                        builder.append(", ");
188
                    }
189
                    builder.append(arg.toString());
190
                }
191
                return builder.toString();
192
            }
193
            return "";
194
        }
195

    
196
    }
197

    
198
    public class BaseCaller extends BaseCode implements Caller {
199

    
200
        private final String name;
201
        private final Arguments args;
202
        private Function function;
203
        private final int type;
204

    
205
        public BaseCaller(String name, int type, Arguments args) {
206
            this.name = name;
207
            this.args = args;
208
            this.type = type;
209
            this.function = null;
210
        }
211

    
212
        @Override
213
        public int code() {
214
            return CALLER;
215
        }
216

    
217
        @Override
218
        public Object call(Interpreter interpreter, Object[] args) throws Exception {
219
            return this.function.call(interpreter, args);
220
        }
221

    
222
        @Override
223
        public String name() {
224
            return this.name;
225
        }
226

    
227
        @Override
228
        public Function function() {
229
            return this.function;
230
        }
231

    
232
        @Override
233
        public Function function(Function function) {
234
            this.function = function;
235
            return this.function;
236
        }
237

    
238
        @Override
239
        public Code.Caller.Arguments args() {
240
            return this.args;
241
        }
242

    
243
        @Override
244
        public int type() {
245
            return this.type;
246
        }
247

    
248
        @Override
249
        public void accept(Visitor visitor) throws BaseException {
250
            visitor.visit(this);
251
            this.args.accept(visitor);
252
        }
253

    
254
        @Override
255
        public String toString() {
256
            StringBuilder builder = new StringBuilder();
257
            builder.append(this.name());
258
            builder.append("(");
259
            if( this.args()!=null ) {
260
                builder.append(this.args().toString());
261
            }
262
            builder.append(")");
263
            return builder.toString();
264
        }
265

    
266
    }
267

    
268
    public class BaseMethod extends BaseCaller implements Method {
269

    
270
        private final Code obj;
271
        private final String methodname;
272
        
273
        public BaseMethod(Code obj, String methodname, Arguments args) {
274
            super(methodname, FUNCTION, args);
275
            this.obj = obj;
276
            this.methodname = methodname;
277
        }
278

    
279
        @Override
280
        public int code() {
281
            return METHOD;
282
        }
283
        
284
        @Override
285
        public String methodname() {
286
            return this.methodname;
287
        }
288

    
289
        @Override
290
        public Code obj() {
291
            return this.obj;
292
        }
293

    
294
        @Override
295
        public String toString() {
296
            StringBuilder builder = new StringBuilder();
297
            builder.append(this.obj.toString());
298
            builder.append("->");
299
            builder.append(this.methodname());
300
            builder.append("(");
301
            if( this.args()!=null ) {
302
                builder.append(this.args().toString());
303
            }
304
            builder.append(")");
305
            return builder.toString();
306
        }
307
    }    
308
    
309
    @Override
310
    public CodeBuilder clone() throws CloneNotSupportedException {
311
        // This implementation of CodeBuilder does not maintain state, so 
312
        // we only call the super class.
313
        DefaultCodeBuilder other = (DefaultCodeBuilder) super.clone();
314
        return other;
315
    }
316

    
317
    @Override
318
    public Constant constant(Object value) {
319
        return new BaseConstant(value);
320
    }
321

    
322
    @Override
323
    public Identifier identifier(String name) {
324
        return new BaseIdentifier(name);
325
    }
326

    
327
    @Override
328
    public Caller.Arguments args() {
329
        return new BaseArguments();
330
    }
331

    
332
    @Override
333
    public Caller function(String name, int type, Arguments args) {
334
        return new BaseCaller(name, type, args);
335
    }
336

    
337
    @Override
338
    public Caller function(String name, Arguments args) {
339
        return function(name, Caller.FUNCTION, args);
340
    }
341
    
342
    @Override
343
    public Code method(Code obj, String methodname, Arguments methodargs) {
344
        Method m = new BaseMethod(obj, methodname, methodargs);
345
        return m;
346
    }
347
    
348
    @Override
349
    public Caller operator(String name, Code arg1) {
350
        Arguments args = args();
351
        ((BaseArguments)args).add(arg1);
352
        return function(name, Caller.UNARY_OPERATOR, args);
353
    }
354

    
355
    @Override
356
    public Caller operator(String name, Code arg1, Code arg2) {
357
        Arguments args = args();
358
        ((BaseArguments)args).add(arg1);
359
        ((BaseArguments)args).add(arg2);
360
        return function(name, Caller.BINARY_OPERATOR, args);
361
    }
362

    
363
    @Override
364
    public Code not(Code op1) {
365
        return operator("not", op1);
366
    }
367

    
368
    @Override
369
    public Code add(Code op1, Code op2) {
370
        return operator("+", op1, op2);
371
    }
372

    
373
    @Override
374
    public Code subst(Code op1, Code op2) {
375
        return operator("-", op1, op2);
376
    }
377

    
378
    @Override
379
    public Code mult(Code op1, Code op2) {
380
        return operator("*", op1, op2);
381
    }
382

    
383
    @Override
384
    public Code div(Code op1, Code op2) {
385
        return operator("/", op1, op2);
386
    }
387

    
388
    @Override
389
    public Code mod(Code op1, Code op2) {
390
        return operator("%", op1, op2);
391
    }
392

    
393
    @Override
394
    public Code or(Code op1, Code op2) {
395
        return operator("or", op1, op2);
396
    }
397

    
398
    @Override
399
    public Code and(Code op1, Code op2) {
400
        return operator("and", op1, op2);
401
    }
402

    
403
    @Override
404
    public Code like(Code op1, Code op2) {
405
        return operator("like", op1, op2);
406
    }
407

    
408
    @Override
409
    public Code ilike(Code op1, Code op2) {
410
        return operator("ilike", op1, op2);
411
    }
412

    
413
    @Override
414
    public Code regexp(Code op1, Code op2) {
415
        return operator("~", op1, op2);
416
    }
417

    
418
    @Override
419
    public Code lt(Code op1, Code op2) {
420
        return operator("<", op1, op2);
421
    }
422

    
423
    @Override
424
    public Code gt(Code op1, Code op2) {
425
        return operator(">", op1, op2);
426
    }
427

    
428
    @Override
429
    public Code le(Code op1, Code op2) {
430
        return operator("<=", op1, op2);
431
    }
432

    
433
    @Override
434
    public Code ge(Code op1, Code op2) {
435
        return operator(">=", op1, op2);
436
    }
437

    
438
    @Override
439
    public Code eq(Code op1, Code op2) {
440
        return operator("=", op1, op2);
441
    }
442

    
443
    @Override
444
    public Code ne(Code op1, Code op2) {
445
        return operator("<>", op1, op2);
446
    }
447

    
448
    @Override
449
    public Code is(Code op1, Code op2) {
450
        return operator("is", op1, op2);
451
    }
452

    
453
    @Override
454
    public Code getattr(Code obj, String attrname) {
455
        Arguments args = args();
456
        ((BaseArguments)args).add(obj);
457
        ((BaseArguments)args).add(constant(attrname));
458
        return function("getattr", args);
459
    }    
460

    
461
}