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 / DefaultExpressionBuilder.java @ 44053

History | View | Annotate | Download (43.1 KB)

1
package org.gvsig.expressionevaluator.impl;
2

    
3
import java.text.MessageFormat;
4
import java.util.ArrayList;
5
import java.util.Collection;
6
import java.util.Collections;
7
import java.util.HashMap;
8
import java.util.HashSet;
9
import java.util.List;
10
import java.util.Map;
11
import java.util.Objects;
12
import java.util.Set;
13
import org.apache.commons.lang3.ObjectUtils;
14
import org.apache.commons.lang3.StringUtils;
15
import org.cresques.cts.IProjection;
16
import org.gvsig.fmap.geom.Geometry;
17
import org.gvsig.fmap.geom.primitive.Envelope;
18

    
19
import org.gvsig.expressionevaluator.ExpressionBuilder;
20

    
21
@SuppressWarnings({"UseSpecificCatch","OverridableMethodCallInConstructor"})
22
public class DefaultExpressionBuilder implements ExpressionBuilder {
23

    
24
    public class ConfigBase implements Config {
25

    
26
        protected Map<String, Object> values;
27

    
28
        public ConfigBase() {
29
            this.values = new HashMap<>();
30

    
31
            this.set(Config.has_spatial_functions, true);
32
            this.set(Config.support_schemas, true);
33
            this.set(Config.constant_true, "(1=1)");
34
            this.set(Config.constant_false, "(1=2)");
35
            this.set(Config.quote_for_identifiers, "\"");
36
            this.set(Config.quote_for_strings, "'");
37
            this.set(Config.geometry_type_support, GeometrySupportType.WKB);
38
            this.set(Config.group, "( {0} )");
39

    
40
            this.set(Config.ST_SRID, "ST_SRID({0})");
41
            this.set(Config.ST_AsText, "ST_AsText({0})");
42
            this.set(Config.ST_AsBinary, "ST_AsBinary({0})");
43
            this.set(Config.ST_AsEWKB, "ST_AsEWKB({0})");
44
            this.set(Config.ST_Contains, "ST_Contains(({0}), ({1}))");
45
            this.set(Config.ST_Crosses, "ST_Crosses(({0}), ({1}))");
46
            this.set(Config.ST_Disjoint, "ST_Disjoint(({0}), ({1}))");
47
            this.set(Config.ST_Equals, "ST_Equals(({0}), ({1}))");
48
            this.set(Config.ST_IsClosed, "ST_IsClosed({0})");
49
            this.set(Config.ST_Overlaps, "ST_Overlaps(({0}), ({1}))");
50
            this.set(Config.ST_Touches, "ST_Touches(({0}), ({1}))");
51
            this.set(Config.ST_Within, "ST_Within(({0}), ({1}))");
52
            this.set(Config.ST_Envelope, "ST_Envelope({0})");
53
            this.set(Config.ST_Intersects, "ST_Intersects(({0}), ({1}))");
54
            this.set(Config.ST_GeomFromText, "ST_GeomFromText({0}, ({1}))");
55
            this.set(Config.ST_GeomFromWKB, "ST_GeomFromWKB(({0}), ({1}))");
56
            this.set(Config.ST_GeomFromEWKB, "ST_GeomFromEWKB(({0}), ({1}))");
57
            
58
            // Por defecto no esta disponible la funcion ST_Simplify
59
            // this.set(Config.ST_Simplify, "ST_Simplify(({0}), ({1}))");
60
            this.remove_functionality(Config.ST_Simplify);
61
            
62
            this.set(Config.lcase, "LCASE({0})");
63
            this.set(Config.ucase, "UCASE({0})");
64
            this.set(Config.iif, "IIF({0},{1},{2})");
65
            this.set(Config.ifnull, "IFNULL({0},{1},{2})");
66
            
67
            this.set(Config.isNull, "( ({0}) IS NULL )");
68
            this.set(Config.notIsNull, "( ({0}) NOT IS NULL )");
69
            this.set(Config.operator_not, "( NOT ({0}) )");
70

    
71
            this.set(Config.operator_AND, "{0} AND {1}");
72
            this.set(Config.operator_OR, "{0} OR {1}");
73
            this.set(Config.operator_EQ, "( ({0}) = ({1}) )");
74
            this.set(Config.operator_NE, "( ({0}) <> ({1}) )");
75
            this.set(Config.operator_GT, "( ({0}) > ({1}) )");
76
            this.set(Config.operator_GE, "( ({0}) >= ({1}) )");
77
            this.set(Config.operator_LT, "( ({0}) < ({1}) )");
78
            this.set(Config.operator_LE, "( ({0}) <= ({1}) )");
79
            this.set(Config.operator_LIKE, "( ({0}) LIKE ({1}) )");
80
            this.set(Config.operator_ILIKE, "( ({0}) ILIKE ({1}) )");
81

    
82
            this.set(Config.operator_add, "{0} + {1}");
83
            this.set(Config.operator_subst, "{0} - {1}");
84
            this.set(Config.operator_mult, "{0} * {1}");
85
            this.set(Config.operator_div, "{0} / {1}");
86
            this.set(Config.operator_concat, "{0} || {1}");
87

    
88
        }
89

    
90
        @Override
91
        public boolean has_functionality(String functionality) {
92
            Object x = this.values.get(functionality);
93
            if (x == null) {
94
                return false;
95
            }
96
            if (x instanceof CharSequence && StringUtils.isEmpty((CharSequence) x)) {
97
                return false;
98
            }
99
            return true;
100
        }
101

    
102
        @Override
103
        public void remove_functionality(String functionality) {
104
            this.values.remove(functionality);
105
        }
106

    
107
        @Override
108
        public boolean has_spatial_functions() {
109
            return this.getBoolean(has_spatial_functions);
110
        }
111

    
112
        @Override
113
        public GeometrySupportType getGeometryTypeSupport() {
114
            return (GeometrySupportType) this.get(geometry_type_support);
115
        }
116

    
117
        @Override
118
        public boolean getBoolean(String name) {
119
            return (boolean) this.values.get(name);
120
        }
121

    
122
        @Override
123
        public String getString(String name) {
124
            return (String) this.values.get(name);
125
        }
126

    
127
        @Override
128
        public Object get(String name) {
129
            return this.values.get(name);
130
        }
131

    
132
        @Override
133
        public void set(String name, Object value) {
134
            this.values.put(name, value);
135
        }
136
    }
137

    
138
    public abstract class AbstractValue implements Value {
139

    
140
        @Override
141
        public void accept(Visitor visitor, VisitorFilter filter) {
142
            if (filter == null || filter.accept(this)) {
143
                visitor.visit(this);
144
            }
145
        }
146

    
147
    }
148

    
149
    public class ClassVisitorFilter implements VisitorFilter {
150

    
151
        private final Class classFilter;
152

    
153
        public ClassVisitorFilter(Class classFilter) {
154
            this.classFilter = classFilter;
155
        }
156

    
157
        @Override
158
        public boolean accept(Visitable visitable) {
159
            return classFilter.isInstance(visitable);
160
        }
161

    
162
    }
163

    
164
    public class GroupBase extends AbstractValue implements Group {
165

    
166
        protected Value value;
167

    
168
        public GroupBase(Value value) {
169
            this.value = value;
170
        }
171

    
172
        @Override
173
        public Value getValue() {
174
            return value;
175
        }
176

    
177
        @Override
178
        public void accept(Visitor visitor, VisitorFilter filter) {
179
            super.accept(visitor, filter);
180
            this.value.accept(visitor, filter);
181
        }
182

    
183
        @Override
184
        public String toString() {
185
            return MessageFormat.format(config.getString(Config.group), this.value.toString());
186
        }
187
    }
188

    
189
    public class VariableBase extends AbstractValue implements Variable {
190

    
191
        protected String name;
192

    
193
        public VariableBase(String name) {
194
            this.name = name;
195
        }
196

    
197
        @Override
198
        public String getName() {
199
            return this.name;
200
        }
201

    
202
        @Override
203
        public String toString() {
204
            return identifier(this.name);
205
        }
206

    
207
        @Override
208
        public int compareTo(Variable o) {
209
            return this.name.compareTo(o.getName());
210
        }
211

    
212
        @Override
213
        public boolean equals(Object obj) {
214
            if (!(obj instanceof Variable)) {
215
                return false;
216
            }
217
            return this.name.equals(((Variable) obj).getName());
218
        }
219

    
220
        @Override
221
        public int hashCode() {
222
            int hash = 7;
223
            hash = 37 * hash + Objects.hashCode(this.name);
224
            return hash;
225
        }
226
    }
227

    
228
    public class ParameterBase extends AbstractValue implements Parameter {
229

    
230
        protected String name;
231
        protected Object value;
232
        protected ParameterType type;
233
        protected Value srs;
234

    
235
        public ParameterBase() {
236
            this.type = ParameterType.Constant;
237
            this.name = null;
238
            this.value = null;
239
        }
240

    
241
        @Override
242
        public void accept(Visitor visitor, VisitorFilter filter) {
243
            super.accept(visitor, filter);
244
            if (this.srs != null) {
245
                this.srs.accept(visitor, filter);
246
            }
247
        }
248

    
249
        @Override
250
        public Parameter as_geometry_variable() {
251
            this.type = ParameterType.Geometry;
252
            if (this.value == null && this.name != null) {
253
                this.value = this.name;
254
            }
255
            return this;
256
        }
257

    
258
        @Override
259
        public Parameter as_constant() {
260
            this.type = ParameterType.Constant;
261
            if (this.value == null && this.name != null) {
262
                this.value = this.name;
263
            }
264
            return this;
265
        }
266

    
267
        @Override
268
        public Parameter as_variable() {
269
            this.type = ParameterType.Variable;
270
            if (this.value != null && this.name == null) {
271
                this.name = (String) this.value;
272
            }
273
            return this;
274
        }
275

    
276
        @Override
277
        public Parameter srs(Value srs) {
278
            this.srs = srs;
279
            if( this.type == ParameterType.Variable ) {
280
                this.type = ParameterType.Geometry;
281
            }
282
            return this;
283
        }
284

    
285
        @Override
286
        public Parameter srs(IProjection srs) {
287
            this.srs = constant(getSRSId(srs));
288
            if( this.type == ParameterType.Variable ) {
289
                this.type = ParameterType.Geometry;
290
            }
291
            return this;
292
        }
293

    
294
        @Override
295
        public String getName() {
296
            switch (this.type) {
297
                case Variable:
298
                case Geometry:
299
                    return this.name;
300
                case Constant:
301
                    if (this.value == null) {
302
                        return null;
303
                    }
304
                    return this.value.toString();
305
                default:
306
                    if (this.name != null) {
307
                        return this.name;
308
                    }
309
                    if (this.value != null) {
310
                        return this.value.toString();
311
                    }
312
                    return null;
313
            }
314
        }
315

    
316
        @Override
317
        public boolean is_constant() {
318
            return this.type == ParameterType.Constant;
319
        }
320

    
321
        @Override
322
        public boolean is_geometry_variable() {
323
            return this.type == ParameterType.Geometry;
324
        }
325

    
326
        @Override
327
        public boolean is_variable() {
328
            return this.type == ParameterType.Variable;
329
        }
330

    
331
        @Override
332
        public Parameter value(Object value) {
333
            this.value = value;
334
            return this;
335
        }
336

    
337
        @Override
338
        public Parameter name(String name) {
339
            this.type = ParameterType.Variable;
340
            this.name = name;
341
            return this;
342
        }
343

    
344
        @Override
345
        public Object getValue() {
346
            try {
347
                switch (this.type) {
348
                    case Constant:
349
                        if (this.value instanceof Geometry) {
350
                            switch (config.getGeometryTypeSupport()) {
351
                                case EWKB:
352
                                    return bytearray(((Geometry) this.value).convertToEWKB());
353
                                case NATIVE:
354
                                case WKB:
355
                                    return bytearray(((Geometry) this.value).convertToWKB());
356
                                case WKT:
357
                                default:
358
                                    return ((Geometry) this.value).convertToWKT();
359
                            }
360
                        } else if (this.value instanceof IProjection) {
361
                            return getSRSId((IProjection) this.value);
362
                        }
363
                        return this.value;
364
                    case Variable:
365
                    case Geometry:
366
                    default:
367
                        return this.value;
368
                }
369
            } catch (Exception ex) {
370
                throw new RuntimeException("Can't get value from parameter.", ex);
371
            }
372
        }
373

    
374
        @Override
375
        public ParameterType getType() {
376
            return this.type;
377
        }
378

    
379
        @Override
380
        public Value getSRS() {
381
            return this.srs;
382
        }
383

    
384
        @Override
385
        public String toString() {
386
            switch (this.type) {
387
                case Constant:
388
                case Variable:
389
                default:
390
                    return "?";
391
                case Geometry:
392
                    switch (config.getGeometryTypeSupport()) {
393
                        case EWKB:
394
                            return MessageFormat.format(
395
                                    config.getString(Config.ST_GeomFromEWKB),
396
                                    "?",
397
                                    String.valueOf(this.srs.toString())
398
                            );
399
                        case WKB:
400
                            return MessageFormat.format(
401
                                    config.getString(Config.ST_GeomFromWKB),
402
                                    "?",
403
                                    String.valueOf(this.srs.toString())
404
                            );
405
                        case WKT:
406
                        default:
407
                            return MessageFormat.format(
408
                                    config.getString(Config.ST_GeomFromText),
409
                                    "?",
410
                                    String.valueOf(this.srs.toString())
411
                            );
412
                    }
413
            }
414
        }
415
    }
416

    
417
    public class ConstantBase extends AbstractValue implements Constant {
418

    
419
        protected Object value;
420

    
421
        public ConstantBase(Object value) {
422
            this.value = value;
423
        }
424

    
425
        @Override
426
        public Object getValue() {
427
            return this.value;
428
        }
429

    
430
        @Override
431
        public String toString() {
432
            if (this.value instanceof String) {
433
                return string((String) this.value);
434
            }
435
            if (this.value instanceof Boolean) {
436
                if (((Boolean) this.value)) {
437
                    return config.getString(Config.constant_true);
438
                } else {
439
                    return config.getString(Config.constant_false);
440
                }
441
            }
442
            return ObjectUtils.toString(this.value, "");
443
        }
444
    }
445

    
446
    public class CustomBase extends AbstractValue implements Custom {
447

    
448
        protected Object value;
449

    
450
        // Esto es para permitir declarar parametros y columnas en una seccion
451
        // custom.
452
        protected List<Value> values;
453

    
454
        public CustomBase(Object value) {
455
            this.value = value;
456
        }
457

    
458
        @Override
459
        public void accept(Visitor visitor, VisitorFilter filter) {
460
            super.accept(visitor, filter);
461
            if (this.values != null) {
462
                for (Value theValue : values) {
463
                    theValue.accept(visitor, filter);
464
                }
465
            }
466
        }
467

    
468
        @Override
469
        public Object getValue() {
470
            return this.value;
471
        }
472

    
473
        @Override
474
        public Custom add(Variable variable) {
475
            if (this.values == null) {
476
                this.values = new ArrayList<>();
477
            }
478
            this.values.add(variable);
479
            return this;
480
        }
481

    
482
        @Override
483
        public Custom add(Parameter parameter) {
484
            if (this.values == null) {
485
                this.values = new ArrayList<>();
486
            }
487
            this.values.add(parameter);
488
            return this;
489
        }
490

    
491
        @Override
492
        public String toString() {
493
            return ObjectUtils.toString(this.value, "");
494
        }
495
    }
496

    
497
    public class GeometryValueBase extends AbstractValue implements GeometryValue {
498

    
499
        protected Geometry geometry;
500
        protected IProjection projection;
501

    
502
        public GeometryValueBase(Geometry geometry, IProjection projection) {
503
            this.geometry = geometry;
504
            this.projection = projection;
505
        }
506

    
507
        @Override
508
        public Geometry getGeometry() {
509
            return this.geometry;
510
        }
511

    
512
        @Override
513
        public IProjection getSRS() {
514
            return this.projection;
515
        }
516

    
517
        @Override
518
        public String toString() {
519
            try {
520
                switch (config.getGeometryTypeSupport()) {
521
                    case EWKB:
522
                        return MessageFormat.format(
523
                                config.getString(Config.ST_GeomFromEWKB),
524
                                bytearray(this.geometry.convertToEWKB()),
525
                                String.valueOf(getSRSId(this.projection))
526
                        );
527
                    case WKB:
528
                        return MessageFormat.format(
529
                                config.getString(Config.ST_GeomFromWKB),
530
                                bytearray(this.geometry.convertToWKB()),
531
                                String.valueOf(getSRSId(this.projection))
532
                        );
533
                    case WKT:
534
                    default:
535
                        return MessageFormat.format(
536
                                config.getString(Config.ST_GeomFromText),
537
                                string(this.geometry.convertToWKT()),
538
                                String.valueOf(getSRSId(this.projection))
539
                        );
540
                }
541
            } catch (Exception ex) {
542
                throw new RuntimeException("Can't convert geometry to string.", ex);
543
            }
544
        }
545
    }
546

    
547
    public class FunctionBase extends AbstractValue implements Function {
548

    
549
        protected String name;
550
        protected String format;
551
        protected List<Value> parameters;
552

    
553
        public FunctionBase(String name, String format) {
554
            this.name = name;
555
            this.format = format;
556
        }
557

    
558
        public FunctionBase(String name) {
559
            this(name,null);
560
        }
561
        
562
        @Override
563
        public List<Value> parameters() {
564
            if (this.parameters == null) {
565
                this.parameters = new ArrayList<>();
566
            }
567
            return this.parameters;
568
        }
569

    
570
        @Override
571
        public Function parameter(Value parameter) {
572
            this.parameters().add(parameter);
573
            return this;
574
        }
575

    
576
        @Override
577
        public String getName() {
578
            return this.name;
579
        }
580

    
581
        @Override
582
        public void accept(Visitor visitor, VisitorFilter filter) {
583
            super.accept(visitor, filter);
584
            for (Value value : this.parameters) {
585
                value.accept(visitor, filter);
586
            }
587
        }
588

    
589
        @Override
590
        public String toString() {
591
            if( this.format==null ) {
592
                StringBuilder builder = new StringBuilder();
593
                builder.append(name);
594
                builder.append("(");
595
                if (this.parameters != null && !this.parameters.isEmpty()) {
596
                    boolean first = true;
597
                    for (Value value : this.parameters) {
598
                        if( first ) {
599
                            first=false;
600
                            builder.append(value.toString());
601
                        } else {
602
                            builder.append(", ");
603
                            builder.append(value.toString());
604
                        }
605
                    }
606
                }
607
                builder.append(")");
608
                return builder.toString();
609
            }
610
            if (this.parameters != null && !this.parameters.isEmpty()) {
611
                List<String> values = new ArrayList<>();
612
                for (Value value : this.parameters) {
613
                    values.add(value.toString());
614
                }
615
                return MessageFormat.format(format, values.toArray());
616
            } else {
617
                return this.format;
618
            }
619
        }
620
    }
621

    
622
    public class BinaryOperatorBase extends AbstractValue implements BinaryOperator {
623

    
624
        protected String name;
625
        protected String format;
626
        protected Value left;
627
        protected Value right;
628

    
629
        public BinaryOperatorBase(String name, String format) {
630
            this.name = name;
631
            this.format = format;
632
        }
633

    
634
        @Override
635
        public String getName() {
636
            return this.name;
637
        }
638

    
639
        @Override
640
        public void accept(Visitor visitor, VisitorFilter filter) {
641
            super.accept(visitor, filter);
642
            this.left.accept(visitor, filter);
643
            this.right.accept(visitor, filter);
644
        }
645

    
646
        @Override
647
        public BinaryOperator setLeft(Value operand) {
648
            this.left = operand;
649
            return this;
650
        }
651

    
652
        @Override
653
        public BinaryOperator setRight(Value operand) {
654
            this.right = operand;
655
            return this;
656
        }
657

    
658
        @Override
659
        public Value getLeft() {
660
            return this.left;
661
        }
662

    
663
        @Override
664
        public Value getRight() {
665
            return this.right;
666
        }
667

    
668
        @Override
669
        public String toString() {
670
            return MessageFormat.format(
671
                    format,
672
                    this.left.toString(),
673
                    this.right.toString()
674
            );
675
        }
676
    }
677

    
678
    protected Value value;
679
    protected Config config;
680

    
681
    public DefaultExpressionBuilder() {
682
        this.config = new ConfigBase();
683
    }
684

    
685
    @Override
686
    public ExpressionBuilder createExpressionBuilder() {
687
        return new DefaultExpressionBuilder();
688
    }
689

    
690
    @Override
691
    public Config getConfig() {
692
        return this.config;
693
    }
694

    
695
    @Override
696
    public Value getValue() {
697
        return this.value;
698
    }
699

    
700
    @Override
701
    public ExpressionBuilder setValue(Value value) {
702
        this.value = value;
703
        return this;
704
    }
705

    
706
    @Override
707
    public String toString() {
708
        return this.value.toString();
709
    }
710

    
711
    @Override
712
    public void accept(Visitor visitor, VisitorFilter filter) {
713
        if( this.value == null) {
714
            return;
715
        }
716
        this.value.accept(visitor, filter);
717
    }
718

    
719
    @Override
720
    public boolean has_spatial_functions() {
721
        return this.config.getBoolean(Config.has_spatial_functions);
722
    }
723

    
724
    @Override
725
    public GeometrySupportType geometry_support_type() {
726
        return (GeometrySupportType) this.config.get(Config.geometry_type_support);
727
    }
728

    
729
    @Override
730
    public String string(String s) {
731
        String quote = this.config.getString(Config.quote_for_strings);
732
//        No se porque no esta disponible wrapIfMissing
733
//        return StringUtils.wrapIfMissing(s,quote);
734
        if (s.startsWith(quote)) {
735
            return s;
736
        }
737
        return quote + s + quote;
738
    }
739

    
740
    @Override
741
    public String identifier(String id) {
742
        String quote = this.config.getString(Config.quote_for_identifiers);
743
//        No se porque no esta disponible wrapIfMissing
744
//        return StringUtils.wrapIfMissing(id,quote);
745
        if (id.startsWith(quote)) {
746
            return id;
747
        }
748
        return quote + id + quote;
749
    }
750

    
751
    @Override
752
    public String bytearray(byte[] data) {
753
        return "DECODE('"+bytearray_hex(data)+"','hex')";
754
    }
755
    
756
    @Override
757
    public String bytearray_hex(byte[] data) {
758
        StringBuilder builder = new StringBuilder();
759
        for (byte abyte : data) {
760
            int v = abyte & 0xff;
761
            builder.append(String.format("%02x", v));
762
        }
763
        return builder.toString();
764
    }
765

    
766
    @Override
767
    public String bytearray_0x(byte[] data) {
768
        return "0x" + bytearray_hex(data);
769
    }
770

    
771
    @Override
772
    public String bytearray_x(byte[] data) {
773
        return "x'" + bytearray_hex(data) + "'";
774
    }
775
    
776
    @Override
777
    public Object getSRSId(IProjection projection) {
778
        if( projection==null ) {
779
            return 0;
780
        }
781
        return ProjectionUtils.getCode(projection);
782
    }
783

    
784
    @Override
785
    public Constant srs(IProjection projection) {
786
        return constant(getSRSId(projection));
787
    }
788

    
789
    @Override
790
    public Variable variable(String name) {
791
        return new VariableBase(name);
792
    }
793

    
794
    @Override
795
    public Variable column(String name) {
796
        return new VariableBase(name);
797
    }
798
    
799
    @Override
800
    public Parameter parameter(String name) {
801
        Parameters parameters = this.getParameters();
802
        Parameter parameter = parameters.get(name);
803
        if( parameter != null ) {
804
            return parameter;
805
        }
806
        parameter = this.parameter();
807
        parameter.name(name);
808
        return parameter;
809
    }
810
    
811
    @Override
812
    public Parameter parameter() {
813
        return new ParameterBase();
814
    }
815
    
816
    @Override
817
    public Constant constant(Object value) {
818
        return new ConstantBase(value);
819
    }
820

    
821
    @Override
822
    public Group group(Value value) {
823
        return new GroupBase(value);
824
    }
825

    
826
    @Override
827
    public GeometryValue geometry(Geometry geom, IProjection projection) {
828
        return new GeometryValueBase(geom, projection);
829
    }
830

    
831
    @Override
832
    public GeometryValue geometry(Geometry geom) {
833
        if( geom.getProjection()==null ) {
834
            throw new IllegalArgumentException("The geometry does not have an associated projection. Use 'geometry(Geometry, IProjection)'.");
835
        }
836
        return new GeometryValueBase(geom, geom.getProjection());
837
    }
838

    
839
    @Override
840
    public GeometryValue envelope(Envelope envelope, IProjection projection) {
841
        return new GeometryValueBase(envelope.getGeometry(), projection);
842
    }
843

    
844
    @Override
845
    public GeometryValue envelope(Envelope envelope) {
846
        if( envelope.getProjection()==null ) {
847
            throw new IllegalArgumentException("The envelope does not have an associated projection. Use 'envelope(Geometry, IProjection)'.");
848
        }
849
        return new GeometryValueBase(envelope.getGeometry(), envelope.getProjection());
850
    }
851

    
852
    @Override
853
    public Custom custom(Object value) {
854
        return new CustomBase(value);
855
    }
856

    
857
    public Function function(String name, Value... values) {
858
        FunctionBase func = new FunctionBase(name);
859
        for (Value theValue : values) {
860
            func.parameter(theValue);
861
        }
862
        return func;
863
    }
864

    
865
    public Function builtin_function(String name, String format, Value... values) {
866
        FunctionBase func = new FunctionBase(name, format);
867
        for (Value theValue : values) {
868
            func.parameter(theValue);
869
        }
870
        return func;
871
    }
872

    
873
    public BinaryOperator binaryOperator(String name, String format, Value leftOperand, Value rightOperand) {
874
        BinaryOperator operator = new BinaryOperatorBase(name, format);
875
        operator.setLeft(leftOperand);
876
        operator.setRight(rightOperand);
877
        return operator;
878
    }
879

    
880
    @Override
881
    public List<Variable> getVariables() {
882
        final Set<Variable> vars = new HashSet<>();
883
        this.accept(new Visitor() {
884
            @Override
885
            public void visit(Visitable value) {
886
                vars.add((Variable) value);
887
            }
888
        }, new ClassVisitorFilter(Variable.class));
889
        List<Variable> lvars = new ArrayList<>(vars);
890
        Collections.sort(lvars);
891
        return lvars;
892
    }
893

    
894
    private static class ParametersBase extends ArrayList<Parameter> implements Parameters {
895

    
896
        private static final long serialVersionUID = -2188534574151780470L;
897

    
898
        public ParametersBase() {
899
            super();
900
        }
901

    
902
        public ParametersBase(Collection parameters) {
903
            super(parameters);
904
        }
905

    
906
        @Override
907
        public Parameter get(String name) {
908
            if( name == null ) {
909
                return null;
910
            }
911
            for (Parameter param : this) {
912
                if( param.is_variable() || param.is_geometry_variable() ) {
913
                    if( name.equalsIgnoreCase(param.getName()) ) {
914
                        return param;
915
                    }
916
                }
917
            }
918
            return null;
919
        }
920

    
921
        
922
        @Override
923
        public String toString() {
924
            boolean first = true;
925
            StringBuilder builder = new StringBuilder();
926
            builder.append("{ ");
927
            for (Parameter param : this) {
928
                if (!first) {
929
                    builder.append(", ");
930
                } else {
931
                    first = false;
932
                }
933
                String s;
934
                Object value = param.getValue();
935
                if (value == null) {
936
                    s = "null";
937
                } else if (value instanceof String) {
938
                    s = "'" + (String) value + "'";
939
                } else {
940
                    s = value.toString();
941
                }
942
                switch (param.getType()) {
943
                    case Constant:
944
                        builder.append(s);
945
                        break;
946
                    case Geometry:
947
                        builder.append("(Geometry)");
948
                    case Variable:
949
                    default:
950
                        builder.append(param.getName());
951
                        builder.append(": ");
952
                        builder.append(s);
953
                }
954
            }
955
            builder.append(" }");
956
            return builder.toString();
957
        }
958
    }
959

    
960
    @Override
961
    public Parameters getParameters() {
962
        final Parameters params = new ParametersBase();
963
        this.accept(new Visitor() {
964
            @Override
965
            public void visit(Visitable value) {
966
                params.add((Parameter) value);
967
            }
968
        }, new ClassVisitorFilter(Parameter.class));
969
        return params;
970
    }
971

    
972
    @Override
973
    public Function getAsGeometry(Value value) {
974
        return builtin_function("ST_AsBinary", config.getString(Config.ST_AsBinary), value);
975
    }
976

    
977
    @Override
978
    public ExpressionBuilder set(Value value) {
979
        this.value = value;
980
        return this;
981
    }
982

    
983
    @Override
984
    public ExpressionBuilder and(Value value) {
985
        if (this.value == null) {
986
            return this.set(value);
987
        }
988
        BinaryOperator operator = binaryOperator("AND", config.getString(Config.operator_AND), this.value, value);
989
        this.value = operator;
990
        return this;
991
    }
992

    
993
    @Override
994
    public ExpressionBuilder or(Value value) {
995
        if (this.value == null) {
996
            return this.set(value);
997
        }
998
        BinaryOperator operator = binaryOperator("OR", config.getString(Config.operator_OR), this.value, value);
999
        this.value = operator;
1000
        return this;
1001
    }
1002

    
1003
    @Override
1004
    public Function ST_Intersects(Value geom1, Value geom2) {
1005
        return builtin_function("ST_Intersects", config.getString(Config.ST_Intersects), geom1, geom2);
1006
    }
1007

    
1008
    @Override
1009
    public Function ST_SRID(Value geom) {
1010
        return builtin_function("ST_SRID", config.getString(Config.ST_SRID), geom);
1011
    }
1012

    
1013
    @Override
1014
    public Function ST_Envelope(Value geom) {
1015
        return builtin_function("ST_Envelope", config.getString(Config.ST_Envelope), geom);
1016
    }
1017

    
1018
    @Override
1019
    public Function ST_AsText(Value geom) {
1020
        return builtin_function("ST_AsText", config.getString(Config.ST_AsText), geom);
1021
    }
1022

    
1023
    @Override
1024
    public Function ST_AsBinary(Value geom) {
1025
        return builtin_function("ST_AsBinary", config.getString(Config.ST_AsBinary), geom);
1026
    }
1027

    
1028
    @Override
1029
    public Function ST_AsEWKB(Value geom) {
1030
        return builtin_function("ST_AsEWKB", config.getString(Config.ST_AsEWKB), geom);
1031
    }
1032

    
1033
    @Override
1034
    public Function ST_GeomFromText(Value geom, Value crs) {
1035
        return builtin_function("ST_GeomFromText", config.getString(Config.ST_GeomFromText), geom, crs);
1036
    }
1037

    
1038
    @Override
1039
    public Function ST_GeomFromWKB(Value geom, Value crs) {
1040
        return builtin_function("ST_GeomFromWKB", config.getString(Config.ST_GeomFromWKB), geom, crs);
1041
    }
1042

    
1043
    @Override
1044
    public Function ST_GeomFromEWKB(Value geom, Value crs) {
1045
        return builtin_function("ST_GeomFromEWKB", config.getString(Config.ST_GeomFromEWKB), geom, crs);
1046
    }
1047

    
1048
    @Override
1049
    public Function ST_Simplify(Value geom, Value tolerance) {
1050
        return builtin_function("ST_Simplify", config.getString(Config.ST_Simplify), tolerance);
1051
    }
1052

    
1053
    @Override
1054
    public Function ST_Disjoint(Value geom1, Value geom2) {
1055
        return builtin_function("ST_Disjoint", config.getString(Config.ST_Disjoint), geom1, geom2);
1056
    }
1057

    
1058
    @Override
1059
    public Function ST_Contains(Value geom1, Value geom2) {
1060
        return builtin_function("ST_Contains", config.getString(Config.ST_Contains), geom1, geom2);
1061
    }
1062

    
1063
    @Override
1064
    public Function ST_Equals(Value geom1, Value geom2) {
1065
        return builtin_function("ST_Equals", config.getString(Config.ST_Equals), geom1, geom2);
1066
    }
1067

    
1068
    @Override
1069
    public Function ST_Crosses(Value geom1, Value geom2) {
1070
        return builtin_function("ST_Crosses", config.getString(Config.ST_Crosses), geom1, geom2);
1071
    }
1072

    
1073
    @Override
1074
    public Function ST_IsClosed(Value geom) {
1075
        return builtin_function("ST_IsClosed", config.getString(Config.ST_IsClosed), geom);
1076
    }
1077

    
1078
    @Override
1079
    public Function ST_Overlaps(Value geom1, Value geom2) {
1080
        return builtin_function("ST_Overlaps", config.getString(Config.ST_Overlaps), geom1, geom2);
1081
    }
1082

    
1083
    @Override
1084
    public Function ST_Touches(Value geom1, Value geom2) {
1085
        return builtin_function("ST_Touches", config.getString(Config.ST_Touches), geom1, geom2);
1086
    }
1087

    
1088
    @Override
1089
    public Function ST_Within(Value geom1, Value geom2) {
1090
        return builtin_function("ST_Within", config.getString(Config.ST_Within), geom1, geom2);
1091
    }
1092

    
1093
    @Override
1094
    public Function isNull(Value value) {
1095
        return builtin_function("IS NULL", config.getString(Config.isNull), value);
1096
    }
1097

    
1098
    @Override
1099
    public Function notIsNull(Value value) {
1100
        return builtin_function("NOT IS NULL", config.getString(Config.notIsNull), value);
1101
    }
1102

    
1103
    @Override
1104
    public Function not(Value value) {
1105
        return builtin_function("NOT", config.getString(Config.operator_not), value);
1106
    }
1107

    
1108
    @Override
1109
    public Function lcase(Value s) {
1110
        return builtin_function("LCASE", config.getString(Config.lcase), s);
1111
    }
1112

    
1113
    @Override
1114
    public Function ucase(Value s) {
1115
        return builtin_function("UCASE", config.getString(Config.ucase), s);
1116
    }
1117

    
1118
    @Override
1119
    public BinaryOperator and(Value leftOperand, Value rightOperand) {
1120
        return binaryOperator("AND", config.getString(Config.operator_AND), leftOperand, rightOperand);
1121
    }
1122

    
1123
    @Override
1124
    public BinaryOperator or(Value leftOperand, Value rightOperand) {
1125
        return binaryOperator("OR", config.getString(Config.operator_OR), leftOperand, rightOperand);
1126
    }
1127

    
1128
    @Override
1129
    public BinaryOperator eq(Value leftOperand, Value rightOperand) {
1130
        return binaryOperator("=", config.getString(Config.operator_EQ), leftOperand, rightOperand);
1131
    }
1132

    
1133
    @Override
1134
    public BinaryOperator ne(Value leftOperand, Value rightOperand) {
1135
        return binaryOperator("<>", config.getString(Config.operator_NE), leftOperand, rightOperand);
1136
    }
1137

    
1138
    @Override
1139
    public BinaryOperator gt(Value op1, Value op2) {
1140
        return binaryOperator(">", config.getString(Config.operator_GT), op1, op2);
1141
    }
1142

    
1143
    @Override
1144
    public BinaryOperator ge(Value op1, Value op2) {
1145
        return binaryOperator(">=", config.getString(Config.operator_GE), op1, op2);
1146
    }
1147

    
1148
    @Override
1149
    public BinaryOperator lt(Value op1, Value op2) {
1150
        return binaryOperator("<", config.getString(Config.operator_LT), op1, op2);
1151
    }
1152

    
1153
    @Override
1154
    public BinaryOperator le(Value op1, Value op2) {
1155
        return binaryOperator("<=", config.getString(Config.operator_LE), op1, op2);
1156
    }
1157

    
1158
    @Override
1159
    public BinaryOperator like(Value op1, Value op2) {
1160
        return binaryOperator("LIKE", config.getString(Config.operator_LIKE), op1, op2);
1161
    }
1162

    
1163
    @Override
1164
    public BinaryOperator ilike(Value op1, Value op2) {
1165
        return binaryOperator("ILIKE", config.getString(Config.operator_ILIKE), op1, op2);
1166
    }
1167

    
1168
    @Override
1169
    public BinaryOperator add(Value op1, Value op2) {
1170
        return binaryOperator("ADD", config.getString(Config.operator_add), op1, op2);
1171
    }
1172

    
1173
    @Override
1174
    public BinaryOperator subst(Value op1, Value op2) {
1175
        return binaryOperator("SUBST", config.getString(Config.operator_subst), op1, op2);
1176
    }
1177

    
1178
    @Override
1179
    public BinaryOperator mult(Value op1, Value op2) {
1180
        return binaryOperator("MULT", config.getString(Config.operator_mult), op1, op2);
1181
    }
1182

    
1183
    @Override
1184
    public BinaryOperator div(Value op1, Value op2) {
1185
        return binaryOperator("DIV", config.getString(Config.operator_div), op1, op2);
1186
    }
1187

    
1188
    @Override
1189
    public BinaryOperator concat(Value op1, Value op2) {
1190
        return binaryOperator("CONCAT", config.getString(Config.operator_concat), op1, op2);
1191
    }
1192
    
1193
    @Override
1194
    public Function iif(Value condition, Value iftrue, Value iffalse) {
1195
        return builtin_function("IIF", config.getString(Config.iif), condition, iftrue, iffalse);
1196
    }
1197

    
1198
    @Override
1199
    public Function ifnull(Value value, Value iftrue, Value iffalse) {
1200
        return builtin_function("IFNULL", config.getString(Config.ifnull), value, iftrue, iffalse);
1201
    }
1202
    
1203
    @Override
1204
    public Function left(Value str, Value size) {
1205
       return function("left", str, size);
1206
       // return builtin_function("left", "left({1})",str,size);
1207
    }
1208
    
1209
    @Override
1210
    public Function right(Value str, Value len) {
1211
       return function("right", str, len);
1212
    }
1213
    
1214
    @Override
1215
    public Function locate(Value search, Value str, Value start) {
1216
       return function("locate", search, str, start);
1217
    }
1218
    
1219
    @Override
1220
    public Function position(Value search, Value str) {
1221
       return function("position", search, str);
1222
    }
1223
    
1224
    @Override
1225
    public Function lpad(Value str, Value len, Value padstr) {
1226
       return function("lpad", str, len, padstr);
1227
    }
1228
    
1229
    @Override
1230
    public Function rpad(Value str, Value len, Value padstr) {
1231
       return function("rpad", str, len, padstr);
1232
    }
1233
    
1234
    @Override
1235
    public Function ltrim(Value str) {
1236
       return function("ltrim", str);
1237
    }
1238
    
1239
    @Override
1240
    public Function rtrim(Value str) {
1241
       return function("rtrim", str);
1242
    }
1243
    
1244
    @Override
1245
    public Function trim(Value str) {
1246
       return function("trim", str);
1247
    }
1248
    
1249
    @Override
1250
    public Function repeat(Value str, Value size) {
1251
       return function("repeat", str, size);
1252
    }
1253
    
1254
    @Override
1255
    public Function replace(Value str, Value search, Value replstr) {
1256
       return function("replace", str, search, replstr);
1257
    }
1258
    
1259
    @Override
1260
    public Function ascii(Value str) {
1261
       return function("ascii", str);
1262
    }
1263
    
1264
    @Override
1265
    public Function lenght(Value str) {
1266
       return function("lenght", str);
1267
    }
1268

    
1269
    @Override
1270
    public Function instr(Value str, Value search, Value start) {
1271
       return function("instr", str, search, start);
1272
    }
1273
    
1274
    @Override
1275
    public Function lower(Value str) {
1276
       return function("lower", str);
1277
    }
1278
    
1279
    @Override
1280
    public Function upper(Value str) {
1281
       return function("upper", str);
1282
    }
1283
    
1284
    @Override
1285
    public Function space(Value size) {
1286
       return function("space", size);
1287
    }
1288
    
1289
    @Override
1290
    public Function substring(Value str, Value start, Value len) {
1291
       return function("substring", str, start, len);
1292
    }
1293
    
1294
    @Override
1295
    public Function acos(Value num) {
1296
       return function("acos", num);
1297
    } 
1298
    
1299
    @Override
1300
    public Function asin(Value num) {
1301
       return function("asin", num);
1302
    }
1303
    
1304
    @Override
1305
    public Function atan(Value num) {
1306
       return function("atan", num);
1307
    }
1308
    
1309
    @Override
1310
    public Function cos(Value num) {
1311
       return function("cos", num);
1312
    }
1313
    
1314
    @Override
1315
    public Function cosh(Value num) {
1316
       return function("cosh", num);
1317
    }
1318
    
1319
    @Override
1320
    public Function cot(Value num) {
1321
       return function("cot", num);
1322
    }  
1323
    
1324
    @Override
1325
    public Function bitand(Value num1, Value num2) {
1326
       return function("bitand", num1, num2);
1327
    } 
1328
    
1329
    @Override
1330
    public Function bitor(Value num1, Value num2) {
1331
       return function("bitor", num1, num2);
1332
    }
1333
    
1334
    @Override
1335
    public Function bitxor(Value num1, Value num2) {
1336
       return function("bitxor", num1, num2);
1337
    }
1338
    
1339
    @Override
1340
    public Function ceil(Value num) {
1341
       return function("ceil", num);
1342
    }
1343
    
1344
    @Override
1345
    public Function degrees(Value num) {
1346
       return function("degrees", num);
1347
    }  
1348
    
1349
    @Override
1350
    public Function exp(Value num) {
1351
       return function("exp", num);
1352
    }  
1353
    
1354
    @Override
1355
    public Function floor(Value num) {
1356
       return function("floor", num);
1357
    }  
1358
    
1359
    @Override
1360
    public Function log(Value num) {
1361
       return function("log", num);
1362
    }  
1363
    
1364
    @Override
1365
    public Function log10(Value num) {
1366
       return function("log10", num);
1367
    }  
1368
    
1369
    @Override
1370
    public Function pi(Value num) {
1371
       return function("pi", num);
1372
    }
1373
    
1374
    @Override
1375
    public Function power(Value num) {
1376
       return function("power", num);
1377
    }
1378
    
1379
    @Override
1380
    public Function radians(Value num) {
1381
       return function("radians", num);
1382
    }
1383
    
1384
    @Override
1385
    public Function rand(Value num) {
1386
       return function("rand", num);
1387
    }
1388
    
1389
    @Override
1390
    public Function round(Value num) {
1391
       return function("round", num);
1392
    }
1393
    
1394
    @Override
1395
    public Function sqrt(Value num) {
1396
       return function("sqrt", num);
1397
    }
1398
    
1399
    @Override
1400
    public Function sign(Value num) {
1401
       return function("sign", num);
1402
    }
1403
    
1404
    @Override
1405
    public Function sin(Value num) {
1406
       return function("sin", num);
1407
    }
1408
    
1409
    @Override
1410
    public Function sinh(Value num) {
1411
       return function("sinh", num);
1412
    }
1413
    
1414
    @Override
1415
    public Function tan(Value num) {
1416
       return function("tan", num);
1417
    }
1418
    @Override
1419
    public Function tanh(Value num) {
1420
       return function("cosh", num);
1421
    }  
1422
    
1423
    @Override
1424
    public Function zero() {
1425
       return function("zero");
1426
    }
1427
    
1428
    @Override
1429
    public Function chr(Value num) {
1430
       return function("chr", num);
1431
    }
1432
}