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

History | View | Annotate | Download (42.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
import org.gvsig.fmap.geom.DataTypes;
21

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

    
25
    public class ConfigBase implements Config {
26

    
27
        protected Map<String, Object> values;
28

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

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

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

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

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

    
86
        }
87

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

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

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

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

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

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

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

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

    
136
    public abstract class AbstractValue implements Value {
137

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

    
145
    }
146

    
147
    public class ClassVisitorFilter implements VisitorFilter {
148

    
149
        private final Class classFilter;
150

    
151
        public ClassVisitorFilter(Class classFilter) {
152
            this.classFilter = classFilter;
153
        }
154

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

    
160
    }
161

    
162
    public class GroupBase extends AbstractValue implements Group {
163

    
164
        protected Value value;
165

    
166
        public GroupBase(Value value) {
167
            this.value = value;
168
        }
169

    
170
        @Override
171
        public Value getValue() {
172
            return value;
173
        }
174

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

    
181
        @Override
182
        public String toString() {
183
            return MessageFormat.format(config.getString(Config.group), this.value.toString());
184
        }
185
    }
186
    protected class ColumnDescriptorBase implements ColumnDescriptor {
187

    
188
        private String name;
189
        private int type;
190
        private int type_p;
191
        private int type_s;
192
        private boolean isPk;
193
        private boolean _allowNulls;
194
        private boolean _isAutomatic;
195
        private Object defaultValue;
196
        private int geom_type;
197
        private int geom_subtype;
198
        private Object geom_srsdbcode;
199
        private boolean _isIndexed;
200

    
201
        public ColumnDescriptorBase(String name, int type, Object defaultValue) {
202
            this.name = name;
203
            this.type = type;
204
            this.type_p = -1;
205
            this.type_s = -1;
206
            this.isPk = false;
207
            this._allowNulls = true;
208
            this._isAutomatic = false;
209
            this.defaultValue = defaultValue;
210
            this.geom_type = Geometry.TYPES.GEOMETRY;
211
            this.geom_subtype = Geometry.SUBTYPES.GEOM2D;
212
            this.geom_srsdbcode = null;
213
            this._isIndexed = false;
214
        }
215

    
216
        public ColumnDescriptorBase(String name, int type, int type_p, int type_s, boolean isPk, boolean isIndexed, boolean allowNulls, boolean isAutomatic, Object defaultValue) {
217
            this.name = name;
218
            this.type = type;
219
            this.type_p = type_p;
220
            this.type_s = type_s;
221
            this.isPk = isPk;
222
            this._allowNulls = allowNulls;
223
            this._isAutomatic = isAutomatic;
224
            this.defaultValue = defaultValue;
225
            this.geom_type = Geometry.TYPES.GEOMETRY;
226
            this.geom_subtype = Geometry.SUBTYPES.GEOM2D;
227
            this.geom_srsdbcode = null;
228
            this._isIndexed = isIndexed;
229
        }
230
        
231
        public ColumnDescriptorBase(String name, int geom_type, int geom_subtype, IProjection proj, boolean isIndexed, boolean allowNulls) {
232
            this.name = name;
233
            this.type = DataTypes.GEOMETRY;
234
            this.type_p = 0;
235
            this.type_s = 0;
236
            this.isPk = false;
237
            this._allowNulls = allowNulls;
238
            this._isAutomatic = false;
239
            this.defaultValue = null;
240
            this.geom_type = geom_type;
241
            this.geom_subtype = geom_subtype;
242
            this.geom_srsdbcode = getSRSId(proj);
243
            this._isIndexed = isIndexed;
244
        }
245
        
246
        public ColumnDescriptorBase(String name, int geom_type, int geom_subtype, Object srsdbcode, boolean isIndexed, boolean allowNulls) {
247
            this.name = name;
248
            this.type = DataTypes.GEOMETRY;
249
            this.type_p = 0;
250
            this.type_s = 0;
251
            this.isPk = false;
252
            this._allowNulls = allowNulls;
253
            this._isAutomatic = false;
254
            this.defaultValue = null;
255
            this.geom_type = geom_type;
256
            this.geom_subtype = geom_subtype;
257
            this.geom_srsdbcode = srsdbcode;
258
            this._isIndexed = isIndexed;
259
        }
260
        
261
        @Override
262
        public String getName() {
263
            return this.name;
264
        }
265
        
266
        @Override
267
        public void setName(String name) {
268
            this.name = name;
269
        }
270

    
271
        @Override
272
        public int getType() {
273
            return this.type;
274
        }
275

    
276
        @Override
277
        public void setType(int type) {
278
            this.type = type;
279
        }
280

    
281
        @Override
282
        public int getPrecision() {
283
            return type_p;
284
        }
285

    
286
        @Override
287
        public void setPrecision(int precision) {
288
            this.type_p = precision;
289
        }
290

    
291
        @Override
292
        public int getSize() {
293
            return type_s;
294
        }
295

    
296
        @Override
297
        public void setSize(int size) {
298
            this.type_s = size;
299
        }
300

    
301
        @Override
302
        public boolean isPrimaryKey() {
303
            return isPk;
304
        }
305

    
306
        @Override
307
        public void setIsPrimaryKey(boolean isPk) {
308
            this.isPk = isPk;
309
        }
310

    
311
        @Override
312
        public boolean allowNulls() {
313
            return _allowNulls;
314
        }
315

    
316
        @Override
317
        public void setAllowNulls(boolean allowNulls) {
318
            this._allowNulls = allowNulls;
319
        }
320

    
321
        @Override
322
        public boolean isAutomatic() {
323
            return _isAutomatic;
324
        }
325

    
326
        @Override
327
        public boolean isIndexed() {
328
            return _isIndexed;
329
        }
330

    
331
        @Override
332
        public void setIsAutomatic(boolean isAutomatic) {
333
            this._isAutomatic = isAutomatic;
334
        }
335

    
336
        @Override
337
        public Object getDefaultValue() {
338
            return defaultValue;
339
        }
340

    
341
        @Override
342
        public void setDefaultValue(Object defaultValue) {
343
            this.defaultValue = defaultValue;
344
        }
345

    
346
        @Override
347
        public int getGeometryType() {
348
            return geom_type;
349
        }
350

    
351
        @Override
352
        public void setGeometryType(int geom_type) {
353
            this.geom_type = geom_type;
354
        }
355

    
356
        @Override
357
        public int getGeometrySubtype() {
358
            return geom_subtype;
359
        }
360

    
361
        @Override
362
        public void setGeometrySubtype(int geom_subtype) {
363
            this.geom_subtype = geom_subtype;
364
        }
365

    
366
        @Override
367
        public Object getGeometrySRSId() {
368
            return geom_srsdbcode;
369
        }
370

    
371
        @Override
372
        public void setGeometrySRSId(Object geom_srsid) {
373
            this.geom_srsdbcode = geom_srsid;
374
        }        
375

    
376
        @Override
377
        public boolean isGeometry() {
378
            return this.type == DataTypes.GEOMETRY;
379
        }
380

    
381
    }
382

    
383
    public class VariableBase extends AbstractValue implements Variable {
384

    
385
        protected String name;
386
        protected ColumnDescriptor descriptor;
387

    
388
        public VariableBase(ColumnDescriptor descriptor) {
389
            this.descriptor = descriptor;
390
            this.name = descriptor.getName();
391
        }
392

    
393
        public VariableBase(String name) {
394
            this.descriptor = null;
395
            this.name = name;
396
        }
397

    
398
        @Override
399
        public ColumnDescriptor getDescriptor() {
400
            return descriptor;
401
        }
402
        
403
        @Override
404
        public String getName() {
405
            return this.name;
406
        }
407

    
408
        @Override
409
        public String toString() {
410
            return identifier(this.name);
411
        }
412

    
413
        @Override
414
        public int compareTo(Variable o) {
415
            return this.name.compareTo(o.getName());
416
        }
417

    
418
        @Override
419
        public boolean equals(Object obj) {
420
            if (!(obj instanceof Variable)) {
421
                return false;
422
            }
423
            return this.name.equals(((Variable) obj).getName());
424
        }
425

    
426
        @Override
427
        public int hashCode() {
428
            int hash = 7;
429
            hash = 37 * hash + Objects.hashCode(this.name);
430
            return hash;
431
        }
432
    }
433

    
434
    public class ParameterBase extends AbstractValue implements Parameter {
435

    
436
        protected String name;
437
        protected Object value;
438
        protected ParameterType type;
439
        protected Value srs;
440

    
441
        public ParameterBase() {
442
            this.type = ParameterType.Constant;
443
            this.name = null;
444
            this.value = null;
445
        }
446

    
447
        @Override
448
        public void accept(Visitor visitor, VisitorFilter filter) {
449
            super.accept(visitor, filter);
450
            if (this.srs != null) {
451
                this.srs.accept(visitor, filter);
452
            }
453
        }
454

    
455
        @Override
456
        public Parameter as_geometry_variable() {
457
            this.type = ParameterType.Geometry;
458
            if (this.value == null && this.name != null) {
459
                this.value = this.name;
460
            }
461
            return this;
462
        }
463

    
464
        @Override
465
        public Parameter as_constant() {
466
            this.type = ParameterType.Constant;
467
            if (this.value == null && this.name != null) {
468
                this.value = this.name;
469
            }
470
            return this;
471
        }
472

    
473
        @Override
474
        public Parameter as_variable() {
475
            this.type = ParameterType.Variable;
476
            if (this.value != null && this.name == null) {
477
                this.name = (String) this.value;
478
            }
479
            return this;
480
        }
481

    
482
        @Override
483
        public Parameter srs(Value srs) {
484
            this.srs = srs;
485
            if( this.type == ParameterType.Variable ) {
486
                this.type = ParameterType.Geometry;
487
            }
488
            return this;
489
        }
490

    
491
        @Override
492
        public Parameter srs(IProjection srs) {
493
            this.srs = constant(getSRSId(srs));
494
            if( this.type == ParameterType.Variable ) {
495
                this.type = ParameterType.Geometry;
496
            }
497
            return this;
498
        }
499

    
500
        @Override
501
        public String getName() {
502
            switch (this.type) {
503
                case Variable:
504
                case Geometry:
505
                    return this.name;
506
                case Constant:
507
                    if (this.value == null) {
508
                        return null;
509
                    }
510
                    return this.value.toString();
511
                default:
512
                    if (this.name != null) {
513
                        return this.name;
514
                    }
515
                    if (this.value != null) {
516
                        return this.value.toString();
517
                    }
518
                    return null;
519
            }
520
        }
521

    
522
        @Override
523
        public boolean is_constant() {
524
            return this.type == ParameterType.Constant;
525
        }
526

    
527
        @Override
528
        public boolean is_geometry_variable() {
529
            return this.type == ParameterType.Geometry;
530
        }
531

    
532
        @Override
533
        public boolean is_variable() {
534
            return this.type == ParameterType.Variable;
535
        }
536

    
537
        @Override
538
        public Parameter value(Object value) {
539
            this.value = value;
540
            return this;
541
        }
542

    
543
        @Override
544
        public Parameter name(String name) {
545
            this.type = ParameterType.Variable;
546
            this.name = name;
547
            return this;
548
        }
549

    
550
        @Override
551
        public Object getValue() {
552
            try {
553
                switch (this.type) {
554
                    case Constant:
555
                        if (this.value instanceof Geometry) {
556
                            switch (config.getGeometryTypeSupport()) {
557
                                case EWKB:
558
                                    return bytearray(((Geometry) this.value).convertToEWKB());
559
                                case NATIVE:
560
                                case WKB:
561
                                    return bytearray(((Geometry) this.value).convertToWKB());
562
                                case WKT:
563
                                default:
564
                                    return ((Geometry) this.value).convertToWKT();
565
                            }
566
                        } else if (this.value instanceof IProjection) {
567
                            return getSRSId((IProjection) this.value);
568
                        }
569
                        return this.value;
570
                    case Variable:
571
                    case Geometry:
572
                    default:
573
                        return this.value;
574
                }
575
            } catch (Exception ex) {
576
                throw new RuntimeException("Can't get value from parameter.", ex);
577
            }
578
        }
579

    
580
        @Override
581
        public ParameterType getType() {
582
            return this.type;
583
        }
584

    
585
        @Override
586
        public Value getSRS() {
587
            return this.srs;
588
        }
589

    
590
        @Override
591
        public String toString() {
592
            switch (this.type) {
593
                case Constant:
594
                case Variable:
595
                default:
596
                    return "?";
597
                case Geometry:
598
                    switch (config.getGeometryTypeSupport()) {
599
                        case EWKB:
600
                            return MessageFormat.format(
601
                                    config.getString(Config.ST_GeomFromEWKB),
602
                                    "?",
603
                                    String.valueOf(this.srs.toString())
604
                            );
605
                        case WKB:
606
                            return MessageFormat.format(
607
                                    config.getString(Config.ST_GeomFromWKB),
608
                                    "?",
609
                                    String.valueOf(this.srs.toString())
610
                            );
611
                        case WKT:
612
                        default:
613
                            return MessageFormat.format(
614
                                    config.getString(Config.ST_GeomFromText),
615
                                    "?",
616
                                    String.valueOf(this.srs.toString())
617
                            );
618
                    }
619
            }
620
        }
621
    }
622

    
623
    public class ConstantBase extends AbstractValue implements Constant {
624

    
625
        protected Object value;
626

    
627
        public ConstantBase(Object value) {
628
            this.value = value;
629
        }
630

    
631
        @Override
632
        public Object getValue() {
633
            return this.value;
634
        }
635

    
636
        @Override
637
        public String toString() {
638
            if (this.value instanceof String) {
639
                return string((String) this.value);
640
            }
641
            if (this.value instanceof Boolean) {
642
                if (((Boolean) this.value)) {
643
                    return config.getString(Config.constant_true);
644
                } else {
645
                    return config.getString(Config.constant_false);
646
                }
647
            }
648
            return ObjectUtils.toString(this.value, "");
649
        }
650
    }
651

    
652
    public class CustomBase extends AbstractValue implements Custom {
653

    
654
        protected Object value;
655

    
656
        // Esto es para permitir declarar parametros y columnas en una seccion
657
        // custom.
658
        protected List<Value> values;
659

    
660
        public CustomBase(Object value) {
661
            this.value = value;
662
        }
663

    
664
        @Override
665
        public void accept(Visitor visitor, VisitorFilter filter) {
666
            super.accept(visitor, filter);
667
            if (this.values != null) {
668
                for (Value theValue : values) {
669
                    theValue.accept(visitor, filter);
670
                }
671
            }
672
        }
673

    
674
        @Override
675
        public Object getValue() {
676
            return this.value;
677
        }
678

    
679
        @Override
680
        public Custom add(Variable variable) {
681
            if (this.values == null) {
682
                this.values = new ArrayList<>();
683
            }
684
            this.values.add(variable);
685
            return this;
686
        }
687

    
688
        @Override
689
        public Custom add(Parameter parameter) {
690
            if (this.values == null) {
691
                this.values = new ArrayList<>();
692
            }
693
            this.values.add(parameter);
694
            return this;
695
        }
696

    
697
        @Override
698
        public String toString() {
699
            return ObjectUtils.toString(this.value, "");
700
        }
701
    }
702

    
703
    public class GeometryValueBase extends AbstractValue implements GeometryValue {
704

    
705
        protected Geometry geometry;
706
        protected IProjection projection;
707

    
708
        public GeometryValueBase(Geometry geometry, IProjection projection) {
709
            this.geometry = geometry;
710
            this.projection = projection;
711
        }
712

    
713
        @Override
714
        public Geometry getGeometry() {
715
            return this.geometry;
716
        }
717

    
718
        @Override
719
        public IProjection getSRS() {
720
            return this.projection;
721
        }
722

    
723
        @Override
724
        public String toString() {
725
            try {
726
                switch (config.getGeometryTypeSupport()) {
727
                    case EWKB:
728
                        return MessageFormat.format(
729
                                config.getString(Config.ST_GeomFromEWKB),
730
                                bytearray(this.geometry.convertToEWKB()),
731
                                String.valueOf(getSRSId(this.projection))
732
                        );
733
                    case WKB:
734
                        return MessageFormat.format(
735
                                config.getString(Config.ST_GeomFromWKB),
736
                                bytearray(this.geometry.convertToWKB()),
737
                                String.valueOf(getSRSId(this.projection))
738
                        );
739
                    case WKT:
740
                    default:
741
                        return MessageFormat.format(
742
                                config.getString(Config.ST_GeomFromText),
743
                                string(this.geometry.convertToWKT()),
744
                                String.valueOf(getSRSId(this.projection))
745
                        );
746
                }
747
            } catch (Exception ex) {
748
                throw new RuntimeException("Can't convert geometry to string.", ex);
749
            }
750
        }
751
    }
752

    
753
    public class FunctionBase extends AbstractValue implements Function {
754

    
755
        protected String name;
756
        protected String format;
757
        protected List<Value> parameters;
758

    
759
        public FunctionBase(String name, String format) {
760
            this.name = name;
761
            this.format = format;
762
        }
763

    
764
        @Override
765
        public List<Value> parameters() {
766
            if (this.parameters == null) {
767
                this.parameters = new ArrayList<>();
768
            }
769
            return this.parameters;
770
        }
771

    
772
        @Override
773
        public Function parameter(Value parameter) {
774
            this.parameters().add(parameter);
775
            return this;
776
        }
777

    
778
        @Override
779
        public String getName() {
780
            return this.name;
781
        }
782

    
783
        @Override
784
        public void accept(Visitor visitor, VisitorFilter filter) {
785
            super.accept(visitor, filter);
786
            for (Value value : this.parameters) {
787
                value.accept(visitor, filter);
788
            }
789
        }
790

    
791
        @Override
792
        public String toString() {
793
            if (this.parameters != null && !this.parameters.isEmpty()) {
794
                List<String> values = new ArrayList<>();
795
                for (Value value : this.parameters) {
796
                    values.add(value.toString());
797
                }
798
                return MessageFormat.format(format, values.toArray());
799
            } else {
800
                return this.format;
801
            }
802
        }
803
    }
804

    
805
    public class BinaryOperatorBase extends AbstractValue implements BinaryOperator {
806

    
807
        protected String name;
808
        protected String format;
809
        protected Value left;
810
        protected Value right;
811

    
812
        public BinaryOperatorBase(String name, String format) {
813
            this.name = name;
814
            this.format = format;
815
        }
816

    
817
        @Override
818
        public String getName() {
819
            return this.name;
820
        }
821

    
822
        @Override
823
        public void accept(Visitor visitor, VisitorFilter filter) {
824
            super.accept(visitor, filter);
825
            this.left.accept(visitor, filter);
826
            this.right.accept(visitor, filter);
827
        }
828

    
829
        @Override
830
        public BinaryOperator setLeft(Value operand) {
831
            this.left = operand;
832
            return this;
833
        }
834

    
835
        @Override
836
        public BinaryOperator setRight(Value operand) {
837
            this.right = operand;
838
            return this;
839
        }
840

    
841
        @Override
842
        public Value getLeft() {
843
            return this.left;
844
        }
845

    
846
        @Override
847
        public Value getRight() {
848
            return this.right;
849
        }
850

    
851
        @Override
852
        public String toString() {
853
            return MessageFormat.format(
854
                    format,
855
                    this.left.toString(),
856
                    this.right.toString()
857
            );
858
        }
859
    }
860

    
861
    protected Value value;
862
    protected Config config;
863

    
864
    public DefaultExpressionBuilder() {
865
        this.config = new ConfigBase();
866
    }
867

    
868
    @Override
869
    public ExpressionBuilder createExpressionBuilder() {
870
        return new DefaultExpressionBuilder();
871
    }
872

    
873
    @Override
874
    public Config getConfig() {
875
        return this.config;
876
    }
877

    
878
    @Override
879
    public Value getValue() {
880
        return this.value;
881
    }
882

    
883
    @Override
884
    public ExpressionBuilder setValue(Value value) {
885
        this.value = value;
886
        return this;
887
    }
888

    
889
    @Override
890
    public String toString() {
891
        return this.value.toString();
892
    }
893

    
894
    @Override
895
    public void accept(Visitor visitor, VisitorFilter filter) {
896
        if( this.value == null) {
897
            return;
898
        }
899
        this.value.accept(visitor, filter);
900
    }
901

    
902
    @Override
903
    public boolean has_spatial_functions() {
904
        return this.config.getBoolean(Config.has_spatial_functions);
905
    }
906

    
907
    @Override
908
    public GeometrySupportType geometry_support_type() {
909
        return (GeometrySupportType) this.config.get(Config.geometry_type_support);
910
    }
911

    
912
    @Override
913
    public String string(String s) {
914
        String quote = this.config.getString(Config.quote_for_strings);
915
//        No se porque no esta disponible wrapIfMissing
916
//        return StringUtils.wrapIfMissing(s,quote);
917
        if (s.startsWith(quote)) {
918
            return s;
919
        }
920
        return quote + s + quote;
921
    }
922

    
923
    @Override
924
    public String identifier(String id) {
925
        String quote = this.config.getString(Config.quote_for_identifiers);
926
//        No se porque no esta disponible wrapIfMissing
927
//        return StringUtils.wrapIfMissing(id,quote);
928
        if (id.startsWith(quote)) {
929
            return id;
930
        }
931
        return quote + id + quote;
932
    }
933

    
934
    @Override
935
    public String bytearray(byte[] data) {
936
        return "DECODE('"+bytearray_hex(data)+"','hex')";
937
    }
938
    
939
    @Override
940
    public String bytearray_hex(byte[] data) {
941
        StringBuilder builder = new StringBuilder();
942
        for (byte abyte : data) {
943
            int v = abyte & 0xff;
944
            builder.append(String.format("%02x", v));
945
        }
946
        return builder.toString();
947
    }
948

    
949
    @Override
950
    public String bytearray_0x(byte[] data) {
951
        return "0x" + bytearray_hex(data);
952
    }
953

    
954
    @Override
955
    public String bytearray_x(byte[] data) {
956
        return "x'" + bytearray_hex(data) + "'";
957
    }
958
    
959
    @Override
960
    public Object getSRSId(IProjection projection) {
961
        if( projection==null ) {
962
            return 0;
963
        }
964
        return ProjectionUtils.getCode(projection);
965
    }
966

    
967
    @Override
968
    public Constant srs(IProjection projection) {
969
        return constant(getSRSId(projection));
970
    }
971

    
972
    @Override
973
    public Variable variable(String name) {
974
        return new VariableBase(name);
975
    }
976

    
977
    @Override
978
    public Variable column(String name) {
979
        return new VariableBase(name);
980
    }
981
    
982
    @Override
983
    public Parameter parameter(String name) {
984
        Parameters parameters = this.getParameters();
985
        Parameter parameter = parameters.get(name);
986
        if( parameter != null ) {
987
            return parameter;
988
        }
989
        parameter = this.parameter();
990
        parameter.name(name);
991
        return parameter;
992
    }
993
    
994
    @Override
995
    public Parameter parameter() {
996
        return new ParameterBase();
997
    }
998
    
999
    @Override
1000
    public Constant constant(Object value) {
1001
        return new ConstantBase(value);
1002
    }
1003

    
1004
    @Override
1005
    public Group group(Value value) {
1006
        return new GroupBase(value);
1007
    }
1008

    
1009
    @Override
1010
    public GeometryValue geometry(Geometry geom, IProjection projection) {
1011
        return new GeometryValueBase(geom, projection);
1012
    }
1013

    
1014
    @Override
1015
    public GeometryValue geometry(Geometry geom) {
1016
        if( geom.getProjection()==null ) {
1017
            throw new IllegalArgumentException("The geometry does not have an associated projection. Use 'geometry(Geometry, IProjection)'.");
1018
        }
1019
        return new GeometryValueBase(geom, geom.getProjection());
1020
    }
1021

    
1022
    @Override
1023
    public GeometryValue envelope(Envelope envelope, IProjection projection) {
1024
        return new GeometryValueBase(envelope.getGeometry(), projection);
1025
    }
1026

    
1027
    @Override
1028
    public GeometryValue envelope(Envelope envelope) {
1029
        if( envelope.getProjection()==null ) {
1030
            throw new IllegalArgumentException("The envelope does not have an associated projection. Use 'envelope(Geometry, IProjection)'.");
1031
        }
1032
        return new GeometryValueBase(envelope.getGeometry(), envelope.getProjection());
1033
    }
1034

    
1035
    @Override
1036
    public Custom custom(Object value) {
1037
        return new CustomBase(value);
1038
    }
1039

    
1040
    public Function function(String name, String format, Value... values) {
1041
        FunctionBase func = new FunctionBase(name, format);
1042
        for (Value theValue : values) {
1043
            func.parameter(theValue);
1044
        }
1045
        return func;
1046
    }
1047

    
1048
    public BinaryOperator binaryOperator(String name, String format, Value leftOperand, Value rightOperand) {
1049
        BinaryOperator operator = new BinaryOperatorBase(name, format);
1050
        operator.setLeft(leftOperand);
1051
        operator.setRight(rightOperand);
1052
        return operator;
1053
    }
1054

    
1055
    @Override
1056
    public List<Variable> getVariables() {
1057
        final Set<Variable> vars = new HashSet<>();
1058
        this.accept(new Visitor() {
1059
            @Override
1060
            public void visit(Visitable value) {
1061
                vars.add((Variable) value);
1062
            }
1063
        }, new ClassVisitorFilter(Variable.class));
1064
        List<Variable> lvars = new ArrayList<>(vars);
1065
        Collections.sort(lvars);
1066
        return lvars;
1067
    }
1068

    
1069
    private static class ParametersBase extends ArrayList<Parameter> implements Parameters {
1070

    
1071
        private static final long serialVersionUID = -2188534574151780470L;
1072

    
1073
        public ParametersBase() {
1074
            super();
1075
        }
1076

    
1077
        public ParametersBase(Collection parameters) {
1078
            super(parameters);
1079
        }
1080

    
1081
        @Override
1082
        public Parameter get(String name) {
1083
            if( name == null ) {
1084
                return null;
1085
            }
1086
            for (Parameter param : this) {
1087
                if( param.is_variable() || param.is_geometry_variable() ) {
1088
                    if( name.equalsIgnoreCase(param.getName()) ) {
1089
                        return param;
1090
                    }
1091
                }
1092
            }
1093
            return null;
1094
        }
1095

    
1096
        
1097
        @Override
1098
        public String toString() {
1099
            boolean first = true;
1100
            StringBuilder builder = new StringBuilder();
1101
            builder.append("{ ");
1102
            for (Parameter param : this) {
1103
                if (!first) {
1104
                    builder.append(", ");
1105
                } else {
1106
                    first = false;
1107
                }
1108
                String s;
1109
                Object value = param.getValue();
1110
                if (value == null) {
1111
                    s = "null";
1112
                } else if (value instanceof String) {
1113
                    s = "'" + (String) value + "'";
1114
                } else {
1115
                    s = value.toString();
1116
                }
1117
                switch (param.getType()) {
1118
                    case Constant:
1119
                        builder.append(s);
1120
                        break;
1121
                    case Geometry:
1122
                        builder.append("(Geometry)");
1123
                    case Variable:
1124
                    default:
1125
                        builder.append(param.getName());
1126
                        builder.append(": ");
1127
                        builder.append(s);
1128
                }
1129
            }
1130
            builder.append(" }");
1131
            return builder.toString();
1132
        }
1133
    }
1134

    
1135
    @Override
1136
    public Parameters getParameters() {
1137
        final Parameters params = new ParametersBase();
1138
        this.accept(new Visitor() {
1139
            @Override
1140
            public void visit(Visitable value) {
1141
                params.add((Parameter) value);
1142
            }
1143
        }, new ClassVisitorFilter(Parameter.class));
1144
        return params;
1145
    }
1146

    
1147
    @Override
1148
    public Function getAsGeometry(Value value) {
1149
        return function("ST_AsBinary", config.getString(Config.ST_AsBinary), value);
1150
    }
1151

    
1152
    @Override
1153
    public ExpressionBuilder set(Value value) {
1154
        this.value = value;
1155
        return this;
1156
    }
1157

    
1158
    @Override
1159
    public ExpressionBuilder and(Value value) {
1160
        if (this.value == null) {
1161
            return this.set(value);
1162
        }
1163
        BinaryOperator operator = binaryOperator("AND", config.getString(Config.operator_AND), this.value, value);
1164
        this.value = operator;
1165
        return this;
1166
    }
1167

    
1168
    @Override
1169
    public ExpressionBuilder or(Value value) {
1170
        if (this.value == null) {
1171
            return this.set(value);
1172
        }
1173
        BinaryOperator operator = binaryOperator("OR", config.getString(Config.operator_OR), this.value, value);
1174
        this.value = operator;
1175
        return this;
1176
    }
1177

    
1178
    @Override
1179
    public Function ST_Intersects(Value geom1, Value geom2) {
1180
        return function("ST_Intersects", config.getString(Config.ST_Intersects), geom1, geom2);
1181
    }
1182

    
1183
    @Override
1184
    public Function ST_SRID(Value geom) {
1185
        return function("ST_SRID", config.getString(Config.ST_SRID), geom);
1186
    }
1187

    
1188
    @Override
1189
    public Function ST_Envelope(Value geom) {
1190
        return function("ST_Envelope", config.getString(Config.ST_Envelope), geom);
1191
    }
1192

    
1193
    @Override
1194
    public Function ST_AsText(Value geom) {
1195
        return function("ST_AsText", config.getString(Config.ST_AsText), geom);
1196
    }
1197

    
1198
    @Override
1199
    public Function ST_AsBinary(Value geom) {
1200
        return function("ST_AsBinary", config.getString(Config.ST_AsBinary), geom);
1201
    }
1202

    
1203
    @Override
1204
    public Function ST_AsEWKB(Value geom) {
1205
        return function("ST_AsEWKB", config.getString(Config.ST_AsEWKB), geom);
1206
    }
1207

    
1208
    @Override
1209
    public Function ST_GeomFromText(Value geom, Value crs) {
1210
        return function("ST_GeomFromText", config.getString(Config.ST_GeomFromText), geom, crs);
1211
    }
1212

    
1213
    @Override
1214
    public Function ST_GeomFromWKB(Value geom, Value crs) {
1215
        return function("ST_GeomFromWKB", config.getString(Config.ST_GeomFromWKB), geom, crs);
1216
    }
1217

    
1218
    @Override
1219
    public Function ST_GeomFromEWKB(Value geom, Value crs) {
1220
        return function("ST_GeomFromEWKB", config.getString(Config.ST_GeomFromEWKB), geom, crs);
1221
    }
1222

    
1223
    @Override
1224
    public Function ST_Simplify(Value geom, Value tolerance) {
1225
        return function("ST_Simplify", config.getString(Config.ST_Simplify), tolerance);
1226
    }
1227

    
1228
    @Override
1229
    public Function ST_Disjoint(Value geom1, Value geom2) {
1230
        return function("ST_Disjoint", config.getString(Config.ST_Disjoint), geom1, geom2);
1231
    }
1232

    
1233
    @Override
1234
    public Function ST_Contains(Value geom1, Value geom2) {
1235
        return function("ST_Contains", config.getString(Config.ST_Contains), geom1, geom2);
1236
    }
1237

    
1238
    @Override
1239
    public Function ST_Equals(Value geom1, Value geom2) {
1240
        return function("ST_Equals", config.getString(Config.ST_Equals), geom1, geom2);
1241
    }
1242

    
1243
    @Override
1244
    public Function ST_Crosses(Value geom1, Value geom2) {
1245
        return function("ST_Crosses", config.getString(Config.ST_Crosses), geom1, geom2);
1246
    }
1247

    
1248
    @Override
1249
    public Function ST_IsClosed(Value geom) {
1250
        return function("ST_IsClosed", config.getString(Config.ST_IsClosed), geom);
1251
    }
1252

    
1253
    @Override
1254
    public Function ST_Overlaps(Value geom1, Value geom2) {
1255
        return function("ST_Overlaps", config.getString(Config.ST_Overlaps), geom1, geom2);
1256
    }
1257

    
1258
    @Override
1259
    public Function ST_Touches(Value geom1, Value geom2) {
1260
        return function("ST_Touches", config.getString(Config.ST_Touches), geom1, geom2);
1261
    }
1262

    
1263
    @Override
1264
    public Function ST_Within(Value geom1, Value geom2) {
1265
        return function("ST_Within", config.getString(Config.ST_Within), geom1, geom2);
1266
    }
1267

    
1268
    @Override
1269
    public Function isNull(Value value) {
1270
        return function("IS NULL", config.getString(Config.isNull), value);
1271
    }
1272

    
1273
    @Override
1274
    public Function notIsNull(Value value) {
1275
        return function("NOT IS NULL", config.getString(Config.notIsNull), value);
1276
    }
1277

    
1278
    @Override
1279
    public Function not(Value value) {
1280
        return function("NOT", config.getString(Config.operator_not), value);
1281
    }
1282

    
1283
    @Override
1284
    public Function lcase(Value s) {
1285
        return function("LCASE", config.getString(Config.lcase), s);
1286
    }
1287

    
1288
    @Override
1289
    public Function ucase(Value s) {
1290
        return function("UCASE", config.getString(Config.ucase), s);
1291
    }
1292

    
1293
    @Override
1294
    public BinaryOperator and(Value leftOperand, Value rightOperand) {
1295
        return binaryOperator("AND", config.getString(Config.operator_AND), leftOperand, rightOperand);
1296
    }
1297

    
1298
    @Override
1299
    public BinaryOperator or(Value leftOperand, Value rightOperand) {
1300
        return binaryOperator("OR", config.getString(Config.operator_OR), leftOperand, rightOperand);
1301
    }
1302

    
1303
    @Override
1304
    public BinaryOperator eq(Value leftOperand, Value rightOperand) {
1305
        return binaryOperator("=", config.getString(Config.operator_EQ), leftOperand, rightOperand);
1306
    }
1307

    
1308
    @Override
1309
    public BinaryOperator ne(Value leftOperand, Value rightOperand) {
1310
        return binaryOperator("<>", config.getString(Config.operator_NE), leftOperand, rightOperand);
1311
    }
1312

    
1313
    @Override
1314
    public BinaryOperator gt(Value op1, Value op2) {
1315
        return binaryOperator(">", config.getString(Config.operator_GT), op1, op2);
1316
    }
1317

    
1318
    @Override
1319
    public BinaryOperator ge(Value op1, Value op2) {
1320
        return binaryOperator(">=", config.getString(Config.operator_GE), op1, op2);
1321
    }
1322

    
1323
    @Override
1324
    public BinaryOperator lt(Value op1, Value op2) {
1325
        return binaryOperator("<", config.getString(Config.operator_LT), op1, op2);
1326
    }
1327

    
1328
    @Override
1329
    public BinaryOperator le(Value op1, Value op2) {
1330
        return binaryOperator("<=", config.getString(Config.operator_LE), op1, op2);
1331
    }
1332

    
1333
    @Override
1334
    public BinaryOperator like(Value op1, Value op2) {
1335
        return binaryOperator("LIKE", config.getString(Config.operator_LIKE), op1, op2);
1336
    }
1337

    
1338
    @Override
1339
    public BinaryOperator ilike(Value op1, Value op2) {
1340
        return binaryOperator("ILIKE", config.getString(Config.operator_ILIKE), op1, op2);
1341
    }
1342

    
1343
    @Override
1344
    public BinaryOperator add(Value op1, Value op2) {
1345
        return binaryOperator("ADD", config.getString(Config.operator_add), op1, op2);
1346
    }
1347

    
1348
    @Override
1349
    public BinaryOperator subst(Value op1, Value op2) {
1350
        return binaryOperator("SUBST", config.getString(Config.operator_subst), op1, op2);
1351
    }
1352

    
1353
    @Override
1354
    public BinaryOperator mult(Value op1, Value op2) {
1355
        return binaryOperator("MULT", config.getString(Config.operator_mult), op1, op2);
1356
    }
1357

    
1358
    @Override
1359
    public BinaryOperator div(Value op1, Value op2) {
1360
        return binaryOperator("DIV", config.getString(Config.operator_div), op1, op2);
1361
    }
1362

    
1363
    @Override
1364
    public BinaryOperator concat(Value op1, Value op2) {
1365
        return binaryOperator("CONCAT", config.getString(Config.operator_concat), op1, op2);
1366
    }
1367

    
1368
}